mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-08 17:33:01 +00:00
Compare commits
54 Commits
v1.80pr1.1
...
v1.12.2-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2bfaafe28 | ||
|
|
1fb3d16b89 | ||
|
|
35645b3d93 | ||
|
|
a4cd1fe77d | ||
|
|
4145914024 | ||
|
|
6bd11a5e4a | ||
|
|
46fa798797 | ||
|
|
70a226207e | ||
|
|
257a35f3ed | ||
|
|
af01b9514b | ||
|
|
070fd1f2ff | ||
|
|
fb59da2b06 | ||
|
|
11e4d0de82 | ||
|
|
e46ab1e267 | ||
|
|
d6e0f368df | ||
|
|
9f2884bc0f | ||
|
|
18d468e887 | ||
|
|
63f6735bb8 | ||
|
|
ab6f0ccd16 | ||
|
|
ae0f093e73 | ||
|
|
e5f988e3fe | ||
|
|
12e82afad2 | ||
|
|
6c2db93cbd | ||
|
|
d5edbe700b | ||
|
|
86ad43c3ab | ||
|
|
f450c0156b | ||
|
|
8abcfcb4ac | ||
|
|
f3cace1d03 | ||
|
|
e1e5e898ab | ||
|
|
3aa3852ff6 | ||
|
|
709a6329c7 | ||
|
|
c9f05a2939 | ||
|
|
e41377f862 | ||
|
|
d173787a94 | ||
|
|
d5aea26f3a | ||
|
|
2681e578c4 | ||
|
|
1f498dcc73 | ||
|
|
83b01d35eb | ||
|
|
8a7e651c99 | ||
|
|
80a5759bae | ||
|
|
e8a4fbb4e3 | ||
|
|
0ce67afcc1 | ||
|
|
a8dad23fa3 | ||
|
|
443e0f8f76 | ||
|
|
a838595e1e | ||
|
|
61daab910e | ||
|
|
7fd19c43e9 | ||
|
|
ce0685c31f | ||
|
|
e33f852baa | ||
|
|
227d5e9e69 | ||
|
|
1c648850ab | ||
|
|
63691707fc | ||
|
|
5d97b9c8f3 | ||
|
|
77666d7399 |
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -6,11 +6,10 @@ about: Report some misbehaviour in the mod
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
## Before reporting
|
## Before reporting
|
||||||
- Search for the bug both here and [on the ComputerCraft issues page](https://github.com/dan200/ComputerCraft/issues?utf8=%E2%9C%93&q=is%3Aissue+)
|
- Search for the bug on the issue tracker. Make sure to look at closed issues too!
|
||||||
- If possible, try to reproduce on vanilla ComputerCraft. If it still occurs, [report on the ComputerCraft repo](https://github.com/dan200/ComputerCraft/issues/new) instead.
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Useful information to include:
|
## Useful information to include:
|
||||||
- Minecraft version
|
- Minecraft version
|
||||||
- CC: Tweaked version
|
- CC: Tweaked version
|
||||||
- Detailed reproduction steps!** Sometimes I can spot a bug pretty easily, but often it's much more obscure. Anything you can give which will help reproduce it means it'll get fixed quicker.
|
- Detailed reproduction steps: sometimes I can spot a bug pretty easily, but often it's much more obscure. The more information I have to help reproduce it, the quicker it'll get fixed.
|
||||||
|
|||||||
7
.github/ISSUE_TEMPLATE/feature_request.md
vendored
7
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -6,10 +6,9 @@ about: Suggest an idea or improvement
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
## Before reporting
|
## Before reporting
|
||||||
- Search for the suggestion both here and [on the ComputerCraft issues page](https://github.com/dan200/ComputerCraft/issues?utf8=%E2%9C%93&q=is%3Aissue+). It's possible someone's suggested it before!
|
- Search for the suggestion here. It's possible someone's suggested it before!
|
||||||
- Unless something is specific to CC:Tweaked, try to [suggest them on the ComputerCraft repo](https://github.com/dan200/ComputerCraft/issues/new). There's a lot more people watching it, so it allows the wider community to contribute.
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Useful information to include:
|
## Useful information to include:
|
||||||
- Explanation of how the feature/change chould work.
|
- Explanation of how the feature/change should work.
|
||||||
- Some rationale/use case for a feature. I'd like to keep CC:T as minimal
|
- Some rationale/use case for a feature. I'd like to keep CC:T as minimal as possible, so I like have a solid justification for each feature.
|
||||||
|
|||||||
9
.github/pull_request_template.md
vendored
9
.github/pull_request_template.md
vendored
@@ -1,9 +0,0 @@
|
|||||||
<!--
|
|
||||||
Unless this feature is specific to CC:Tweaked, try to [target the original ComputerCraft repo](https://github.com/dan200/ComputerCraft/) instead. There's a lot more people watching it, so it allows the wider community to contribute.
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Useful information to include:
|
|
||||||
- Brief explanation of the changes you've made.
|
|
||||||
- Rationale of why this change has been made/reasoning behind it.
|
|
||||||
|
|
||||||
The more information you can provide, the easier it is to review something now _and_ to see why a change was made, when the code needs updating in the future.
|
|
||||||
19
LICENSE-luaj
19
LICENSE-luaj
@@ -1,19 +0,0 @@
|
|||||||
Copyright (c) 2007 LuaJ. All rights reserved.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
50
README.md
50
README.md
@@ -1,35 +1,35 @@
|
|||||||
# 
|
# 
|
||||||
[](https://travis-ci.org/SquidDev-CC/CC-Tweaked)
|
[](https://travis-ci.org/SquidDev-CC/CC-Tweaked)
|
||||||
|
|
||||||
CC: Tweaked is a fork of ComputerCraft which aims to provide earlier access to the more experimental and in-development
|
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
|
||||||
features of the mod. For a more stable experience, I recommend checking out the
|
turtles and more to Minecraft.
|
||||||
[original mod](https://github.com/dan200/ComputerCraft).
|
|
||||||
|
|
||||||
## What?
|
## What?
|
||||||
CC: Tweaked (or CC:T for short) does not aim to create a competing fork of ComputerCraft, nor am I planning to take it
|
ComputerCraft has always held a fond place in my heart: it's the mod which really got me into Minecraft, and it's the
|
||||||
in in a vastly different direction to the original mod. In fact, CC:T aims to be a nurturing ground for various
|
mod which has kept me playing it for many years. However, development of the original mod has slowed, as the original
|
||||||
features, with a pull request against the original mod being the end goal.
|
developers have had less time to work on the mod, and moved onto other projects and commitments.
|
||||||
|
|
||||||
CC:T also includes many pull requests from the community which have not yet been merged, offering a large number
|
CC:Tweaked (or CC:T for short) is an attempt to continue ComputerCraft's legacy. It's not intended to be a competitor
|
||||||
of additional bug fixes and features over the original mod.
|
to CC, nor do I want to take it in a vastly different direction to the original mod. Instead, CC:T focuses on making the
|
||||||
|
ComputerCraft experience as _solid_ as possible, ironing out any wrinkles that may have developed over time.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
CC: Tweaked contains all the features of the latest alpha, as well as numerous fixes, performance improvements and
|
CC: Tweaked contains all the features of the latest version of ComputerCraft, as well as numerous fixes, performance
|
||||||
several additional features. I'd recommend checking out [the releases page](https://github.com/SquidDev-CC/CC-Tweaked/releases)
|
improvements and several nifty additions. I'd recommend checking out [the releases page](https://github.com/SquidDev-CC/CC-Tweaked/releases)
|
||||||
to see the full changes, but here's a couple of the more interesting changes:
|
to see the full set of changes, but here's a couple of the more interesting additions:
|
||||||
|
|
||||||
- Replace LuaJ with Cobalt.
|
- Improvements to the `http` library, including websockets, support for other HTTP methods (`PUT`, `DELETE`, etc...)
|
||||||
- Allow running multiple computers at the same time.
|
and configurable limits on HTTP usage.
|
||||||
- Websocket support in the HTTP library.
|
- Full-block wired modems, allowing one to wrap non-solid peripherals (such as turtles, or chests if Plethora is
|
||||||
- Wired modems and cables act more like multiparts.
|
|
||||||
- Add map-like rendering for pocket computers and printed pages/books.
|
|
||||||
- Adds the `/computercraft` command, offering various diagnostic tools for server owners. This allows operators to
|
|
||||||
track which computers are hogging resources, turn on and shutdown multiple computers at once and interact with
|
|
||||||
computers remotely.
|
|
||||||
- Add full-block wired modems, allowing one to wrap non-solid peripherals (such as turtles, or chests if Plethora is
|
|
||||||
installed).
|
installed).
|
||||||
- Extended binary file handles. They support file seeking, and reading new lines, allowing full (and accurate)
|
- Pocket computers can be held like maps, allowing you to view the screen without entering a GUI.
|
||||||
emulation of the standard Lua `io` library.
|
- Printed pages and books can be placed in item frames and held like maps.
|
||||||
|
- Several profiling and administration tools for server owners, via the `/computercraft` command. This allows operators
|
||||||
|
to track which computers are hogging resources, turn on and shutdown multiple computers at once and interact with
|
||||||
|
computers remotely.
|
||||||
|
- Closer emulation of standard Lua, adding the `debug` and `io` libraries. This also enables seeking within binary
|
||||||
|
files, meaning you don't need to read large files into memory.
|
||||||
|
- Allow running multiple computers on multiple threads, reducing latency on worlds with many computers.
|
||||||
|
|
||||||
## Relation to CCTweaks?
|
## Relation to CCTweaks?
|
||||||
This mod has nothing to do with CCTweaks, though there is no denying the name is a throwback to it. That being said,
|
This mod has nothing to do with CCTweaks, though there is no denying the name is a throwback to it. That being said,
|
||||||
@@ -37,10 +37,8 @@ several features have been included, such as full block modems, the Cobalt runti
|
|||||||
computers.
|
computers.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. If you do wish to contribute
|
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. In order to start helping
|
||||||
code, do consider submitting it to the ComputerCraft repository first.
|
develop CC:T, you'll need to follow these steps:
|
||||||
|
|
||||||
That being said, in order to start helping 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`
|
- **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
|
||||||
- **Setup Forge:** `./gradlew setupDecompWorkspace`
|
- **Setup Forge:** `./gradlew setupDecompWorkspace`
|
||||||
|
|||||||
146
build.gradle
146
build.gradle
@@ -9,8 +9,10 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
|
classpath 'com.google.code.gson:gson:2.8.1'
|
||||||
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||||
classpath 'org.ajoberstar:gradle-git:1.6.0'
|
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta1'
|
||||||
|
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,14 +25,17 @@ apply plugin: 'org.ajoberstar.grgit'
|
|||||||
apply plugin: 'maven-publish'
|
apply plugin: 'maven-publish'
|
||||||
apply plugin: 'maven'
|
apply plugin: 'maven'
|
||||||
|
|
||||||
version = "1.80pr1.13"
|
def mc_version = "1.12.2"
|
||||||
|
def main_version = "1.81.1"
|
||||||
|
version = "${mc_version}-${main_version}"
|
||||||
|
|
||||||
group = "org.squiddev"
|
group = "org.squiddev"
|
||||||
archivesBaseName = "cc-tweaked"
|
archivesBaseName = "cc-tweaked"
|
||||||
|
|
||||||
minecraft {
|
minecraft {
|
||||||
version = "1.12.2-14.23.4.2749"
|
version = "${mc_version}-14.23.4.2749"
|
||||||
runDir = "run"
|
runDir = "run"
|
||||||
replace '${version}', project.version
|
replace '${version}', main_version
|
||||||
|
|
||||||
// the mappings can be changed at any time, and must be in the following format.
|
// the mappings can be changed at any time, and must be in the following format.
|
||||||
// snapshot_YYYYMMDD snapshot are built nightly.
|
// snapshot_YYYYMMDD snapshot are built nightly.
|
||||||
@@ -48,7 +53,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
name = "squiddev"
|
name = "squiddev"
|
||||||
url = "https://dl.bintray.com/squiddev/maven"
|
url = "https://squiddev.cc/maven"
|
||||||
}
|
}
|
||||||
|
|
||||||
ivy { artifactPattern "https://asie.pl/files/mods/Charset/LibOnly/[module]-[revision](-[classifier]).[ext]" }
|
ivy { artifactPattern "https://asie.pl/files/mods/Charset/LibOnly/[module]-[revision](-[classifier]).[ext]" }
|
||||||
@@ -66,7 +71,7 @@ dependencies {
|
|||||||
|
|
||||||
runtime "mezz.jei:jei_1.12.2:4.8.5.159"
|
runtime "mezz.jei:jei_1.12.2:4.8.5.159"
|
||||||
|
|
||||||
shade 'org.squiddev:Cobalt:0.4.0'
|
shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT'
|
||||||
|
|
||||||
testCompile 'junit:junit:4.11'
|
testCompile 'junit:junit:4.11'
|
||||||
|
|
||||||
@@ -84,39 +89,91 @@ jar {
|
|||||||
attributes('FMLAT': 'computercraft_at.cfg')
|
attributes('FMLAT': 'computercraft_at.cfg')
|
||||||
}
|
}
|
||||||
|
|
||||||
into("docs", { from (javadoc.destinationDir) })
|
from (sourceSets.main.allSource) {
|
||||||
|
|
||||||
into("api", { from (sourceSets.main.allSource) {
|
|
||||||
include "dan200/computercraft/api/**/*.java"
|
include "dan200/computercraft/api/**/*.java"
|
||||||
}})
|
}
|
||||||
|
|
||||||
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
|
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.nio.file.*
|
||||||
|
import java.util.zip.*
|
||||||
|
|
||||||
|
import com.google.gson.GsonBuilder
|
||||||
|
import com.google.gson.JsonElement
|
||||||
import org.ajoberstar.grgit.Grgit
|
import org.ajoberstar.grgit.Grgit
|
||||||
|
import proguard.gradle.ProGuardTask
|
||||||
|
|
||||||
|
task proguard(type: ProGuardTask, dependsOn: jar) {
|
||||||
|
description "Removes unused shadowed classes from the jar"
|
||||||
|
group "compact"
|
||||||
|
|
||||||
|
injars jar.archivePath
|
||||||
|
outjars "${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar"
|
||||||
|
|
||||||
|
// Add the main runtime jar and all non-shadowed dependencies
|
||||||
|
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
|
||||||
|
doFirst {
|
||||||
|
sourceSets.main.compileClasspath
|
||||||
|
.filter { !it.name.contains("Cobalt") }
|
||||||
|
.each { libraryjars it }
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want to avoid as much obfuscation as possible. We're only doing this to shrink code size.
|
||||||
|
dontobfuscate; dontoptimize; keepattributes; keepparameternames
|
||||||
|
|
||||||
|
// Proguard will remove directories by default, but that breaks JarMount.
|
||||||
|
keepdirectories 'assets/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>(...); }'
|
||||||
|
}
|
||||||
|
|
||||||
|
task proguardMove(dependsOn: proguard) {
|
||||||
|
description "Replace the original jar with the minified version"
|
||||||
|
group "compact"
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
Files.move(
|
||||||
|
file("${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar").toPath(),
|
||||||
|
file(jar.archivePath).toPath(),
|
||||||
|
StandardCopyOption.REPLACE_EXISTING
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reobfJar.dependsOn proguardMove
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
inputs.property "version", project.version
|
inputs.property "version", main_version
|
||||||
inputs.property "mcversion", project.minecraft.version
|
inputs.property "mcversion", mc_version
|
||||||
|
|
||||||
def grgit = Grgit.open(dir: '.')
|
def hash = 'none'
|
||||||
inputs.property "commithash", grgit.head().id
|
|
||||||
|
|
||||||
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
|
|
||||||
Set<String> contributors = []
|
Set<String> contributors = []
|
||||||
|
try {
|
||||||
|
def grgit = Grgit.open(dir: '.')
|
||||||
|
hash = grgit.head().id
|
||||||
|
|
||||||
grgit.log().each {
|
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
|
||||||
if (!blacklist.contains(it.author.name)) contributors.add(it.author.name)
|
grgit.log().each {
|
||||||
if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
|
if (!blacklist.contains(it.author.name)) contributors.add(it.author.name)
|
||||||
}
|
if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
|
||||||
|
}
|
||||||
|
} catch(Exception ignored) { }
|
||||||
|
|
||||||
|
inputs.property "commithash", hash
|
||||||
|
|
||||||
from(sourceSets.main.resources.srcDirs) {
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
include 'mcmod.info'
|
include 'mcmod.info'
|
||||||
include 'assets/computercraft/lua/rom/help/credits.txt'
|
include 'assets/computercraft/lua/rom/help/credits.txt'
|
||||||
|
|
||||||
expand 'version':project.version,
|
expand 'version': main_version,
|
||||||
'mcversion':project.minecraft.version,
|
'mcversion': mc_version,
|
||||||
'gitcontributors':contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
|
'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
from(sourceSets.main.resources.srcDirs) {
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
@@ -125,12 +182,53 @@ processResources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task compressJson(dependsOn: extractAnnotationsJar) {
|
||||||
|
group "compact"
|
||||||
|
description "Minifies all JSON files, stripping whitespace"
|
||||||
|
|
||||||
|
def jarPath = file(jar.archivePath)
|
||||||
|
|
||||||
|
def tempPath = File.createTempFile("input", ".jar", temporaryDir)
|
||||||
|
tempPath.deleteOnExit()
|
||||||
|
|
||||||
|
def gson = new GsonBuilder().create()
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
// Copy over all files in the current jar to the new one, running json files from GSON. As pretty printing
|
||||||
|
// is turned off, they should be minified.
|
||||||
|
new ZipFile(jarPath).withCloseable { inJar ->
|
||||||
|
new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tempPath))).withCloseable { outJar ->
|
||||||
|
inJar.entries().each { entry ->
|
||||||
|
if(entry.directory) {
|
||||||
|
outJar.putNextEntry(entry)
|
||||||
|
} else if(!entry.name.endsWith(".json")) {
|
||||||
|
outJar.putNextEntry(entry)
|
||||||
|
inJar.getInputStream(entry).withCloseable { outJar << it }
|
||||||
|
} else {
|
||||||
|
ZipEntry newEntry = new ZipEntry(entry.name)
|
||||||
|
newEntry.setTime(entry.time)
|
||||||
|
outJar.putNextEntry(newEntry)
|
||||||
|
|
||||||
|
def element = inJar.getInputStream(entry).withCloseable { gson.fromJson(it.newReader("UTF8"), JsonElement.class) }
|
||||||
|
outJar.write(gson.toJson(element).getBytes(StandardCharsets.UTF_8))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// And replace the original jar again
|
||||||
|
Files.move(tempPath.toPath(), jarPath.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assemble.dependsOn compressJson
|
||||||
|
|
||||||
curseforge {
|
curseforge {
|
||||||
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
|
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
|
||||||
project {
|
project {
|
||||||
id = '282001'
|
id = '282001'
|
||||||
releaseType = 'beta'
|
releaseType = 'release'
|
||||||
changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${project.version})."
|
changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${project.version})."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import dan200.computercraft.core.apis.ApiFactories;
|
|||||||
import dan200.computercraft.core.apis.http.websocket.Websocket;
|
import dan200.computercraft.core.apis.http.websocket.Websocket;
|
||||||
import dan200.computercraft.core.filesystem.ComboMount;
|
import dan200.computercraft.core.filesystem.ComboMount;
|
||||||
import dan200.computercraft.core.filesystem.FileMount;
|
import dan200.computercraft.core.filesystem.FileMount;
|
||||||
import dan200.computercraft.core.filesystem.FileSystemMount;
|
import dan200.computercraft.core.filesystem.JarMount;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.core.tracking.Tracking;
|
import dan200.computercraft.core.tracking.Tracking;
|
||||||
import dan200.computercraft.shared.*;
|
import dan200.computercraft.shared.*;
|
||||||
@@ -37,15 +37,21 @@ import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
|
|||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
|
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.ItemDiskExpanded;
|
||||||
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
|
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
|
||||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||||
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
|
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
|
||||||
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
|
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
|
||||||
|
import dan200.computercraft.shared.peripheral.common.ItemPeripheral;
|
||||||
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
||||||
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
|
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
|
||||||
import dan200.computercraft.shared.peripheral.modem.wired.BlockWiredModemFull;
|
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.BlockAdvancedModem;
|
||||||
|
import dan200.computercraft.shared.peripheral.modem.wireless.ItemAdvancedModem;
|
||||||
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
|
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
|
||||||
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||||
@@ -55,6 +61,9 @@ import dan200.computercraft.shared.proxy.ICCTurtleProxy;
|
|||||||
import dan200.computercraft.shared.proxy.IComputerCraftProxy;
|
import dan200.computercraft.shared.proxy.IComputerCraftProxy;
|
||||||
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
|
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
|
||||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||||
|
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.upgrades.*;
|
import dan200.computercraft.shared.turtle.upgrades.*;
|
||||||
import dan200.computercraft.shared.util.CreativeTabMain;
|
import dan200.computercraft.shared.util.CreativeTabMain;
|
||||||
import dan200.computercraft.shared.util.IDAssigner;
|
import dan200.computercraft.shared.util.IDAssigner;
|
||||||
@@ -62,7 +71,7 @@ import dan200.computercraft.shared.util.IoUtil;
|
|||||||
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
||||||
import dan200.computercraft.shared.wired.WiredNode;
|
import dan200.computercraft.shared.wired.WiredNode;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.item.ItemBlock;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
@@ -71,13 +80,11 @@ import net.minecraft.util.EnumHand;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.DimensionManager;
|
||||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.SidedProxy;
|
import net.minecraftforge.fml.common.SidedProxy;
|
||||||
import net.minecraftforge.fml.common.event.*;
|
import net.minecraftforge.fml.common.event.*;
|
||||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
@@ -85,13 +92,9 @@ import java.io.*;
|
|||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.FileSystem;
|
|
||||||
import java.nio.file.FileSystems;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ServiceConfigurationError;
|
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
@@ -172,51 +175,74 @@ public class ComputerCraft
|
|||||||
public static class Blocks
|
public static class Blocks
|
||||||
{
|
{
|
||||||
public static BlockComputer computer;
|
public static BlockComputer computer;
|
||||||
public static BlockPeripheral peripheral;
|
public static BlockCommandComputer commandComputer;
|
||||||
public static BlockCable cable;
|
|
||||||
public static BlockTurtle turtle;
|
public static BlockTurtle turtle;
|
||||||
public static BlockTurtle turtleExpanded;
|
public static BlockTurtle turtleExpanded;
|
||||||
public static BlockTurtle turtleAdvanced;
|
public static BlockTurtle turtleAdvanced;
|
||||||
public static BlockCommandComputer commandComputer;
|
|
||||||
|
public static BlockPeripheral peripheral;
|
||||||
|
public static BlockCable cable;
|
||||||
public static BlockAdvancedModem advancedModem;
|
public static BlockAdvancedModem advancedModem;
|
||||||
public static BlockWiredModemFull wiredModemFull;
|
public static BlockWiredModemFull wiredModemFull;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Items
|
public static class Items
|
||||||
{
|
{
|
||||||
|
public static ItemComputer computer;
|
||||||
|
public static ItemCommandComputer commandComputer;
|
||||||
|
|
||||||
|
public static ItemTurtleLegacy turtle;
|
||||||
|
public static ItemTurtleNormal turtleExpanded;
|
||||||
|
public static ItemTurtleAdvanced turtleAdvanced;
|
||||||
|
|
||||||
|
public static ItemPocketComputer pocketComputer;
|
||||||
|
|
||||||
public static ItemDiskLegacy disk;
|
public static ItemDiskLegacy disk;
|
||||||
public static ItemDiskExpanded diskExpanded;
|
public static ItemDiskExpanded diskExpanded;
|
||||||
public static ItemPrintout printout;
|
|
||||||
public static ItemTreasureDisk treasureDisk;
|
public static ItemTreasureDisk treasureDisk;
|
||||||
public static ItemPocketComputer pocketComputer;
|
|
||||||
|
public static ItemPrintout printout;
|
||||||
|
|
||||||
|
public static ItemPeripheral peripheral;
|
||||||
|
public static ItemAdvancedModem advancedModem;
|
||||||
|
public static ItemCable cable;
|
||||||
|
public static ItemBlock wiredModemFull;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Upgrades
|
public static class TurtleUpgrades
|
||||||
{
|
{
|
||||||
public static TurtleModem wirelessModem;
|
public static TurtleModem wirelessModem;
|
||||||
|
public static TurtleModem advancedModem;
|
||||||
|
public static TurtleSpeaker speaker;
|
||||||
|
|
||||||
public static TurtleCraftingTable craftingTable;
|
public static TurtleCraftingTable craftingTable;
|
||||||
public static TurtleSword diamondSword;
|
public static TurtleSword diamondSword;
|
||||||
public static TurtleShovel diamondShovel;
|
public static TurtleShovel diamondShovel;
|
||||||
public static TurtleTool diamondPickaxe;
|
public static TurtleTool diamondPickaxe;
|
||||||
public static TurtleAxe diamondAxe;
|
public static TurtleAxe diamondAxe;
|
||||||
public static TurtleHoe diamondHoe;
|
public static TurtleHoe diamondHoe;
|
||||||
public static TurtleModem advancedModem;
|
|
||||||
public static TurtleSpeaker turtleSpeaker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PocketUpgrades
|
public static class PocketUpgrades
|
||||||
{
|
{
|
||||||
public static PocketModem wirelessModem;
|
public static PocketModem wirelessModem;
|
||||||
public static PocketModem advancedModem;
|
public static PocketModem advancedModem;
|
||||||
|
public static PocketSpeaker speaker;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static PocketSpeaker pocketSpeaker;
|
public static PocketSpeaker pocketSpeaker;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registries
|
@Deprecated
|
||||||
public static ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry();
|
public static class Upgrades
|
||||||
public static ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();
|
{
|
||||||
|
public static TurtleModem advancedModem;
|
||||||
|
}
|
||||||
|
|
||||||
// Networking
|
// Registries
|
||||||
public static SimpleNetworkWrapper networkWrapper;
|
public static final ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry();
|
||||||
|
public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();
|
||||||
|
|
||||||
// Creative
|
// Creative
|
||||||
public static CreativeTabMain mainCreativeTab;
|
public static CreativeTabMain mainCreativeTab;
|
||||||
@@ -231,11 +257,17 @@ public class ComputerCraft
|
|||||||
@Mod.Instance( value = ComputerCraft.MOD_ID )
|
@Mod.Instance( value = ComputerCraft.MOD_ID )
|
||||||
public static ComputerCraft instance;
|
public static ComputerCraft instance;
|
||||||
|
|
||||||
@SidedProxy( clientSide = "dan200.computercraft.client.proxy.ComputerCraftProxyClient", serverSide = "dan200.computercraft.server.proxy.ComputerCraftProxyServer" )
|
@SidedProxy(
|
||||||
public static IComputerCraftProxy proxy;
|
clientSide = "dan200.computercraft.client.proxy.ComputerCraftProxyClient",
|
||||||
|
serverSide = "dan200.computercraft.shared.proxy.ComputerCraftProxyCommon"
|
||||||
|
)
|
||||||
|
private static IComputerCraftProxy proxy;
|
||||||
|
|
||||||
@SidedProxy( clientSide = "dan200.computercraft.client.proxy.CCTurtleProxyClient", serverSide = "dan200.computercraft.server.proxy.CCTurtleProxyServer" )
|
@SidedProxy(
|
||||||
public static ICCTurtleProxy turtleProxy;
|
clientSide = "dan200.computercraft.client.proxy.CCTurtleProxyClient",
|
||||||
|
serverSide = "dan200.computercraft.shared.proxy.CCTurtleProxyCommon"
|
||||||
|
)
|
||||||
|
private static ICCTurtleProxy turtleProxy;
|
||||||
|
|
||||||
@Mod.EventHandler
|
@Mod.EventHandler
|
||||||
public void preInit( FMLPreInitializationEvent event )
|
public void preInit( FMLPreInitializationEvent event )
|
||||||
@@ -246,7 +278,7 @@ public class ComputerCraft
|
|||||||
Config.load( event.getSuggestedConfigurationFile() );
|
Config.load( event.getSuggestedConfigurationFile() );
|
||||||
|
|
||||||
// Setup network
|
// Setup network
|
||||||
networkWrapper = NetworkRegistry.INSTANCE.newSimpleChannel( ComputerCraft.MOD_ID );
|
NetworkHandler.setup();
|
||||||
|
|
||||||
proxy.preInit();
|
proxy.preInit();
|
||||||
turtleProxy.preInit();
|
turtleProxy.preInit();
|
||||||
@@ -354,31 +386,6 @@ public class ComputerCraft
|
|||||||
return new File( getBaseDir(), "resourcepacks" );
|
return new File( getBaseDir(), "resourcepacks" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getWorldDir( World world )
|
|
||||||
{
|
|
||||||
return proxy.getWorldDir( world );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendToPlayer( EntityPlayer player, IMessage packet )
|
|
||||||
{
|
|
||||||
networkWrapper.sendTo( packet, (EntityPlayerMP) player );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendToAllPlayers( IMessage packet )
|
|
||||||
{
|
|
||||||
networkWrapper.sendToAll( packet );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendToServer( IMessage packet )
|
|
||||||
{
|
|
||||||
networkWrapper.sendToServer( packet );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendToAllAround( IMessage packet, NetworkRegistry.TargetPoint point )
|
|
||||||
{
|
|
||||||
networkWrapper.sendToAllAround( packet, point );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean canPlayerUseCommands( EntityPlayer player )
|
public static boolean canPlayerUseCommands( EntityPlayer player )
|
||||||
{
|
{
|
||||||
MinecraftServer server = player.getServer();
|
MinecraftServer server = player.getServer();
|
||||||
@@ -455,7 +462,7 @@ public class ComputerCraft
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
|
public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
|
||||||
{
|
{
|
||||||
return IDAssigner.getNextIDFromDirectory( new File( getWorldDir( world ), parentSubPath ) );
|
return IDAssigner.getNextIDFromDirectory( parentSubPath );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@@ -463,7 +470,7 @@ public class ComputerCraft
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new FileMount( new File( getWorldDir( world ), subPath ), capacity );
|
return new FileMount( new File( getWorldDir(), subPath ), capacity );
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
@@ -496,13 +503,11 @@ public class ComputerCraft
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FileSystem fs = FileSystems.newFileSystem( modJar.toPath(), ComputerCraft.class.getClassLoader() );
|
mounts.add( new JarMount( modJar, subPath ) );
|
||||||
mounts.add( new FileSystemMount( fs, subPath ) );
|
|
||||||
}
|
}
|
||||||
catch( IOException | RuntimeException | ServiceConfigurationError e )
|
catch( IOException | RuntimeException e )
|
||||||
{
|
{
|
||||||
ComputerCraft.log.error( "Could not load mount from mod jar", e );
|
ComputerCraft.log.error( "Could not load mount from mod jar", e );
|
||||||
// Ignore
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,21 +524,16 @@ public class ComputerCraft
|
|||||||
if( !resourcePack.isDirectory() )
|
if( !resourcePack.isDirectory() )
|
||||||
{
|
{
|
||||||
// Mount a resource pack from a jar
|
// Mount a resource pack from a jar
|
||||||
FileSystem fs = FileSystems.newFileSystem( resourcePack.toPath(), ComputerCraft.class.getClassLoader() );
|
mounts.add( new JarMount( resourcePack, subPath ) );
|
||||||
if( Files.exists( fs.getPath( subPath ) ) ) mounts.add( new FileSystemMount( fs, subPath ) );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Mount a resource pack from a folder
|
// Mount a resource pack from a folder
|
||||||
File subResource = new File( resourcePack, subPath );
|
File subResource = new File( resourcePack, subPath );
|
||||||
if( subResource.exists() )
|
if( subResource.exists() ) mounts.add( new FileMount( subResource, 0 ) );
|
||||||
{
|
|
||||||
IMount resourcePackMount = new FileMount( subResource, 0 );
|
|
||||||
mounts.add( resourcePackMount );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( IOException | RuntimeException | ServiceConfigurationError e )
|
catch( IOException | RuntimeException e )
|
||||||
{
|
{
|
||||||
ComputerCraft.log.error( "Could not load resource pack '" + resourcePackName + "'", e );
|
ComputerCraft.log.error( "Could not load resource pack '" + resourcePackName + "'", e );
|
||||||
}
|
}
|
||||||
@@ -680,10 +680,21 @@ public class ComputerCraft
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static void registerTurtleUpgrade( ITurtleUpgrade upgrade )
|
public static void registerTurtleUpgrade( ITurtleUpgrade upgrade )
|
||||||
{
|
{
|
||||||
TurtleUpgrades.register( upgrade );
|
dan200.computercraft.shared.TurtleUpgrades.register( upgrade );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getWorldDir()
|
||||||
|
{
|
||||||
|
return DimensionManager.getCurrentSaveRootDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
//region Compatibility
|
//region Compatibility
|
||||||
|
@Deprecated
|
||||||
|
public static File getWorldDir( World world )
|
||||||
|
{
|
||||||
|
return DimensionManager.getCurrentSaveRootDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static IMedia getMedia( ItemStack stack )
|
public static IMedia getMedia( ItemStack stack )
|
||||||
{
|
{
|
||||||
@@ -699,7 +710,7 @@ public class ComputerCraft
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static ITurtleUpgrade getTurtleUpgrade( ItemStack stack )
|
public static ITurtleUpgrade getTurtleUpgrade( ItemStack stack )
|
||||||
{
|
{
|
||||||
return TurtleUpgrades.get( stack );
|
return dan200.computercraft.shared.TurtleUpgrades.get( stack );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@@ -711,7 +722,7 @@ public class ComputerCraft
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static ITurtleUpgrade getTurtleUpgrade( String id )
|
public static ITurtleUpgrade getTurtleUpgrade( String id )
|
||||||
{
|
{
|
||||||
return TurtleUpgrades.get( id );
|
return dan200.computercraft.shared.TurtleUpgrades.get( id );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|||||||
193
src/main/java/dan200/computercraft/client/ClientRegistry.java
Normal file
193
src/main/java/dan200/computercraft/client/ClientRegistry.java
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.client.render.TurtleModelLoader;
|
||||||
|
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
|
||||||
|
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.vertex.DefaultVertexFormats;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
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.ModelLoader;
|
||||||
|
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers textures and models for items.
|
||||||
|
*/
|
||||||
|
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
|
||||||
|
public class ClientRegistry
|
||||||
|
{
|
||||||
|
private static final String[] EXTRA_MODELS = {
|
||||||
|
"turtle_modem_off_left",
|
||||||
|
"turtle_modem_on_left",
|
||||||
|
"turtle_modem_off_right",
|
||||||
|
"turtle_modem_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_elf_overlay",
|
||||||
|
};
|
||||||
|
|
||||||
|
@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 )
|
||||||
|
{
|
||||||
|
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( "computercraft", "block/" + upgrade ) );
|
||||||
|
for( ResourceLocation texture : model.getTextures() ) map.registerSprite( texture );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onModelBakeEvent( ModelBakeEvent event )
|
||||||
|
{
|
||||||
|
// Load all extra models
|
||||||
|
for( String model : EXTRA_MODELS ) loadBlockModel( event, model );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onItemColours( ColorHandlerEvent.Item event )
|
||||||
|
{
|
||||||
|
event.getItemColors().registerItemColorHandler(
|
||||||
|
( stack, layer ) -> layer == 0 ? 0xFFFFFF : ((ItemDiskLegacy) stack.getItem()).getColour( stack ),
|
||||||
|
ComputerCraft.Items.disk, ComputerCraft.Items.diskExpanded
|
||||||
|
);
|
||||||
|
|
||||||
|
event.getItemColors().registerItemColorHandler( ( stack, layer ) -> {
|
||||||
|
switch( layer )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
return 0xFFFFFF;
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
// Frame colour
|
||||||
|
int colour = ComputerCraft.Items.pocketComputer.getColour( stack );
|
||||||
|
return colour == -1 ? 0xFFFFFF : colour;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
// Light colour
|
||||||
|
int colour = ComputerCraft.Items.pocketComputer.getLightState( stack );
|
||||||
|
return colour == -1 ? Colour.Black.getHex() : colour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, ComputerCraft.Items.pocketComputer );
|
||||||
|
|
||||||
|
// Setup turtle colours
|
||||||
|
event.getItemColors().registerItemColorHandler( ( stack, tintIndex ) -> {
|
||||||
|
if( tintIndex == 0 )
|
||||||
|
{
|
||||||
|
ItemTurtleBase turtle = (ItemTurtleBase) stack.getItem();
|
||||||
|
int colour = turtle.getColour( stack );
|
||||||
|
if( colour != -1 ) return colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0xFFFFFF;
|
||||||
|
}, ComputerCraft.Blocks.turtle, ComputerCraft.Blocks.turtleExpanded, ComputerCraft.Blocks.turtleAdvanced );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void registerItemModel( Item item, int damage, String name )
|
||||||
|
{
|
||||||
|
ResourceLocation location = new ResourceLocation( ComputerCraft.MOD_ID, name );
|
||||||
|
final ModelResourceLocation res = new ModelResourceLocation( location, "inventory" );
|
||||||
|
ModelBakery.registerItemVariants( item, location );
|
||||||
|
ModelLoader.setCustomModelResourceLocation( item, damage, res );
|
||||||
|
}
|
||||||
|
|
||||||
|
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() )
|
||||||
|
);
|
||||||
|
|
||||||
|
event.getModelRegistry().putObject( new ModelResourceLocation( ComputerCraft.MOD_ID + ":" + name, "inventory" ), bakedModel );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,12 +13,14 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
|||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.FontRenderer;
|
import net.minecraft.client.gui.FontRenderer;
|
||||||
import net.minecraft.client.gui.GuiNewChat;
|
import net.minecraft.client.gui.GuiNewChat;
|
||||||
|
import net.minecraft.client.gui.GuiUtilRenderComponents;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
import net.minecraft.util.text.TextFormatting;
|
import net.minecraft.util.text.TextFormatting;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ClientTableFormatter implements TableFormatter
|
public class ClientTableFormatter implements TableFormatter
|
||||||
{
|
{
|
||||||
@@ -62,7 +64,13 @@ public class ClientTableFormatter implements TableFormatter
|
|||||||
@Override
|
@Override
|
||||||
public void writeLine( int id, ITextComponent component )
|
public void writeLine( int id, ITextComponent component )
|
||||||
{
|
{
|
||||||
Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion( component, id );
|
Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
GuiNewChat 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 );
|
||||||
|
if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,43 +6,40 @@
|
|||||||
|
|
||||||
package dan200.computercraft.client;
|
package dan200.computercraft.client;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
|
||||||
public class FrameInfo
|
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
|
||||||
|
public final class FrameInfo
|
||||||
{
|
{
|
||||||
private static final FrameInfo instance = new FrameInfo();
|
private static int tick;
|
||||||
|
private static long renderFrame;
|
||||||
public static FrameInfo instance()
|
|
||||||
{
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int tick;
|
|
||||||
private long renderFrame;
|
|
||||||
|
|
||||||
private FrameInfo()
|
private FrameInfo()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getGlobalCursorBlink()
|
public static boolean getGlobalCursorBlink()
|
||||||
{
|
{
|
||||||
return (tick / 8) % 2 == 0;
|
return (tick / 8) % 2 == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getRenderFrame()
|
public static long getRenderFrame()
|
||||||
{
|
{
|
||||||
return renderFrame;
|
return renderFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onTick( TickEvent.ClientTickEvent event )
|
public static void onTick( TickEvent.ClientTickEvent event )
|
||||||
{
|
{
|
||||||
if( event.phase == TickEvent.Phase.START ) tick++;
|
if( event.phase == TickEvent.Phase.START ) tick++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onRenderTick( TickEvent.RenderTickEvent event )
|
public static void onRenderTick( TickEvent.RenderTickEvent event )
|
||||||
{
|
{
|
||||||
if( event.phase == TickEvent.Phase.START ) renderFrame++;
|
if( event.phase == TickEvent.Phase.START ) renderFrame++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ public class WidgetTerminal extends Widget
|
|||||||
// Get the data from the terminal first
|
// 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.
|
// Unfortunately we have to keep the lock for the whole of drawing, so the text doesn't change under us.
|
||||||
FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance();
|
FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance();
|
||||||
boolean tblink = m_focus && terminal.getCursorBlink() && FrameInfo.instance().getGlobalCursorBlink();
|
boolean tblink = m_focus && terminal.getCursorBlink() && FrameInfo.getGlobalCursorBlink();
|
||||||
int tw = terminal.getWidth();
|
int tw = terminal.getWidth();
|
||||||
int th = terminal.getHeight();
|
int th = terminal.getHeight();
|
||||||
int tx = terminal.getCursorX();
|
int tx = terminal.getCursorX();
|
||||||
|
|||||||
@@ -6,209 +6,19 @@
|
|||||||
|
|
||||||
package dan200.computercraft.client.proxy;
|
package dan200.computercraft.client.proxy;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
|
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
|
||||||
import dan200.computercraft.client.render.TurtleSmartItemModel;
|
|
||||||
import dan200.computercraft.shared.proxy.CCTurtleProxyCommon;
|
import dan200.computercraft.shared.proxy.CCTurtleProxyCommon;
|
||||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||||
import dan200.computercraft.shared.turtle.items.ItemTurtleBase;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
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.color.IItemColor;
|
|
||||||
import net.minecraft.client.renderer.texture.TextureMap;
|
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|
||||||
import net.minecraft.client.resources.IResourceManager;
|
|
||||||
import net.minecraft.client.resources.SimpleReloadableResourceManager;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
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.ModelLoader;
|
|
||||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
|
||||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
public class CCTurtleProxyClient extends CCTurtleProxyCommon
|
public class CCTurtleProxyClient extends CCTurtleProxyCommon
|
||||||
{
|
{
|
||||||
// IComputerCraftProxy implementation
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preInit()
|
|
||||||
{
|
|
||||||
super.preInit();
|
|
||||||
|
|
||||||
// Setup client forge handlers
|
|
||||||
registerForgeHandlers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public void registerModels( ModelRegistryEvent event )
|
|
||||||
{
|
|
||||||
// Register item models
|
|
||||||
ItemMeshDefinition turtleMeshDefinition = new ItemMeshDefinition()
|
|
||||||
{
|
|
||||||
private ModelResourceLocation turtle_dynamic = new ModelResourceLocation( "computercraft:turtle_dynamic", "inventory" );
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
|
|
||||||
{
|
|
||||||
return turtle_dynamic;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
String[] turtleModelNames = new String[] {
|
|
||||||
"turtle_dynamic",
|
|
||||||
"turtle", "turtle_advanced",
|
|
||||||
"turtle_white",
|
|
||||||
"turtle_elf_overlay"
|
|
||||||
};
|
|
||||||
registerItemModel( ComputerCraft.Blocks.turtle, turtleMeshDefinition, turtleModelNames );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.turtleExpanded, turtleMeshDefinition, turtleModelNames );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.turtleAdvanced, turtleMeshDefinition, turtleModelNames );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
super.init();
|
super.init();
|
||||||
|
|
||||||
// Setup turtle colours
|
|
||||||
Minecraft.getMinecraft().getItemColors().registerItemColorHandler(
|
|
||||||
new TurtleItemColour(),
|
|
||||||
ComputerCraft.Blocks.turtle, ComputerCraft.Blocks.turtleExpanded, ComputerCraft.Blocks.turtleAdvanced
|
|
||||||
);
|
|
||||||
|
|
||||||
// Setup renderers
|
// Setup renderers
|
||||||
ClientRegistry.bindTileEntitySpecialRenderer( TileTurtle.class, new TileEntityTurtleRenderer() );
|
ClientRegistry.bindTileEntitySpecialRenderer( TileTurtle.class, new TileEntityTurtleRenderer() );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerItemModel( Block block, ItemMeshDefinition definition, String[] names )
|
|
||||||
{
|
|
||||||
registerItemModel( Item.getItemFromBlock( block ), definition, names );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerItemModel( Item item, ItemMeshDefinition definition, String[] names )
|
|
||||||
{
|
|
||||||
ResourceLocation[] resources = new ResourceLocation[names.length];
|
|
||||||
for( int i = 0; i < names.length; i++ )
|
|
||||||
{
|
|
||||||
resources[i] = new ResourceLocation( "computercraft:" + names[i] );
|
|
||||||
}
|
|
||||||
ModelBakery.registerItemVariants( item, resources );
|
|
||||||
ModelLoader.setCustomMeshDefinition( item, definition );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerForgeHandlers()
|
|
||||||
{
|
|
||||||
ForgeHandlers handlers = new ForgeHandlers();
|
|
||||||
MinecraftForge.EVENT_BUS.register( handlers );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ForgeHandlers
|
|
||||||
{
|
|
||||||
private static final String[] TURTLE_UPGRADES = {
|
|
||||||
"turtle_modem_off_left",
|
|
||||||
"turtle_modem_on_left",
|
|
||||||
"turtle_modem_off_right",
|
|
||||||
"turtle_modem_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",
|
|
||||||
};
|
|
||||||
|
|
||||||
private TurtleSmartItemModel m_turtleSmartItemModel;
|
|
||||||
|
|
||||||
public ForgeHandlers()
|
|
||||||
{
|
|
||||||
m_turtleSmartItemModel = new TurtleSmartItemModel();
|
|
||||||
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
|
|
||||||
if( resourceManager instanceof SimpleReloadableResourceManager )
|
|
||||||
{
|
|
||||||
SimpleReloadableResourceManager reloadableResourceManager = (SimpleReloadableResourceManager) resourceManager;
|
|
||||||
reloadableResourceManager.registerReloadListener( m_turtleSmartItemModel );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public void onTextureStitchEvent( TextureStitchEvent.Pre event )
|
|
||||||
{
|
|
||||||
// Load all textures for upgrades
|
|
||||||
TextureMap map = event.getMap();
|
|
||||||
for( String upgrade : TURTLE_UPGRADES )
|
|
||||||
{
|
|
||||||
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( "computercraft", "block/" + upgrade ) );
|
|
||||||
for( ResourceLocation texture : model.getTextures() )
|
|
||||||
{
|
|
||||||
map.registerSprite( texture );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public void onModelBakeEvent( ModelBakeEvent event )
|
|
||||||
{
|
|
||||||
// Load all upgrade models
|
|
||||||
for( String upgrade : TURTLE_UPGRADES )
|
|
||||||
{
|
|
||||||
loadModel( event, upgrade );
|
|
||||||
}
|
|
||||||
|
|
||||||
loadSmartModel( event, "turtle_dynamic", m_turtleSmartItemModel );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadModel( ModelBakeEvent event, String name )
|
|
||||||
{
|
|
||||||
IModel model = ModelLoaderRegistry.getModelOrMissing(
|
|
||||||
new ResourceLocation( "computercraft", "block/" + name )
|
|
||||||
);
|
|
||||||
IBakedModel bakedModel = model.bake(
|
|
||||||
model.getDefaultState(),
|
|
||||||
DefaultVertexFormats.ITEM,
|
|
||||||
location -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( location.toString() )
|
|
||||||
);
|
|
||||||
event.getModelRegistry().putObject(
|
|
||||||
new ModelResourceLocation( "computercraft:" + name, "inventory" ),
|
|
||||||
bakedModel
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadSmartModel( ModelBakeEvent event, String name, IBakedModel smartModel )
|
|
||||||
{
|
|
||||||
event.getModelRegistry().putObject(
|
|
||||||
new ModelResourceLocation( "computercraft:" + name, "inventory" ),
|
|
||||||
smartModel
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TurtleItemColour implements IItemColor
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public int colorMultiplier( @Nonnull ItemStack stack, int tintIndex )
|
|
||||||
{
|
|
||||||
if( tintIndex == 0 )
|
|
||||||
{
|
|
||||||
ItemTurtleBase turtle = (ItemTurtleBase) stack.getItem();
|
|
||||||
int colour = turtle.getColour( stack );
|
|
||||||
if( colour != -1 ) return colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0xFFFFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,41 +7,19 @@
|
|||||||
package dan200.computercraft.client.proxy;
|
package dan200.computercraft.client.proxy;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.client.ClientTableFormatter;
|
import dan200.computercraft.client.render.TileEntityCableRenderer;
|
||||||
import dan200.computercraft.client.FrameInfo;
|
import dan200.computercraft.client.render.TileEntityMonitorRenderer;
|
||||||
import dan200.computercraft.client.render.*;
|
|
||||||
import dan200.computercraft.shared.command.CommandCopy;
|
import dan200.computercraft.shared.command.CommandCopy;
|
||||||
import dan200.computercraft.shared.command.text.TableBuilder;
|
|
||||||
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
|
|
||||||
import dan200.computercraft.shared.peripheral.modem.wired.TileCable;
|
import dan200.computercraft.shared.peripheral.modem.wired.TileCable;
|
||||||
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
||||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||||
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
|
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
|
||||||
import dan200.computercraft.shared.util.Colour;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.renderer.ItemMeshDefinition;
|
|
||||||
import net.minecraft.client.renderer.block.model.ModelBakery;
|
|
||||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
|
||||||
import net.minecraft.client.renderer.color.IItemColor;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.SoundEvent;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.client.ClientCommandHandler;
|
import net.minecraftforge.client.ClientCommandHandler;
|
||||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
|
||||||
import net.minecraftforge.client.model.ModelLoader;
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
|
||||||
import net.minecraftforge.event.world.WorldEvent;
|
import net.minecraftforge.event.world.WorldEvent;
|
||||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
||||||
{
|
{
|
||||||
@@ -50,143 +28,25 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
|||||||
{
|
{
|
||||||
super.preInit();
|
super.preInit();
|
||||||
|
|
||||||
// Setup client forge handlers
|
|
||||||
registerForgeHandlers();
|
|
||||||
|
|
||||||
// Register any client-specific commands
|
// Register any client-specific commands
|
||||||
ClientCommandHandler.instance.registerCommand( CommandCopy.INSTANCE );
|
ClientCommandHandler.instance.registerCommand( CommandCopy.INSTANCE );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public void registerModels( ModelRegistryEvent event )
|
|
||||||
{
|
|
||||||
// Register item models
|
|
||||||
registerItemModel( ComputerCraft.Blocks.computer, "computer" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.peripheral, 0, "peripheral" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.peripheral, 1, "wireless_modem" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.peripheral, 2, "monitor" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.peripheral, 3, "printer" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.peripheral, 4, "advanced_monitor" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.cable, 0, "cable" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.cable, 1, "wired_modem" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.commandComputer, "command_computer" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.advancedModem, "advanced_modem" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.peripheral, 5, "speaker" );
|
|
||||||
registerItemModel( ComputerCraft.Blocks.wiredModemFull, "wired_modem_full" );
|
|
||||||
|
|
||||||
registerItemModel( ComputerCraft.Items.disk, "disk" );
|
|
||||||
registerItemModel( ComputerCraft.Items.diskExpanded, "disk_expanded" );
|
|
||||||
registerItemModel( ComputerCraft.Items.treasureDisk, "treasure_disk" );
|
|
||||||
registerItemModel( ComputerCraft.Items.printout, 0, "printout" );
|
|
||||||
registerItemModel( ComputerCraft.Items.printout, 1, "pages" );
|
|
||||||
registerItemModel( ComputerCraft.Items.printout, 2, "book" );
|
|
||||||
registerItemModel( ComputerCraft.Items.pocketComputer, "pocket_computer" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
super.init();
|
super.init();
|
||||||
|
|
||||||
// Load textures
|
|
||||||
Minecraft mc = Minecraft.getMinecraft();
|
|
||||||
|
|
||||||
// Setup
|
|
||||||
mc.getItemColors().registerItemColorHandler( new DiskColorHandler( ComputerCraft.Items.disk ), ComputerCraft.Items.disk );
|
|
||||||
mc.getItemColors().registerItemColorHandler( new DiskColorHandler( ComputerCraft.Items.diskExpanded ), ComputerCraft.Items.diskExpanded );
|
|
||||||
|
|
||||||
mc.getItemColors().registerItemColorHandler( ( stack, layer ) ->
|
|
||||||
{
|
|
||||||
switch( layer )
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
return 0xFFFFFF;
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
// Frame colour
|
|
||||||
int colour = ComputerCraft.Items.pocketComputer.getColour( stack );
|
|
||||||
return colour == -1 ? 0xFFFFFF : colour;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
// Light colour
|
|
||||||
int colour = ComputerCraft.Items.pocketComputer.getLightState( stack );
|
|
||||||
return colour == -1 ? Colour.Black.getHex() : colour;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, ComputerCraft.Items.pocketComputer );
|
|
||||||
|
|
||||||
// Setup renderers
|
// Setup renderers
|
||||||
ClientRegistry.bindTileEntitySpecialRenderer( TileMonitor.class, new TileEntityMonitorRenderer() );
|
ClientRegistry.bindTileEntitySpecialRenderer( TileMonitor.class, new TileEntityMonitorRenderer() );
|
||||||
ClientRegistry.bindTileEntitySpecialRenderer( TileCable.class, new TileEntityCableRenderer() );
|
ClientRegistry.bindTileEntitySpecialRenderer( TileCable.class, new TileEntityCableRenderer() );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerItemModel( Block block, int damage, String name )
|
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
|
||||||
{
|
public static class ForgeHandlers
|
||||||
registerItemModel( Item.getItemFromBlock( block ), damage, name );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerItemModel( Item item, int damage, String name )
|
|
||||||
{
|
|
||||||
ModelResourceLocation res = new ModelResourceLocation( "computercraft:" + name, "inventory" );
|
|
||||||
ModelBakery.registerItemVariants( item, new ResourceLocation( "computercraft", name ) );
|
|
||||||
ModelLoader.setCustomModelResourceLocation( item, damage, res );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerItemModel( Block block, String name )
|
|
||||||
{
|
|
||||||
registerItemModel( Item.getItemFromBlock( block ), name );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerItemModel( Item item, String name )
|
|
||||||
{
|
|
||||||
final ModelResourceLocation res = new ModelResourceLocation( "computercraft:" + name, "inventory" );
|
|
||||||
ModelBakery.registerItemVariants( item, new ResourceLocation( "computercraft", name ) );
|
|
||||||
ModelLoader.setCustomMeshDefinition( item, new ItemMeshDefinition()
|
|
||||||
{
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
|
|
||||||
{
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public File getWorldDir( World world )
|
|
||||||
{
|
|
||||||
return world.getSaveHandler().getWorldDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerForgeHandlers()
|
|
||||||
{
|
|
||||||
MinecraftForge.EVENT_BUS.register( new ForgeHandlers() );
|
|
||||||
MinecraftForge.EVENT_BUS.register( new RenderOverlayCable() );
|
|
||||||
MinecraftForge.EVENT_BUS.register( new ItemPocketRenderer() );
|
|
||||||
MinecraftForge.EVENT_BUS.register( new ItemPrintoutRenderer() );
|
|
||||||
MinecraftForge.EVENT_BUS.register( FrameInfo.instance() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void playRecordClient( BlockPos pos, SoundEvent record, String info )
|
|
||||||
{
|
|
||||||
Minecraft mc = Minecraft.getMinecraft();
|
|
||||||
mc.world.playRecord( pos, record );
|
|
||||||
if( info != null ) mc.ingameGUI.setRecordPlayingMessage( info );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void showTableClient( TableBuilder table )
|
|
||||||
{
|
|
||||||
ClientTableFormatter.INSTANCE.display( table );
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ForgeHandlers
|
|
||||||
{
|
{
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onWorldUnload( WorldEvent.Unload event )
|
public static void onWorldUnload( WorldEvent.Unload event )
|
||||||
{
|
{
|
||||||
if( event.getWorld().isRemote )
|
if( event.getWorld().isRemote )
|
||||||
{
|
{
|
||||||
@@ -195,20 +55,5 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SideOnly( Side.CLIENT )
|
|
||||||
private static class DiskColorHandler implements IItemColor
|
|
||||||
{
|
|
||||||
private final ItemDiskLegacy disk;
|
|
||||||
|
|
||||||
private DiskColorHandler( ItemDiskLegacy disk )
|
|
||||||
{
|
|
||||||
this.disk = disk;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int colorMultiplier( @Nonnull ItemStack stack, int layer )
|
|
||||||
{
|
|
||||||
return layer == 0 ? 0xFFFFFF : disk.getColour( stack );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ import net.minecraft.client.renderer.texture.TextureMap;
|
|||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraftforge.client.ForgeHooksClient;
|
import net.minecraftforge.client.ForgeHooksClient;
|
||||||
import net.minecraftforge.client.event.RenderSpecificHandEvent;
|
import net.minecraftforge.client.event.RenderSpecificHandEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
|
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
|
||||||
@@ -35,17 +35,23 @@ import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
|
|||||||
/**
|
/**
|
||||||
* Emulates map rendering for pocket computers
|
* Emulates map rendering for pocket computers
|
||||||
*/
|
*/
|
||||||
@SideOnly( Side.CLIENT )
|
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
|
||||||
public class ItemPocketRenderer extends ItemMapLikeRenderer
|
public final class ItemPocketRenderer extends ItemMapLikeRenderer
|
||||||
{
|
{
|
||||||
|
private static final ItemPocketRenderer INSTANCE = new ItemPocketRenderer();
|
||||||
|
|
||||||
|
private ItemPocketRenderer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void renderItem( RenderSpecificHandEvent event )
|
public static void renderItem( RenderSpecificHandEvent event )
|
||||||
{
|
{
|
||||||
ItemStack stack = event.getItemStack();
|
ItemStack stack = event.getItemStack();
|
||||||
if( !(stack.getItem() instanceof ItemPocketComputer) ) return;
|
if( !(stack.getItem() instanceof ItemPocketComputer) ) return;
|
||||||
|
|
||||||
event.setCanceled( true );
|
event.setCanceled( true );
|
||||||
renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
|
INSTANCE.renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -145,7 +151,7 @@ public class ItemPocketRenderer extends ItemMapLikeRenderer
|
|||||||
|
|
||||||
// And render the cursor;
|
// And render the cursor;
|
||||||
int tx = terminal.getCursorX(), ty = terminal.getCursorY();
|
int tx = terminal.getCursorX(), ty = terminal.getCursorY();
|
||||||
if( terminal.getCursorBlink() && FrameInfo.instance().getGlobalCursorBlink() &&
|
if( terminal.getCursorBlink() && FrameInfo.getGlobalCursorBlink() &&
|
||||||
tx >= 0 && ty >= 0 && tx < tw && ty < th )
|
tx >= 0 && ty >= 0 && tx < tw && ty < th )
|
||||||
{
|
{
|
||||||
TextBuffer cursorColour = new TextBuffer( "0123456789abcdef".charAt( terminal.getTextColour() ), 1 );
|
TextBuffer cursorColour = new TextBuffer( "0123456789abcdef".charAt( terminal.getTextColour() ), 1 );
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import net.minecraft.client.renderer.GlStateManager;
|
|||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraftforge.client.event.RenderItemInFrameEvent;
|
import net.minecraftforge.client.event.RenderItemInFrameEvent;
|
||||||
import net.minecraftforge.client.event.RenderSpecificHandEvent;
|
import net.minecraftforge.client.event.RenderSpecificHandEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
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_HEIGHT;
|
||||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
|
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
|
||||||
@@ -20,17 +22,27 @@ import static dan200.computercraft.client.render.PrintoutRenderer.*;
|
|||||||
import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE;
|
import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE;
|
||||||
import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH;
|
import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH;
|
||||||
|
|
||||||
public class ItemPrintoutRenderer extends ItemMapLikeRenderer
|
/**
|
||||||
|
* Emulates map and item-frame rendering for prinouts
|
||||||
|
*/
|
||||||
|
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
|
||||||
|
public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
|
||||||
{
|
{
|
||||||
|
private static final ItemPrintoutRenderer INSTANCE = new ItemPrintoutRenderer();
|
||||||
|
|
||||||
|
private ItemPrintoutRenderer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onRenderInHand( RenderSpecificHandEvent event )
|
public static void onRenderInHand( RenderSpecificHandEvent event )
|
||||||
{
|
{
|
||||||
ItemStack stack = event.getItemStack();
|
ItemStack stack = event.getItemStack();
|
||||||
if( stack.getItem() != ComputerCraft.Items.printout ) return;
|
if( stack.getItem() != ComputerCraft.Items.printout ) return;
|
||||||
|
|
||||||
event.setCanceled( true );
|
event.setCanceled( true );
|
||||||
|
|
||||||
renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
|
INSTANCE.renderItemFirstPerson( event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -51,7 +63,7 @@ public class ItemPrintoutRenderer extends ItemMapLikeRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onRenderInFrame( RenderItemInFrameEvent event )
|
public static void onRenderInFrame( RenderItemInFrameEvent event )
|
||||||
{
|
{
|
||||||
ItemStack stack = event.getItem();
|
ItemStack stack = event.getItem();
|
||||||
if( stack.getItem() != ComputerCraft.Items.printout ) return;
|
if( stack.getItem() != ComputerCraft.Items.printout ) return;
|
||||||
@@ -69,6 +81,7 @@ public class ItemPrintoutRenderer extends ItemMapLikeRenderer
|
|||||||
drawPrintout( stack );
|
drawPrintout( stack );
|
||||||
|
|
||||||
GlStateManager.enableLighting();
|
GlStateManager.enableLighting();
|
||||||
|
GlStateManager.disableBlend();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void drawPrintout( ItemStack stack )
|
private static void drawPrintout( ItemStack stack )
|
||||||
|
|||||||
@@ -23,17 +23,24 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
|
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
public class RenderOverlayCable
|
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
|
||||||
|
public final class RenderOverlayCable
|
||||||
{
|
{
|
||||||
private static final float EXPAND = 0.002f;
|
private static final float EXPAND = 0.002f;
|
||||||
private static final double MIN = CableBounds.MIN - EXPAND;
|
private static final double MIN = CableBounds.MIN - EXPAND;
|
||||||
private static final double MAX = CableBounds.MAX + EXPAND;
|
private static final double MAX = CableBounds.MAX + EXPAND;
|
||||||
|
|
||||||
|
private RenderOverlayCable()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void drawHighlight( DrawBlockHighlightEvent event )
|
public static void drawHighlight( DrawBlockHighlightEvent event )
|
||||||
{
|
{
|
||||||
if( event.getTarget().typeOfHit != RayTraceResult.Type.BLOCK ) return;
|
if( event.getTarget().typeOfHit != RayTraceResult.Type.BLOCK ) return;
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
|
|||||||
// Ensure each monitor terminal is rendered only once. We allow rendering a specific tile
|
// Ensure each monitor terminal is rendered only once. We allow rendering a specific tile
|
||||||
// multiple times in a single frame to ensure compatibility with shaders which may run a
|
// multiple times in a single frame to ensure compatibility with shaders which may run a
|
||||||
// pass multiple times.
|
// pass multiple times.
|
||||||
long renderFrame = FrameInfo.instance().getRenderFrame();
|
long renderFrame = FrameInfo.getRenderFrame();
|
||||||
if( originTerminal.lastRenderFrame == renderFrame && !monitorPos.equals( originTerminal.lastRenderPos ) )
|
if( originTerminal.lastRenderFrame == renderFrame && !monitorPos.equals( originTerminal.lastRenderPos ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -230,7 +230,7 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer<TileMon
|
|||||||
GlStateManager.glEndList();
|
GlStateManager.glEndList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( FrameInfo.instance().getGlobalCursorBlink() )
|
if( FrameInfo.getGlobalCursorBlink() )
|
||||||
{
|
{
|
||||||
GlStateManager.callList( originTerminal.renderDisplayLists[2] );
|
GlStateManager.callList( originTerminal.renderDisplayLists[2] );
|
||||||
GlStateManager.resetColor();
|
GlStateManager.resetColor();
|
||||||
|
|||||||
@@ -14,23 +14,20 @@ import dan200.computercraft.shared.util.Holiday;
|
|||||||
import dan200.computercraft.shared.util.HolidayUtil;
|
import dan200.computercraft.shared.util.HolidayUtil;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.FontRenderer;
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.EntityRenderer;
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||||
import net.minecraft.client.renderer.block.model.ModelManager;
|
import net.minecraft.client.renderer.block.model.ModelManager;
|
||||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||||
import net.minecraft.client.renderer.entity.RenderManager;
|
|
||||||
import net.minecraft.client.renderer.texture.TextureMap;
|
import net.minecraft.client.renderer.texture.TextureMap;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraftforge.client.ForgeHooksClient;
|
import net.minecraftforge.client.ForgeHooksClient;
|
||||||
import net.minecraftforge.client.model.pipeline.LightUtil;
|
import net.minecraftforge.client.model.pipeline.LightUtil;
|
||||||
@@ -65,7 +62,7 @@ public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModelResourceLocation getTurtleOverlayModel( ComputerFamily family, ResourceLocation overlay, boolean christmas )
|
public static ModelResourceLocation getTurtleOverlayModel( ResourceLocation overlay, boolean christmas )
|
||||||
{
|
{
|
||||||
if( overlay != null )
|
if( overlay != null )
|
||||||
{
|
{
|
||||||
@@ -83,6 +80,19 @@ public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurt
|
|||||||
|
|
||||||
private void renderTurtleAt( TileTurtle turtle, double posX, double posY, double posZ, float f, int i )
|
private void renderTurtleAt( TileTurtle turtle, double posX, double posY, double posZ, float f, int i )
|
||||||
{
|
{
|
||||||
|
// Render the label
|
||||||
|
String label = turtle.createProxy().getLabel();
|
||||||
|
if( label != null && rendererDispatcher.cameraHitResult != null && turtle.getPos().equals( rendererDispatcher.cameraHitResult.getBlockPos() ) )
|
||||||
|
{
|
||||||
|
setLightmapDisabled( true );
|
||||||
|
EntityRenderer.drawNameplate(
|
||||||
|
getFontRenderer(), label,
|
||||||
|
(float) posX + 0.5F, (float) posY + 1.2F, (float) posZ + 0.5F, 0,
|
||||||
|
rendererDispatcher.entityYaw, rendererDispatcher.entityPitch, false, false
|
||||||
|
);
|
||||||
|
setLightmapDisabled( false );
|
||||||
|
}
|
||||||
|
|
||||||
IBlockState state = turtle.getWorld().getBlockState( turtle.getPos() );
|
IBlockState state = turtle.getWorld().getBlockState( turtle.getPos() );
|
||||||
GlStateManager.pushMatrix();
|
GlStateManager.pushMatrix();
|
||||||
try
|
try
|
||||||
@@ -94,13 +104,6 @@ public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurt
|
|||||||
yaw = turtle.getRenderYaw( f );
|
yaw = turtle.getRenderYaw( f );
|
||||||
GlStateManager.translate( posX + offset.x, posY + offset.y, posZ + offset.z );
|
GlStateManager.translate( posX + offset.x, posY + offset.y, posZ + offset.z );
|
||||||
|
|
||||||
// Render the label
|
|
||||||
String label = turtle.createProxy().getLabel();
|
|
||||||
if( label != null )
|
|
||||||
{
|
|
||||||
renderLabel( turtle.getAccess().getPosition(), label );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render the turtle
|
// Render the turtle
|
||||||
GlStateManager.translate( 0.5f, 0.5f, 0.5f );
|
GlStateManager.translate( 0.5f, 0.5f, 0.5f );
|
||||||
GlStateManager.rotate( 180.0f - yaw, 0.0f, 1.0f, 0.0f );
|
GlStateManager.rotate( 180.0f - yaw, 0.0f, 1.0f, 0.0f );
|
||||||
@@ -123,7 +126,6 @@ public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurt
|
|||||||
|
|
||||||
// Render the overlay
|
// Render the overlay
|
||||||
ModelResourceLocation overlayModel = getTurtleOverlayModel(
|
ModelResourceLocation overlayModel = getTurtleOverlayModel(
|
||||||
family,
|
|
||||||
overlay,
|
overlay,
|
||||||
HolidayUtil.getCurrentHoliday() == Holiday.Christmas
|
HolidayUtil.getCurrentHoliday() == Holiday.Christmas
|
||||||
);
|
);
|
||||||
@@ -232,72 +234,4 @@ public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurt
|
|||||||
}
|
}
|
||||||
tessellator.draw();
|
tessellator.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderLabel( BlockPos position, String label )
|
|
||||||
{
|
|
||||||
Minecraft mc = Minecraft.getMinecraft();
|
|
||||||
RayTraceResult mop = mc.objectMouseOver;
|
|
||||||
if( mop != null && mop.typeOfHit == RayTraceResult.Type.BLOCK && mop.getBlockPos().equals( position ) )
|
|
||||||
{
|
|
||||||
RenderManager renderManager = mc.getRenderManager();
|
|
||||||
FontRenderer fontrenderer = renderManager.getFontRenderer();
|
|
||||||
float scale = 0.016666668F * 1.6f;
|
|
||||||
|
|
||||||
GlStateManager.pushMatrix();
|
|
||||||
GlStateManager.disableLighting();
|
|
||||||
GlStateManager.enableBlend();
|
|
||||||
GlStateManager.blendFunc( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA );
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GlStateManager.translate( 0.5f, 1.25f, 0.5f );
|
|
||||||
GlStateManager.rotate( -renderManager.playerViewY, 0.0F, 1.0F, 0.0F );
|
|
||||||
GlStateManager.rotate( renderManager.playerViewX, 1.0F, 0.0F, 0.0F );
|
|
||||||
GlStateManager.scale( -scale, -scale, scale );
|
|
||||||
|
|
||||||
int yOffset = 0;
|
|
||||||
int xOffset = fontrenderer.getStringWidth( label ) / 2;
|
|
||||||
|
|
||||||
// Draw background
|
|
||||||
GlStateManager.depthMask( false );
|
|
||||||
GlStateManager.disableDepth();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Quad
|
|
||||||
GlStateManager.disableTexture2D();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Tessellator tessellator = Tessellator.getInstance();
|
|
||||||
BufferBuilder renderer = tessellator.getBuffer();
|
|
||||||
renderer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR );
|
|
||||||
renderer.pos( -xOffset - 1, -1 + yOffset, 0.0D ).color( 0.0F, 0.0F, 0.0F, 0.25F ).endVertex();
|
|
||||||
renderer.pos( -xOffset - 1, 8 + yOffset, 0.0D ).color( 0.0F, 0.0F, 0.0F, 0.25F ).endVertex();
|
|
||||||
renderer.pos( xOffset + 1, 8 + yOffset, 0.0D ).color( 0.0F, 0.0F, 0.0F, 0.25F ).endVertex();
|
|
||||||
renderer.pos( xOffset + 1, -1 + yOffset, 0.0D ).color( 0.0F, 0.0F, 0.0F, 0.25F ).endVertex();
|
|
||||||
tessellator.draw();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
GlStateManager.enableTexture2D();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text
|
|
||||||
fontrenderer.drawString( label, -fontrenderer.getStringWidth( label ) / 2, yOffset, 0x20ffffff );
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
GlStateManager.enableDepth();
|
|
||||||
GlStateManager.depthMask( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw foreground text
|
|
||||||
fontrenderer.drawString( label, -fontrenderer.getStringWidth( label ) / 2, yOffset, -1 );
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
GlStateManager.disableBlend();
|
|
||||||
GlStateManager.enableLighting();
|
|
||||||
GlStateManager.popMatrix();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* 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.render;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||||
|
import net.minecraft.client.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.function.Function;
|
||||||
|
|
||||||
|
public 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" );
|
||||||
|
|
||||||
|
public static final TurtleModelLoader INSTANCE = new TurtleModelLoader();
|
||||||
|
|
||||||
|
private TurtleModelLoader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResourceManagerReload( @Nonnull IResourceManager manager )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accepts( @Nonnull ResourceLocation name )
|
||||||
|
{
|
||||||
|
return name.getNamespace().equals( ComputerCraft.MOD_ID )
|
||||||
|
&& (name.getPath().equals( "turtle" ) || name.getPath().equals( "turtle_advanced" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public IModel loadModel( @Nonnull ResourceLocation name ) throws Exception
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException( "Loader does not accept " + name );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TurtleModel implements IModel
|
||||||
|
{
|
||||||
|
private final IModel family;
|
||||||
|
private final IModel colour;
|
||||||
|
|
||||||
|
private TurtleModel( IModel family, IModel colour )
|
||||||
|
{
|
||||||
|
this.family = family;
|
||||||
|
this.colour = colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public IBakedModel bake( @Nonnull IModelState state, @Nonnull VertexFormat format, @Nonnull Function<ResourceLocation, TextureAtlasSprite> function )
|
||||||
|
{
|
||||||
|
return new TurtleSmartItemModel(
|
||||||
|
family.bake( state, format, function ),
|
||||||
|
colour.bake( state, format, function )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,6 @@ package dan200.computercraft.client.render;
|
|||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||||
import dan200.computercraft.api.turtle.TurtleSide;
|
import dan200.computercraft.api.turtle.TurtleSide;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
|
||||||
import dan200.computercraft.shared.turtle.items.ItemTurtleBase;
|
import dan200.computercraft.shared.turtle.items.ItemTurtleBase;
|
||||||
import dan200.computercraft.shared.util.Holiday;
|
import dan200.computercraft.shared.util.Holiday;
|
||||||
import dan200.computercraft.shared.util.HolidayUtil;
|
import dan200.computercraft.shared.util.HolidayUtil;
|
||||||
@@ -17,15 +16,11 @@ import net.minecraft.block.state.IBlockState;
|
|||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.block.model.*;
|
import net.minecraft.client.renderer.block.model.*;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.client.resources.IResourceManager;
|
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.client.resource.IResourceType;
|
|
||||||
import net.minecraftforge.client.resource.ISelectiveResourceReloadListener;
|
|
||||||
import net.minecraftforge.client.resource.VanillaResourceType;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@@ -34,9 +29,8 @@ import javax.vecmath.Matrix4f;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
public class TurtleSmartItemModel implements IBakedModel, ISelectiveResourceReloadListener
|
public class TurtleSmartItemModel implements IBakedModel
|
||||||
{
|
{
|
||||||
private static final Matrix4f s_identity, s_flip;
|
private static final Matrix4f s_identity, s_flip;
|
||||||
|
|
||||||
@@ -53,17 +47,15 @@ public class TurtleSmartItemModel implements IBakedModel, ISelectiveResourceRelo
|
|||||||
|
|
||||||
private static class TurtleModelCombination
|
private static class TurtleModelCombination
|
||||||
{
|
{
|
||||||
public final ComputerFamily m_family;
|
final boolean m_colour;
|
||||||
public final boolean m_colour;
|
final ITurtleUpgrade m_leftUpgrade;
|
||||||
public final ITurtleUpgrade m_leftUpgrade;
|
final ITurtleUpgrade m_rightUpgrade;
|
||||||
public final ITurtleUpgrade m_rightUpgrade;
|
final ResourceLocation m_overlay;
|
||||||
public final ResourceLocation m_overlay;
|
final boolean m_christmas;
|
||||||
public final boolean m_christmas;
|
final boolean m_flip;
|
||||||
public final boolean m_flip;
|
|
||||||
|
|
||||||
public TurtleModelCombination( ComputerFamily family, boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, ResourceLocation overlay, boolean christmas, boolean flip )
|
TurtleModelCombination( boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, ResourceLocation overlay, boolean christmas, boolean flip )
|
||||||
{
|
{
|
||||||
m_family = family;
|
|
||||||
m_colour = colour;
|
m_colour = colour;
|
||||||
m_leftUpgrade = leftUpgrade;
|
m_leftUpgrade = leftUpgrade;
|
||||||
m_rightUpgrade = rightUpgrade;
|
m_rightUpgrade = rightUpgrade;
|
||||||
@@ -79,8 +71,7 @@ public class TurtleSmartItemModel implements IBakedModel, ISelectiveResourceRelo
|
|||||||
if( !(other instanceof TurtleModelCombination) ) return false;
|
if( !(other instanceof TurtleModelCombination) ) return false;
|
||||||
|
|
||||||
TurtleModelCombination otherCombo = (TurtleModelCombination) other;
|
TurtleModelCombination otherCombo = (TurtleModelCombination) other;
|
||||||
return otherCombo.m_family == m_family &&
|
return otherCombo.m_colour == m_colour &&
|
||||||
otherCombo.m_colour == m_colour &&
|
|
||||||
otherCombo.m_leftUpgrade == m_leftUpgrade &&
|
otherCombo.m_leftUpgrade == m_leftUpgrade &&
|
||||||
otherCombo.m_rightUpgrade == m_rightUpgrade &&
|
otherCombo.m_rightUpgrade == m_rightUpgrade &&
|
||||||
Objects.equal( otherCombo.m_overlay, m_overlay ) &&
|
Objects.equal( otherCombo.m_overlay, m_overlay ) &&
|
||||||
@@ -92,8 +83,7 @@ public class TurtleSmartItemModel implements IBakedModel, ISelectiveResourceRelo
|
|||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 0;
|
||||||
result = prime * result + m_family.hashCode();
|
|
||||||
result = prime * result + (m_colour ? 1 : 0);
|
result = prime * result + (m_colour ? 1 : 0);
|
||||||
result = prime * result + (m_leftUpgrade != null ? m_leftUpgrade.hashCode() : 0);
|
result = prime * result + (m_leftUpgrade != null ? m_leftUpgrade.hashCode() : 0);
|
||||||
result = prime * result + (m_rightUpgrade != null ? m_rightUpgrade.hashCode() : 0);
|
result = prime * result + (m_rightUpgrade != null ? m_rightUpgrade.hashCode() : 0);
|
||||||
@@ -104,14 +94,18 @@ public class TurtleSmartItemModel implements IBakedModel, ISelectiveResourceRelo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final IBakedModel familyModel;
|
||||||
|
private final IBakedModel colourModel;
|
||||||
|
|
||||||
private HashMap<TurtleModelCombination, IBakedModel> m_cachedModels;
|
private HashMap<TurtleModelCombination, IBakedModel> m_cachedModels;
|
||||||
private ItemOverrideList m_overrides;
|
private ItemOverrideList m_overrides;
|
||||||
private final TurtleModelCombination m_defaultCombination;
|
|
||||||
|
|
||||||
public TurtleSmartItemModel()
|
public TurtleSmartItemModel( IBakedModel familyModel, IBakedModel colourModel )
|
||||||
{
|
{
|
||||||
|
this.familyModel = familyModel;
|
||||||
|
this.colourModel = colourModel;
|
||||||
|
|
||||||
m_cachedModels = new HashMap<>();
|
m_cachedModels = new HashMap<>();
|
||||||
m_defaultCombination = new TurtleModelCombination( ComputerFamily.Normal, false, null, null, null, false, false );
|
|
||||||
m_overrides = new ItemOverrideList( new ArrayList<>() )
|
m_overrides = new ItemOverrideList( new ArrayList<>() )
|
||||||
{
|
{
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@@ -119,7 +113,6 @@ public class TurtleSmartItemModel implements IBakedModel, ISelectiveResourceRelo
|
|||||||
public IBakedModel handleItemState( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity )
|
public IBakedModel handleItemState( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity )
|
||||||
{
|
{
|
||||||
ItemTurtleBase turtle = (ItemTurtleBase) stack.getItem();
|
ItemTurtleBase turtle = (ItemTurtleBase) stack.getItem();
|
||||||
ComputerFamily family = turtle.getFamily( stack );
|
|
||||||
int colour = turtle.getColour( stack );
|
int colour = turtle.getColour( stack );
|
||||||
ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.Left );
|
ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.Left );
|
||||||
ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.Right );
|
ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.Right );
|
||||||
@@ -127,17 +120,11 @@ public class TurtleSmartItemModel implements IBakedModel, ISelectiveResourceRelo
|
|||||||
boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.Christmas;
|
boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.Christmas;
|
||||||
String label = turtle.getLabel( stack );
|
String label = turtle.getLabel( stack );
|
||||||
boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" ));
|
boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" ));
|
||||||
TurtleModelCombination combo = new TurtleModelCombination( family, colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip );
|
TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip );
|
||||||
if( m_cachedModels.containsKey( combo ) )
|
|
||||||
{
|
IBakedModel model = m_cachedModels.get( combo );
|
||||||
return m_cachedModels.get( combo );
|
if( model == null ) m_cachedModels.put( combo, model = buildModel( combo ) );
|
||||||
}
|
return model;
|
||||||
else
|
|
||||||
{
|
|
||||||
IBakedModel model = buildModel( combo );
|
|
||||||
m_cachedModels.put( combo, model );
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -149,19 +136,13 @@ public class TurtleSmartItemModel implements IBakedModel, ISelectiveResourceRelo
|
|||||||
return m_overrides;
|
return m_overrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResourceManagerReload( @Nonnull IResourceManager resourceManager, @Nonnull Predicate<IResourceType> resourcePredicate )
|
|
||||||
{
|
|
||||||
if( resourcePredicate.test( VanillaResourceType.MODELS ) ) m_cachedModels.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private IBakedModel buildModel( TurtleModelCombination combo )
|
private IBakedModel buildModel( TurtleModelCombination combo )
|
||||||
{
|
{
|
||||||
Minecraft mc = Minecraft.getMinecraft();
|
Minecraft mc = Minecraft.getMinecraft();
|
||||||
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
|
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
|
||||||
ModelResourceLocation baseModelLocation = TileEntityTurtleRenderer.getTurtleModel( combo.m_family, combo.m_colour );
|
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_overlay, combo.m_christmas );
|
||||||
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_family, combo.m_overlay, combo.m_christmas );
|
|
||||||
IBakedModel baseModel = modelManager.getModel( baseModelLocation );
|
IBakedModel baseModel = combo.m_colour ? colourModel : familyModel;
|
||||||
IBakedModel overlayModel = (overlayModelLocation != null) ? modelManager.getModel( overlayModelLocation ) : null;
|
IBakedModel overlayModel = (overlayModelLocation != null) ? modelManager.getModel( overlayModelLocation ) : null;
|
||||||
Matrix4f transform = combo.m_flip ? s_flip : s_identity;
|
Matrix4f transform = combo.m_flip ? s_flip : s_identity;
|
||||||
Pair<IBakedModel, Matrix4f> leftModel = (combo.m_leftUpgrade != null) ? combo.m_leftUpgrade.getModel( null, TurtleSide.Left ) : null;
|
Pair<IBakedModel, Matrix4f> leftModel = (combo.m_leftUpgrade != null) ? combo.m_leftUpgrade.getModel( null, TurtleSide.Left ) : null;
|
||||||
@@ -184,38 +165,36 @@ public class TurtleSmartItemModel implements IBakedModel, ISelectiveResourceRelo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// These should not be called:
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<BakedQuad> getQuads( IBlockState state, EnumFacing facing, long rand )
|
public List<BakedQuad> getQuads( IBlockState state, EnumFacing facing, long rand )
|
||||||
{
|
{
|
||||||
return getDefaultModel().getQuads( state, facing, rand );
|
return familyModel.getQuads( state, facing, rand );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAmbientOcclusion()
|
public boolean isAmbientOcclusion()
|
||||||
{
|
{
|
||||||
return getDefaultModel().isAmbientOcclusion();
|
return familyModel.isAmbientOcclusion();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGui3d()
|
public boolean isGui3d()
|
||||||
{
|
{
|
||||||
return getDefaultModel().isGui3d();
|
return familyModel.isGui3d();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBuiltInRenderer()
|
public boolean isBuiltInRenderer()
|
||||||
{
|
{
|
||||||
return getDefaultModel().isBuiltInRenderer();
|
return familyModel.isBuiltInRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public TextureAtlasSprite getParticleTexture()
|
public TextureAtlasSprite getParticleTexture()
|
||||||
{
|
{
|
||||||
return getDefaultModel().getParticleTexture();
|
return familyModel.getParticleTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@@ -223,18 +202,7 @@ public class TurtleSmartItemModel implements IBakedModel, ISelectiveResourceRelo
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public ItemCameraTransforms getItemCameraTransforms()
|
public ItemCameraTransforms getItemCameraTransforms()
|
||||||
{
|
{
|
||||||
return getDefaultModel().getItemCameraTransforms();
|
return familyModel.getItemCameraTransforms();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBakedModel getDefaultModel()
|
|
||||||
{
|
|
||||||
IBakedModel model = m_cachedModels.get( m_defaultCombination );
|
|
||||||
if( model == null )
|
|
||||||
{
|
|
||||||
model = buildModel( m_defaultCombination );
|
|
||||||
m_cachedModels.put( m_defaultCombination, model );
|
|
||||||
}
|
|
||||||
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,20 +14,32 @@ import dan200.computercraft.core.filesystem.FileSystem;
|
|||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.core.tracking.TrackingField;
|
import dan200.computercraft.core.tracking.TrackingField;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public interface IAPIEnvironment extends IComputerOwned
|
public interface IAPIEnvironment extends IComputerOwned
|
||||||
{
|
{
|
||||||
|
String[] SIDE_NAMES = new String[] {
|
||||||
|
"bottom", "top", "back", "front", "right", "left",
|
||||||
|
};
|
||||||
|
|
||||||
|
int SIDE_COUNT = 6;
|
||||||
|
|
||||||
interface IPeripheralChangeListener
|
interface IPeripheralChangeListener
|
||||||
{
|
{
|
||||||
void onPeripheralChanged( int side, IPeripheral newPeripheral );
|
void onPeripheralChanged( int side, @Nullable IPeripheral newPeripheral );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
Computer getComputer();
|
Computer getComputer();
|
||||||
|
|
||||||
int getComputerID();
|
int getComputerID();
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
IComputerEnvironment getComputerEnvironment();
|
IComputerEnvironment getComputerEnvironment();
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
Terminal getTerminal();
|
Terminal getTerminal();
|
||||||
|
|
||||||
FileSystem getFileSystem();
|
FileSystem getFileSystem();
|
||||||
@@ -50,17 +62,18 @@ public interface IAPIEnvironment extends IComputerOwned
|
|||||||
|
|
||||||
int getBundledInput( int side );
|
int getBundledInput( int side );
|
||||||
|
|
||||||
void setPeripheralChangeListener( IPeripheralChangeListener listener );
|
void setPeripheralChangeListener( @Nullable IPeripheralChangeListener listener );
|
||||||
|
|
||||||
|
@Nullable
|
||||||
IPeripheral getPeripheral( int side );
|
IPeripheral getPeripheral( int side );
|
||||||
|
|
||||||
String getLabel();
|
String getLabel();
|
||||||
|
|
||||||
void setLabel( String label );
|
void setLabel( @Nullable String label );
|
||||||
|
|
||||||
void addTrackingChange( TrackingField field, long change );
|
void addTrackingChange( @Nonnull TrackingField field, long change );
|
||||||
|
|
||||||
default void addTrackingChange( TrackingField field )
|
default void addTrackingChange( @Nonnull TrackingField field )
|
||||||
{
|
{
|
||||||
addTrackingChange( field, 1 );
|
addTrackingChange( field, 1 );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public interface ILuaAPI extends dan200.computercraft.api.lua.ILuaAPI
|
|||||||
{
|
{
|
||||||
void advance( double v );
|
void advance( double v );
|
||||||
|
|
||||||
|
@Override
|
||||||
default void update()
|
default void update()
|
||||||
{
|
{
|
||||||
advance( 0.05 );
|
advance( 0.05 );
|
||||||
|
|||||||
@@ -278,13 +278,13 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
}, null );
|
}, null );
|
||||||
|
|
||||||
// Queue a detachment event
|
// Queue a detachment event
|
||||||
m_environment.queueEvent( "peripheral_detach", new Object[] { Computer.s_sideNames[side] } );
|
m_environment.queueEvent( "peripheral_detach", new Object[] { IAPIEnvironment.SIDE_NAMES[side] } );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the new peripheral
|
// Assign the new peripheral
|
||||||
if( newPeripheral != null )
|
if( newPeripheral != null )
|
||||||
{
|
{
|
||||||
m_peripherals[side] = new PeripheralWrapper( newPeripheral, Computer.s_sideNames[side] );
|
m_peripherals[side] = new PeripheralWrapper( newPeripheral, IAPIEnvironment.SIDE_NAMES[side] );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -317,7 +317,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
}, null );
|
}, null );
|
||||||
|
|
||||||
// Queue an attachment event
|
// Queue an attachment event
|
||||||
m_environment.queueEvent( "peripheral", new Object[] { Computer.s_sideNames[side] } );
|
m_environment.queueEvent( "peripheral", new Object[] { IAPIEnvironment.SIDE_NAMES[side] } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,9 +483,9 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
private int parseSide( Object[] args ) throws LuaException
|
private int parseSide( Object[] args ) throws LuaException
|
||||||
{
|
{
|
||||||
String side = getString( args, 0 );
|
String side = getString( args, 0 );
|
||||||
for( int n = 0; n < Computer.s_sideNames.length; n++ )
|
for( int n = 0; n < IAPIEnvironment.SIDE_NAMES.length; n++ )
|
||||||
{
|
{
|
||||||
if( side.equals( Computer.s_sideNames[n] ) )
|
if( side.equals( IAPIEnvironment.SIDE_NAMES[n] ) )
|
||||||
{
|
{
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ package dan200.computercraft.core.apis;
|
|||||||
import dan200.computercraft.api.lua.ILuaAPI;
|
import dan200.computercraft.api.lua.ILuaAPI;
|
||||||
import dan200.computercraft.api.lua.ILuaContext;
|
import dan200.computercraft.api.lua.ILuaContext;
|
||||||
import dan200.computercraft.api.lua.LuaException;
|
import dan200.computercraft.api.lua.LuaException;
|
||||||
import dan200.computercraft.core.computer.Computer;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -65,9 +64,9 @@ public class RedstoneAPI implements ILuaAPI
|
|||||||
{
|
{
|
||||||
// getSides
|
// getSides
|
||||||
Map<Object, Object> table = new HashMap<>();
|
Map<Object, Object> table = new HashMap<>();
|
||||||
for( int i = 0; i < Computer.s_sideNames.length; i++ )
|
for( int i = 0; i < IAPIEnvironment.SIDE_NAMES.length; i++ )
|
||||||
{
|
{
|
||||||
table.put( i + 1, Computer.s_sideNames[i] );
|
table.put( i + 1, IAPIEnvironment.SIDE_NAMES[i] );
|
||||||
}
|
}
|
||||||
return new Object[] { table };
|
return new Object[] { table };
|
||||||
}
|
}
|
||||||
@@ -156,9 +155,9 @@ public class RedstoneAPI implements ILuaAPI
|
|||||||
private int parseSide( Object[] args ) throws LuaException
|
private int parseSide( Object[] args ) throws LuaException
|
||||||
{
|
{
|
||||||
String side = getString( args, 0 );
|
String side = getString( args, 0 );
|
||||||
for( int n = 0; n < Computer.s_sideNames.length; n++ )
|
for( int n = 0; n < IAPIEnvironment.SIDE_NAMES.length; n++ )
|
||||||
{
|
{
|
||||||
if( side.equals( Computer.s_sideNames[n] ) )
|
if( side.equals( IAPIEnvironment.SIDE_NAMES[n] ) )
|
||||||
{
|
{
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import dan200.computercraft.api.lua.ILuaContext;
|
|||||||
import dan200.computercraft.api.lua.LuaException;
|
import dan200.computercraft.api.lua.LuaException;
|
||||||
import dan200.computercraft.core.computer.IComputerEnvironment;
|
import dan200.computercraft.core.computer.IComputerEnvironment;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
|
import dan200.computercraft.shared.util.Colour;
|
||||||
import dan200.computercraft.shared.util.Palette;
|
import dan200.computercraft.shared.util.Palette;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
@@ -65,6 +66,8 @@ public class TermAPI implements ILuaAPI
|
|||||||
"setPaletteColor",
|
"setPaletteColor",
|
||||||
"getPaletteColour",
|
"getPaletteColour",
|
||||||
"getPaletteColor",
|
"getPaletteColor",
|
||||||
|
"nativePaletteColour",
|
||||||
|
"nativePaletteColor",
|
||||||
"getCursorBlink",
|
"getCursorBlink",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -289,6 +292,19 @@ public class TermAPI implements ILuaAPI
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
case 23:
|
case 23:
|
||||||
|
case 24:
|
||||||
|
{
|
||||||
|
// nativePaletteColour/nativePaletteColor
|
||||||
|
int colour = 15 - parseColour( args );
|
||||||
|
Colour c = Colour.fromInt( colour );
|
||||||
|
|
||||||
|
float[] rgb = c.getRGB();
|
||||||
|
|
||||||
|
Object[] rgbObj = new Object[rgb.length];
|
||||||
|
for( int i = 0; i < rgbObj.length; ++i ) rgbObj[i] = rgb[i];
|
||||||
|
return rgbObj;
|
||||||
|
}
|
||||||
|
case 25:
|
||||||
// getCursorBlink
|
// getCursorBlink
|
||||||
return new Object[] { m_terminal.getCursorBlink() };
|
return new Object[] { m_terminal.getCursorBlink() };
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -169,27 +169,42 @@ public class BinaryReadableHandle extends HandleGeneric
|
|||||||
{
|
{
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
boolean readAnything = false;
|
boolean readAnything = false, readRc = false;
|
||||||
while( true )
|
while( true )
|
||||||
{
|
{
|
||||||
single.clear();
|
single.clear();
|
||||||
int r = m_reader.read( single );
|
int read = m_reader.read( single );
|
||||||
if( r == -1 ) break;
|
if( read <= 0 )
|
||||||
|
{
|
||||||
|
// Nothing else to read, and we saw no \n. Return the array. If we saw a \r, then add it
|
||||||
|
// back.
|
||||||
|
if( readRc ) stream.write( '\r' );
|
||||||
|
return readAnything ? new Object[] { stream.toByteArray() } : null;
|
||||||
|
}
|
||||||
|
|
||||||
readAnything = true;
|
readAnything = true;
|
||||||
byte b = single.get( 0 );
|
|
||||||
if( b == '\n' )
|
byte chr = single.get( 0 );
|
||||||
|
if( chr == '\n' )
|
||||||
{
|
{
|
||||||
if( withTrailing ) stream.write( b );
|
if( withTrailing )
|
||||||
break;
|
{
|
||||||
|
if( readRc ) stream.write( '\r' );
|
||||||
|
stream.write( chr );
|
||||||
|
}
|
||||||
|
return new Object[] { stream.toByteArray() };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stream.write( b );
|
// We want to skip \r\n, but obviously need to include cases where \r is not followed by \n.
|
||||||
|
// Note, this behaviour is non-standard compliant (strictly speaking we should have no
|
||||||
|
// special logic for \r), but we preserve compatibility with EncodedReadableHandle and
|
||||||
|
// previous behaviour of the io library.
|
||||||
|
if( readRc ) stream.write( '\r' );
|
||||||
|
readRc = chr == '\r';
|
||||||
|
if( !readRc ) stream.write( chr );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return readAnything ? new Object[] { stream.toByteArray() } : null;
|
|
||||||
}
|
}
|
||||||
catch( IOException e )
|
catch( IOException e )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,12 +26,14 @@ public class ResourceQueue<T extends Resource<T>> extends ResourceGroup<T>
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized void shutdown()
|
public synchronized void shutdown()
|
||||||
{
|
{
|
||||||
super.shutdown();
|
super.shutdown();
|
||||||
pending.clear();
|
pending.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized boolean queue( Supplier<T> resource )
|
public synchronized boolean queue( Supplier<T> resource )
|
||||||
{
|
{
|
||||||
if( !active ) return false;
|
if( !active ) return false;
|
||||||
@@ -40,6 +42,7 @@ public class ResourceQueue<T extends Resource<T>> extends ResourceGroup<T>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized void release( T resource )
|
public synchronized void release( T resource )
|
||||||
{
|
{
|
||||||
super.release( resource );
|
super.release( resource );
|
||||||
|
|||||||
@@ -239,6 +239,7 @@ public class HttpRequest extends Resource<HttpRequest>
|
|||||||
if( tryClose() ) environment.queueEvent( SUCCESS_EVENT, new Object[] { address, object } );
|
if( tryClose() ) environment.queueEvent( SUCCESS_EVENT, new Object[] { address, object } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void dispose()
|
protected void dispose()
|
||||||
{
|
{
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|||||||
@@ -161,7 +161,10 @@ public class Websocket extends Resource<Websocket>
|
|||||||
}
|
}
|
||||||
} )
|
} )
|
||||||
.remoteAddress( socketAddress )
|
.remoteAddress( socketAddress )
|
||||||
.connect();
|
.connect()
|
||||||
|
.addListener( c -> {
|
||||||
|
if( !c.isSuccess() ) failure( c.cause().getMessage() );
|
||||||
|
} );
|
||||||
|
|
||||||
// Do an additional check for cancellation
|
// Do an additional check for cancellation
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
|||||||
@@ -83,6 +83,11 @@ public class WebsocketHandler extends SimpleChannelInboundHandler<Object>
|
|||||||
CloseWebSocketFrame closeFrame = (CloseWebSocketFrame) frame;
|
CloseWebSocketFrame closeFrame = (CloseWebSocketFrame) frame;
|
||||||
websocket.close( closeFrame.statusCode(), closeFrame.reasonText() );
|
websocket.close( closeFrame.statusCode(), closeFrame.reasonText() );
|
||||||
}
|
}
|
||||||
|
else if( frame instanceof PingWebSocketFrame )
|
||||||
|
{
|
||||||
|
frame.content().retain();
|
||||||
|
ctx.channel().writeAndFlush( new PongWebSocketFrame( frame.content() ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -108,6 +113,13 @@ public class WebsocketHandler extends SimpleChannelInboundHandler<Object>
|
|||||||
message = "Could not connect";
|
message = "Could not connect";
|
||||||
}
|
}
|
||||||
|
|
||||||
websocket.failure( message );
|
if( handshaker.isHandshakeComplete() )
|
||||||
|
{
|
||||||
|
websocket.close( -1, message );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
websocket.failure( message );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.computer;
|
||||||
|
|
||||||
|
import dan200.computercraft.api.lua.ILuaAPI;
|
||||||
|
import dan200.computercraft.api.lua.ILuaContext;
|
||||||
|
import dan200.computercraft.api.lua.LuaException;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper for {@link ILuaAPI}s which cleans up after a {@link ComputerSystem} when the computer is shutdown.
|
||||||
|
*/
|
||||||
|
public class ApiWrapper implements ILuaAPI
|
||||||
|
{
|
||||||
|
private final ILuaAPI delegate;
|
||||||
|
private final ComputerSystem system;
|
||||||
|
|
||||||
|
ApiWrapper( ILuaAPI delegate, ComputerSystem system )
|
||||||
|
{
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.system = system;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getNames()
|
||||||
|
{
|
||||||
|
return delegate.getNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startup()
|
||||||
|
{
|
||||||
|
delegate.startup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update()
|
||||||
|
{
|
||||||
|
delegate.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown()
|
||||||
|
{
|
||||||
|
delegate.shutdown();
|
||||||
|
system.unmountAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String[] getMethodNames()
|
||||||
|
{
|
||||||
|
return delegate.getMethodNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException
|
||||||
|
{
|
||||||
|
return delegate.callMethod( context, method, arguments );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,11 +8,10 @@ package dan200.computercraft.core.computer;
|
|||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.filesystem.IFileSystem;
|
|
||||||
import dan200.computercraft.api.filesystem.IMount;
|
import dan200.computercraft.api.filesystem.IMount;
|
||||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||||
import dan200.computercraft.api.lua.ILuaAPI;
|
import dan200.computercraft.api.lua.ILuaAPI;
|
||||||
import dan200.computercraft.api.lua.*;
|
import dan200.computercraft.api.lua.ILuaAPIFactory;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.core.apis.*;
|
import dan200.computercraft.core.apis.*;
|
||||||
import dan200.computercraft.core.filesystem.FileSystem;
|
import dan200.computercraft.core.filesystem.FileSystem;
|
||||||
@@ -20,11 +19,7 @@ import dan200.computercraft.core.filesystem.FileSystemException;
|
|||||||
import dan200.computercraft.core.lua.CobaltLuaMachine;
|
import dan200.computercraft.core.lua.CobaltLuaMachine;
|
||||||
import dan200.computercraft.core.lua.ILuaMachine;
|
import dan200.computercraft.core.lua.ILuaMachine;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.core.tracking.Tracking;
|
|
||||||
import dan200.computercraft.core.tracking.TrackingField;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -32,10 +27,6 @@ import java.util.List;
|
|||||||
|
|
||||||
public class Computer
|
public class Computer
|
||||||
{
|
{
|
||||||
public static final String[] s_sideNames = new String[] {
|
|
||||||
"bottom", "top", "back", "front", "right", "left",
|
|
||||||
};
|
|
||||||
|
|
||||||
private enum State
|
private enum State
|
||||||
{
|
{
|
||||||
Off,
|
Off,
|
||||||
@@ -44,319 +35,81 @@ public class Computer
|
|||||||
Stopping,
|
Stopping,
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class APIEnvironment implements IAPIEnvironment
|
|
||||||
{
|
|
||||||
private Computer m_computer;
|
|
||||||
private IAPIEnvironment.IPeripheralChangeListener m_peripheralListener;
|
|
||||||
|
|
||||||
public APIEnvironment( Computer computer )
|
|
||||||
{
|
|
||||||
m_computer = computer;
|
|
||||||
m_peripheralListener = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Computer getComputer()
|
|
||||||
{
|
|
||||||
return m_computer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getComputerID()
|
|
||||||
{
|
|
||||||
return m_computer.assignID();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IComputerEnvironment getComputerEnvironment()
|
|
||||||
{
|
|
||||||
return m_computer.m_environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Terminal getTerminal()
|
|
||||||
{
|
|
||||||
return m_computer.m_terminal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileSystem getFileSystem()
|
|
||||||
{
|
|
||||||
return m_computer.m_fileSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void shutdown()
|
|
||||||
{
|
|
||||||
m_computer.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reboot()
|
|
||||||
{
|
|
||||||
m_computer.reboot();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void queueEvent( String event, Object[] args )
|
|
||||||
{
|
|
||||||
m_computer.queueEvent( event, args );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOutput( int side, int output )
|
|
||||||
{
|
|
||||||
m_computer.setRedstoneOutput( side, output );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOutput( int side )
|
|
||||||
{
|
|
||||||
return m_computer.getInternalRedstoneOutput( side );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInput( int side )
|
|
||||||
{
|
|
||||||
return m_computer.getRedstoneInput( side );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBundledOutput( int side, int output )
|
|
||||||
{
|
|
||||||
m_computer.setBundledRedstoneOutput( side, output );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBundledOutput( int side )
|
|
||||||
{
|
|
||||||
return m_computer.getInternalBundledRedstoneOutput( side );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBundledInput( int side )
|
|
||||||
{
|
|
||||||
return m_computer.getBundledRedstoneInput( side );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPeripheral getPeripheral( int side )
|
|
||||||
{
|
|
||||||
synchronized( m_computer.m_peripherals )
|
|
||||||
{
|
|
||||||
return m_computer.m_peripherals[side];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPeripheralChangeListener( IPeripheralChangeListener listener )
|
|
||||||
{
|
|
||||||
synchronized( m_computer.m_peripherals )
|
|
||||||
{
|
|
||||||
m_peripheralListener = listener;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLabel()
|
|
||||||
{
|
|
||||||
return m_computer.getLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLabel( String label )
|
|
||||||
{
|
|
||||||
m_computer.setLabel( label );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTrackingChange( TrackingField field, long change )
|
|
||||||
{
|
|
||||||
Tracking.addValue( m_computer, field, change );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPeripheralChanged( int side, IPeripheral peripheral )
|
|
||||||
{
|
|
||||||
synchronized( m_computer.m_peripherals )
|
|
||||||
{
|
|
||||||
if( m_peripheralListener != null )
|
|
||||||
{
|
|
||||||
m_peripheralListener.onPeripheralChanged( side, peripheral );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ComputerSystem extends ComputerAccess implements IComputerSystem
|
|
||||||
{
|
|
||||||
private final IAPIEnvironment m_environment;
|
|
||||||
|
|
||||||
private ComputerSystem( IAPIEnvironment m_environment )
|
|
||||||
{
|
|
||||||
super( m_environment );
|
|
||||||
this.m_environment = m_environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public String getAttachmentName()
|
|
||||||
{
|
|
||||||
return "computer";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public IFileSystem getFileSystem()
|
|
||||||
{
|
|
||||||
FileSystem fs = m_environment.getFileSystem();
|
|
||||||
return fs == null ? null : fs.getMountWrapper();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public String getLabel()
|
|
||||||
{
|
|
||||||
return m_environment.getLabel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class APIWrapper implements ILuaAPI
|
|
||||||
{
|
|
||||||
private final ILuaAPI delegate;
|
|
||||||
private final ComputerSystem system;
|
|
||||||
|
|
||||||
private APIWrapper( ILuaAPI delegate, ComputerSystem system )
|
|
||||||
{
|
|
||||||
this.delegate = delegate;
|
|
||||||
this.system = system;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getNames()
|
|
||||||
{
|
|
||||||
return delegate.getNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startup()
|
|
||||||
{
|
|
||||||
delegate.startup();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update()
|
|
||||||
{
|
|
||||||
delegate.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void shutdown()
|
|
||||||
{
|
|
||||||
delegate.shutdown();
|
|
||||||
system.unmountAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public String[] getMethodNames()
|
|
||||||
{
|
|
||||||
return delegate.getMethodNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException
|
|
||||||
{
|
|
||||||
return delegate.callMethod( context, method, arguments );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IMount s_romMount = null;
|
private static IMount s_romMount = null;
|
||||||
|
|
||||||
private int m_id;
|
private int m_id;
|
||||||
private String m_label;
|
private String m_label = null;
|
||||||
private final IComputerEnvironment m_environment;
|
private final IComputerEnvironment m_environment;
|
||||||
|
|
||||||
private int m_ticksSinceStart;
|
private int m_ticksSinceStart = -1;
|
||||||
private boolean m_startRequested;
|
private boolean m_startRequested = false;
|
||||||
private State m_state;
|
private State m_state = State.Off;
|
||||||
private boolean m_blinking;
|
private boolean m_blinking = false;
|
||||||
|
|
||||||
private ILuaMachine m_machine;
|
private ILuaMachine m_machine = null;
|
||||||
private final List<ILuaAPI> m_apis;
|
private final List<ILuaAPI> m_apis = new ArrayList<>();
|
||||||
private final APIEnvironment m_apiEnvironment;
|
private final Environment m_internalEnvironment = new Environment( this );
|
||||||
|
|
||||||
private final Terminal m_terminal;
|
private final Terminal m_terminal;
|
||||||
private FileSystem m_fileSystem;
|
private FileSystem m_fileSystem = null;
|
||||||
private IWritableMount m_rootMount;
|
private IWritableMount m_rootMount = null;
|
||||||
|
|
||||||
private final int[] m_internalOutput;
|
|
||||||
private final int[] m_internalBundledOutput;
|
|
||||||
private boolean m_internalOutputChanged;
|
|
||||||
|
|
||||||
private final int[] m_externalOutput;
|
|
||||||
private final int[] m_externalBundledOutput;
|
|
||||||
private boolean m_externalOutputChanged;
|
private boolean m_externalOutputChanged;
|
||||||
|
|
||||||
private final int[] m_input;
|
|
||||||
private final int[] m_bundledInput;
|
|
||||||
private boolean m_inputChanged;
|
|
||||||
|
|
||||||
private final IPeripheral[] m_peripherals;
|
|
||||||
|
|
||||||
public Computer( IComputerEnvironment environment, Terminal terminal, int id )
|
public Computer( IComputerEnvironment environment, Terminal terminal, int id )
|
||||||
{
|
{
|
||||||
|
m_id = id;
|
||||||
|
m_environment = environment;
|
||||||
|
m_terminal = terminal;
|
||||||
|
|
||||||
|
// Ensure the computer thread is running as required.
|
||||||
ComputerThread.start();
|
ComputerThread.start();
|
||||||
|
|
||||||
m_id = id;
|
// Add all default APIs to the loaded list.
|
||||||
m_label = null;
|
m_apis.add( new TermAPI( m_internalEnvironment ) );
|
||||||
m_environment = environment;
|
m_apis.add( new RedstoneAPI( m_internalEnvironment ) );
|
||||||
|
m_apis.add( new FSAPI( m_internalEnvironment ) );
|
||||||
|
m_apis.add( new PeripheralAPI( m_internalEnvironment ) );
|
||||||
|
m_apis.add( new OSAPI( m_internalEnvironment ) );
|
||||||
|
if( ComputerCraft.http_enable ) m_apis.add( new HTTPAPI( m_internalEnvironment ) );
|
||||||
|
|
||||||
m_ticksSinceStart = -1;
|
// Load in the API registered APIs.
|
||||||
m_startRequested = false;
|
for( ILuaAPIFactory factory : ApiFactories.getAll() )
|
||||||
m_state = State.Off;
|
|
||||||
m_blinking = false;
|
|
||||||
|
|
||||||
m_terminal = terminal;
|
|
||||||
m_fileSystem = null;
|
|
||||||
|
|
||||||
m_machine = null;
|
|
||||||
m_apis = new ArrayList<>();
|
|
||||||
m_apiEnvironment = new APIEnvironment( this );
|
|
||||||
|
|
||||||
m_internalOutput = new int[6];
|
|
||||||
m_internalBundledOutput = new int[6];
|
|
||||||
m_internalOutputChanged = true;
|
|
||||||
|
|
||||||
m_externalOutput = new int[6];
|
|
||||||
m_externalBundledOutput = new int[6];
|
|
||||||
m_externalOutputChanged = true;
|
|
||||||
|
|
||||||
m_input = new int[6];
|
|
||||||
m_bundledInput = new int[6];
|
|
||||||
m_inputChanged = false;
|
|
||||||
|
|
||||||
m_peripherals = new IPeripheral[6];
|
|
||||||
for( int i = 0; i < 6; i++ )
|
|
||||||
{
|
{
|
||||||
m_peripherals[i] = null;
|
ComputerSystem system = new ComputerSystem( m_internalEnvironment );
|
||||||
|
ILuaAPI api = factory.create( system );
|
||||||
|
if( api != null ) m_apis.add( new ApiWrapper( api, system ) );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_rootMount = null;
|
IComputerEnvironment getComputerEnvironment()
|
||||||
createAPIs();
|
{
|
||||||
|
return m_environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSystem getFileSystem()
|
||||||
|
{
|
||||||
|
return m_fileSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
Terminal getTerminal()
|
||||||
|
{
|
||||||
|
return m_terminal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Environment getEnvironment()
|
||||||
|
{
|
||||||
|
return m_internalEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAPIEnvironment getAPIEnvironment()
|
public IAPIEnvironment getAPIEnvironment()
|
||||||
{
|
{
|
||||||
return m_apiEnvironment;
|
return m_internalEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void turnOn()
|
public void turnOn()
|
||||||
{
|
{
|
||||||
if( m_state == State.Off )
|
if( m_state == State.Off ) m_startRequested = true;
|
||||||
{
|
|
||||||
m_startRequested = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutdown()
|
public void shutdown()
|
||||||
@@ -397,10 +150,7 @@ public class Computer
|
|||||||
|
|
||||||
public void unload()
|
public void unload()
|
||||||
{
|
{
|
||||||
synchronized( this )
|
stopComputer( false );
|
||||||
{
|
|
||||||
stopComputer( false );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getID()
|
public int getID()
|
||||||
@@ -436,7 +186,7 @@ public class Computer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void advance( double _dt )
|
public void advance()
|
||||||
{
|
{
|
||||||
synchronized( this )
|
synchronized( this )
|
||||||
{
|
{
|
||||||
@@ -453,67 +203,27 @@ public class Computer
|
|||||||
|
|
||||||
if( m_state == State.Running )
|
if( m_state == State.Running )
|
||||||
{
|
{
|
||||||
// Fire the redstone event if our redstone input has changed
|
// Update the environment's internal state.
|
||||||
synchronized( m_input )
|
m_internalEnvironment.update();
|
||||||
{
|
|
||||||
if( m_inputChanged )
|
|
||||||
{
|
|
||||||
queueEvent( "redstone", null );
|
|
||||||
m_inputChanged = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Advance our APIs
|
// Advance our APIs
|
||||||
synchronized( m_apis )
|
for( ILuaAPI api : m_apis ) api.update();
|
||||||
{
|
|
||||||
for( ILuaAPI api : m_apis )
|
|
||||||
{
|
|
||||||
api.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set outputchanged if the internal redstone has changed
|
// Prepare to propagate the environment's output to the world.
|
||||||
synchronized( m_internalOutput )
|
if( m_internalEnvironment.updateOutput() ) m_externalOutputChanged = true;
|
||||||
{
|
|
||||||
if( m_internalOutputChanged )
|
|
||||||
{
|
|
||||||
boolean changed = false;
|
|
||||||
for( int i = 0; i < 6; i++ )
|
|
||||||
{
|
|
||||||
if( m_externalOutput[i] != m_internalOutput[i] )
|
|
||||||
{
|
|
||||||
m_externalOutput[i] = m_internalOutput[i];
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if( m_externalBundledOutput[i] != m_internalBundledOutput[i] )
|
|
||||||
{
|
|
||||||
m_externalBundledOutput[i] = m_internalBundledOutput[i];
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_internalOutputChanged = false;
|
|
||||||
if( changed )
|
|
||||||
{
|
|
||||||
m_externalOutputChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set outputchanged if the terminal has changed from blinking to not
|
// Set output changed if the terminal has changed from blinking to not
|
||||||
synchronized( m_terminal )
|
boolean blinking =
|
||||||
{
|
m_terminal.getCursorBlink() &&
|
||||||
boolean blinking =
|
m_terminal.getCursorX() >= 0 && m_terminal.getCursorX() < m_terminal.getWidth() &&
|
||||||
m_terminal.getCursorBlink() &&
|
m_terminal.getCursorY() >= 0 && m_terminal.getCursorY() < m_terminal.getHeight();
|
||||||
m_terminal.getCursorX() >= 0 && m_terminal.getCursorX() < m_terminal.getWidth() &&
|
|
||||||
m_terminal.getCursorY() >= 0 && m_terminal.getCursorY() < m_terminal.getHeight();
|
|
||||||
|
|
||||||
if( blinking != m_blinking )
|
if( blinking != m_blinking )
|
||||||
{
|
{
|
||||||
m_blinking = blinking;
|
m_blinking = blinking;
|
||||||
m_externalOutputChanged = true;
|
m_externalOutputChanged = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,10 +239,7 @@ public class Computer
|
|||||||
|
|
||||||
public boolean isBlinking()
|
public boolean isBlinking()
|
||||||
{
|
{
|
||||||
synchronized( m_terminal )
|
return isOn() && m_blinking;
|
||||||
{
|
|
||||||
return isOn() && m_blinking;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWritableMount getRootMount()
|
public IWritableMount getRootMount()
|
||||||
@@ -553,10 +260,7 @@ public class Computer
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_fileSystem = new FileSystem( "hdd", getRootMount() );
|
m_fileSystem = new FileSystem( "hdd", getRootMount() );
|
||||||
if( s_romMount == null )
|
if( s_romMount == null ) s_romMount = m_environment.createResourceMount( "computercraft", "lua/rom" );
|
||||||
{
|
|
||||||
s_romMount = m_environment.createResourceMount( "computercraft", "lua/rom" );
|
|
||||||
}
|
|
||||||
if( s_romMount != null )
|
if( s_romMount != null )
|
||||||
{
|
{
|
||||||
m_fileSystem.mount( "rom", "rom", s_romMount );
|
m_fileSystem.mount( "rom", "rom", s_romMount );
|
||||||
@@ -571,104 +275,6 @@ public class Computer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redstone
|
|
||||||
|
|
||||||
public int getRedstoneOutput( int side )
|
|
||||||
{
|
|
||||||
synchronized( m_internalOutput )
|
|
||||||
{
|
|
||||||
return isOn() ? m_externalOutput[side] : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getInternalRedstoneOutput( int side )
|
|
||||||
{
|
|
||||||
synchronized( m_internalOutput )
|
|
||||||
{
|
|
||||||
return isOn() ? m_internalOutput[side] : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setRedstoneOutput( int side, int level )
|
|
||||||
{
|
|
||||||
synchronized( m_internalOutput )
|
|
||||||
{
|
|
||||||
if( m_internalOutput[side] != level )
|
|
||||||
{
|
|
||||||
m_internalOutput[side] = level;
|
|
||||||
m_internalOutputChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedstoneInput( int side, int level )
|
|
||||||
{
|
|
||||||
synchronized( m_input )
|
|
||||||
{
|
|
||||||
if( m_input[side] != level )
|
|
||||||
{
|
|
||||||
m_input[side] = level;
|
|
||||||
m_inputChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getRedstoneInput( int side )
|
|
||||||
{
|
|
||||||
synchronized( m_input )
|
|
||||||
{
|
|
||||||
return m_input[side];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBundledRedstoneOutput( int side )
|
|
||||||
{
|
|
||||||
synchronized( m_internalOutput )
|
|
||||||
{
|
|
||||||
return isOn() ? m_externalBundledOutput[side] : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getInternalBundledRedstoneOutput( int side )
|
|
||||||
{
|
|
||||||
synchronized( m_internalOutput )
|
|
||||||
{
|
|
||||||
return isOn() ? m_internalBundledOutput[side] : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setBundledRedstoneOutput( int side, int combination )
|
|
||||||
{
|
|
||||||
synchronized( m_internalOutput )
|
|
||||||
{
|
|
||||||
if( m_internalBundledOutput[side] != combination )
|
|
||||||
{
|
|
||||||
m_internalBundledOutput[side] = combination;
|
|
||||||
m_internalOutputChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBundledRedstoneInput( int side, int combination )
|
|
||||||
{
|
|
||||||
synchronized( m_input )
|
|
||||||
{
|
|
||||||
if( m_bundledInput[side] != combination )
|
|
||||||
{
|
|
||||||
m_bundledInput[side] = combination;
|
|
||||||
m_inputChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getBundledRedstoneInput( int side )
|
|
||||||
{
|
|
||||||
synchronized( m_input )
|
|
||||||
{
|
|
||||||
return m_bundledInput[side];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Peripherals
|
// Peripherals
|
||||||
|
|
||||||
public void addAPI( ILuaAPI api )
|
public void addAPI( ILuaAPI api )
|
||||||
@@ -676,57 +282,8 @@ public class Computer
|
|||||||
m_apis.add( api );
|
m_apis.add( api );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( "deprecation" )
|
|
||||||
public void addAPI( dan200.computercraft.core.apis.ILuaAPI api )
|
|
||||||
{
|
|
||||||
addAPI( (ILuaAPI) api );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPeripheral( int side, IPeripheral peripheral )
|
|
||||||
{
|
|
||||||
synchronized( m_peripherals )
|
|
||||||
{
|
|
||||||
IPeripheral existing = m_peripherals[side];
|
|
||||||
if( (existing == null && peripheral != null) ||
|
|
||||||
(existing != null && peripheral == null) ||
|
|
||||||
(existing != null && !existing.equals( peripheral )) )
|
|
||||||
{
|
|
||||||
m_peripherals[side] = peripheral;
|
|
||||||
m_apiEnvironment.onPeripheralChanged( side, peripheral );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IPeripheral getPeripheral( int side )
|
|
||||||
{
|
|
||||||
synchronized( m_peripherals )
|
|
||||||
{
|
|
||||||
return m_peripherals[side];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lua
|
// Lua
|
||||||
|
|
||||||
private void createAPIs()
|
|
||||||
{
|
|
||||||
m_apis.add( new TermAPI( m_apiEnvironment ) );
|
|
||||||
m_apis.add( new RedstoneAPI( m_apiEnvironment ) );
|
|
||||||
m_apis.add( new FSAPI( m_apiEnvironment ) );
|
|
||||||
m_apis.add( new PeripheralAPI( m_apiEnvironment ) );
|
|
||||||
m_apis.add( new OSAPI( m_apiEnvironment ) );
|
|
||||||
if( ComputerCraft.http_enable )
|
|
||||||
{
|
|
||||||
m_apis.add( new HTTPAPI( m_apiEnvironment ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
for( ILuaAPIFactory factory : ApiFactories.getAll() )
|
|
||||||
{
|
|
||||||
ComputerSystem system = new ComputerSystem( m_apiEnvironment );
|
|
||||||
ILuaAPI api = factory.create( system );
|
|
||||||
if( api != null ) m_apis.add( api );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initLua()
|
private void initLua()
|
||||||
{
|
{
|
||||||
// Create the lua machine
|
// Create the lua machine
|
||||||
@@ -824,10 +381,7 @@ public class Computer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init terminal
|
// Init terminal
|
||||||
synchronized( m_terminal )
|
m_terminal.reset();
|
||||||
{
|
|
||||||
m_terminal.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init filesystem
|
// Init filesystem
|
||||||
if( !initFileSystem() )
|
if( !initFileSystem() )
|
||||||
@@ -920,10 +474,7 @@ public class Computer
|
|||||||
|
|
||||||
if( m_machine != null )
|
if( m_machine != null )
|
||||||
{
|
{
|
||||||
synchronized( m_terminal )
|
m_terminal.reset();
|
||||||
{
|
|
||||||
m_terminal.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized( m_machine )
|
synchronized( m_machine )
|
||||||
{
|
{
|
||||||
@@ -933,15 +484,7 @@ public class Computer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reset redstone output
|
// Reset redstone output
|
||||||
synchronized( m_internalOutput )
|
m_internalEnvironment.resetOutput();
|
||||||
{
|
|
||||||
for( int i = 0; i < 6; i++ )
|
|
||||||
{
|
|
||||||
m_internalOutput[i] = 0;
|
|
||||||
m_internalBundledOutput[i] = 0;
|
|
||||||
}
|
|
||||||
m_internalOutputChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_state = State.Off;
|
m_state = State.Off;
|
||||||
m_externalOutputChanged = true;
|
m_externalOutputChanged = true;
|
||||||
@@ -1002,4 +545,31 @@ public class Computer
|
|||||||
|
|
||||||
ComputerThread.queueTask( task, computer );
|
ComputerThread.queueTask( task, computer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public IPeripheral getPeripheral( int side )
|
||||||
|
{
|
||||||
|
return m_internalEnvironment.getPeripheral( side );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void setPeripheral( int side, IPeripheral peripheral )
|
||||||
|
{
|
||||||
|
m_internalEnvironment.setPeripheral( side, peripheral );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void addAPI( dan200.computercraft.core.apis.ILuaAPI api )
|
||||||
|
{
|
||||||
|
addAPI( (ILuaAPI) api );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@SuppressWarnings( "unused" )
|
||||||
|
public void advance( double dt )
|
||||||
|
{
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String[] s_sideNames = IAPIEnvironment.SIDE_NAMES;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.computer;
|
||||||
|
|
||||||
|
import dan200.computercraft.api.filesystem.IFileSystem;
|
||||||
|
import dan200.computercraft.api.lua.IComputerSystem;
|
||||||
|
import dan200.computercraft.api.lua.ILuaAPIFactory;
|
||||||
|
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||||
|
import dan200.computercraft.core.apis.ComputerAccess;
|
||||||
|
import dan200.computercraft.core.apis.IAPIEnvironment;
|
||||||
|
import dan200.computercraft.core.filesystem.FileSystem;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link IComputerAccess}/{@link IComputerSystem} for external APIs.
|
||||||
|
*
|
||||||
|
* @see dan200.computercraft.api.ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory)
|
||||||
|
* @see ILuaAPIFactory
|
||||||
|
* @see ApiWrapper
|
||||||
|
*/
|
||||||
|
public class ComputerSystem extends ComputerAccess implements IComputerSystem
|
||||||
|
{
|
||||||
|
private final IAPIEnvironment m_environment;
|
||||||
|
|
||||||
|
ComputerSystem( IAPIEnvironment m_environment )
|
||||||
|
{
|
||||||
|
super( m_environment );
|
||||||
|
this.m_environment = m_environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getAttachmentName()
|
||||||
|
{
|
||||||
|
return "computer";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IFileSystem getFileSystem()
|
||||||
|
{
|
||||||
|
FileSystem fs = m_environment.getFileSystem();
|
||||||
|
return fs == null ? null : fs.getMountWrapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getLabel()
|
||||||
|
{
|
||||||
|
return m_environment.getLabel();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ import java.util.WeakHashMap;
|
|||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
public class ComputerThread
|
public class ComputerThread
|
||||||
{
|
{
|
||||||
@@ -216,22 +217,37 @@ public class ComputerThread
|
|||||||
// Interrupt the thread
|
// Interrupt the thread
|
||||||
if( !done )
|
if( !done )
|
||||||
{
|
{
|
||||||
StringBuilder builder = new StringBuilder( "Terminating " );
|
if( ComputerCraft.logPeripheralErrors )
|
||||||
if( computer != null )
|
|
||||||
{
|
{
|
||||||
builder.append( "computer " ).append( computer.getID() );
|
long time = System.nanoTime() - start;
|
||||||
}
|
StringBuilder builder = new StringBuilder( "Terminating " );
|
||||||
else
|
if( computer != null )
|
||||||
{
|
{
|
||||||
builder.append( "unknown computer" );
|
builder.append( "computer #" ).append( computer.getID() );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.append( "unknown computer" );
|
||||||
|
}
|
||||||
|
|
||||||
builder.append( ". Thread is currently running" );
|
{
|
||||||
for( StackTraceElement element : thread.getStackTrace() )
|
builder.append( " due to timeout (running for " )
|
||||||
{
|
.append( time / 1e9 )
|
||||||
builder.append( "\n at " ).append( element );
|
.append( " seconds). This is NOT a bug, but may mean a computer is misbehaving. " )
|
||||||
|
.append( thread.getName() )
|
||||||
|
.append( " is currently " )
|
||||||
|
.append( thread.getState() );
|
||||||
|
Object blocking = LockSupport.getBlocker( thread );
|
||||||
|
if( blocking != null ) builder.append( "\n on " ).append( blocking );
|
||||||
|
|
||||||
|
for( StackTraceElement element : thread.getStackTrace() )
|
||||||
|
{
|
||||||
|
builder.append( "\n at " ).append( element );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ComputerCraft.log.warn( builder.toString() );
|
||||||
}
|
}
|
||||||
ComputerCraft.log.error( builder.toString() );
|
|
||||||
|
|
||||||
thread.interrupt();
|
thread.interrupt();
|
||||||
thread = null;
|
thread = null;
|
||||||
|
|||||||
@@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.computer;
|
||||||
|
|
||||||
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
import dan200.computercraft.core.apis.IAPIEnvironment;
|
||||||
|
import dan200.computercraft.core.filesystem.FileSystem;
|
||||||
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
|
import dan200.computercraft.core.tracking.Tracking;
|
||||||
|
import dan200.computercraft.core.tracking.TrackingField;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the "environment" that a {@link Computer} exists in.
|
||||||
|
*
|
||||||
|
* This handles storing and updating of peripherals and redstone.
|
||||||
|
*
|
||||||
|
* <h2>Redstone</h2>
|
||||||
|
* We holds three kinds of arrays for redstone, in normal and bundled versions:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link #internalOutput} is the redstone output which the computer has currently set. This is read on both
|
||||||
|
* threads, and written on the computer thread.</li>
|
||||||
|
* <li>{@link #externalOutput} is the redstone output currently propagated to the world. This is only read and written
|
||||||
|
* on the main thread.</li>
|
||||||
|
* <li>{@link #input} is the redstone input from external sources. This is read on both threads, and written on the main
|
||||||
|
* thread.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <h2>Peripheral</h2>
|
||||||
|
* We also keep track of peripherals. These are read on both threads, and only written on the main thread.
|
||||||
|
*/
|
||||||
|
public final class Environment implements IAPIEnvironment
|
||||||
|
{
|
||||||
|
private final Computer computer;
|
||||||
|
|
||||||
|
private boolean internalOutputChanged = false;
|
||||||
|
private final int[] internalOutput = new int[SIDE_COUNT];
|
||||||
|
private final int[] internalBundledOutput = new int[SIDE_COUNT];
|
||||||
|
|
||||||
|
private final int[] externalOutput = new int[SIDE_COUNT];
|
||||||
|
private final int[] externalBundledOutput = new int[SIDE_COUNT];
|
||||||
|
|
||||||
|
private boolean inputChanged = false;
|
||||||
|
private final int[] input = new int[SIDE_COUNT];
|
||||||
|
private final int[] bundledInput = new int[SIDE_COUNT];
|
||||||
|
|
||||||
|
private final IPeripheral[] peripherals = new IPeripheral[SIDE_COUNT];
|
||||||
|
private IPeripheralChangeListener peripheralListener = null;
|
||||||
|
|
||||||
|
Environment( Computer computer )
|
||||||
|
{
|
||||||
|
this.computer = computer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Computer getComputer()
|
||||||
|
{
|
||||||
|
return computer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getComputerID()
|
||||||
|
{
|
||||||
|
return computer.assignID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public IComputerEnvironment getComputerEnvironment()
|
||||||
|
{
|
||||||
|
return computer.getComputerEnvironment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Terminal getTerminal()
|
||||||
|
{
|
||||||
|
return computer.getTerminal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileSystem getFileSystem()
|
||||||
|
{
|
||||||
|
return computer.getFileSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown()
|
||||||
|
{
|
||||||
|
computer.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reboot()
|
||||||
|
{
|
||||||
|
computer.reboot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueEvent( String event, Object[] args )
|
||||||
|
{
|
||||||
|
computer.queueEvent( event, args );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInput( int side )
|
||||||
|
{
|
||||||
|
return input[side];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBundledInput( int side )
|
||||||
|
{
|
||||||
|
return bundledInput[side];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOutput( int side, int output )
|
||||||
|
{
|
||||||
|
synchronized( internalOutput )
|
||||||
|
{
|
||||||
|
if( internalOutput[side] != output )
|
||||||
|
{
|
||||||
|
internalOutput[side] = output;
|
||||||
|
internalOutputChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOutput( int side )
|
||||||
|
{
|
||||||
|
synchronized( internalOutput )
|
||||||
|
{
|
||||||
|
return computer.isOn() ? internalOutput[side] : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBundledOutput( int side, int output )
|
||||||
|
{
|
||||||
|
synchronized( internalOutput )
|
||||||
|
{
|
||||||
|
if( internalBundledOutput[side] != output )
|
||||||
|
{
|
||||||
|
internalBundledOutput[side] = output;
|
||||||
|
internalOutputChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBundledOutput( int side )
|
||||||
|
{
|
||||||
|
synchronized( internalOutput )
|
||||||
|
{
|
||||||
|
return computer.isOn() ? internalBundledOutput[side] : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExternalRedstoneOutput( int side )
|
||||||
|
{
|
||||||
|
return computer.isOn() ? externalOutput[side] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExternalBundledRedstoneOutput( int side )
|
||||||
|
{
|
||||||
|
return computer.isOn() ? externalBundledOutput[side] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRedstoneInput( int side, int level )
|
||||||
|
{
|
||||||
|
if( input[side] != level )
|
||||||
|
{
|
||||||
|
input[side] = level;
|
||||||
|
inputChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBundledRedstoneInput( int side, int combination )
|
||||||
|
{
|
||||||
|
if( bundledInput[side] != combination )
|
||||||
|
{
|
||||||
|
bundledInput[side] = combination;
|
||||||
|
inputChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on the main thread to update the internal state of the computer.
|
||||||
|
*
|
||||||
|
* This just queues a {@code redstone} event if the input has changed.
|
||||||
|
*/
|
||||||
|
void update()
|
||||||
|
{
|
||||||
|
if( inputChanged )
|
||||||
|
{
|
||||||
|
inputChanged = false;
|
||||||
|
queueEvent( "redstone", null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on the main thread to propagate the internal outputs to the external ones.
|
||||||
|
*
|
||||||
|
* @return If the outputs have changed.
|
||||||
|
*/
|
||||||
|
boolean updateOutput()
|
||||||
|
{
|
||||||
|
// Set outputchanged if the internal redstone has changed
|
||||||
|
synchronized( internalOutput )
|
||||||
|
{
|
||||||
|
if( !internalOutputChanged ) return false;
|
||||||
|
|
||||||
|
boolean changed = false;
|
||||||
|
|
||||||
|
for( int i = 0; i < SIDE_COUNT; i++ )
|
||||||
|
{
|
||||||
|
if( externalOutput[i] != internalOutput[i] )
|
||||||
|
{
|
||||||
|
externalOutput[i] = internalOutput[i];
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( externalBundledOutput[i] != internalBundledOutput[i] )
|
||||||
|
{
|
||||||
|
externalBundledOutput[i] = internalBundledOutput[i];
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internalOutputChanged = false;
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetOutput()
|
||||||
|
{
|
||||||
|
// Reset redstone output
|
||||||
|
synchronized( internalOutput )
|
||||||
|
{
|
||||||
|
Arrays.fill( internalOutput, 0 );
|
||||||
|
Arrays.fill( internalBundledOutput, 0 );
|
||||||
|
internalOutputChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPeripheral getPeripheral( int side )
|
||||||
|
{
|
||||||
|
synchronized( peripherals )
|
||||||
|
{
|
||||||
|
return peripherals[side];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPeripheral( int side, IPeripheral peripheral )
|
||||||
|
{
|
||||||
|
synchronized( peripherals )
|
||||||
|
{
|
||||||
|
IPeripheral existing = peripherals[side];
|
||||||
|
if( (existing == null && peripheral != null) ||
|
||||||
|
(existing != null && peripheral == null) ||
|
||||||
|
(existing != null && !existing.equals( peripheral )) )
|
||||||
|
{
|
||||||
|
peripherals[side] = peripheral;
|
||||||
|
if( peripheralListener != null ) peripheralListener.onPeripheralChanged( side, peripheral );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPeripheralChangeListener( IPeripheralChangeListener listener )
|
||||||
|
{
|
||||||
|
synchronized( peripherals )
|
||||||
|
{
|
||||||
|
peripheralListener = listener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLabel()
|
||||||
|
{
|
||||||
|
return computer.getLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLabel( String label )
|
||||||
|
{
|
||||||
|
computer.setLabel( label );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTrackingChange( @Nonnull TrackingField field, long change )
|
||||||
|
{
|
||||||
|
Tracking.addValue( computer, field, change );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,144 +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.core.filesystem;
|
|
||||||
|
|
||||||
import dan200.computercraft.api.filesystem.IMount;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.channels.ReadableByteChannel;
|
|
||||||
import java.nio.file.FileSystem;
|
|
||||||
import java.nio.file.*;
|
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class FileSystemMount implements IMount
|
|
||||||
{
|
|
||||||
private final Entry rootEntry;
|
|
||||||
|
|
||||||
public FileSystemMount( FileSystem fileSystem, String root ) throws IOException
|
|
||||||
{
|
|
||||||
Path rootPath = fileSystem.getPath( root );
|
|
||||||
rootEntry = new Entry( "", rootPath );
|
|
||||||
populate( rootEntry );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populate( Entry root ) throws IOException
|
|
||||||
{
|
|
||||||
if( !root.directory ) return;
|
|
||||||
|
|
||||||
Queue<Entry> entries = new ArrayDeque<>();
|
|
||||||
entries.add( root );
|
|
||||||
while( !entries.isEmpty() )
|
|
||||||
{
|
|
||||||
Entry entry = entries.remove();
|
|
||||||
try( Stream<Path> childStream = Files.list( entry.path ) )
|
|
||||||
{
|
|
||||||
Iterator<Path> children = childStream.iterator();
|
|
||||||
while( children.hasNext() )
|
|
||||||
{
|
|
||||||
Path childPath = children.next();
|
|
||||||
Entry child = new Entry( childPath.getFileName().toString(), childPath );
|
|
||||||
entry.children.put( child.name, child );
|
|
||||||
if( child.directory ) entries.add( child );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean exists( @Nonnull String path )
|
|
||||||
{
|
|
||||||
return getFile( path ) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDirectory( @Nonnull String path )
|
|
||||||
{
|
|
||||||
Entry entry = getFile( path );
|
|
||||||
return entry != null && entry.directory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException
|
|
||||||
{
|
|
||||||
Entry entry = getFile( path );
|
|
||||||
if( entry == null || !entry.directory ) throw new IOException( "/" + path + ": Not a directory" );
|
|
||||||
|
|
||||||
contents.addAll( entry.children.keySet() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getSize( @Nonnull String path ) throws IOException
|
|
||||||
{
|
|
||||||
Entry file = getFile( path );
|
|
||||||
if( file == null ) throw new IOException( "/" + path + ": No such file" );
|
|
||||||
return file.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public InputStream openForRead( @Nonnull String path ) throws IOException
|
|
||||||
{
|
|
||||||
Entry file = getFile( path );
|
|
||||||
if( file == null || file.directory ) throw new IOException( "/" + path + ": No such file" );
|
|
||||||
|
|
||||||
return Files.newInputStream( file.path, StandardOpenOption.READ );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOException
|
|
||||||
{
|
|
||||||
Entry file = getFile( path );
|
|
||||||
if( file == null || file.directory ) throw new IOException( "/" + path + ": No such file" );
|
|
||||||
|
|
||||||
return Files.newByteChannel( file.path, StandardOpenOption.READ );
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entry getFile( String path )
|
|
||||||
{
|
|
||||||
if( path.equals( "" ) ) return rootEntry;
|
|
||||||
if( !path.contains( "/" ) ) return rootEntry.children.get( path );
|
|
||||||
|
|
||||||
String[] components = path.split( "/" );
|
|
||||||
Entry entry = rootEntry;
|
|
||||||
for( String component : components )
|
|
||||||
{
|
|
||||||
if( entry == null || entry.children == null ) return null;
|
|
||||||
entry = entry.children.get( component );
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Entry
|
|
||||||
{
|
|
||||||
final String name;
|
|
||||||
final Path path;
|
|
||||||
|
|
||||||
final boolean directory;
|
|
||||||
final long size;
|
|
||||||
final Map<String, Entry> children;
|
|
||||||
|
|
||||||
private Entry( String name, Path path ) throws IOException
|
|
||||||
{
|
|
||||||
if( name.endsWith( "/" ) || name.endsWith( "\\" ) ) name = name.substring( 0, name.length() - 1 );
|
|
||||||
|
|
||||||
this.name = name;
|
|
||||||
this.path = path;
|
|
||||||
|
|
||||||
BasicFileAttributes attributes = Files.readAttributes( path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS );
|
|
||||||
this.directory = attributes.isDirectory();
|
|
||||||
this.size = directory ? 0 : attributes.size();
|
|
||||||
this.children = directory ? new HashMap<>() : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,242 +6,266 @@
|
|||||||
|
|
||||||
package dan200.computercraft.core.filesystem;
|
package dan200.computercraft.core.filesystem;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
import dan200.computercraft.api.filesystem.IMount;
|
import dan200.computercraft.api.filesystem.IMount;
|
||||||
|
import dan200.computercraft.core.apis.handles.ArrayByteChannel;
|
||||||
|
import dan200.computercraft.shared.util.IoUtil;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.ref.Reference;
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class JarMount implements IMount
|
public class JarMount implements IMount
|
||||||
{
|
{
|
||||||
private static class FileInZip
|
/**
|
||||||
{
|
* Only cache files smaller than 1MiB.
|
||||||
private String m_path;
|
*/
|
||||||
private boolean m_directory;
|
private static final int MAX_CACHED_SIZE = 1 << 20;
|
||||||
private long m_size;
|
|
||||||
private Map<String, FileInZip> m_children;
|
|
||||||
|
|
||||||
public FileInZip( String path, boolean directory, long size )
|
/**
|
||||||
{
|
* Limit the entire cache to 64MiB.
|
||||||
m_path = path;
|
*/
|
||||||
m_directory = directory;
|
private static final int MAX_CACHE_SIZE = 64 << 20;
|
||||||
m_size = m_directory ? 0 : size;
|
|
||||||
m_children = new LinkedHashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPath()
|
/**
|
||||||
{
|
* We maintain a cache of the contents of all files in the mount. This allows us to allow
|
||||||
return m_path;
|
* seeking within ROM files, and reduces the amount we need to access disk for computer startup.
|
||||||
}
|
*/
|
||||||
|
private static final Cache<FileEntry, byte[]> CONTENTS_CACHE = CacheBuilder.newBuilder()
|
||||||
|
.concurrencyLevel( 4 )
|
||||||
|
.expireAfterAccess( 60, TimeUnit.SECONDS )
|
||||||
|
.maximumWeight( MAX_CACHE_SIZE )
|
||||||
|
.weakKeys()
|
||||||
|
.<FileEntry, byte[]>weigher( ( k, v ) -> v.length )
|
||||||
|
.build();
|
||||||
|
|
||||||
public boolean isDirectory()
|
/**
|
||||||
{
|
* We have a {@link ReferenceQueue} of all mounts, a long with their corresponding {@link ZipFile}. If
|
||||||
return m_directory;
|
* the mount has been destroyed, we clean up after it.
|
||||||
}
|
*/
|
||||||
|
private static final ReferenceQueue<JarMount> MOUNT_QUEUE = new ReferenceQueue<>();
|
||||||
|
|
||||||
public long getSize()
|
private final ZipFile zip;
|
||||||
{
|
private final FileEntry root;
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void list( List<String> contents )
|
|
||||||
{
|
|
||||||
contents.addAll( m_children.keySet() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insertChild( FileInZip child )
|
|
||||||
{
|
|
||||||
String localPath = FileSystem.toLocal( child.getPath(), m_path );
|
|
||||||
m_children.put( localPath, child );
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileInZip getFile( String path )
|
|
||||||
{
|
|
||||||
// If we've reached the target, return this
|
|
||||||
if( path.equals( m_path ) )
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, get the next component of the path
|
|
||||||
String localPath = FileSystem.toLocal( path, m_path );
|
|
||||||
int slash = localPath.indexOf( "/" );
|
|
||||||
if( slash >= 0 )
|
|
||||||
{
|
|
||||||
localPath = localPath.substring( 0, slash );
|
|
||||||
}
|
|
||||||
|
|
||||||
// And recurse down using it
|
|
||||||
FileInZip subFile = m_children.get( localPath );
|
|
||||||
if( subFile != null )
|
|
||||||
{
|
|
||||||
return subFile.getFile( path );
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileInZip getParent( String path )
|
|
||||||
{
|
|
||||||
if( path.length() == 0 )
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInZip file = getFile( FileSystem.getDirectory( path ) );
|
|
||||||
if( file.isDirectory() )
|
|
||||||
{
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ZipFile m_zipFile;
|
|
||||||
private FileInZip m_root;
|
|
||||||
private String m_rootPath;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public JarMount( File jarFile, String subPath ) throws IOException
|
public JarMount( File jarFile, String subPath ) throws IOException
|
||||||
{
|
{
|
||||||
if( !jarFile.exists() || jarFile.isDirectory() )
|
// Cleanup any old mounts. It's unlikely that there will be any, but it's best to be safe.
|
||||||
{
|
cleanup();
|
||||||
throw new FileNotFoundException();
|
|
||||||
}
|
if( !jarFile.exists() || jarFile.isDirectory() ) throw new FileNotFoundException();
|
||||||
|
|
||||||
// Open the zip file
|
// Open the zip file
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_zipFile = new ZipFile( jarFile );
|
zip = new ZipFile( jarFile );
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
throw new IOException( "Error loading zip file" );
|
throw new IOException( "Error loading zip file" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_zipFile.getEntry( subPath ) == null )
|
// Ensure the root entry exists.
|
||||||
|
if( zip.getEntry( subPath ) == null )
|
||||||
{
|
{
|
||||||
m_zipFile.close();
|
zip.close();
|
||||||
throw new IOException( "Zip does not contain path" );
|
throw new IOException( "Zip does not contain path" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We now create a weak reference to this mount. This is automatically added to the appropriate queue.
|
||||||
|
new MountReference( this );
|
||||||
|
|
||||||
// Read in all the entries
|
// Read in all the entries
|
||||||
Enumeration<? extends ZipEntry> zipEntries = m_zipFile.entries();
|
root = new FileEntry( "" );
|
||||||
|
Enumeration<? extends ZipEntry> zipEntries = zip.entries();
|
||||||
while( zipEntries.hasMoreElements() )
|
while( zipEntries.hasMoreElements() )
|
||||||
{
|
{
|
||||||
ZipEntry entry = zipEntries.nextElement();
|
ZipEntry entry = zipEntries.nextElement();
|
||||||
String entryName = entry.getName();
|
|
||||||
if( entryName.startsWith( subPath ) )
|
String entryPath = entry.getName();
|
||||||
{
|
if( !entryPath.startsWith( subPath ) ) continue;
|
||||||
entryName = FileSystem.toLocal( entryName, subPath );
|
|
||||||
if( m_root == null )
|
String localPath = FileSystem.toLocal( entryPath, subPath );
|
||||||
{
|
create( entry, localPath );
|
||||||
if( entryName.equals( "" ) )
|
|
||||||
{
|
|
||||||
m_root = new FileInZip( entryName, entry.isDirectory(), entry.getSize() );
|
|
||||||
m_rootPath = subPath;
|
|
||||||
if( !m_root.isDirectory() ) break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: handle this case. The code currently assumes we find the root before anything else
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FileInZip parent = m_root.getParent( entryName );
|
|
||||||
if( parent != null )
|
|
||||||
{
|
|
||||||
parent.insertChild( new FileInZip( entryName, entry.isDirectory(), entry.getSize() ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: handle this case. The code currently assumes we find folders before their contents
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMount implementation
|
private FileEntry get( String path )
|
||||||
|
{
|
||||||
|
FileEntry lastEntry = root;
|
||||||
|
int lastIndex = 0;
|
||||||
|
|
||||||
|
while( lastEntry != null && lastIndex < path.length() )
|
||||||
|
{
|
||||||
|
int nextIndex = path.indexOf( '/', lastIndex );
|
||||||
|
if( nextIndex < 0 ) nextIndex = path.length();
|
||||||
|
|
||||||
|
lastEntry = lastEntry.children == null ? null : lastEntry.children.get( path.substring( lastIndex, nextIndex ) );
|
||||||
|
lastIndex = nextIndex + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void create( ZipEntry entry, String localPath )
|
||||||
|
{
|
||||||
|
FileEntry lastEntry = root;
|
||||||
|
|
||||||
|
int lastIndex = 0;
|
||||||
|
while( lastIndex < localPath.length() )
|
||||||
|
{
|
||||||
|
int nextIndex = localPath.indexOf( '/', lastIndex );
|
||||||
|
if( nextIndex < 0 ) nextIndex = localPath.length();
|
||||||
|
|
||||||
|
String part = localPath.substring( lastIndex, nextIndex );
|
||||||
|
if( lastEntry.children == null ) lastEntry.children = new HashMap<>( 0 );
|
||||||
|
|
||||||
|
FileEntry nextEntry = lastEntry.children.get( part );
|
||||||
|
if( nextEntry == null || !nextEntry.isDirectory() )
|
||||||
|
{
|
||||||
|
lastEntry.children.put( part, nextEntry = new FileEntry( part ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
lastEntry = nextEntry;
|
||||||
|
lastIndex = nextIndex + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastEntry.setup( entry );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean exists( @Nonnull String path )
|
public boolean exists( @Nonnull String path )
|
||||||
{
|
{
|
||||||
FileInZip file = m_root.getFile( path );
|
return get( path ) != null;
|
||||||
return file != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDirectory( @Nonnull String path )
|
public boolean isDirectory( @Nonnull String path )
|
||||||
{
|
{
|
||||||
FileInZip file = m_root.getFile( path );
|
FileEntry file = get( path );
|
||||||
if( file != null )
|
return file != null && file.isDirectory();
|
||||||
{
|
|
||||||
return file.isDirectory();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException
|
public void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException
|
||||||
{
|
{
|
||||||
FileInZip file = m_root.getFile( path );
|
FileEntry file = get( path );
|
||||||
if( file != null && file.isDirectory() )
|
if( file == null || !file.isDirectory() ) throw new IOException( "/" + path + ": Not a directory" );
|
||||||
{
|
|
||||||
file.list( contents );
|
file.list( contents );
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IOException( "/" + path + ": Not a directory" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getSize( @Nonnull String path ) throws IOException
|
public long getSize( @Nonnull String path ) throws IOException
|
||||||
{
|
{
|
||||||
FileInZip file = m_root.getFile( path );
|
FileEntry file = get( path );
|
||||||
if( file != null )
|
if( file != null ) return file.size;
|
||||||
{
|
|
||||||
return file.getSize();
|
|
||||||
}
|
|
||||||
throw new IOException( "/" + path + ": No such file" );
|
throw new IOException( "/" + path + ": No such file" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public InputStream openForRead( @Nonnull String path ) throws IOException
|
public InputStream openForRead( @Nonnull String path ) throws IOException
|
||||||
{
|
{
|
||||||
FileInZip file = m_root.getFile( path );
|
return Channels.newInputStream( openChannelForRead( path ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOException
|
||||||
|
{
|
||||||
|
FileEntry file = get( path );
|
||||||
if( file != null && !file.isDirectory() )
|
if( file != null && !file.isDirectory() )
|
||||||
{
|
{
|
||||||
|
byte[] contents = CONTENTS_CACHE.getIfPresent( file );
|
||||||
|
if( contents != null ) return new ArrayByteChannel( contents );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String fullPath = m_rootPath;
|
ZipEntry entry = zip.getEntry( file.path );
|
||||||
if( path.length() > 0 )
|
|
||||||
{
|
|
||||||
fullPath = fullPath + "/" + path;
|
|
||||||
}
|
|
||||||
ZipEntry entry = m_zipFile.getEntry( fullPath );
|
|
||||||
if( entry != null )
|
if( entry != null )
|
||||||
{
|
{
|
||||||
return m_zipFile.getInputStream( entry );
|
try( InputStream stream = zip.getInputStream( entry ) )
|
||||||
|
{
|
||||||
|
if( stream.available() > MAX_CACHED_SIZE ) return Channels.newChannel( stream );
|
||||||
|
|
||||||
|
contents = ByteStreams.toByteArray( stream );
|
||||||
|
CONTENTS_CACHE.put( file, contents );
|
||||||
|
return new ArrayByteChannel( contents );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
// treat errors as non-existance of file
|
// Treat errors as non-existence of file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IOException( "/" + path + ": No such file" );
|
throw new IOException( "/" + path + ": No such file" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class FileEntry
|
||||||
|
{
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
String path;
|
||||||
|
long size;
|
||||||
|
Map<String, FileEntry> children;
|
||||||
|
|
||||||
|
FileEntry( String name )
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup( ZipEntry entry )
|
||||||
|
{
|
||||||
|
path = entry.getName();
|
||||||
|
size = entry.getSize();
|
||||||
|
if( children == null && entry.isDirectory() ) children = new HashMap<>( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isDirectory()
|
||||||
|
{
|
||||||
|
return children != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void list( List<String> contents )
|
||||||
|
{
|
||||||
|
if( children != null ) contents.addAll( children.keySet() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MountReference extends WeakReference<JarMount>
|
||||||
|
{
|
||||||
|
final ZipFile file;
|
||||||
|
|
||||||
|
MountReference( JarMount file )
|
||||||
|
{
|
||||||
|
super( file, MOUNT_QUEUE );
|
||||||
|
this.file = file.zip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void cleanup()
|
||||||
|
{
|
||||||
|
Reference<? extends JarMount> next;
|
||||||
|
while( (next = MOUNT_QUEUE.poll()) != null ) IoUtil.closeQuietly( ((MountReference) next).file );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
{
|
{
|
||||||
private static final ThreadPoolExecutor coroutines = new ThreadPoolExecutor(
|
private static final ThreadPoolExecutor coroutines = new ThreadPoolExecutor(
|
||||||
0, Integer.MAX_VALUE,
|
0, Integer.MAX_VALUE,
|
||||||
60L, TimeUnit.SECONDS,
|
5L, TimeUnit.MINUTES,
|
||||||
new SynchronousQueue<>(),
|
new SynchronousQueue<>(),
|
||||||
ThreadUtils.factory( "Coroutine" )
|
ThreadUtils.factory( "Coroutine" )
|
||||||
);
|
);
|
||||||
@@ -74,12 +74,12 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
private boolean hasSoftAbort;
|
private boolean hasSoftAbort;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInstruction( DebugState ds, DebugFrame di, int pc, Varargs extras, int top ) throws LuaError
|
public void onInstruction( DebugState ds, DebugFrame di, int pc ) throws LuaError, UnwindThrowable
|
||||||
{
|
{
|
||||||
int count = ++this.count;
|
int count = ++this.count;
|
||||||
if( count > 100000 )
|
if( count > 100000 )
|
||||||
{
|
{
|
||||||
if( m_hardAbortMessage != null ) LuaThread.yield( m_state, NONE );
|
if( m_hardAbortMessage != null ) throw HardAbortError.INSTANCE;
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -87,13 +87,13 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
handleSoftAbort();
|
handleSoftAbort();
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onInstruction( ds, di, pc, extras, top );
|
super.onInstruction( ds, di, pc );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void poll() throws LuaError
|
public void poll() throws LuaError
|
||||||
{
|
{
|
||||||
if( m_hardAbortMessage != null ) LuaThread.yield( m_state, NONE );
|
if( m_hardAbortMessage != null ) throw HardAbortError.INSTANCE;
|
||||||
handleSoftAbort();
|
handleSoftAbort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
throw new LuaError( message );
|
throw new LuaError( message );
|
||||||
}
|
}
|
||||||
} )
|
} )
|
||||||
.coroutineFactory( command -> {
|
.yieldThreader( command -> {
|
||||||
Tracking.addValue( m_computer, TrackingField.COROUTINES_CREATED, 1 );
|
Tracking.addValue( m_computer, TrackingField.COROUTINES_CREATED, 1 );
|
||||||
coroutines.execute( () -> {
|
coroutines.execute( () -> {
|
||||||
try
|
try
|
||||||
@@ -145,10 +145,10 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
if( ComputerCraft.debug_enable ) m_globals.load( state, new DebugLib() );
|
if( ComputerCraft.debug_enable ) m_globals.load( state, new DebugLib() );
|
||||||
|
|
||||||
// Register custom load/loadstring provider which automatically adds prefixes.
|
// Register custom load/loadstring provider which automatically adds prefixes.
|
||||||
LibFunction.bind( state, m_globals, PrefixLoader.class, new String[] { "load", "loadstring" } );
|
LibFunction.bind( m_globals, PrefixLoader.class, new String[] { "load", "loadstring" } );
|
||||||
|
|
||||||
// Remove globals we don't want to expose
|
// Remove globals we don't want to expose
|
||||||
// m_globals.rawset( "collectgarbage", Constants.NIL );
|
m_globals.rawset( "collectgarbage", Constants.NIL );
|
||||||
m_globals.rawset( "dofile", Constants.NIL );
|
m_globals.rawset( "dofile", Constants.NIL );
|
||||||
m_globals.rawset( "loadfile", Constants.NIL );
|
m_globals.rawset( "loadfile", Constants.NIL );
|
||||||
m_globals.rawset( "print", Constants.NIL );
|
m_globals.rawset( "print", Constants.NIL );
|
||||||
@@ -222,26 +222,18 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
resumeArgs = varargsOf( valueOf( eventName ), toValues( arguments ) );
|
resumeArgs = varargsOf( valueOf( eventName ), toValues( arguments ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Varargs results = m_mainRoutine.resume( resumeArgs );
|
Varargs results = LuaThread.run( m_mainRoutine, resumeArgs );
|
||||||
if( m_hardAbortMessage != null )
|
if( m_hardAbortMessage != null ) throw new LuaError( m_hardAbortMessage );
|
||||||
{
|
|
||||||
throw new LuaError( m_hardAbortMessage );
|
LuaValue filter = results.first();
|
||||||
}
|
m_eventFilter = filter.isString() ? filter.toString() : null;
|
||||||
else if( !results.first().checkBoolean() )
|
|
||||||
{
|
|
||||||
throw new LuaError( results.arg( 2 ).checkString() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LuaValue filter = results.arg( 2 );
|
|
||||||
m_eventFilter = filter.isString() ? filter.toString() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_mainRoutine.getStatus().equals( "dead" ) ) unload();
|
if( m_mainRoutine.getStatus().equals( "dead" ) ) unload();
|
||||||
}
|
}
|
||||||
catch( LuaError e )
|
catch( LuaError | HardAbortError e )
|
||||||
{
|
{
|
||||||
unload();
|
unload();
|
||||||
|
ComputerCraft.log.warn( "Top level coroutine errored", e );
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -339,16 +331,12 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Varargs results = LuaThread.yield( state, toValues( yieldArgs ) );
|
Varargs results = LuaThread.yieldBlocking( state, toValues( yieldArgs ) );
|
||||||
return toObjects( results, 1 );
|
return toObjects( results, 1 );
|
||||||
}
|
}
|
||||||
catch( OrphanedThread e )
|
catch( LuaError e )
|
||||||
{
|
{
|
||||||
throw new InterruptedException();
|
throw new IllegalStateException( e );
|
||||||
}
|
|
||||||
catch( Throwable e )
|
|
||||||
{
|
|
||||||
throw new RuntimeException( e );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,7 +687,7 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
LuaValue s;
|
LuaValue s;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
s = OperationHelper.call( state, func );
|
s = OperationHelper.noYield( state, () -> OperationHelper.call( state, func ) );
|
||||||
}
|
}
|
||||||
catch( LuaError e )
|
catch( LuaError e )
|
||||||
{
|
{
|
||||||
@@ -731,4 +719,16 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
return bytes[offset++];
|
return bytes[offset++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class HardAbortError extends Error
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 7954092008586367501L;
|
||||||
|
|
||||||
|
public static final HardAbortError INSTANCE = new HardAbortError();
|
||||||
|
|
||||||
|
private HardAbortError()
|
||||||
|
{
|
||||||
|
super( "Hard Abort", null, true, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,18 @@ public class Terminal
|
|||||||
private final Palette m_palette;
|
private final Palette m_palette;
|
||||||
|
|
||||||
private boolean m_changed;
|
private boolean m_changed;
|
||||||
|
private final Runnable onChanged;
|
||||||
|
|
||||||
public Terminal( int width, int height )
|
public Terminal( int width, int height )
|
||||||
|
{
|
||||||
|
this( width, height, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Terminal( int width, int height, Runnable changedCallback )
|
||||||
{
|
{
|
||||||
m_width = width;
|
m_width = width;
|
||||||
m_height = height;
|
m_height = height;
|
||||||
|
this.onChanged = changedCallback;
|
||||||
|
|
||||||
m_cursorColour = 0;
|
m_cursorColour = 0;
|
||||||
m_cursorBackgroundColour = 15;
|
m_cursorBackgroundColour = 15;
|
||||||
@@ -65,7 +72,7 @@ public class Terminal
|
|||||||
m_cursorY = 0;
|
m_cursorY = 0;
|
||||||
m_cursorBlink = false;
|
m_cursorBlink = false;
|
||||||
clear();
|
clear();
|
||||||
m_changed = true;
|
setChanged();
|
||||||
m_palette.resetColours();
|
m_palette.resetColours();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +129,7 @@ public class Terminal
|
|||||||
m_backgroundColour[i].write( oldBackgroundColour[i] );
|
m_backgroundColour[i].write( oldBackgroundColour[i] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCursorPos( int x, int y )
|
public void setCursorPos( int x, int y )
|
||||||
@@ -131,7 +138,7 @@ public class Terminal
|
|||||||
{
|
{
|
||||||
m_cursorX = x;
|
m_cursorX = x;
|
||||||
m_cursorY = y;
|
m_cursorY = y;
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +147,7 @@ public class Terminal
|
|||||||
if( m_cursorBlink != blink )
|
if( m_cursorBlink != blink )
|
||||||
{
|
{
|
||||||
m_cursorBlink = blink;
|
m_cursorBlink = blink;
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +156,7 @@ public class Terminal
|
|||||||
if( m_cursorColour != colour )
|
if( m_cursorColour != colour )
|
||||||
{
|
{
|
||||||
m_cursorColour = colour;
|
m_cursorColour = colour;
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +165,7 @@ public class Terminal
|
|||||||
if( m_cursorBackgroundColour != colour )
|
if( m_cursorBackgroundColour != colour )
|
||||||
{
|
{
|
||||||
m_cursorBackgroundColour = colour;
|
m_cursorBackgroundColour = colour;
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +208,7 @@ public class Terminal
|
|||||||
m_text[y].write( text, x );
|
m_text[y].write( text, x );
|
||||||
m_textColour[y].write( textColour, x );
|
m_textColour[y].write( textColour, x );
|
||||||
m_backgroundColour[y].write( backgroundColour, x );
|
m_backgroundColour[y].write( backgroundColour, x );
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +221,7 @@ public class Terminal
|
|||||||
m_text[y].write( text, x );
|
m_text[y].write( text, x );
|
||||||
m_textColour[y].fill( base16.charAt( m_cursorColour ), x, x + text.length() );
|
m_textColour[y].fill( base16.charAt( m_cursorColour ), x, x + text.length() );
|
||||||
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ), x, x + text.length() );
|
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ), x, x + text.length() );
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,7 +251,7 @@ public class Terminal
|
|||||||
m_text = newText;
|
m_text = newText;
|
||||||
m_textColour = newTextColour;
|
m_textColour = newTextColour;
|
||||||
m_backgroundColour = newBackgroundColour;
|
m_backgroundColour = newBackgroundColour;
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +263,7 @@ public class Terminal
|
|||||||
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
|
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
|
||||||
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
|
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
|
||||||
}
|
}
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void clearLine()
|
public synchronized void clearLine()
|
||||||
@@ -267,7 +274,7 @@ public class Terminal
|
|||||||
m_text[y].fill( ' ' );
|
m_text[y].fill( ' ' );
|
||||||
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
|
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
|
||||||
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
|
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +292,7 @@ public class Terminal
|
|||||||
m_text[y].write( text );
|
m_text[y].write( text );
|
||||||
m_textColour[y].write( textColour );
|
m_textColour[y].write( textColour );
|
||||||
m_backgroundColour[y].write( backgroundColour );
|
m_backgroundColour[y].write( backgroundColour );
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized TextBuffer getTextColourLine( int y )
|
public synchronized TextBuffer getTextColourLine( int y )
|
||||||
@@ -306,17 +313,23 @@ public class Terminal
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getChanged()
|
/**
|
||||||
|
* @deprecated All {@code *Changed()} methods are deprecated: one should pass in a callback
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public final boolean getChanged()
|
||||||
{
|
{
|
||||||
return m_changed;
|
return m_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChanged()
|
public final void setChanged()
|
||||||
{
|
{
|
||||||
m_changed = true;
|
m_changed = true;
|
||||||
|
if( onChanged != null ) onChanged.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearChanged()
|
public final void clearChanged()
|
||||||
{
|
{
|
||||||
m_changed = false;
|
m_changed = false;
|
||||||
}
|
}
|
||||||
@@ -371,6 +384,6 @@ public class Terminal
|
|||||||
{
|
{
|
||||||
m_palette.readFromNBT( nbt );
|
m_palette.readFromNBT( nbt );
|
||||||
}
|
}
|
||||||
m_changed = true;
|
setChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +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.server.proxy;
|
|
||||||
|
|
||||||
import dan200.computercraft.shared.proxy.CCTurtleProxyCommon;
|
|
||||||
|
|
||||||
public class CCTurtleProxyServer extends CCTurtleProxyCommon
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,22 +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.server.proxy;
|
|
||||||
|
|
||||||
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.common.DimensionManager;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class ComputerCraftProxyServer extends ComputerCraftProxyCommon
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public File getWorldDir( World world )
|
|
||||||
{
|
|
||||||
return DimensionManager.getWorld( 0 ).getSaveHandler().getWorldDirectory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -49,7 +49,7 @@ public final class PocketUpgrades
|
|||||||
for( IPocketUpgrade upgrade : upgrades.values() )
|
for( IPocketUpgrade upgrade : upgrades.values() )
|
||||||
{
|
{
|
||||||
ItemStack craftingStack = upgrade.getCraftingItem();
|
ItemStack craftingStack = upgrade.getCraftingItem();
|
||||||
if( !craftingStack.isEmpty() && InventoryUtil.areItemsStackable( stack, craftingStack ) )
|
if( !craftingStack.isEmpty() && InventoryUtil.areItemsSimilar( stack, craftingStack ) )
|
||||||
{
|
{
|
||||||
return upgrade;
|
return upgrade;
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ public final class PocketUpgrades
|
|||||||
List<IPocketUpgrade> vanilla = new ArrayList<>();
|
List<IPocketUpgrade> vanilla = new ArrayList<>();
|
||||||
vanilla.add( ComputerCraft.PocketUpgrades.wirelessModem );
|
vanilla.add( ComputerCraft.PocketUpgrades.wirelessModem );
|
||||||
vanilla.add( ComputerCraft.PocketUpgrades.advancedModem );
|
vanilla.add( ComputerCraft.PocketUpgrades.advancedModem );
|
||||||
vanilla.add( ComputerCraft.PocketUpgrades.pocketSpeaker );
|
vanilla.add( ComputerCraft.PocketUpgrades.speaker );
|
||||||
return vanilla;
|
return vanilla;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
432
src/main/java/dan200/computercraft/shared/Registry.java
Normal file
432
src/main/java/dan200/computercraft/shared/Registry.java
Normal file
@@ -0,0 +1,432 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dan200.computercraft.shared;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.api.ComputerCraftAPI;
|
||||||
|
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||||
|
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||||
|
import dan200.computercraft.shared.computer.blocks.BlockCommandComputer;
|
||||||
|
import dan200.computercraft.shared.computer.blocks.BlockComputer;
|
||||||
|
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
|
||||||
|
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||||
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
|
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.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.TileDiskDrive;
|
||||||
|
import dan200.computercraft.shared.peripheral.modem.wired.*;
|
||||||
|
import dan200.computercraft.shared.peripheral.modem.wireless.BlockAdvancedModem;
|
||||||
|
import dan200.computercraft.shared.peripheral.modem.wireless.ItemAdvancedModem;
|
||||||
|
import dan200.computercraft.shared.peripheral.modem.wireless.TileAdvancedModem;
|
||||||
|
import dan200.computercraft.shared.peripheral.modem.wireless.TileWirelessModem;
|
||||||
|
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||||
|
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||||
|
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
|
||||||
|
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||||
|
import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory;
|
||||||
|
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
|
||||||
|
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
|
||||||
|
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
|
||||||
|
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||||
|
import dan200.computercraft.shared.turtle.blocks.TileTurtleAdvanced;
|
||||||
|
import dan200.computercraft.shared.turtle.blocks.TileTurtleExpanded;
|
||||||
|
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.TurtleItemFactory;
|
||||||
|
import dan200.computercraft.shared.turtle.upgrades.*;
|
||||||
|
import dan200.computercraft.shared.util.Colour;
|
||||||
|
import dan200.computercraft.shared.util.ImpostorRecipe;
|
||||||
|
import dan200.computercraft.shared.util.ImpostorShapelessRecipe;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.init.Items;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemBlock;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
|
import net.minecraft.util.NonNullList;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.event.RegistryEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||||
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
|
||||||
|
public final class Registry
|
||||||
|
{
|
||||||
|
private Registry()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void registerBlocks( RegistryEvent.Register<Block> event )
|
||||||
|
{
|
||||||
|
IForgeRegistry<Block> registry = event.getRegistry();
|
||||||
|
|
||||||
|
// Computers
|
||||||
|
ComputerCraft.Blocks.computer = new BlockComputer();
|
||||||
|
ComputerCraft.Blocks.commandComputer = new BlockCommandComputer();
|
||||||
|
|
||||||
|
registry.registerAll(
|
||||||
|
ComputerCraft.Blocks.computer.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) ),
|
||||||
|
ComputerCraft.Blocks.commandComputer.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "command_computer" ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Turtle
|
||||||
|
ComputerCraft.Blocks.turtle = new BlockTurtle();
|
||||||
|
ComputerCraft.Blocks.turtleExpanded = new BlockTurtle();
|
||||||
|
ComputerCraft.Blocks.turtleAdvanced = new BlockTurtle();
|
||||||
|
|
||||||
|
registry.registerAll(
|
||||||
|
ComputerCraft.Blocks.turtle.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) ),
|
||||||
|
ComputerCraft.Blocks.turtleExpanded.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_expanded" ) ),
|
||||||
|
ComputerCraft.Blocks.turtleAdvanced.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_advanced" ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Peripheral
|
||||||
|
ComputerCraft.Blocks.peripheral = new BlockPeripheral();
|
||||||
|
registry.register( ComputerCraft.Blocks.peripheral.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "peripheral" ) ) );
|
||||||
|
|
||||||
|
// Cable
|
||||||
|
ComputerCraft.Blocks.cable = new BlockCable();
|
||||||
|
registry.register( ComputerCraft.Blocks.cable.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "cable" ) ) );
|
||||||
|
|
||||||
|
// Advanced modem
|
||||||
|
ComputerCraft.Blocks.advancedModem = new BlockAdvancedModem();
|
||||||
|
registry.register( ComputerCraft.Blocks.advancedModem.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "advanced_modem" ) ) );
|
||||||
|
|
||||||
|
// Full block modem
|
||||||
|
ComputerCraft.Blocks.wiredModemFull = new BlockWiredModemFull();
|
||||||
|
registry.register( ComputerCraft.Blocks.wiredModemFull.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full" ) ) );
|
||||||
|
|
||||||
|
registerTileEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void registerTileEntities()
|
||||||
|
{
|
||||||
|
GameRegistry.registerTileEntity( TileComputer.class, new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) );
|
||||||
|
GameRegistry.registerTileEntity( TileCommandComputer.class, new ResourceLocation( ComputerCraft.MOD_ID, "command_computer" ) );
|
||||||
|
|
||||||
|
GameRegistry.registerTileEntity( TileTurtle.class, new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ) );
|
||||||
|
GameRegistry.registerTileEntity( TileTurtleExpanded.class, new ResourceLocation( ComputerCraft.MOD_ID, "turtleex" ) );
|
||||||
|
GameRegistry.registerTileEntity( TileTurtleAdvanced.class, new ResourceLocation( ComputerCraft.MOD_ID, "turtleadv" ) );
|
||||||
|
|
||||||
|
GameRegistry.registerTileEntity( TileDiskDrive.class, new ResourceLocation( ComputerCraft.MOD_ID, "diskdrive" ) );
|
||||||
|
GameRegistry.registerTileEntity( TileWirelessModem.class, new ResourceLocation( ComputerCraft.MOD_ID, "wirelessmodem" ) );
|
||||||
|
GameRegistry.registerTileEntity( TileMonitor.class, new ResourceLocation( ComputerCraft.MOD_ID, "monitor" ) );
|
||||||
|
GameRegistry.registerTileEntity( TilePrinter.class, new ResourceLocation( ComputerCraft.MOD_ID, "ccprinter" ) );
|
||||||
|
GameRegistry.registerTileEntity( TileCable.class, new ResourceLocation( ComputerCraft.MOD_ID, "wiredmodem" ) );
|
||||||
|
GameRegistry.registerTileEntity( TileAdvancedModem.class, new ResourceLocation( ComputerCraft.MOD_ID, "advanced_modem" ) );
|
||||||
|
GameRegistry.registerTileEntity( TileSpeaker.class, new ResourceLocation( ComputerCraft.MOD_ID, "speaker" ) );
|
||||||
|
GameRegistry.registerTileEntity( TileWiredModemFull.class, new ResourceLocation( ComputerCraft.MOD_ID, "wired_modem_full" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends ItemBlock> T setupItemBlock( T item )
|
||||||
|
{
|
||||||
|
item.setRegistryName( item.getBlock().getRegistryName() );
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void registerItems( RegistryEvent.Register<Item> event )
|
||||||
|
{
|
||||||
|
IForgeRegistry<Item> registry = event.getRegistry();
|
||||||
|
|
||||||
|
// Computers
|
||||||
|
ComputerCraft.Items.computer = new ItemComputer( ComputerCraft.Blocks.computer );
|
||||||
|
ComputerCraft.Items.commandComputer = new ItemCommandComputer( ComputerCraft.Blocks.commandComputer );
|
||||||
|
|
||||||
|
registry.registerAll(
|
||||||
|
setupItemBlock( ComputerCraft.Items.computer ),
|
||||||
|
setupItemBlock( ComputerCraft.Items.commandComputer )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Pocket computer
|
||||||
|
ComputerCraft.Items.pocketComputer = new ItemPocketComputer();
|
||||||
|
registry.register(
|
||||||
|
ComputerCraft.Items.pocketComputer.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "pocket_computer" ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Turtle
|
||||||
|
ComputerCraft.Items.turtle = new ItemTurtleLegacy( ComputerCraft.Blocks.turtle );
|
||||||
|
ComputerCraft.Items.turtleExpanded = new ItemTurtleNormal( ComputerCraft.Blocks.turtleExpanded );
|
||||||
|
ComputerCraft.Items.turtleAdvanced = new ItemTurtleAdvanced( ComputerCraft.Blocks.turtleAdvanced );
|
||||||
|
|
||||||
|
registry.registerAll(
|
||||||
|
setupItemBlock( ComputerCraft.Items.turtle ),
|
||||||
|
setupItemBlock( ComputerCraft.Items.turtleExpanded ),
|
||||||
|
setupItemBlock( ComputerCraft.Items.turtleAdvanced )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Printouts
|
||||||
|
ComputerCraft.Items.printout = new ItemPrintout();
|
||||||
|
registry.register( ComputerCraft.Items.printout.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "printout" ) ) );
|
||||||
|
|
||||||
|
// Disks
|
||||||
|
ComputerCraft.Items.disk = new ItemDiskLegacy();
|
||||||
|
ComputerCraft.Items.diskExpanded = new ItemDiskExpanded();
|
||||||
|
ComputerCraft.Items.treasureDisk = new ItemTreasureDisk();
|
||||||
|
|
||||||
|
registry.registerAll(
|
||||||
|
ComputerCraft.Items.disk.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "disk" ) ),
|
||||||
|
ComputerCraft.Items.diskExpanded.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "disk_expanded" ) ),
|
||||||
|
ComputerCraft.Items.treasureDisk.setRegistryName( new ResourceLocation( ComputerCraft.MOD_ID, "treasure_disk" ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Peripherals
|
||||||
|
ComputerCraft.Items.peripheral = new ItemPeripheral( ComputerCraft.Blocks.peripheral );
|
||||||
|
ComputerCraft.Items.advancedModem = new ItemAdvancedModem( ComputerCraft.Blocks.advancedModem );
|
||||||
|
ComputerCraft.Items.cable = new ItemCable( ComputerCraft.Blocks.cable );
|
||||||
|
ComputerCraft.Items.wiredModemFull = new ItemWiredModemFull( ComputerCraft.Blocks.wiredModemFull );
|
||||||
|
|
||||||
|
registry.registerAll(
|
||||||
|
setupItemBlock( ComputerCraft.Items.peripheral ),
|
||||||
|
setupItemBlock( ComputerCraft.Items.advancedModem ),
|
||||||
|
setupItemBlock( ComputerCraft.Items.cable ),
|
||||||
|
setupItemBlock( ComputerCraft.Items.wiredModemFull )
|
||||||
|
);
|
||||||
|
|
||||||
|
registerTurtleUpgrades();
|
||||||
|
registerPocketUpgrades();
|
||||||
|
registerLegacyUpgrades();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void registerRecipes( RegistryEvent.Register<IRecipe> event )
|
||||||
|
{
|
||||||
|
IForgeRegistry<IRecipe> registry = event.getRegistry();
|
||||||
|
|
||||||
|
// Register fake recipes for the recipe book and JEI. We have several dynamic recipes,
|
||||||
|
// and we'd like people to be able to see them.
|
||||||
|
|
||||||
|
// Turtle upgrades
|
||||||
|
// TODO: Figure out a way to do this in a "nice" way.
|
||||||
|
for( ITurtleUpgrade upgrade : TurtleUpgrades.getVanillaUpgrades() )
|
||||||
|
{
|
||||||
|
ItemStack craftingItem = upgrade.getCraftingItem();
|
||||||
|
|
||||||
|
// A turtle just containing this upgrade
|
||||||
|
for( ComputerFamily family : ComputerFamily.values() )
|
||||||
|
{
|
||||||
|
if( !TurtleUpgrades.suitableForFamily( family, upgrade ) ) continue;
|
||||||
|
|
||||||
|
ItemStack baseTurtle = TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null );
|
||||||
|
if( !baseTurtle.isEmpty() )
|
||||||
|
{
|
||||||
|
ItemStack craftedTurtle = TurtleItemFactory.create( -1, null, -1, family, upgrade, null, 0, null );
|
||||||
|
ItemStack craftedTurtleFlipped = TurtleItemFactory.create( -1, null, -1, family, null, upgrade, 0, null );
|
||||||
|
registry.register(
|
||||||
|
new ImpostorRecipe( "computercraft:" + family.toString() + "_turtle_upgrade", 2, 1, new ItemStack[] { baseTurtle, craftingItem }, craftedTurtle )
|
||||||
|
.setRegistryName( new ResourceLocation( "computercraft:" + family + "_turtle_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) + "_1" ) )
|
||||||
|
);
|
||||||
|
registry.register(
|
||||||
|
new ImpostorRecipe( "computercraft:" + family.toString() + "_turtle_upgrade", 2, 1, new ItemStack[] { craftingItem, baseTurtle }, craftedTurtleFlipped )
|
||||||
|
.setRegistryName( new ResourceLocation( "computercraft:" + family + "_turtle_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) + "_2" ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coloured disks
|
||||||
|
ItemStack paper = new ItemStack( Items.PAPER, 1 );
|
||||||
|
ItemStack redstone = new ItemStack( Items.REDSTONE, 1 );
|
||||||
|
for( int colour = 0; colour < 16; colour++ )
|
||||||
|
{
|
||||||
|
ItemStack disk = ItemDiskLegacy.createFromIDAndColour( -1, null, Colour.values()[colour].getHex() );
|
||||||
|
ItemStack dye = new ItemStack( Items.DYE, 1, colour );
|
||||||
|
|
||||||
|
int diskIdx = 0;
|
||||||
|
ItemStack[] disks = new ItemStack[15];
|
||||||
|
for( int otherColour = 0; otherColour < 16; otherColour++ )
|
||||||
|
{
|
||||||
|
if( colour != otherColour )
|
||||||
|
{
|
||||||
|
disks[diskIdx++] = ItemDiskLegacy.createFromIDAndColour( -1, null, Colour.values()[otherColour].getHex() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal recipe
|
||||||
|
registry.register(
|
||||||
|
new ImpostorShapelessRecipe( "computercraft:disk", disk, new ItemStack[] { redstone, paper, dye } )
|
||||||
|
.setRegistryName( new ResourceLocation( "computercraft:disk_imposter_" + colour ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Conversion recipe
|
||||||
|
registry.register(
|
||||||
|
new ImpostorShapelessRecipe( "computercraft:disk", disk, NonNullList.from( Ingredient.EMPTY, Ingredient.fromStacks( disks ), Ingredient.fromStacks( dye ) ) )
|
||||||
|
.setRegistryName( new ResourceLocation( "computercraft:disk_imposter_convert_" + colour ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pocket computer upgrades
|
||||||
|
ItemStack pocketComputer = PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Normal, null );
|
||||||
|
ItemStack advancedPocketComputer = PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Advanced, null );
|
||||||
|
for( IPocketUpgrade upgrade : PocketUpgrades.getVanillaUpgrades() )
|
||||||
|
{
|
||||||
|
registry.register( new ImpostorRecipe(
|
||||||
|
"computercraft:normal_pocket_upgrade",
|
||||||
|
1, 2,
|
||||||
|
new ItemStack[] { upgrade.getCraftingItem(), pocketComputer },
|
||||||
|
PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Normal, upgrade )
|
||||||
|
).setRegistryName( new ResourceLocation( "computercraft:normal_pocket_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
registry.register(
|
||||||
|
new ImpostorRecipe( "computercraft:advanced_pocket_upgrade",
|
||||||
|
1, 2,
|
||||||
|
new ItemStack[] { upgrade.getCraftingItem(), advancedPocketComputer },
|
||||||
|
PocketComputerItemFactory.create( -1, null, -1, ComputerFamily.Advanced, upgrade )
|
||||||
|
).setRegistryName( new ResourceLocation( "computercraft:advanced_pocket_upgrade_" + upgrade.getUpgradeID().toString().replace( ':', '_' ) ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void registerTurtleUpgrades()
|
||||||
|
{
|
||||||
|
// Upgrades
|
||||||
|
ComputerCraft.TurtleUpgrades.wirelessModem = new TurtleModem( false, new ResourceLocation( "computercraft", "wireless_modem" ), 1 );
|
||||||
|
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.wirelessModem );
|
||||||
|
|
||||||
|
ComputerCraft.TurtleUpgrades.advancedModem = new TurtleModem( true, new ResourceLocation( "computercraft", "advanced_modem" ), -1 );
|
||||||
|
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.advancedModem );
|
||||||
|
|
||||||
|
ComputerCraft.TurtleUpgrades.speaker = new TurtleSpeaker( new ResourceLocation( "computercraft", "speaker" ), 8 );
|
||||||
|
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.speaker );
|
||||||
|
|
||||||
|
ComputerCraft.TurtleUpgrades.craftingTable = new TurtleCraftingTable( new ResourceLocation( "minecraft", "crafting_table" ), 2 );
|
||||||
|
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.craftingTable );
|
||||||
|
|
||||||
|
ComputerCraft.TurtleUpgrades.diamondSword = new TurtleSword( new ResourceLocation( "minecraft", "diamond_sword" ), 3, Items.DIAMOND_SWORD );
|
||||||
|
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.diamondSword );
|
||||||
|
|
||||||
|
ComputerCraft.TurtleUpgrades.diamondShovel = new TurtleShovel( new ResourceLocation( "minecraft", "diamond_shovel" ), 4, Items.DIAMOND_SHOVEL );
|
||||||
|
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.diamondShovel );
|
||||||
|
|
||||||
|
ComputerCraft.TurtleUpgrades.diamondPickaxe = new TurtleTool( new ResourceLocation( "minecraft", "diamond_pickaxe" ), 5, Items.DIAMOND_PICKAXE );
|
||||||
|
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.diamondPickaxe );
|
||||||
|
|
||||||
|
ComputerCraft.TurtleUpgrades.diamondAxe = new TurtleAxe( new ResourceLocation( "minecraft", "diamond_axe" ), 6, Items.DIAMOND_AXE );
|
||||||
|
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.diamondAxe );
|
||||||
|
|
||||||
|
ComputerCraft.TurtleUpgrades.diamondHoe = new TurtleHoe( new ResourceLocation( "minecraft", "diamond_hoe" ), 7, Items.DIAMOND_HOE );
|
||||||
|
TurtleUpgrades.registerInternal( ComputerCraft.TurtleUpgrades.diamondHoe );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerPocketUpgrades()
|
||||||
|
{
|
||||||
|
// Register pocket upgrades
|
||||||
|
ComputerCraft.PocketUpgrades.wirelessModem = new PocketModem( false );
|
||||||
|
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.wirelessModem );
|
||||||
|
ComputerCraft.PocketUpgrades.advancedModem = new PocketModem( true );
|
||||||
|
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.advancedModem );
|
||||||
|
|
||||||
|
ComputerCraft.PocketUpgrades.speaker = new PocketSpeaker();
|
||||||
|
ComputerCraftAPI.registerPocketUpgrade( ComputerCraft.PocketUpgrades.speaker );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings( "deprecation" )
|
||||||
|
private static void registerLegacyUpgrades()
|
||||||
|
{
|
||||||
|
ComputerCraft.PocketUpgrades.pocketSpeaker = ComputerCraft.PocketUpgrades.speaker;
|
||||||
|
ComputerCraft.Upgrades.advancedModem = ComputerCraft.TurtleUpgrades.advancedModem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void remapItems( RegistryEvent.MissingMappings<Item> mappings )
|
||||||
|
{
|
||||||
|
// We have to use mappings.getAllMappings() as the mod ID is upper case but the domain lower.
|
||||||
|
for( RegistryEvent.MissingMappings.Mapping<Item> mapping : mappings.getAllMappings() )
|
||||||
|
{
|
||||||
|
String domain = mapping.key.getNamespace();
|
||||||
|
if( !domain.equalsIgnoreCase( ComputerCraft.MOD_ID ) ) continue;
|
||||||
|
|
||||||
|
String key = mapping.key.getPath();
|
||||||
|
if( key.equalsIgnoreCase( "CC-Computer" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Items.computer );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "CC-Peripheral" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Items.peripheral );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "CC-Cable" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Items.cable );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "diskExpanded" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Items.diskExpanded );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "treasureDisk" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Items.treasureDisk );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "pocketComputer" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Items.pocketComputer );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "CC-Turtle" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Items.turtle );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "CC-TurtleExpanded" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Items.turtleExpanded );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "CC-TurtleAdvanced" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Items.turtleAdvanced );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void remapBlocks( RegistryEvent.MissingMappings<Block> mappings )
|
||||||
|
{
|
||||||
|
// We have to use mappings.getAllMappings() as the mod ID is upper case but the domain lower.
|
||||||
|
for( RegistryEvent.MissingMappings.Mapping<Block> mapping : mappings.getAllMappings() )
|
||||||
|
{
|
||||||
|
String domain = mapping.key.getNamespace();
|
||||||
|
if( !domain.equalsIgnoreCase( ComputerCraft.MOD_ID ) ) continue;
|
||||||
|
|
||||||
|
String key = mapping.key.getPath();
|
||||||
|
if( key.equalsIgnoreCase( "CC-Computer" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Blocks.computer );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "CC-Peripheral" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Blocks.peripheral );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "CC-Cable" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Blocks.cable );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "CC-Turtle" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Blocks.turtle );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "CC-TurtleExpanded" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Blocks.turtleExpanded );
|
||||||
|
}
|
||||||
|
else if( key.equalsIgnoreCase( "CC-TurtleAdvanced" ) )
|
||||||
|
{
|
||||||
|
mapping.remap( ComputerCraft.Blocks.turtleAdvanced );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,20 +7,29 @@
|
|||||||
package dan200.computercraft.shared;
|
package dan200.computercraft.shared;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.permissions.ITurtlePermissionProvider;
|
import dan200.computercraft.api.permissions.ITurtlePermissionProvider;
|
||||||
|
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
|
||||||
public final class TurtlePermissions
|
public final class TurtlePermissions
|
||||||
{
|
{
|
||||||
private static final Collection<ITurtlePermissionProvider> providers = new LinkedHashSet<>();
|
private static final Collection<ITurtlePermissionProvider> providers = new LinkedHashSet<>();
|
||||||
|
|
||||||
|
private TurtlePermissions()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public static void register( @Nonnull ITurtlePermissionProvider upgrade )
|
public static void register( @Nonnull ITurtlePermissionProvider upgrade )
|
||||||
{
|
{
|
||||||
Preconditions.checkNotNull( upgrade, "upgrade cannot be null" );
|
Preconditions.checkNotNull( upgrade, "upgrade cannot be null" );
|
||||||
@@ -57,4 +66,13 @@ public final class TurtlePermissions
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onTurtleAction( TurtleActionEvent event )
|
||||||
|
{
|
||||||
|
if( ComputerCraft.turtleDisabledActions.contains( event.getAction() ) )
|
||||||
|
{
|
||||||
|
event.setCanceled( true, "Action has been disabled" );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public final class TurtleUpgrades
|
|||||||
for( ITurtleUpgrade upgrade : upgrades.values() )
|
for( ITurtleUpgrade upgrade : upgrades.values() )
|
||||||
{
|
{
|
||||||
ItemStack craftingStack = upgrade.getCraftingItem();
|
ItemStack craftingStack = upgrade.getCraftingItem();
|
||||||
if( !craftingStack.isEmpty() && InventoryUtil.areItemsStackable( stack, craftingStack ) )
|
if( !craftingStack.isEmpty() && InventoryUtil.areItemsSimilar( stack, craftingStack ) )
|
||||||
{
|
{
|
||||||
return upgrade;
|
return upgrade;
|
||||||
}
|
}
|
||||||
@@ -113,15 +113,15 @@ public final class TurtleUpgrades
|
|||||||
public static Iterable<ITurtleUpgrade> getVanillaUpgrades()
|
public static Iterable<ITurtleUpgrade> getVanillaUpgrades()
|
||||||
{
|
{
|
||||||
List<ITurtleUpgrade> vanilla = new ArrayList<>();
|
List<ITurtleUpgrade> vanilla = new ArrayList<>();
|
||||||
vanilla.add( ComputerCraft.Upgrades.diamondPickaxe );
|
vanilla.add( ComputerCraft.TurtleUpgrades.diamondPickaxe );
|
||||||
vanilla.add( ComputerCraft.Upgrades.diamondAxe );
|
vanilla.add( ComputerCraft.TurtleUpgrades.diamondAxe );
|
||||||
vanilla.add( ComputerCraft.Upgrades.diamondSword );
|
vanilla.add( ComputerCraft.TurtleUpgrades.diamondSword );
|
||||||
vanilla.add( ComputerCraft.Upgrades.diamondShovel );
|
vanilla.add( ComputerCraft.TurtleUpgrades.diamondShovel );
|
||||||
vanilla.add( ComputerCraft.Upgrades.diamondHoe );
|
vanilla.add( ComputerCraft.TurtleUpgrades.diamondHoe );
|
||||||
vanilla.add( ComputerCraft.Upgrades.craftingTable );
|
vanilla.add( ComputerCraft.TurtleUpgrades.craftingTable );
|
||||||
vanilla.add( ComputerCraft.Upgrades.wirelessModem );
|
vanilla.add( ComputerCraft.TurtleUpgrades.wirelessModem );
|
||||||
vanilla.add( ComputerCraft.Upgrades.advancedModem );
|
vanilla.add( ComputerCraft.TurtleUpgrades.advancedModem );
|
||||||
vanilla.add( ComputerCraft.Upgrades.turtleSpeaker );
|
vanilla.add( ComputerCraft.TurtleUpgrades.speaker );
|
||||||
return vanilla;
|
return vanilla;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ package dan200.computercraft.shared.command;
|
|||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
import dan200.computercraft.core.apis.IAPIEnvironment;
|
||||||
import dan200.computercraft.core.computer.Computer;
|
import dan200.computercraft.core.computer.Computer;
|
||||||
import dan200.computercraft.core.tracking.ComputerTracker;
|
import dan200.computercraft.core.tracking.ComputerTracker;
|
||||||
import dan200.computercraft.core.tracking.Tracking;
|
import dan200.computercraft.core.tracking.Tracking;
|
||||||
@@ -126,7 +127,7 @@ public final class CommandComputerCraft extends CommandDelegate
|
|||||||
IPeripheral peripheral = computer.getPeripheral( i );
|
IPeripheral peripheral = computer.getPeripheral( i );
|
||||||
if( peripheral != null )
|
if( peripheral != null )
|
||||||
{
|
{
|
||||||
table.row( header( "Peripheral " + Computer.s_sideNames[i] ), text( peripheral.getType() ) );
|
table.row( header( "Peripheral " + IAPIEnvironment.SIDE_NAMES[i] ), text( peripheral.getType() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,11 @@ import javax.annotation.Nonnull;
|
|||||||
public class CommandCopy extends CommandBase implements IClientCommand
|
public class CommandCopy extends CommandBase implements IClientCommand
|
||||||
{
|
{
|
||||||
public static final CommandCopy INSTANCE = new CommandCopy();
|
public static final CommandCopy INSTANCE = new CommandCopy();
|
||||||
private static final String NAME = "computercraft_copy";
|
|
||||||
|
/**
|
||||||
|
* We start with a "~" so we're less likely to show up on completions.
|
||||||
|
*/
|
||||||
|
private static final String NAME = "~computercraft_copy";
|
||||||
|
|
||||||
private CommandCopy()
|
private CommandCopy()
|
||||||
{
|
{
|
||||||
@@ -47,7 +51,7 @@ public class CommandCopy extends CommandBase implements IClientCommand
|
|||||||
@Override
|
@Override
|
||||||
public String getUsage( @Nonnull ICommandSender sender )
|
public String getUsage( @Nonnull ICommandSender sender )
|
||||||
{
|
{
|
||||||
return "computercraft_copy <text>";
|
return "/" + NAME + " <text>";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.command.text;
|
package dan200.computercraft.shared.command.text;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.shared.command.CommandUtils;
|
import dan200.computercraft.shared.command.CommandUtils;
|
||||||
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
import dan200.computercraft.shared.network.client.ChatTableClientMessage;
|
import dan200.computercraft.shared.network.client.ChatTableClientMessage;
|
||||||
import net.minecraft.command.ICommandSender;
|
import net.minecraft.command.ICommandSender;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
@@ -101,6 +101,11 @@ public class TableBuilder
|
|||||||
return additional;
|
return additional;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAdditional( int additional )
|
||||||
|
{
|
||||||
|
this.additional = additional;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trim this table to a given height
|
* Trim this table to a given height
|
||||||
*
|
*
|
||||||
@@ -110,8 +115,8 @@ public class TableBuilder
|
|||||||
{
|
{
|
||||||
if( rows.size() > height )
|
if( rows.size() > height )
|
||||||
{
|
{
|
||||||
additional += rows.size() - height;
|
additional += rows.size() - height - 1;
|
||||||
rows.subList( height, rows.size() ).clear();
|
rows.subList( height - 1, rows.size() ).clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +125,7 @@ public class TableBuilder
|
|||||||
if( CommandUtils.isPlayer( source ) )
|
if( CommandUtils.isPlayer( source ) )
|
||||||
{
|
{
|
||||||
trim( 18 );
|
trim( 18 );
|
||||||
ComputerCraft.sendToPlayer( (EntityPlayerMP) source, new ChatTableClientMessage( this ) );
|
NetworkHandler.sendToPlayer( (EntityPlayerMP) source, new ChatTableClientMessage( this ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,8 +74,6 @@ public interface TableFormatter
|
|||||||
int totalWidth = (columns - 1) * getWidth( SEPARATOR );
|
int totalWidth = (columns - 1) * getWidth( SEPARATOR );
|
||||||
for( int x : maxWidths ) totalWidth += x;
|
for( int x : maxWidths ) totalWidth += x;
|
||||||
|
|
||||||
// TODO: Limit the widths of some entries if totalWidth > maxWidth
|
|
||||||
|
|
||||||
if( headers != null )
|
if( headers != null )
|
||||||
{
|
{
|
||||||
TextComponentString line = new TextComponentString( "" );
|
TextComponentString line = new TextComponentString( "" );
|
||||||
|
|||||||
@@ -10,18 +10,16 @@ import net.minecraft.block.Block;
|
|||||||
import net.minecraft.block.ITileEntityProvider;
|
import net.minecraft.block.ITileEntityProvider;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
public abstract class BlockGeneric extends Block implements ITileEntityProvider
|
public abstract class BlockGeneric extends Block implements ITileEntityProvider
|
||||||
{
|
{
|
||||||
@@ -31,122 +29,47 @@ public abstract class BlockGeneric extends Block implements ITileEntityProvider
|
|||||||
this.hasTileEntity = true;
|
this.hasTileEntity = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract IBlockState getDefaultBlockState( int damage, EnumFacing placedSide );
|
|
||||||
|
|
||||||
protected abstract TileGeneric createTile( IBlockState state );
|
protected abstract TileGeneric createTile( IBlockState state );
|
||||||
|
|
||||||
protected abstract TileGeneric createTile( int damage );
|
protected abstract TileGeneric createTile( int damage );
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void dropBlockAsItemWithChance( World world, @Nonnull BlockPos pos, @Nonnull IBlockState state, float chance, int fortune )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void getDrops( @Nonnull NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, @Nonnull IBlockState state, int fortune )
|
|
||||||
{
|
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
|
||||||
if( tile instanceof TileGeneric )
|
|
||||||
{
|
|
||||||
TileGeneric generic = (TileGeneric) tile;
|
|
||||||
generic.getDroppedItems( drops, false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
|
|
||||||
{
|
|
||||||
return getDefaultBlockState( damage, side );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removedByPlayer( @Nonnull IBlockState state, World world, @Nonnull BlockPos pos, @Nonnull EntityPlayer player, boolean willHarvest )
|
|
||||||
{
|
|
||||||
if( !world.isRemote )
|
|
||||||
{
|
|
||||||
// Drop items
|
|
||||||
boolean creative = player.capabilities.isCreativeMode;
|
|
||||||
dropAllItems( world, pos, creative );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove block
|
|
||||||
return super.removedByPlayer( state, world, pos, player, willHarvest );
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void dropAllItems( World world, BlockPos pos, boolean creative )
|
|
||||||
{
|
|
||||||
// Get items to drop
|
|
||||||
NonNullList<ItemStack> drops = NonNullList.create();
|
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
|
||||||
if( tile instanceof TileGeneric )
|
|
||||||
{
|
|
||||||
TileGeneric generic = (TileGeneric) tile;
|
|
||||||
generic.getDroppedItems( drops, creative );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop items
|
|
||||||
if( drops.size() > 0 )
|
|
||||||
{
|
|
||||||
for( ItemStack item : drops )
|
|
||||||
{
|
|
||||||
dropItem( world, pos, item );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void dropItem( World world, BlockPos pos, @Nonnull ItemStack stack )
|
|
||||||
{
|
|
||||||
Block.spawnAsEntity( world, pos, stack );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void breakBlock( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState newState )
|
public final void breakBlock( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState newState )
|
||||||
{
|
{
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
super.breakBlock( world, pos, newState );
|
super.breakBlock( world, pos, newState );
|
||||||
world.removeTileEntity( pos );
|
world.removeTileEntity( pos );
|
||||||
if( tile instanceof TileGeneric )
|
if( tile instanceof TileGeneric ) ((TileGeneric) tile).destroy();
|
||||||
{
|
|
||||||
TileGeneric generic = (TileGeneric) tile;
|
|
||||||
generic.destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean onBlockActivated( World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ )
|
public final boolean onBlockActivated( World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ )
|
||||||
{
|
{
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TileGeneric )
|
return tile instanceof TileGeneric && ((TileGeneric) tile).onActivate( player, hand, side, hitX, hitY, hitZ );
|
||||||
{
|
|
||||||
TileGeneric generic = (TileGeneric) tile;
|
|
||||||
return generic.onActivate( player, hand, side, hitX, hitY, hitZ );
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public final void neighborChanged( IBlockState state, World world, BlockPos pos, Block block, BlockPos neighorPos )
|
@SuppressWarnings( "deprecation" )
|
||||||
|
public final void neighborChanged( IBlockState state, World world, BlockPos pos, Block block, BlockPos neighbour )
|
||||||
{
|
{
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TileGeneric )
|
if( tile instanceof TileGeneric ) ((TileGeneric) tile).onNeighbourChange( neighbour );
|
||||||
{
|
|
||||||
TileGeneric generic = (TileGeneric) tile;
|
|
||||||
generic.onNeighbourChange();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onNeighborChange( IBlockAccess world, BlockPos pos, BlockPos neighbour )
|
public final void onNeighborChange( IBlockAccess world, BlockPos pos, BlockPos neighbour )
|
||||||
{
|
{
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TileGeneric )
|
if( tile instanceof TileGeneric ) ((TileGeneric) tile).onNeighbourTileEntityChange( neighbour );
|
||||||
{
|
}
|
||||||
TileGeneric generic = (TileGeneric) tile;
|
|
||||||
generic.onNeighbourTileEntityChange( neighbour );
|
@Override
|
||||||
}
|
public void updateTick( World world, BlockPos pos, IBlockState state, Random rand )
|
||||||
|
{
|
||||||
|
TileEntity te = world.getTileEntity( pos );
|
||||||
|
if( te instanceof TileGeneric ) ((TileGeneric) te).updateTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -160,12 +83,7 @@ public abstract class BlockGeneric extends Block implements ITileEntityProvider
|
|||||||
public final boolean canConnectRedstone( IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side )
|
public final boolean canConnectRedstone( IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side )
|
||||||
{
|
{
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TileGeneric )
|
return tile instanceof TileGeneric && ((TileGeneric) tile).getRedstoneConnectivity( side );
|
||||||
{
|
|
||||||
TileGeneric generic = (TileGeneric) tile;
|
|
||||||
return generic.getRedstoneConnectivity( side );
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -175,8 +93,7 @@ public abstract class BlockGeneric extends Block implements ITileEntityProvider
|
|||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TileGeneric && tile.hasWorld() )
|
if( tile instanceof TileGeneric && tile.hasWorld() )
|
||||||
{
|
{
|
||||||
TileGeneric generic = (TileGeneric) tile;
|
return ((TileGeneric) tile).getRedstoneOutput( oppositeSide.getOpposite() );
|
||||||
return generic.getRedstoneOutput( oppositeSide.getOpposite() );
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -193,8 +110,7 @@ public abstract class BlockGeneric extends Block implements ITileEntityProvider
|
|||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TileGeneric )
|
if( tile instanceof TileGeneric )
|
||||||
{
|
{
|
||||||
TileGeneric generic = (TileGeneric) tile;
|
return ((TileGeneric) tile).getBundledRedstoneConnectivity( side );
|
||||||
return generic.getBundledRedstoneConnectivity( side );
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -204,8 +120,7 @@ public abstract class BlockGeneric extends Block implements ITileEntityProvider
|
|||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TileGeneric && tile.hasWorld() )
|
if( tile instanceof TileGeneric && tile.hasWorld() )
|
||||||
{
|
{
|
||||||
TileGeneric generic = (TileGeneric) tile;
|
return ((TileGeneric) tile).getBundledRedstoneOutput( side );
|
||||||
return generic.getBundledRedstoneOutput( side );
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,19 +22,14 @@ public class ClientTerminal implements ITerminal
|
|||||||
m_terminalChanged = false;
|
m_terminalChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update()
|
|
||||||
{
|
|
||||||
if( m_terminal != null )
|
|
||||||
{
|
|
||||||
m_terminalChanged |= m_terminal.getChanged();
|
|
||||||
m_terminal.clearChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean pollTerminalChanged()
|
public boolean pollTerminalChanged()
|
||||||
{
|
{
|
||||||
boolean changed = m_terminalChanged;
|
boolean changed = m_terminalChanged;
|
||||||
m_terminalChanged = false;
|
m_terminalChanged = false;
|
||||||
|
|
||||||
|
Terminal terminal = m_terminal;
|
||||||
|
if( terminal != null ) terminal.clearChanged();
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +66,7 @@ public class ClientTerminal implements ITerminal
|
|||||||
{
|
{
|
||||||
if( m_terminal == null )
|
if( m_terminal == null )
|
||||||
{
|
{
|
||||||
m_terminal = new Terminal( width, height );
|
m_terminal = new Terminal( width, height, () -> m_terminalChanged = true );
|
||||||
m_terminalChanged = true;
|
m_terminalChanged = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -9,35 +9,33 @@ package dan200.computercraft.shared.common;
|
|||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class ServerTerminal implements ITerminal
|
public class ServerTerminal implements ITerminal
|
||||||
{
|
{
|
||||||
private final boolean m_colour;
|
private final boolean m_colour;
|
||||||
private Terminal m_terminal;
|
private Terminal m_terminal;
|
||||||
private boolean m_terminalChanged;
|
private final AtomicBoolean m_terminalChanged = new AtomicBoolean( false );
|
||||||
private boolean m_terminalChangedLastFrame;
|
private boolean m_terminalChangedLastFrame = false;
|
||||||
|
|
||||||
public ServerTerminal( boolean colour )
|
public ServerTerminal( boolean colour )
|
||||||
{
|
{
|
||||||
m_colour = colour;
|
m_colour = colour;
|
||||||
m_terminal = null;
|
m_terminal = null;
|
||||||
m_terminalChanged = false;
|
|
||||||
m_terminalChangedLastFrame = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerTerminal( boolean colour, int terminalWidth, int terminalHeight )
|
public ServerTerminal( boolean colour, int terminalWidth, int terminalHeight )
|
||||||
{
|
{
|
||||||
m_colour = colour;
|
m_colour = colour;
|
||||||
m_terminal = new Terminal( terminalWidth, terminalHeight );
|
m_terminal = new Terminal( terminalWidth, terminalHeight, this::markTerminalChanged );
|
||||||
m_terminalChanged = false;
|
|
||||||
m_terminalChangedLastFrame = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resize( int width, int height )
|
protected void resize( int width, int height )
|
||||||
{
|
{
|
||||||
if( m_terminal == null )
|
if( m_terminal == null )
|
||||||
{
|
{
|
||||||
m_terminal = new Terminal( width, height );
|
m_terminal = new Terminal( width, height, this::markTerminalChanged );
|
||||||
m_terminalChanged = true;
|
markTerminalChanged();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -50,23 +48,21 @@ public class ServerTerminal implements ITerminal
|
|||||||
if( m_terminal != null )
|
if( m_terminal != null )
|
||||||
{
|
{
|
||||||
m_terminal = null;
|
m_terminal = null;
|
||||||
m_terminalChanged = true;
|
markTerminalChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void markTerminalChanged()
|
protected void markTerminalChanged()
|
||||||
{
|
{
|
||||||
m_terminalChanged = true;
|
m_terminalChanged.set( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update()
|
public void update()
|
||||||
{
|
{
|
||||||
m_terminalChangedLastFrame = m_terminalChanged || (m_terminal != null && m_terminal.getChanged());
|
Terminal terminal = m_terminal;
|
||||||
if( m_terminal != null )
|
if( terminal != null ) terminal.clearChanged();
|
||||||
{
|
|
||||||
m_terminal.clearChanged();
|
m_terminalChangedLastFrame = m_terminalChanged.getAndSet( false );
|
||||||
}
|
|
||||||
m_terminalChanged = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasTerminalChanged()
|
public boolean hasTerminalChanged()
|
||||||
|
|||||||
@@ -9,14 +9,12 @@ package dan200.computercraft.shared.common;
|
|||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
|
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
@@ -55,23 +53,30 @@ public abstract class TileGeneric extends TileEntity
|
|||||||
getWorld().setBlockState( getPos(), newState, 3 );
|
getWorld().setBlockState( getPos(), newState, 3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean onActivate( EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ )
|
public boolean onActivate( EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void onNeighbourChange()
|
public void onNeighbourChange()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings( "deprecation" )
|
||||||
|
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||||
|
{
|
||||||
|
onNeighbourChange();
|
||||||
|
}
|
||||||
|
|
||||||
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateTick()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getRedstoneConnectivity( EnumFacing side )
|
public boolean getRedstoneConnectivity( EnumFacing side )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -8,19 +8,17 @@ package dan200.computercraft.shared.computer.blocks;
|
|||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.util.DirectionUtil;
|
import dan200.computercraft.shared.computer.items.ComputerItemFactory;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.properties.PropertyDirection;
|
import net.minecraft.block.properties.PropertyDirection;
|
||||||
import net.minecraft.block.properties.PropertyEnum;
|
import net.minecraft.block.properties.PropertyEnum;
|
||||||
import net.minecraft.block.state.BlockStateContainer;
|
import net.minecraft.block.state.BlockStateContainer;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@@ -87,14 +85,7 @@ public class BlockCommandComputer extends BlockComputerBase
|
|||||||
@Override
|
@Override
|
||||||
protected IBlockState getDefaultBlockState( ComputerFamily family, EnumFacing placedSide )
|
protected IBlockState getDefaultBlockState( ComputerFamily family, EnumFacing placedSide )
|
||||||
{
|
{
|
||||||
if( placedSide.getAxis() != EnumFacing.Axis.Y )
|
return getDefaultState().withProperty( Properties.FACING, placedSide );
|
||||||
{
|
|
||||||
return getDefaultState().withProperty( Properties.FACING, placedSide );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return getDefaultState();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -115,19 +106,10 @@ public class BlockCommandComputer extends BlockComputerBase
|
|||||||
return new TileCommandComputer();
|
return new TileCommandComputer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, @Nonnull ItemStack itemstack )
|
protected ItemStack getItem( TileComputerBase tile )
|
||||||
{
|
{
|
||||||
// Not sure why this is necessary
|
return tile instanceof TileCommandComputer ? ComputerItemFactory.create( (TileComputer) tile ) : ItemStack.EMPTY;
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
|
||||||
if( tile instanceof TileCommandComputer )
|
|
||||||
{
|
|
||||||
tile.setWorld( world ); // Not sure why this is necessary
|
|
||||||
tile.setPos( pos ); // Not sure why this is necessary
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set direction
|
|
||||||
EnumFacing dir = DirectionUtil.fromEntityRot( player );
|
|
||||||
setDirection( world, pos, dir );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,24 +9,17 @@ package dan200.computercraft.shared.computer.blocks;
|
|||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.items.ComputerItemFactory;
|
import dan200.computercraft.shared.computer.items.ComputerItemFactory;
|
||||||
import dan200.computercraft.shared.computer.items.ItemComputer;
|
|
||||||
import dan200.computercraft.shared.util.DirectionUtil;
|
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.properties.PropertyBool;
|
import net.minecraft.block.properties.PropertyBool;
|
||||||
import net.minecraft.block.properties.PropertyDirection;
|
import net.minecraft.block.properties.PropertyDirection;
|
||||||
import net.minecraft.block.properties.PropertyEnum;
|
import net.minecraft.block.properties.PropertyEnum;
|
||||||
import net.minecraft.block.state.BlockStateContainer;
|
import net.minecraft.block.state.BlockStateContainer;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@@ -99,24 +92,9 @@ public class BlockComputer extends BlockComputerBase
|
|||||||
@Override
|
@Override
|
||||||
protected IBlockState getDefaultBlockState( ComputerFamily family, EnumFacing placedSide )
|
protected IBlockState getDefaultBlockState( ComputerFamily family, EnumFacing placedSide )
|
||||||
{
|
{
|
||||||
IBlockState state = getDefaultState();
|
return getDefaultState()
|
||||||
if( placedSide.getAxis() != EnumFacing.Axis.Y )
|
.withProperty( Properties.FACING, placedSide )
|
||||||
{
|
.withProperty( Properties.ADVANCED, family == ComputerFamily.Advanced );
|
||||||
state = state.withProperty( Properties.FACING, placedSide );
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( family )
|
|
||||||
{
|
|
||||||
case Normal:
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return state.withProperty( Properties.ADVANCED, false );
|
|
||||||
}
|
|
||||||
case Advanced:
|
|
||||||
{
|
|
||||||
return state.withProperty( Properties.ADVANCED, true );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@@ -131,7 +109,7 @@ public class BlockComputer extends BlockComputerBase
|
|||||||
@Override
|
@Override
|
||||||
public ComputerFamily getFamily( int damage )
|
public ComputerFamily getFamily( int damage )
|
||||||
{
|
{
|
||||||
return ((ItemComputer) Item.getItemFromBlock( this )).getFamily( damage );
|
return ComputerCraft.Items.computer.getFamily( damage );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -153,27 +131,10 @@ public class BlockComputer extends BlockComputerBase
|
|||||||
return new TileComputer();
|
return new TileComputer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, @Nonnull ItemStack stack )
|
|
||||||
{
|
|
||||||
// Not sure why this is necessary
|
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
|
||||||
if( tile instanceof TileComputer )
|
|
||||||
{
|
|
||||||
tile.setWorld( world ); // Not sure why this is necessary
|
|
||||||
tile.setPos( pos ); // Not sure why this is necessary
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set direction
|
|
||||||
EnumFacing dir = DirectionUtil.fromEntityRot( player );
|
|
||||||
setDirection( world, pos, dir );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult target, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
|
protected ItemStack getItem( TileComputerBase tile )
|
||||||
{
|
{
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
return tile instanceof TileComputer ? ComputerItemFactory.create( (TileComputer) tile ) : ItemStack.EMPTY;
|
||||||
return tile instanceof TileComputer ? ComputerItemFactory.create( (TileComputer) tile ) : super.getPickBlock( state, target, world, pos, player );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,16 +8,22 @@ package dan200.computercraft.shared.computer.blocks;
|
|||||||
|
|
||||||
import dan200.computercraft.shared.common.BlockDirectional;
|
import dan200.computercraft.shared.common.BlockDirectional;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.items.ItemComputerBase;
|
import dan200.computercraft.shared.util.DirectionUtil;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public abstract class BlockComputerBase extends BlockDirectional
|
public abstract class BlockComputerBase extends BlockDirectional
|
||||||
{
|
{
|
||||||
public BlockComputerBase( Material material )
|
public BlockComputerBase( Material material )
|
||||||
@@ -47,11 +53,15 @@ public abstract class BlockComputerBase extends BlockDirectional
|
|||||||
|
|
||||||
protected abstract TileComputerBase createTile( ComputerFamily family );
|
protected abstract TileComputerBase createTile( ComputerFamily family );
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
protected abstract ItemStack getItem( TileComputerBase tile );
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
protected final IBlockState getDefaultBlockState( int damage, EnumFacing placedSide )
|
@Deprecated
|
||||||
|
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
|
||||||
{
|
{
|
||||||
ItemComputerBase item = (ItemComputerBase) Item.getItemFromBlock( this );
|
return getDefaultBlockState( getFamily( damage ), DirectionUtil.fromEntityRot( placer ) );
|
||||||
return getDefaultBlockState( item.getFamily( damage ), placedSide );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,4 +90,55 @@ public abstract class BlockComputerBase extends BlockDirectional
|
|||||||
computer.updateInput();
|
computer.updateInput();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nonnull
|
||||||
|
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult target, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
|
||||||
|
{
|
||||||
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
|
if( tile instanceof TileComputerBase )
|
||||||
|
{
|
||||||
|
ItemStack result = getItem( (TileComputerBase) tile );
|
||||||
|
if( !result.isEmpty() ) return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getPickBlock( state, target, world, pos, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void dropBlockAsItemWithChance( World world, @Nonnull BlockPos pos, @Nonnull IBlockState state, float chance, int fortune )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void getDrops( @Nonnull NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, @Nonnull IBlockState state, int fortune )
|
||||||
|
{
|
||||||
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
|
if( tile instanceof TileComputerBase )
|
||||||
|
{
|
||||||
|
ItemStack stack = getItem( (TileComputerBase) tile );
|
||||||
|
if( !stack.isEmpty() ) drops.add( stack );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removedByPlayer( @Nonnull IBlockState state, World world, @Nonnull BlockPos pos, @Nonnull EntityPlayer player, boolean willHarvest )
|
||||||
|
{
|
||||||
|
if( !world.isRemote )
|
||||||
|
{
|
||||||
|
// We drop the item here instead of doing it in the harvest method, as we
|
||||||
|
// need to drop it for creative players too.
|
||||||
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
|
if( tile instanceof TileComputerBase )
|
||||||
|
{
|
||||||
|
TileComputerBase computer = (TileComputerBase) tile;
|
||||||
|
if( !player.capabilities.isCreativeMode || computer.getLabel() != null )
|
||||||
|
{
|
||||||
|
spawnAsEntity( world, pos, getItem( computer ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.removedByPlayer( state, world, pos, player, willHarvest );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,10 @@ package dan200.computercraft.shared.computer.blocks;
|
|||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.computer.items.ComputerItemFactory;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@@ -60,12 +57,6 @@ public class TileComputer extends TileComputerBase
|
|||||||
return m_proxy;
|
return m_proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
|
|
||||||
{
|
|
||||||
if( !creative || getLabel() != null ) drops.add( ComputerItemFactory.create( this ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void openGUI( EntityPlayer player )
|
public void openGUI( EntityPlayer player )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -173,9 +173,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNeighbourChange()
|
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||||
{
|
{
|
||||||
updateInput();
|
updateInput( neighbour );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -296,7 +296,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
int localDir = remapLocalSide( DirectionUtil.toLocal( this, dir ) );
|
int localDir = remapLocalSide( DirectionUtil.toLocal( this, dir ) );
|
||||||
if( !isRedstoneBlockedOnSide( localDir ) )
|
if( !isRedstoneBlockedOnSide( localDir ) )
|
||||||
{
|
{
|
||||||
computer.setRedstoneInput( localDir, getWorld().getRedstonePower( offset, offsetSide ) );
|
computer.setRedstoneInput( localDir, getWorld().getRedstonePower( offset, dir ) );
|
||||||
computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getWorld(), offset, offsetSide ) );
|
computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getWorld(), offset, offsetSide ) );
|
||||||
}
|
}
|
||||||
if( !isPeripheralBlockedOnSide( localDir ) )
|
if( !isPeripheralBlockedOnSide( localDir ) )
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
package dan200.computercraft.shared.computer.core;
|
package dan200.computercraft.shared.computer.core;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.shared.common.ClientTerminal;
|
import dan200.computercraft.shared.common.ClientTerminal;
|
||||||
import dan200.computercraft.shared.computer.blocks.ComputerState;
|
import dan200.computercraft.shared.computer.blocks.ComputerState;
|
||||||
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
import dan200.computercraft.shared.network.server.ComputerActionServerMessage;
|
import dan200.computercraft.shared.network.server.ComputerActionServerMessage;
|
||||||
import dan200.computercraft.shared.network.server.QueueEventServerMessage;
|
import dan200.computercraft.shared.network.server.QueueEventServerMessage;
|
||||||
import dan200.computercraft.shared.network.server.RequestComputerMessage;
|
import dan200.computercraft.shared.network.server.RequestComputerMessage;
|
||||||
@@ -32,10 +32,8 @@ public class ClientComputer extends ClientTerminal implements IComputer
|
|||||||
m_instanceID = instanceID;
|
m_instanceID = instanceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update()
|
public void update()
|
||||||
{
|
{
|
||||||
super.update();
|
|
||||||
m_changedLastFrame = m_changed;
|
m_changedLastFrame = m_changed;
|
||||||
m_changed = false;
|
m_changed = false;
|
||||||
}
|
}
|
||||||
@@ -53,7 +51,7 @@ public class ClientComputer extends ClientTerminal implements IComputer
|
|||||||
public void requestState()
|
public void requestState()
|
||||||
{
|
{
|
||||||
// Request state from server
|
// Request state from server
|
||||||
ComputerCraft.sendToServer( new RequestComputerMessage( getInstanceID() ) );
|
NetworkHandler.sendToServer( new RequestComputerMessage( getInstanceID() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// IComputer
|
// IComputer
|
||||||
@@ -94,28 +92,28 @@ public class ClientComputer extends ClientTerminal implements IComputer
|
|||||||
public void turnOn()
|
public void turnOn()
|
||||||
{
|
{
|
||||||
// Send turnOn to server
|
// Send turnOn to server
|
||||||
ComputerCraft.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.TURN_ON ) );
|
NetworkHandler.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.TURN_ON ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown()
|
public void shutdown()
|
||||||
{
|
{
|
||||||
// Send shutdown to server
|
// Send shutdown to server
|
||||||
ComputerCraft.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.SHUTDOWN ) );
|
NetworkHandler.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.SHUTDOWN ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reboot()
|
public void reboot()
|
||||||
{
|
{
|
||||||
// Send reboot to server
|
// Send reboot to server
|
||||||
ComputerCraft.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.REBOOT ) );
|
NetworkHandler.sendToServer( new ComputerActionServerMessage( m_instanceID, ComputerActionServerMessage.Action.REBOOT ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void queueEvent( String event, Object[] arguments )
|
public void queueEvent( String event, Object[] arguments )
|
||||||
{
|
{
|
||||||
// Send event to server
|
// Send event to server
|
||||||
ComputerCraft.sendToServer( new QueueEventServerMessage( m_instanceID, event, arguments ) );
|
NetworkHandler.sendToServer( new QueueEventServerMessage( m_instanceID, event, arguments ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setState( ComputerState state, NBTTagCompound userData )
|
public void setState( ComputerState state, NBTTagCompound userData )
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import dan200.computercraft.core.apis.IAPIEnvironment;
|
|||||||
import dan200.computercraft.core.computer.Computer;
|
import dan200.computercraft.core.computer.Computer;
|
||||||
import dan200.computercraft.core.computer.IComputerEnvironment;
|
import dan200.computercraft.core.computer.IComputerEnvironment;
|
||||||
import dan200.computercraft.shared.common.ServerTerminal;
|
import dan200.computercraft.shared.common.ServerTerminal;
|
||||||
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
import dan200.computercraft.shared.network.client.ComputerDataClientMessage;
|
import dan200.computercraft.shared.network.client.ComputerDataClientMessage;
|
||||||
import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage;
|
import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage;
|
||||||
import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage;
|
import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage;
|
||||||
@@ -104,7 +105,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
public void update()
|
public void update()
|
||||||
{
|
{
|
||||||
super.update();
|
super.update();
|
||||||
m_computer.advance( 0.05 );
|
m_computer.advance();
|
||||||
|
|
||||||
m_changedLastFrame = m_computer.pollAndResetChanged() || m_changed;
|
m_changedLastFrame = m_computer.pollAndResetChanged() || m_changed;
|
||||||
m_changed = false;
|
m_changed = false;
|
||||||
@@ -163,7 +164,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
if( hasOutputChanged() || force )
|
if( hasOutputChanged() || force )
|
||||||
{
|
{
|
||||||
// Send computer state to all clients
|
// Send computer state to all clients
|
||||||
ComputerCraft.sendToAllPlayers( createComputerPacket() );
|
NetworkHandler.sendToAllPlayers( createComputerPacket() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hasTerminalChanged() || force )
|
if( hasTerminalChanged() || force )
|
||||||
@@ -178,7 +179,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
{
|
{
|
||||||
if( isInteracting( player ) )
|
if( isInteracting( player ) )
|
||||||
{
|
{
|
||||||
ComputerCraft.sendToPlayer( player, packet );
|
NetworkHandler.sendToPlayer( player, packet );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,19 +189,19 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
public void sendComputerState( EntityPlayer player )
|
public void sendComputerState( EntityPlayer player )
|
||||||
{
|
{
|
||||||
// Send state to client
|
// Send state to client
|
||||||
ComputerCraft.sendToPlayer( player, createComputerPacket() );
|
NetworkHandler.sendToPlayer( player, createComputerPacket() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendTerminalState( EntityPlayer player )
|
public void sendTerminalState( EntityPlayer player )
|
||||||
{
|
{
|
||||||
// Send terminal state to client
|
// Send terminal state to client
|
||||||
ComputerCraft.sendToPlayer( player, createTerminalPacket() );
|
NetworkHandler.sendToPlayer( player, createTerminalPacket() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void broadcastDelete()
|
public void broadcastDelete()
|
||||||
{
|
{
|
||||||
// Send deletion to client
|
// Send deletion to client
|
||||||
ComputerCraft.sendToAllPlayers( new ComputerDeletedClientMessage( getInstanceID() ) );
|
NetworkHandler.sendToAllPlayers( new ComputerDeletedClientMessage( getInstanceID() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWritableMount getRootMount()
|
public IWritableMount getRootMount()
|
||||||
@@ -282,22 +283,22 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
|
|
||||||
public int getRedstoneOutput( int side )
|
public int getRedstoneOutput( int side )
|
||||||
{
|
{
|
||||||
return m_computer.getRedstoneOutput( side );
|
return m_computer.getEnvironment().getExternalRedstoneOutput( side );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRedstoneInput( int side, int level )
|
public void setRedstoneInput( int side, int level )
|
||||||
{
|
{
|
||||||
m_computer.setRedstoneInput( side, level );
|
m_computer.getEnvironment().setRedstoneInput( side, level );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBundledRedstoneOutput( int side )
|
public int getBundledRedstoneOutput( int side )
|
||||||
{
|
{
|
||||||
return m_computer.getBundledRedstoneOutput( side );
|
return m_computer.getEnvironment().getExternalBundledRedstoneOutput( side );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBundledRedstoneInput( int side, int combination )
|
public void setBundledRedstoneInput( int side, int combination )
|
||||||
{
|
{
|
||||||
m_computer.setBundledRedstoneInput( side, combination );
|
m_computer.getEnvironment().setBundledRedstoneInput( side, combination );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAPI( ILuaAPI api )
|
public void addAPI( ILuaAPI api )
|
||||||
@@ -305,7 +306,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
m_computer.addAPI( api );
|
m_computer.addAPI( api );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( "deprecation" )
|
@Deprecated
|
||||||
public void addAPI( dan200.computercraft.core.apis.ILuaAPI api )
|
public void addAPI( dan200.computercraft.core.apis.ILuaAPI api )
|
||||||
{
|
{
|
||||||
m_computer.addAPI( api );
|
m_computer.addAPI( api );
|
||||||
@@ -313,12 +314,12 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
|
|
||||||
public void setPeripheral( int side, IPeripheral peripheral )
|
public void setPeripheral( int side, IPeripheral peripheral )
|
||||||
{
|
{
|
||||||
m_computer.setPeripheral( side, peripheral );
|
m_computer.getEnvironment().setPeripheral( side, peripheral );
|
||||||
}
|
}
|
||||||
|
|
||||||
public IPeripheral getPeripheral( int side )
|
public IPeripheral getPeripheral( int side )
|
||||||
{
|
{
|
||||||
return m_computer.getPeripheral( side );
|
return m_computer.getEnvironment().getPeripheral( side );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLabel( String label )
|
public void setLabel( String label )
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ package dan200.computercraft.shared.computer.items;
|
|||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@@ -31,15 +30,9 @@ public class ComputerItemFactory
|
|||||||
{
|
{
|
||||||
case Normal:
|
case Normal:
|
||||||
case Advanced:
|
case Advanced:
|
||||||
{
|
return ComputerCraft.Items.computer.create( id, label, family );
|
||||||
ItemComputer computer = ((ItemComputer) Item.getItemFromBlock( ComputerCraft.Blocks.computer ));
|
|
||||||
return computer.create( id, label, family );
|
|
||||||
}
|
|
||||||
case Command:
|
case Command:
|
||||||
{
|
return ComputerCraft.Items.commandComputer.create( id, label, family );
|
||||||
ItemCommandComputer commandComputer = ((ItemCommandComputer) Item.getItemFromBlock( ComputerCraft.Blocks.commandComputer ));
|
|
||||||
return commandComputer.create( id, label, family );
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ public class JEIComputerCraft implements IModPlugin
|
|||||||
@Override
|
@Override
|
||||||
public void registerItemSubtypes( ISubtypeRegistry subtypeRegistry )
|
public void registerItemSubtypes( ISubtypeRegistry subtypeRegistry )
|
||||||
{
|
{
|
||||||
subtypeRegistry.registerSubtypeInterpreter( Item.getItemFromBlock( ComputerCraft.Blocks.turtle ), turtleSubtype );
|
subtypeRegistry.registerSubtypeInterpreter( ComputerCraft.Items.turtle, turtleSubtype );
|
||||||
subtypeRegistry.registerSubtypeInterpreter( Item.getItemFromBlock( ComputerCraft.Blocks.turtleExpanded ), turtleSubtype );
|
subtypeRegistry.registerSubtypeInterpreter( ComputerCraft.Items.turtleExpanded, turtleSubtype );
|
||||||
subtypeRegistry.registerSubtypeInterpreter( Item.getItemFromBlock( ComputerCraft.Blocks.turtleAdvanced ), turtleSubtype );
|
subtypeRegistry.registerSubtypeInterpreter( ComputerCraft.Items.turtleAdvanced, turtleSubtype );
|
||||||
|
|
||||||
subtypeRegistry.registerSubtypeInterpreter( ComputerCraft.Items.pocketComputer, pocketSubtype );
|
subtypeRegistry.registerSubtypeInterpreter( ComputerCraft.Items.pocketComputer, pocketSubtype );
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,10 @@ final class BundledCapabilityProvider implements ICapabilityProvider
|
|||||||
if( capability == CAPABILITY_RECEIVER )
|
if( capability == CAPABILITY_RECEIVER )
|
||||||
{
|
{
|
||||||
IBundledReceiver receiver = this.receiver;
|
IBundledReceiver receiver = this.receiver;
|
||||||
if( receiver == null ) receiver = this.receiver = tile::onNeighbourChange;
|
if( receiver == null )
|
||||||
|
{
|
||||||
|
receiver = this.receiver = () -> tile.onNeighbourChange( tile.getPos().offset( side ) );
|
||||||
|
}
|
||||||
|
|
||||||
return CAPABILITY_RECEIVER.cast( receiver );
|
return CAPABILITY_RECEIVER.cast( receiver );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dan200.computercraft.shared.network;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.shared.network.client.*;
|
||||||
|
import dan200.computercraft.shared.network.server.ComputerActionServerMessage;
|
||||||
|
import dan200.computercraft.shared.network.server.QueueEventServerMessage;
|
||||||
|
import dan200.computercraft.shared.network.server.RequestComputerMessage;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
|
import net.minecraft.util.IThreadListener;
|
||||||
|
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public final class NetworkHandler
|
||||||
|
{
|
||||||
|
public static SimpleNetworkWrapper network;
|
||||||
|
|
||||||
|
private NetworkHandler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int COMPUTER_ACTION_SERVER_MESSAGE = 0;
|
||||||
|
private static final int QUEUE_EVENT_SERVER_MESSAGE = 1;
|
||||||
|
private static final int REQUEST_COMPUTER_SERVER_MESSAGE = 2;
|
||||||
|
|
||||||
|
private static final int CHAT_TABLE_CLIENT_MESSAGE = 10;
|
||||||
|
private static final int COMPUTER_DATA_CLIENT_MESSAGE = 11;
|
||||||
|
private static final int COMPUTER_DELETED_CLIENT_MESSAGE = 12;
|
||||||
|
private static final int COMPUTER_TERMINAL_CLIENT_MESSAGE = 13;
|
||||||
|
private static final int PLAY_RECORD_CLIENT_MESSAGE = 14;
|
||||||
|
|
||||||
|
public static void setup()
|
||||||
|
{
|
||||||
|
network = NetworkRegistry.INSTANCE.newSimpleChannel( ComputerCraft.MOD_ID );
|
||||||
|
|
||||||
|
// Server messages
|
||||||
|
registerMainThread( NetworkHandler.COMPUTER_ACTION_SERVER_MESSAGE, Side.SERVER, ComputerActionServerMessage::new );
|
||||||
|
registerMainThread( NetworkHandler.QUEUE_EVENT_SERVER_MESSAGE, Side.SERVER, QueueEventServerMessage::new );
|
||||||
|
registerMainThread( NetworkHandler.REQUEST_COMPUTER_SERVER_MESSAGE, Side.SERVER, RequestComputerMessage::new );
|
||||||
|
|
||||||
|
// Client messages
|
||||||
|
registerMainThread( NetworkHandler.PLAY_RECORD_CLIENT_MESSAGE, Side.CLIENT, PlayRecordClientMessage::new );
|
||||||
|
registerMainThread( NetworkHandler.COMPUTER_DATA_CLIENT_MESSAGE, Side.CLIENT, ComputerDataClientMessage::new );
|
||||||
|
registerMainThread( NetworkHandler.COMPUTER_TERMINAL_CLIENT_MESSAGE, Side.CLIENT, ComputerTerminalClientMessage::new );
|
||||||
|
registerMainThread( NetworkHandler.COMPUTER_DELETED_CLIENT_MESSAGE, Side.CLIENT, ComputerDeletedClientMessage::new );
|
||||||
|
registerMainThread( NetworkHandler.CHAT_TABLE_CLIENT_MESSAGE, Side.CLIENT, ChatTableClientMessage::new );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendToPlayer( EntityPlayer player, IMessage packet )
|
||||||
|
{
|
||||||
|
network.sendTo( packet, (EntityPlayerMP) player );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendToAllPlayers( IMessage packet )
|
||||||
|
{
|
||||||
|
network.sendToAll( packet );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendToServer( IMessage packet )
|
||||||
|
{
|
||||||
|
network.sendToServer( packet );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendToAllAround( IMessage packet, NetworkRegistry.TargetPoint point )
|
||||||
|
{
|
||||||
|
network.sendToAllAround( packet, point );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* /**
|
||||||
|
* Register packet, and a thread-unsafe handler for it.
|
||||||
|
*
|
||||||
|
* @param id The identifier for this packet type
|
||||||
|
* @param side The side to register this packet handler under
|
||||||
|
* @param factory The factory for this type of packet.
|
||||||
|
*/
|
||||||
|
private static <T extends NetworkMessage> void registerMainThread( int id, Side side, Supplier<T> factory )
|
||||||
|
{
|
||||||
|
network.registerMessage( MAIN_THREAD_HANDLER, factory.get().getClass(), id, side );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final IMessageHandler<NetworkMessage, IMessage> MAIN_THREAD_HANDLER = ( packet, context ) -> {
|
||||||
|
IThreadListener listener = context.side == Side.CLIENT ? Minecraft.getMinecraft() : context.getServerHandler().player.server;
|
||||||
|
if( listener.isCallingFromMinecraftThread() )
|
||||||
|
{
|
||||||
|
packet.handle( context );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
listener.addScheduledTask( () -> packet.handle( context ) );
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -6,18 +6,12 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.network;
|
package dan200.computercraft.shared.network;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.util.IThreadListener;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base interface for any message which will be sent to the client or server.
|
* The base interface for any message which will be sent to the client or server.
|
||||||
@@ -27,13 +21,6 @@ import java.util.function.Supplier;
|
|||||||
*/
|
*/
|
||||||
public interface NetworkMessage extends IMessage
|
public interface NetworkMessage extends IMessage
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The unique identifier for this packet type
|
|
||||||
*
|
|
||||||
* @return This packet type's identifier
|
|
||||||
*/
|
|
||||||
int getId();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write this packet to a buffer.
|
* Write this packet to a buffer.
|
||||||
*
|
*
|
||||||
@@ -52,6 +39,13 @@ public interface NetworkMessage extends IMessage
|
|||||||
*/
|
*/
|
||||||
void fromBytes( @Nonnull PacketBuffer buf );
|
void fromBytes( @Nonnull PacketBuffer buf );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle this {@link NetworkMessage}.
|
||||||
|
*
|
||||||
|
* @param context The context with which to handle this message
|
||||||
|
*/
|
||||||
|
void handle( MessageContext context );
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void fromBytes( ByteBuf buf )
|
default void fromBytes( ByteBuf buf )
|
||||||
{
|
{
|
||||||
@@ -63,56 +57,4 @@ public interface NetworkMessage extends IMessage
|
|||||||
{
|
{
|
||||||
toBytes( new PacketBuffer( buf ) );
|
toBytes( new PacketBuffer( buf ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a packet, and a thread-safe handler for it.
|
|
||||||
*
|
|
||||||
* @param side The side to register this packet handler under
|
|
||||||
* @param factory The factory for this type of packet.
|
|
||||||
* @param handler The handler for this type of packet. Note, this may be called on any thread,
|
|
||||||
* and so should be thread-safe.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings( "unchecked" )
|
|
||||||
static <T extends NetworkMessage> void register(
|
|
||||||
Side side,
|
|
||||||
Supplier<T> factory,
|
|
||||||
BiConsumer<MessageContext, T> handler
|
|
||||||
)
|
|
||||||
{
|
|
||||||
T instance = factory.get();
|
|
||||||
ComputerCraft.networkWrapper.registerMessage( ( packet, ctx ) -> {
|
|
||||||
handler.accept( ctx, (T) packet );
|
|
||||||
return null;
|
|
||||||
}, instance.getClass(), instance.getId(), side );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register packet, and a thread-unsafe handler for it.
|
|
||||||
*
|
|
||||||
* @param side The side to register this packet handler under
|
|
||||||
* @param factory The factory for this type of packet.
|
|
||||||
* @param handler The handler for this type of packet. This will be called on the "main"
|
|
||||||
* thread (either client or server).
|
|
||||||
*/
|
|
||||||
@SuppressWarnings( "unchecked" )
|
|
||||||
static <T extends NetworkMessage> void registerMainThread(
|
|
||||||
Side side,
|
|
||||||
Supplier<T> factory,
|
|
||||||
BiConsumer<MessageContext, T> handler
|
|
||||||
)
|
|
||||||
{
|
|
||||||
T instance = factory.get();
|
|
||||||
ComputerCraft.networkWrapper.registerMessage( ( packet, ctx ) -> {
|
|
||||||
IThreadListener listener = side == Side.CLIENT ? Minecraft.getMinecraft() : ctx.getServerHandler().player.server;
|
|
||||||
if( listener.isCallingFromMinecraftThread() )
|
|
||||||
{
|
|
||||||
handler.accept( ctx, (T) packet );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
listener.addScheduledTask( () -> handler.accept( ctx, (T) packet ) );
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}, instance.getClass(), instance.getId(), side );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
package dan200.computercraft.shared.network;
|
|
||||||
|
|
||||||
public final class NetworkMessages
|
|
||||||
{
|
|
||||||
private NetworkMessages()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final int COMPUTER_ACTION_SERVER_MESSAGE = 0;
|
|
||||||
public static final int QUEUE_EVENT_SERVER_MESSAGE = 1;
|
|
||||||
public static final int REQUEST_COMPUTER_SERVER_MESSAGE = 2;
|
|
||||||
|
|
||||||
public static final int CHAT_TABLE_CLIENT_MESSAGE = 10;
|
|
||||||
public static final int COMPUTER_DATA_CLIENT_MESSAGE = 11;
|
|
||||||
public static final int COMPUTER_DELETED_CLIENT_MESSAGE = 12;
|
|
||||||
public static final int COMPUTER_TERMINAL_CLIENT_MESSAGE = 13;
|
|
||||||
public static final int PLAY_RECORD_CLIENT_MESSAGE = 14;
|
|
||||||
}
|
|
||||||
@@ -6,12 +6,15 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.network.client;
|
package dan200.computercraft.shared.network.client;
|
||||||
|
|
||||||
|
import dan200.computercraft.client.ClientTableFormatter;
|
||||||
import dan200.computercraft.shared.command.text.TableBuilder;
|
import dan200.computercraft.shared.command.text.TableBuilder;
|
||||||
import dan200.computercraft.shared.network.NetworkMessage;
|
import dan200.computercraft.shared.network.NetworkMessage;
|
||||||
import dan200.computercraft.shared.network.NetworkMessages;
|
|
||||||
import dan200.computercraft.shared.util.NBTUtil;
|
import dan200.computercraft.shared.util.NBTUtil;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@@ -29,17 +32,6 @@ public class ChatTableClientMessage implements NetworkMessage
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId()
|
|
||||||
{
|
|
||||||
return NetworkMessages.CHAT_TABLE_CLIENT_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TableBuilder getTable()
|
|
||||||
{
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
@@ -56,6 +48,8 @@ public class ChatTableClientMessage implements NetworkMessage
|
|||||||
{
|
{
|
||||||
for( ITextComponent column : row ) buf.writeTextComponent( column );
|
for( ITextComponent column : row ) buf.writeTextComponent( column );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf.writeVarInt( table.getAdditional() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -82,6 +76,15 @@ public class ChatTableClientMessage implements NetworkMessage
|
|||||||
for( int j = 0; j < columns; j++ ) row[j] = NBTUtil.readTextComponent( buf );
|
for( int j = 0; j < columns; j++ ) row[j] = NBTUtil.readTextComponent( buf );
|
||||||
table.row( row );
|
table.row( row );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.setAdditional( buf.readVarInt() );
|
||||||
this.table = table;
|
this.table = table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SideOnly( Side.CLIENT )
|
||||||
|
public void handle( MessageContext context )
|
||||||
|
{
|
||||||
|
ClientTableFormatter.INSTANCE.display( table );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,8 @@ import dan200.computercraft.ComputerCraft;
|
|||||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||||
import dan200.computercraft.shared.network.NetworkMessage;
|
import dan200.computercraft.shared.network.NetworkMessage;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A packet, which performs an action on a {@link ClientComputer}.
|
* A packet, which performs an action on a {@link ClientComputer}.
|
||||||
@@ -58,12 +55,4 @@ public abstract class ComputerClientMessage implements NetworkMessage
|
|||||||
}
|
}
|
||||||
return computer;
|
return computer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends ComputerClientMessage> void register( Supplier<T> factory, BiConsumer<ClientComputer, T> handler )
|
|
||||||
{
|
|
||||||
NetworkMessage.registerMainThread( Side.CLIENT, factory, ( context, packet ) -> {
|
|
||||||
ClientComputer computer = packet.getComputer();
|
|
||||||
if( computer != null ) handler.accept( computer, packet );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ package dan200.computercraft.shared.network.client;
|
|||||||
|
|
||||||
import dan200.computercraft.shared.computer.blocks.ComputerState;
|
import dan200.computercraft.shared.computer.blocks.ComputerState;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.network.NetworkMessages;
|
|
||||||
import dan200.computercraft.shared.util.NBTUtil;
|
import dan200.computercraft.shared.util.NBTUtil;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@@ -34,22 +34,6 @@ public class ComputerDataClientMessage extends ComputerClientMessage
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId()
|
|
||||||
{
|
|
||||||
return NetworkMessages.COMPUTER_DATA_CLIENT_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ComputerState getState()
|
|
||||||
{
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NBTTagCompound getUserData()
|
|
||||||
{
|
|
||||||
return userData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
@@ -65,4 +49,10 @@ public class ComputerDataClientMessage extends ComputerClientMessage
|
|||||||
state = buf.readEnumValue( ComputerState.class );
|
state = buf.readEnumValue( ComputerState.class );
|
||||||
userData = NBTUtil.readCompoundTag( buf );
|
userData = NBTUtil.readCompoundTag( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle( MessageContext context )
|
||||||
|
{
|
||||||
|
getComputer().setState( state, userData );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.network.client;
|
package dan200.computercraft.shared.network.client;
|
||||||
|
|
||||||
import dan200.computercraft.shared.network.NetworkMessages;
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
|
||||||
public class ComputerDeletedClientMessage extends ComputerClientMessage
|
public class ComputerDeletedClientMessage extends ComputerClientMessage
|
||||||
{
|
{
|
||||||
@@ -20,8 +21,8 @@ public class ComputerDeletedClientMessage extends ComputerClientMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId()
|
public void handle( MessageContext context )
|
||||||
{
|
{
|
||||||
return NetworkMessages.COMPUTER_DELETED_CLIENT_MESSAGE;
|
ComputerCraft.clientComputerRegistry.remove( getInstanceId() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.network.client;
|
package dan200.computercraft.shared.network.client;
|
||||||
|
|
||||||
import dan200.computercraft.shared.network.NetworkMessages;
|
|
||||||
import dan200.computercraft.shared.util.NBTUtil;
|
import dan200.computercraft.shared.util.NBTUtil;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@@ -27,17 +27,6 @@ public class ComputerTerminalClientMessage extends ComputerClientMessage
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId()
|
|
||||||
{
|
|
||||||
return NetworkMessages.COMPUTER_TERMINAL_CLIENT_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NBTTagCompound getTag()
|
|
||||||
{
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
@@ -51,4 +40,10 @@ public class ComputerTerminalClientMessage extends ComputerClientMessage
|
|||||||
super.fromBytes( buf );
|
super.fromBytes( buf );
|
||||||
tag = NBTUtil.readCompoundTag( buf );
|
tag = NBTUtil.readCompoundTag( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle( MessageContext context )
|
||||||
|
{
|
||||||
|
getComputer().readDescription( tag );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,13 @@
|
|||||||
package dan200.computercraft.shared.network.client;
|
package dan200.computercraft.shared.network.client;
|
||||||
|
|
||||||
import dan200.computercraft.shared.network.NetworkMessage;
|
import dan200.computercraft.shared.network.NetworkMessage;
|
||||||
import dan200.computercraft.shared.network.NetworkMessages;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.util.SoundEvent;
|
import net.minecraft.util.SoundEvent;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@@ -43,27 +46,6 @@ public class PlayRecordClientMessage implements NetworkMessage
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId()
|
|
||||||
{
|
|
||||||
return NetworkMessages.PLAY_RECORD_CLIENT_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPos getPos()
|
|
||||||
{
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SoundEvent getSoundEvent()
|
|
||||||
{
|
|
||||||
return soundEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
@@ -90,4 +72,13 @@ public class PlayRecordClientMessage implements NetworkMessage
|
|||||||
soundEvent = SoundEvent.REGISTRY.getObjectById( buf.readInt() );
|
soundEvent = SoundEvent.REGISTRY.getObjectById( buf.readInt() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SideOnly( Side.CLIENT )
|
||||||
|
public void handle( MessageContext context )
|
||||||
|
{
|
||||||
|
Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
mc.world.playRecord( pos, soundEvent );
|
||||||
|
if( name != null ) mc.ingameGUI.setRecordPlayingMessage( name );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
import dan200.computercraft.shared.network.NetworkMessages;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@@ -25,12 +25,6 @@ public class ComputerActionServerMessage extends ComputerServerMessage
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId()
|
|
||||||
{
|
|
||||||
return NetworkMessages.COMPUTER_ACTION_SERVER_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
@@ -45,9 +39,21 @@ public class ComputerActionServerMessage extends ComputerServerMessage
|
|||||||
action = buf.readEnumValue( Action.class );
|
action = buf.readEnumValue( Action.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Action getAction()
|
@Override
|
||||||
|
protected void handle( ServerComputer computer )
|
||||||
{
|
{
|
||||||
return action;
|
switch( action )
|
||||||
|
{
|
||||||
|
case TURN_ON:
|
||||||
|
computer.turnOn();
|
||||||
|
break;
|
||||||
|
case REBOOT:
|
||||||
|
computer.reboot();
|
||||||
|
break;
|
||||||
|
case SHUTDOWN:
|
||||||
|
computer.shutdown();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Action
|
public enum Action
|
||||||
|
|||||||
@@ -12,11 +12,8 @@ import dan200.computercraft.shared.network.NetworkMessage;
|
|||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A packet, which performs an action on a {@link ServerComputer}.
|
* A packet, which performs an action on a {@link ServerComputer}.
|
||||||
@@ -61,11 +58,12 @@ public abstract class ComputerServerMessage implements NetworkMessage
|
|||||||
return computer;
|
return computer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends ComputerServerMessage> void register( Supplier<T> factory, BiConsumer<ServerComputer, T> handler )
|
@Override
|
||||||
|
public void handle( MessageContext context )
|
||||||
{
|
{
|
||||||
NetworkMessage.registerMainThread( Side.SERVER, factory, ( context, packet ) -> {
|
ServerComputer computer = getComputer( context );
|
||||||
ServerComputer computer = packet.getComputer( context );
|
if( computer != null ) handle( computer );
|
||||||
if( computer != null ) handler.accept( computer, packet );
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void handle( ServerComputer computer );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
import dan200.computercraft.shared.network.NetworkMessages;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.util.NBTUtil;
|
import dan200.computercraft.shared.util.NBTUtil;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
@@ -36,24 +36,6 @@ public class QueueEventServerMessage extends ComputerServerMessage
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId()
|
|
||||||
{
|
|
||||||
return NetworkMessages.QUEUE_EVENT_SERVER_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public String getEvent()
|
|
||||||
{
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Object[] getArgs()
|
|
||||||
{
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
@@ -71,4 +53,10 @@ public class QueueEventServerMessage extends ComputerServerMessage
|
|||||||
NBTTagCompound args = NBTUtil.readCompoundTag( buf );
|
NBTTagCompound args = NBTUtil.readCompoundTag( buf );
|
||||||
this.args = args == null ? null : NBTUtil.decodeObjects( args );
|
this.args = args == null ? null : NBTUtil.decodeObjects( args );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handle( ServerComputer computer )
|
||||||
|
{
|
||||||
|
computer.queueEvent( event, args );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.network.NetworkMessage;
|
import dan200.computercraft.shared.network.NetworkMessage;
|
||||||
import dan200.computercraft.shared.network.NetworkMessages;
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@@ -25,17 +27,6 @@ public class RequestComputerMessage implements NetworkMessage
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getId()
|
|
||||||
{
|
|
||||||
return NetworkMessages.REQUEST_COMPUTER_SERVER_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getInstance()
|
|
||||||
{
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
@@ -47,4 +38,11 @@ public class RequestComputerMessage implements NetworkMessage
|
|||||||
{
|
{
|
||||||
instance = buf.readVarInt();
|
instance = buf.readVarInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle( MessageContext context )
|
||||||
|
{
|
||||||
|
ServerComputer computer = ComputerCraft.serverComputerRegistry.get( instance );
|
||||||
|
if( computer != null ) computer.sendComputerState( context.getServerHandler().player );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
package dan200.computercraft.shared.peripheral.common;
|
package dan200.computercraft.shared.peripheral.common;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.shared.common.BlockGeneric;
|
||||||
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||||
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemBounds;
|
import dan200.computercraft.shared.peripheral.modem.ModemBounds;
|
||||||
@@ -15,19 +17,22 @@ import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
|||||||
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||||
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
|
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
|
||||||
import dan200.computercraft.shared.util.DirectionUtil;
|
import dan200.computercraft.shared.util.DirectionUtil;
|
||||||
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.properties.PropertyDirection;
|
import net.minecraft.block.properties.PropertyDirection;
|
||||||
import net.minecraft.block.properties.PropertyEnum;
|
import net.minecraft.block.properties.PropertyEnum;
|
||||||
import net.minecraft.block.state.BlockFaceShape;
|
import net.minecraft.block.state.BlockFaceShape;
|
||||||
import net.minecraft.block.state.BlockStateContainer;
|
import net.minecraft.block.state.BlockStateContainer;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.BlockRenderLayer;
|
import net.minecraft.util.BlockRenderLayer;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
@@ -35,7 +40,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class BlockPeripheral extends BlockPeripheralBase
|
public class BlockPeripheral extends BlockGeneric
|
||||||
{
|
{
|
||||||
public static class Properties
|
public static class Properties
|
||||||
{
|
{
|
||||||
@@ -45,6 +50,7 @@ public class BlockPeripheral extends BlockPeripheralBase
|
|||||||
|
|
||||||
public BlockPeripheral()
|
public BlockPeripheral()
|
||||||
{
|
{
|
||||||
|
super( Material.ROCK );
|
||||||
setHardness( 2.0f );
|
setHardness( 2.0f );
|
||||||
setTranslationKey( "computercraft:peripheral" );
|
setTranslationKey( "computercraft:peripheral" );
|
||||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||||
@@ -188,202 +194,107 @@ public class BlockPeripheral extends BlockPeripheralBase
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess world, BlockPos pos )
|
public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess world, BlockPos pos )
|
||||||
{
|
{
|
||||||
int anim;
|
|
||||||
EnumFacing dir;
|
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TilePeripheralBase )
|
|
||||||
{
|
|
||||||
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
|
|
||||||
anim = peripheral.getAnim();
|
|
||||||
dir = peripheral.getDirection();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
anim = 0;
|
|
||||||
dir = state.getValue( Properties.FACING );
|
|
||||||
switch( state.getValue( Properties.VARIANT ) )
|
|
||||||
{
|
|
||||||
case WirelessModemDownOff:
|
|
||||||
case WirelessModemDownOn:
|
|
||||||
{
|
|
||||||
dir = EnumFacing.DOWN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WirelessModemUpOff:
|
|
||||||
case WirelessModemUpOn:
|
|
||||||
{
|
|
||||||
dir = EnumFacing.UP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PeripheralType type = getPeripheralType( state );
|
PeripheralType type = getPeripheralType( state );
|
||||||
switch( type )
|
switch( type )
|
||||||
{
|
{
|
||||||
case DiskDrive:
|
case DiskDrive:
|
||||||
{
|
{
|
||||||
state = state.withProperty( Properties.FACING, dir );
|
if( !(tile instanceof TileDiskDrive) ) return state;
|
||||||
switch( anim )
|
|
||||||
|
TileDiskDrive drive = (TileDiskDrive) tile;
|
||||||
|
state = state.withProperty( Properties.FACING, drive.getDirection() );
|
||||||
|
switch( drive.getAnim() )
|
||||||
{
|
{
|
||||||
case 0:
|
|
||||||
default:
|
default:
|
||||||
{
|
case 0:
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty );
|
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty );
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
case 1:
|
||||||
{
|
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveInvalid );
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveInvalid );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
case 2:
|
||||||
{
|
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveFull );
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveFull );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case Printer:
|
case Printer:
|
||||||
{
|
{
|
||||||
state = state.withProperty( Properties.FACING, dir );
|
if( !(tile instanceof TilePrinter) ) return state;
|
||||||
switch( anim )
|
|
||||||
|
TilePrinter printer = (TilePrinter) tile;
|
||||||
|
state = state.withProperty( Properties.FACING, printer.getDirection() );
|
||||||
|
switch( printer.getAnim() )
|
||||||
{
|
{
|
||||||
case 0:
|
|
||||||
default:
|
default:
|
||||||
{
|
case 0:
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
|
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
case 1:
|
||||||
{
|
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterTopFull );
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterTopFull );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
case 2:
|
||||||
{
|
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBottomFull );
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBottomFull );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3:
|
case 3:
|
||||||
{
|
return state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBothFull );
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterBothFull );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case WirelessModem:
|
case WirelessModem:
|
||||||
{
|
{
|
||||||
switch( dir )
|
if( !(tile instanceof TileWirelessModem) ) return state;
|
||||||
|
|
||||||
|
TileWirelessModem modem = (TileWirelessModem) tile;
|
||||||
|
EnumFacing direction = modem.getDirection();
|
||||||
|
switch( direction )
|
||||||
{
|
{
|
||||||
case UP:
|
case UP:
|
||||||
{
|
return state
|
||||||
state = state.withProperty( Properties.FACING, EnumFacing.NORTH );
|
.withProperty( Properties.FACING, EnumFacing.NORTH )
|
||||||
switch( anim )
|
.withProperty( Properties.VARIANT,
|
||||||
{
|
modem.isOn() ? BlockPeripheralVariant.WirelessModemUpOn : BlockPeripheralVariant.WirelessModemUpOff );
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemUpOff );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemUpOn );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DOWN:
|
case DOWN:
|
||||||
{
|
return state
|
||||||
state = state.withProperty( Properties.FACING, EnumFacing.NORTH );
|
.withProperty( Properties.FACING, EnumFacing.NORTH )
|
||||||
switch( anim )
|
.withProperty( Properties.VARIANT,
|
||||||
{
|
modem.isOn() ? BlockPeripheralVariant.WirelessModemDownOn : BlockPeripheralVariant.WirelessModemDownOff );
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemDownOff );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemDownOn );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
state = state.withProperty( Properties.FACING, dir );
|
return state
|
||||||
switch( anim )
|
.withProperty( Properties.FACING, direction )
|
||||||
{
|
.withProperty( Properties.VARIANT,
|
||||||
case 0:
|
modem.isOn() ? BlockPeripheralVariant.WirelessModemOn : BlockPeripheralVariant.WirelessModemOff );
|
||||||
default:
|
|
||||||
{
|
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemOff );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
state = state.withProperty( Properties.VARIANT, BlockPeripheralVariant.WirelessModemOn );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case Speaker:
|
case Speaker:
|
||||||
{
|
{
|
||||||
state = state.withProperty( Properties.FACING, dir );
|
if( !(tile instanceof TileSpeaker) ) return state;
|
||||||
break;
|
return state.withProperty( Properties.FACING, ((TileSpeaker) tile).getDirection() );
|
||||||
}
|
}
|
||||||
case Monitor:
|
case Monitor:
|
||||||
case AdvancedMonitor:
|
case AdvancedMonitor:
|
||||||
{
|
{
|
||||||
EnumFacing front;
|
if( !(tile instanceof TileMonitor) ) return state;
|
||||||
int xIndex, yIndex, width, height;
|
|
||||||
if( tile instanceof TileMonitor )
|
TileMonitor monitor = (TileMonitor) tile;
|
||||||
{
|
EnumFacing dir = monitor.getDirection();
|
||||||
TileMonitor monitor = (TileMonitor) tile;
|
EnumFacing front = monitor.getFront();
|
||||||
dir = monitor.getDirection();
|
int xIndex = monitor.getXIndex();
|
||||||
front = monitor.getFront();
|
int yIndex = monitor.getYIndex();
|
||||||
xIndex = monitor.getXIndex();
|
int width = monitor.getWidth();
|
||||||
yIndex = monitor.getYIndex();
|
int height = monitor.getHeight();
|
||||||
width = monitor.getWidth();
|
|
||||||
height = monitor.getHeight();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dir = EnumFacing.NORTH;
|
|
||||||
front = EnumFacing.NORTH;
|
|
||||||
xIndex = 0;
|
|
||||||
yIndex = 0;
|
|
||||||
width = 1;
|
|
||||||
height = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockPeripheralVariant baseVariant;
|
BlockPeripheralVariant baseVariant;
|
||||||
if( front == EnumFacing.UP )
|
if( front == EnumFacing.UP )
|
||||||
{
|
{
|
||||||
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
|
baseVariant = type == PeripheralType.AdvancedMonitor ?
|
||||||
BlockPeripheralVariant.AdvancedMonitorUp :
|
BlockPeripheralVariant.AdvancedMonitorUp :
|
||||||
BlockPeripheralVariant.MonitorUp;
|
BlockPeripheralVariant.MonitorUp;
|
||||||
}
|
}
|
||||||
else if( front == EnumFacing.DOWN )
|
else if( front == EnumFacing.DOWN )
|
||||||
{
|
{
|
||||||
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
|
baseVariant = type == PeripheralType.AdvancedMonitor ?
|
||||||
BlockPeripheralVariant.AdvancedMonitorDown :
|
BlockPeripheralVariant.AdvancedMonitorDown :
|
||||||
BlockPeripheralVariant.MonitorDown;
|
BlockPeripheralVariant.MonitorDown;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
baseVariant = (type == PeripheralType.AdvancedMonitor) ?
|
baseVariant = type == PeripheralType.AdvancedMonitor ?
|
||||||
BlockPeripheralVariant.AdvancedMonitor :
|
BlockPeripheralVariant.AdvancedMonitor :
|
||||||
BlockPeripheralVariant.Monitor;
|
BlockPeripheralVariant.Monitor;
|
||||||
}
|
}
|
||||||
@@ -447,34 +358,27 @@ public class BlockPeripheral extends BlockPeripheralBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state = state.withProperty( Properties.FACING, dir );
|
return state
|
||||||
state = state.withProperty( Properties.VARIANT,
|
.withProperty( Properties.FACING, dir )
|
||||||
BlockPeripheralVariant.values()[baseVariant.ordinal() + subType]
|
.withProperty( Properties.VARIANT, BlockPeripheralVariant.values()[baseVariant.ordinal() + subType] );
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
|
@Deprecated
|
||||||
|
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing placedSide, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
|
||||||
{
|
{
|
||||||
switch( type )
|
switch( getPeripheralType( damage ) )
|
||||||
{
|
{
|
||||||
case DiskDrive:
|
case DiskDrive:
|
||||||
default:
|
default:
|
||||||
{
|
return getDefaultState()
|
||||||
IBlockState state = getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty );
|
.withProperty( Properties.VARIANT, BlockPeripheralVariant.DiskDriveEmpty )
|
||||||
if( placedSide.getAxis() != EnumFacing.Axis.Y )
|
.withProperty( Properties.FACING, placedSide.getAxis() == EnumFacing.Axis.Y ? EnumFacing.NORTH : placedSide );
|
||||||
{
|
|
||||||
return state.withProperty( Properties.FACING, placedSide );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return state.withProperty( Properties.FACING, EnumFacing.NORTH );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case WirelessModem:
|
case WirelessModem:
|
||||||
{
|
{
|
||||||
EnumFacing dir = placedSide.getOpposite();
|
EnumFacing dir = placedSide.getOpposite();
|
||||||
@@ -498,95 +402,63 @@ public class BlockPeripheral extends BlockPeripheralBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case Monitor:
|
case Monitor:
|
||||||
{
|
|
||||||
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.Monitor );
|
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.Monitor );
|
||||||
}
|
|
||||||
case Printer:
|
case Printer:
|
||||||
{
|
|
||||||
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
|
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.PrinterEmpty );
|
||||||
}
|
|
||||||
case AdvancedMonitor:
|
case AdvancedMonitor:
|
||||||
{
|
|
||||||
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.AdvancedMonitor );
|
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.AdvancedMonitor );
|
||||||
}
|
|
||||||
case Speaker:
|
case Speaker:
|
||||||
{
|
|
||||||
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.Speaker );
|
return getDefaultState().withProperty( Properties.VARIANT, BlockPeripheralVariant.Speaker );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PeripheralType getPeripheralType( int damage )
|
public PeripheralType getPeripheralType( int damage )
|
||||||
{
|
{
|
||||||
return ((ItemPeripheral) Item.getItemFromBlock( this )).getPeripheralType( damage );
|
return ComputerCraft.Items.peripheral.getPeripheralType( damage );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PeripheralType getPeripheralType( IBlockState state )
|
public PeripheralType getPeripheralType( IBlockState state )
|
||||||
{
|
{
|
||||||
return state.getValue( Properties.VARIANT ).getPeripheralType();
|
return state.getValue( Properties.VARIANT ).getPeripheralType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private TileGeneric createTile( PeripheralType type )
|
||||||
public TilePeripheralBase createTile( PeripheralType type )
|
|
||||||
{
|
{
|
||||||
switch( type )
|
switch( type )
|
||||||
{
|
{
|
||||||
case DiskDrive:
|
case DiskDrive:
|
||||||
default:
|
default:
|
||||||
{
|
|
||||||
return new TileDiskDrive();
|
return new TileDiskDrive();
|
||||||
}
|
|
||||||
case WirelessModem:
|
case WirelessModem:
|
||||||
{
|
|
||||||
return new TileWirelessModem();
|
return new TileWirelessModem();
|
||||||
}
|
|
||||||
case Monitor:
|
case Monitor:
|
||||||
case AdvancedMonitor:
|
case AdvancedMonitor:
|
||||||
{
|
|
||||||
return new TileMonitor();
|
return new TileMonitor();
|
||||||
}
|
|
||||||
case Printer:
|
case Printer:
|
||||||
{
|
|
||||||
return new TilePrinter();
|
return new TilePrinter();
|
||||||
}
|
|
||||||
case Speaker:
|
case Speaker:
|
||||||
{
|
|
||||||
return new TileSpeaker();
|
return new TileSpeaker();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, @Nonnull ItemStack stack )
|
public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, EntityLivingBase player, @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
// Not sure why this is necessary
|
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TilePeripheralBase )
|
|
||||||
{
|
|
||||||
tile.setWorld( world ); // Not sure why this is necessary
|
|
||||||
tile.setPos( pos ); // Not sure why this is necessary
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( getPeripheralType( state ) )
|
switch( getPeripheralType( state ) )
|
||||||
{
|
{
|
||||||
case Speaker:
|
case Speaker:
|
||||||
case DiskDrive:
|
case DiskDrive:
|
||||||
case Printer:
|
case Printer:
|
||||||
{
|
if( tile instanceof TilePeripheralBase )
|
||||||
EnumFacing dir = DirectionUtil.fromEntityRot( player );
|
|
||||||
setDirection( world, pos, dir );
|
|
||||||
if( stack.hasDisplayName() && tile instanceof TilePeripheralBase )
|
|
||||||
{
|
{
|
||||||
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
|
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
|
||||||
peripheral.setLabel( stack.getDisplayName() );
|
peripheral.setDirection( DirectionUtil.fromEntityRot( player ) );
|
||||||
|
if( stack.hasDisplayName() ) peripheral.setLabel( stack.getDisplayName() );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case Monitor:
|
case Monitor:
|
||||||
case AdvancedMonitor:
|
case AdvancedMonitor:
|
||||||
{
|
|
||||||
if( tile instanceof TileMonitor )
|
if( tile instanceof TileMonitor )
|
||||||
{
|
{
|
||||||
int direction = DirectionUtil.fromEntityRot( player ).getIndex();
|
int direction = DirectionUtil.fromEntityRot( player ).getIndex();
|
||||||
@@ -613,7 +485,6 @@ public class BlockPeripheral extends BlockPeripheralBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,13 +538,52 @@ public class BlockPeripheral extends BlockPeripheralBase
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess source, BlockPos pos )
|
@Nonnull
|
||||||
|
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess world, BlockPos pos )
|
||||||
{
|
{
|
||||||
if( getPeripheralType( state ) == PeripheralType.WirelessModem )
|
if( getPeripheralType( state ) == PeripheralType.WirelessModem )
|
||||||
{
|
{
|
||||||
return ModemBounds.getBounds( getDirection( source, pos ) );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
|
if( tile instanceof TileWirelessModem )
|
||||||
|
{
|
||||||
|
return ModemBounds.getBounds( ((TileWirelessModem) tile).getDirection() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getBoundingBox( state, source, pos );
|
return super.getBoundingBox( state, world, pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean canPlaceBlockOnSide( @Nonnull World world, @Nonnull BlockPos pos, EnumFacing side )
|
||||||
|
{
|
||||||
|
return true; // ItemPeripheralBase handles this
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final TileGeneric createTile( IBlockState state )
|
||||||
|
{
|
||||||
|
return createTile( getPeripheralType( state ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final TileGeneric createTile( int damage )
|
||||||
|
{
|
||||||
|
return createTile( getPeripheralType( damage ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult target, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
|
||||||
|
{
|
||||||
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
|
return tile instanceof ITilePeripheral
|
||||||
|
? PeripheralItemFactory.create( (ITilePeripheral) tile )
|
||||||
|
: super.getPickBlock( state, target, world, pos, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getDrops( @Nonnull NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, @Nonnull IBlockState state, int fortune )
|
||||||
|
{
|
||||||
|
drops.add( PeripheralItemFactory.create( getPeripheralType( state ), null, 1 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
package dan200.computercraft.shared.peripheral.common;
|
|
||||||
|
|
||||||
import dan200.computercraft.shared.common.BlockDirectional;
|
|
||||||
import dan200.computercraft.shared.common.TileGeneric;
|
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
|
||||||
import net.minecraft.block.material.Material;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
|
||||||
import net.minecraft.world.IBlockAccess;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
public abstract class BlockPeripheralBase extends BlockDirectional
|
|
||||||
{
|
|
||||||
public BlockPeripheralBase()
|
|
||||||
{
|
|
||||||
super( Material.ROCK );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide );
|
|
||||||
|
|
||||||
protected abstract PeripheralType getPeripheralType( int damage );
|
|
||||||
|
|
||||||
protected abstract PeripheralType getPeripheralType( IBlockState state );
|
|
||||||
|
|
||||||
protected abstract TilePeripheralBase createTile( PeripheralType type );
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean canPlaceBlockOnSide( @Nonnull World world, @Nonnull BlockPos pos, EnumFacing side )
|
|
||||||
{
|
|
||||||
return true; // ItemPeripheralBase handles this
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected final IBlockState getDefaultBlockState( int damage, EnumFacing placedSide )
|
|
||||||
{
|
|
||||||
ItemPeripheralBase item = (ItemPeripheralBase) Item.getItemFromBlock( this );
|
|
||||||
return getDefaultBlockState( item.getPeripheralType( damage ), placedSide );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final TileGeneric createTile( IBlockState state )
|
|
||||||
{
|
|
||||||
return createTile( getPeripheralType( state ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final TileGeneric createTile( int damage )
|
|
||||||
{
|
|
||||||
return createTile( getPeripheralType( damage ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
public final PeripheralType getPeripheralType( IBlockAccess world, BlockPos pos )
|
|
||||||
{
|
|
||||||
return getPeripheralType( world.getBlockState( pos ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult target, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
|
|
||||||
{
|
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
|
||||||
return tile instanceof IPeripheralTile ? PeripheralItemFactory.create( (IPeripheralTile) tile ) : super.getPickBlock( state, target, world, pos, player );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,15 +7,9 @@
|
|||||||
package dan200.computercraft.shared.peripheral.common;
|
package dan200.computercraft.shared.peripheral.common;
|
||||||
|
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.shared.common.IDirectionalTile;
|
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
|
|
||||||
public interface IPeripheralTile extends IDirectionalTile
|
public interface IPeripheralTile
|
||||||
{
|
{
|
||||||
PeripheralType getPeripheralType();
|
|
||||||
|
|
||||||
IPeripheral getPeripheral( EnumFacing side );
|
IPeripheral getPeripheral( EnumFacing side );
|
||||||
|
|
||||||
String getLabel();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dan200.computercraft.shared.peripheral.common;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tile for {@link BlockPeripheral}.
|
||||||
|
*/
|
||||||
|
public interface ITilePeripheral
|
||||||
|
{
|
||||||
|
PeripheralType getPeripheralType();
|
||||||
|
|
||||||
|
default String getLabel()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
default void setLabel( String label )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,9 +8,6 @@ package dan200.computercraft.shared.peripheral.common;
|
|||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||||
import dan200.computercraft.shared.peripheral.modem.wired.ItemCable;
|
|
||||||
import dan200.computercraft.shared.peripheral.modem.wireless.ItemAdvancedModem;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@@ -18,7 +15,7 @@ import javax.annotation.Nonnull;
|
|||||||
public class PeripheralItemFactory
|
public class PeripheralItemFactory
|
||||||
{
|
{
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static ItemStack create( IPeripheralTile tile )
|
public static ItemStack create( ITilePeripheral tile )
|
||||||
{
|
{
|
||||||
return create( tile.getPeripheralType(), tile.getLabel(), 1 );
|
return create( tile.getPeripheralType(), tile.getLabel(), 1 );
|
||||||
}
|
}
|
||||||
@@ -26,9 +23,6 @@ public class PeripheralItemFactory
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public static ItemStack create( PeripheralType type, String label, int quantity )
|
public static ItemStack create( PeripheralType type, String label, int quantity )
|
||||||
{
|
{
|
||||||
ItemPeripheral peripheral = ((ItemPeripheral) Item.getItemFromBlock( ComputerCraft.Blocks.peripheral ));
|
|
||||||
ItemCable cable = ((ItemCable) Item.getItemFromBlock( ComputerCraft.Blocks.cable ));
|
|
||||||
ItemAdvancedModem advancedModem = ((ItemAdvancedModem) Item.getItemFromBlock( ComputerCraft.Blocks.advancedModem ));
|
|
||||||
switch( type )
|
switch( type )
|
||||||
{
|
{
|
||||||
case Speaker:
|
case Speaker:
|
||||||
@@ -37,18 +31,12 @@ public class PeripheralItemFactory
|
|||||||
case Monitor:
|
case Monitor:
|
||||||
case AdvancedMonitor:
|
case AdvancedMonitor:
|
||||||
case WirelessModem:
|
case WirelessModem:
|
||||||
{
|
return ComputerCraft.Items.peripheral.create( type, label, quantity );
|
||||||
return peripheral.create( type, label, quantity );
|
|
||||||
}
|
|
||||||
case WiredModem:
|
case WiredModem:
|
||||||
case Cable:
|
case Cable:
|
||||||
{
|
return ComputerCraft.Items.cable.create( type, quantity );
|
||||||
return cable.create( type, label, quantity );
|
|
||||||
}
|
|
||||||
case AdvancedModem:
|
case AdvancedModem:
|
||||||
{
|
return new ItemStack( ComputerCraft.Blocks.advancedModem, quantity );
|
||||||
return advancedModem.create( type, label, quantity );
|
|
||||||
}
|
|
||||||
case WiredModemFull:
|
case WiredModemFull:
|
||||||
return new ItemStack( ComputerCraft.Blocks.wiredModemFull, quantity );
|
return new ItemStack( ComputerCraft.Blocks.wiredModemFull, quantity );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,22 +7,18 @@
|
|||||||
package dan200.computercraft.shared.peripheral.common;
|
package dan200.computercraft.shared.peripheral.common;
|
||||||
|
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
import dan200.computercraft.shared.common.IDirectionalTile;
|
||||||
import dan200.computercraft.shared.common.TileGeneric;
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.ITickable;
|
import net.minecraft.util.ITickable;
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public abstract class TilePeripheralBase extends TileGeneric
|
public abstract class TilePeripheralBase extends TileGeneric implements IPeripheralTile, ITickable, IDirectionalTile, ITilePeripheral
|
||||||
implements IPeripheralTile, ITickable
|
|
||||||
{
|
{
|
||||||
// Statics
|
private EnumFacing m_dir;
|
||||||
|
|
||||||
protected EnumFacing m_dir;
|
|
||||||
private int m_anim;
|
private int m_anim;
|
||||||
private boolean m_changed;
|
private boolean m_changed;
|
||||||
|
|
||||||
@@ -39,22 +35,11 @@ public abstract class TilePeripheralBase extends TileGeneric
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockPeripheralBase getBlock()
|
public BlockPeripheral getBlock()
|
||||||
{
|
{
|
||||||
return (BlockPeripheralBase) super.getBlock();
|
return (BlockPeripheral) super.getBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
|
|
||||||
{
|
|
||||||
if( !creative )
|
|
||||||
{
|
|
||||||
drops.add( PeripheralItemFactory.create( this ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IPeripheralTile implementation
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final PeripheralType getPeripheralType()
|
public final PeripheralType getPeripheralType()
|
||||||
{
|
{
|
||||||
@@ -77,6 +62,7 @@ public abstract class TilePeripheralBase extends TileGeneric
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setLabel( String label )
|
public void setLabel( String label )
|
||||||
{
|
{
|
||||||
m_label = label;
|
m_label = label;
|
||||||
@@ -90,11 +76,6 @@ public abstract class TilePeripheralBase extends TileGeneric
|
|||||||
return m_dir;
|
return m_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnumFacing getCachedDirection()
|
|
||||||
{
|
|
||||||
return m_dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDirection( EnumFacing dir )
|
public void setDirection( EnumFacing dir )
|
||||||
{
|
{
|
||||||
@@ -110,7 +91,7 @@ public abstract class TilePeripheralBase extends TileGeneric
|
|||||||
return m_anim;
|
return m_anim;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAnim( int anim )
|
protected void setAnim( int anim )
|
||||||
{
|
{
|
||||||
if( anim != m_anim )
|
if( anim != m_anim )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -181,21 +181,19 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
|||||||
int channel = parseChannel( arguments, 0 );
|
int channel = parseChannel( arguments, 0 );
|
||||||
int replyChannel = parseChannel( arguments, 1 );
|
int replyChannel = parseChannel( arguments, 1 );
|
||||||
Object payload = arguments.length > 2 ? arguments[2] : null;
|
Object payload = arguments.length > 2 ? arguments[2] : null;
|
||||||
synchronized( this )
|
World world = getWorld();
|
||||||
|
Vec3d position = getPosition();
|
||||||
|
IPacketNetwork network = m_network;
|
||||||
|
if( world != null && position != null && network != null )
|
||||||
{
|
{
|
||||||
World world = getWorld();
|
Packet packet = new Packet( channel, replyChannel, payload, this );
|
||||||
Vec3d position = getPosition();
|
if( isInterdimensional() )
|
||||||
if( world != null && position != null && m_network != null )
|
|
||||||
{
|
{
|
||||||
Packet packet = new Packet( channel, replyChannel, payload, this );
|
network.transmitInterdimensional( packet );
|
||||||
if( isInterdimensional() )
|
}
|
||||||
{
|
else
|
||||||
m_network.transmitInterdimensional( packet );
|
{
|
||||||
}
|
network.transmitSameDimension( packet, getRange() );
|
||||||
else
|
|
||||||
{
|
|
||||||
m_network.transmitSameDimension( packet, getRange() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -14,16 +14,27 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
|
|
||||||
public class ModemState
|
public class ModemState
|
||||||
{
|
{
|
||||||
private boolean open = false;
|
private final Runnable onChanged;
|
||||||
private AtomicBoolean changed = new AtomicBoolean( true );
|
private final AtomicBoolean changed = new AtomicBoolean( true );
|
||||||
|
|
||||||
|
private boolean open = false;
|
||||||
private final IntSet channels = new IntOpenHashSet();
|
private final IntSet channels = new IntOpenHashSet();
|
||||||
|
|
||||||
|
public ModemState()
|
||||||
|
{
|
||||||
|
this.onChanged = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModemState( Runnable onChanged )
|
||||||
|
{
|
||||||
|
this.onChanged = onChanged;
|
||||||
|
}
|
||||||
|
|
||||||
private void setOpen( boolean open )
|
private void setOpen( boolean open )
|
||||||
{
|
{
|
||||||
if( this.open == open ) return;
|
if( this.open == open ) return;
|
||||||
this.open = open;
|
this.open = open;
|
||||||
this.changed.set( true );
|
if( !changed.getAndSet( true ) && onChanged != null ) onChanged.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean pollChanged()
|
public boolean pollChanged()
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
package dan200.computercraft.shared.peripheral.modem;
|
|
||||||
|
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
|
||||||
import dan200.computercraft.shared.common.BlockGeneric;
|
|
||||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
public abstract class TileModemBase extends TilePeripheralBase
|
|
||||||
{
|
|
||||||
|
|
||||||
protected ModemPeripheral m_modem;
|
|
||||||
|
|
||||||
protected TileModemBase()
|
|
||||||
{
|
|
||||||
m_modem = createPeripheral();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract ModemPeripheral createPeripheral();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void destroy()
|
|
||||||
{
|
|
||||||
if( m_modem != null )
|
|
||||||
{
|
|
||||||
m_modem.destroy();
|
|
||||||
m_modem = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNeighbourChange()
|
|
||||||
{
|
|
||||||
EnumFacing dir = getDirection();
|
|
||||||
if( !getWorld().isSideSolid( getPos().offset( dir ), dir.getOpposite() ) )
|
|
||||||
{
|
|
||||||
// Drop everything and remove block
|
|
||||||
((BlockGeneric) getBlockType()).dropAllItems( getWorld(), getPos(), false );
|
|
||||||
getWorld().setBlockToAir( getPos() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update()
|
|
||||||
{
|
|
||||||
super.update();
|
|
||||||
if( !getWorld().isRemote && m_modem.getModemState().pollChanged() )
|
|
||||||
{
|
|
||||||
updateAnim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateAnim()
|
|
||||||
{
|
|
||||||
setAnim( m_modem.getModemState().isOpen() ? 1 : 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void readDescription( @Nonnull NBTTagCompound nbt )
|
|
||||||
{
|
|
||||||
super.readDescription( nbt );
|
|
||||||
updateBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// IPeripheralTile implementation
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPeripheral getPeripheral( EnumFacing side )
|
|
||||||
{
|
|
||||||
return side == getDirection() ? m_modem : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,11 +9,13 @@ package dan200.computercraft.shared.peripheral.modem.wired;
|
|||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.ComputerCraftAPI;
|
import dan200.computercraft.api.ComputerCraftAPI;
|
||||||
|
import dan200.computercraft.shared.common.BlockGeneric;
|
||||||
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheralBase;
|
|
||||||
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
|
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
|
||||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
|
||||||
import dan200.computercraft.shared.util.WorldUtil;
|
import dan200.computercraft.shared.util.WorldUtil;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.properties.PropertyBool;
|
import net.minecraft.block.properties.PropertyBool;
|
||||||
import net.minecraft.block.properties.PropertyEnum;
|
import net.minecraft.block.properties.PropertyEnum;
|
||||||
import net.minecraft.block.state.BlockFaceShape;
|
import net.minecraft.block.state.BlockFaceShape;
|
||||||
@@ -22,10 +24,10 @@ import net.minecraft.block.state.IBlockState;
|
|||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
@@ -39,7 +41,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BlockCable extends BlockPeripheralBase
|
public class BlockCable extends BlockGeneric
|
||||||
{
|
{
|
||||||
// Statics
|
// Statics
|
||||||
|
|
||||||
@@ -66,6 +68,7 @@ public class BlockCable extends BlockPeripheralBase
|
|||||||
|
|
||||||
public BlockCable()
|
public BlockCable()
|
||||||
{
|
{
|
||||||
|
super( Material.ROCK );
|
||||||
setHardness( 1.5f );
|
setHardness( 1.5f );
|
||||||
setTranslationKey( "computercraft:cable" );
|
setTranslationKey( "computercraft:cable" );
|
||||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||||
@@ -142,10 +145,12 @@ public class BlockCable extends BlockPeripheralBase
|
|||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
|
@Deprecated
|
||||||
|
public final IBlockState getStateForPlacement( World world, BlockPos pos, EnumFacing placedSide, float hitX, float hitY, float hitZ, int damage, EntityLivingBase placer )
|
||||||
{
|
{
|
||||||
switch( type )
|
switch( ComputerCraft.Items.cable.getPeripheralType( damage ) )
|
||||||
{
|
{
|
||||||
case Cable:
|
case Cable:
|
||||||
return getDefaultState()
|
return getDefaultState()
|
||||||
@@ -190,7 +195,7 @@ public class BlockCable extends BlockPeripheralBase
|
|||||||
.withProperty( Properties.DOWN, doesConnectVisually( state, world, pos, EnumFacing.DOWN ) );
|
.withProperty( Properties.DOWN, doesConnectVisually( state, world, pos, EnumFacing.DOWN ) );
|
||||||
|
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
int anim = tile instanceof TilePeripheralBase ? ((TilePeripheralBase) tile).getAnim() : 0;
|
int anim = tile instanceof TileCable ? ((TileCable) tile).getState() : 0;
|
||||||
|
|
||||||
BlockCableModemVariant modem = state.getValue( Properties.MODEM );
|
BlockCableModemVariant modem = state.getValue( Properties.MODEM );
|
||||||
if( modem != BlockCableModemVariant.None )
|
if( modem != BlockCableModemVariant.None )
|
||||||
@@ -209,13 +214,6 @@ public class BlockCable extends BlockPeripheralBase
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PeripheralType getPeripheralType( int damage )
|
|
||||||
{
|
|
||||||
return ((ItemCable) Item.getItemFromBlock( this )).getPeripheralType( damage );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PeripheralType getPeripheralType( IBlockState state )
|
public PeripheralType getPeripheralType( IBlockState state )
|
||||||
{
|
{
|
||||||
boolean cable = state.getValue( Properties.CABLE );
|
boolean cable = state.getValue( Properties.CABLE );
|
||||||
@@ -235,7 +233,13 @@ public class BlockCable extends BlockPeripheralBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TilePeripheralBase createTile( PeripheralType type )
|
protected TileGeneric createTile( IBlockState state )
|
||||||
|
{
|
||||||
|
return new TileCable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TileGeneric createTile( int damage )
|
||||||
{
|
{
|
||||||
return new TileCable();
|
return new TileCable();
|
||||||
}
|
}
|
||||||
@@ -320,7 +324,10 @@ public class BlockCable extends BlockPeripheralBase
|
|||||||
|
|
||||||
cable.modemChanged();
|
cable.modemChanged();
|
||||||
cable.connectionsChanged();
|
cable.connectionsChanged();
|
||||||
if( !world.isRemote && !player.capabilities.isCreativeMode ) dropItem( world, pos, item );
|
if( !world.isRemote && !player.capabilities.isCreativeMode )
|
||||||
|
{
|
||||||
|
Block.spawnAsEntity( world, pos, item );
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -330,6 +337,23 @@ public class BlockCable extends BlockPeripheralBase
|
|||||||
return super.removedByPlayer( state, world, pos, player, willHarvest );
|
return super.removedByPlayer( state, world, pos, player, willHarvest );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getDrops( @Nonnull NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, @Nonnull IBlockState state, int fortune )
|
||||||
|
{
|
||||||
|
PeripheralType type = getPeripheralType( state );
|
||||||
|
switch( type )
|
||||||
|
{
|
||||||
|
case Cable:
|
||||||
|
case WiredModem:
|
||||||
|
drops.add( PeripheralItemFactory.create( type, null, 1 ) );
|
||||||
|
break;
|
||||||
|
case WiredModemWithCable:
|
||||||
|
drops.add( PeripheralItemFactory.create( PeripheralType.WiredModem, null, 1 ) );
|
||||||
|
drops.add( PeripheralItemFactory.create( PeripheralType.Cable, null, 1 ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult hit, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
|
public ItemStack getPickBlock( @Nonnull IBlockState state, RayTraceResult hit, @Nonnull World world, @Nonnull BlockPos pos, EntityPlayer player )
|
||||||
@@ -381,4 +405,11 @@ public class BlockCable extends BlockPeripheralBase
|
|||||||
{
|
{
|
||||||
return BlockFaceShape.UNDEFINED;
|
return BlockFaceShape.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public boolean hasCustomBreakingProgress( IBlockState state )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,20 +7,19 @@
|
|||||||
package dan200.computercraft.shared.peripheral.modem.wired;
|
package dan200.computercraft.shared.peripheral.modem.wired;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.common.BlockGeneric;
|
||||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheralBase;
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.properties.PropertyBool;
|
import net.minecraft.block.properties.PropertyBool;
|
||||||
import net.minecraft.block.state.BlockStateContainer;
|
import net.minecraft.block.state.BlockStateContainer;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class BlockWiredModemFull extends BlockPeripheralBase
|
public class BlockWiredModemFull extends BlockGeneric
|
||||||
{
|
{
|
||||||
// Statics
|
// Statics
|
||||||
|
|
||||||
@@ -34,6 +33,7 @@ public class BlockWiredModemFull extends BlockPeripheralBase
|
|||||||
|
|
||||||
public BlockWiredModemFull()
|
public BlockWiredModemFull()
|
||||||
{
|
{
|
||||||
|
super( Material.ROCK );
|
||||||
setHardness( 1.5f );
|
setHardness( 1.5f );
|
||||||
setTranslationKey( "computercraft:wired_modem_full" );
|
setTranslationKey( "computercraft:wired_modem_full" );
|
||||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||||
@@ -43,12 +43,6 @@ public class BlockWiredModemFull extends BlockPeripheralBase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
|
|
||||||
{
|
|
||||||
return getDefaultState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
protected BlockStateContainer createBlockState()
|
protected BlockStateContainer createBlockState()
|
||||||
@@ -74,7 +68,7 @@ public class BlockWiredModemFull extends BlockPeripheralBase
|
|||||||
if( te instanceof TileWiredModemFull )
|
if( te instanceof TileWiredModemFull )
|
||||||
{
|
{
|
||||||
TileWiredModemFull modem = (TileWiredModemFull) te;
|
TileWiredModemFull modem = (TileWiredModemFull) te;
|
||||||
int anim = modem.getAnim();
|
int anim = modem.getState();
|
||||||
state = state
|
state = state
|
||||||
.withProperty( Properties.MODEM_ON, (anim & 1) != 0 )
|
.withProperty( Properties.MODEM_ON, (anim & 1) != 0 )
|
||||||
.withProperty( Properties.PERIPHERAL_ON, (anim & 2) != 0 );
|
.withProperty( Properties.PERIPHERAL_ON, (anim & 2) != 0 );
|
||||||
@@ -84,19 +78,13 @@ public class BlockWiredModemFull extends BlockPeripheralBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PeripheralType getPeripheralType( int damage )
|
protected TileGeneric createTile( IBlockState state )
|
||||||
{
|
{
|
||||||
return PeripheralType.WiredModemFull;
|
return new TileWiredModemFull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PeripheralType getPeripheralType( IBlockState state )
|
protected TileGeneric createTile( int damage )
|
||||||
{
|
|
||||||
return PeripheralType.WiredModemFull;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TilePeripheralBase createTile( PeripheralType type )
|
|
||||||
{
|
{
|
||||||
return new TileWiredModemFull();
|
return new TileWiredModemFull();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class ItemCable extends ItemPeripheralBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public ItemStack create( PeripheralType type, String label, int quantity )
|
public ItemStack create( PeripheralType type, int quantity )
|
||||||
{
|
{
|
||||||
ItemStack stack;
|
ItemStack stack;
|
||||||
switch( type )
|
switch( type )
|
||||||
@@ -54,10 +54,7 @@ public class ItemCable extends ItemPeripheralBase
|
|||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( label != null )
|
|
||||||
{
|
|
||||||
stack.setStackDisplayName( label );
|
|
||||||
}
|
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,11 +78,11 @@ public class ItemCable extends ItemPeripheralBase
|
|||||||
|
|
||||||
// Try to add a cable to a modem
|
// Try to add a cable to a modem
|
||||||
PeripheralType type = getPeripheralType( stack );
|
PeripheralType type = getPeripheralType( stack );
|
||||||
Block existing = world.getBlockState( pos ).getBlock();
|
|
||||||
IBlockState existingState = world.getBlockState( pos );
|
IBlockState existingState = world.getBlockState( pos );
|
||||||
|
Block existing = existingState.getBlock();
|
||||||
if( existing == ComputerCraft.Blocks.cable )
|
if( existing == ComputerCraft.Blocks.cable )
|
||||||
{
|
{
|
||||||
PeripheralType existingType = ComputerCraft.Blocks.cable.getPeripheralType( world, pos );
|
PeripheralType existingType = ComputerCraft.Blocks.cable.getPeripheralType( existingState );
|
||||||
if( existingType == PeripheralType.WiredModem && type == PeripheralType.Cable )
|
if( existingType == PeripheralType.WiredModem && type == PeripheralType.Cable )
|
||||||
{
|
{
|
||||||
if( !stack.isEmpty() )
|
if( !stack.isEmpty() )
|
||||||
@@ -112,12 +109,12 @@ public class ItemCable extends ItemPeripheralBase
|
|||||||
if( !existing.isAir( existingState, world, pos ) && (type == PeripheralType.Cable || existingState.isSideSolid( world, pos, side )) )
|
if( !existing.isAir( existingState, world, pos ) && (type == PeripheralType.Cable || existingState.isSideSolid( world, pos, side )) )
|
||||||
{
|
{
|
||||||
BlockPos offset = pos.offset( side );
|
BlockPos offset = pos.offset( side );
|
||||||
Block offsetExisting = world.getBlockState( offset ).getBlock();
|
|
||||||
IBlockState offsetExistingState = world.getBlockState( offset );
|
IBlockState offsetExistingState = world.getBlockState( offset );
|
||||||
|
Block offsetExisting = offsetExistingState.getBlock();
|
||||||
if( offsetExisting == ComputerCraft.Blocks.cable )
|
if( offsetExisting == ComputerCraft.Blocks.cable )
|
||||||
{
|
{
|
||||||
// Try to add a modem to a cable
|
// Try to add a modem to a cable
|
||||||
PeripheralType offsetExistingType = ComputerCraft.Blocks.cable.getPeripheralType( world, offset );
|
PeripheralType offsetExistingType = ComputerCraft.Blocks.cable.getPeripheralType( offsetExistingState );
|
||||||
if( offsetExistingType == PeripheralType.Cable && type == PeripheralType.WiredModem )
|
if( offsetExistingType == PeripheralType.Cable && type == PeripheralType.WiredModem )
|
||||||
{
|
{
|
||||||
if( !stack.isEmpty() )
|
if( !stack.isEmpty() )
|
||||||
|
|||||||
@@ -7,25 +7,25 @@
|
|||||||
package dan200.computercraft.shared.peripheral.modem.wired;
|
package dan200.computercraft.shared.peripheral.modem.wired;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.ComputerCraftAPI;
|
import dan200.computercraft.api.ComputerCraftAPI;
|
||||||
import dan200.computercraft.api.network.wired.IWiredElement;
|
import dan200.computercraft.api.network.wired.IWiredElement;
|
||||||
import dan200.computercraft.api.network.wired.IWiredNode;
|
import dan200.computercraft.api.network.wired.IWiredNode;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.shared.command.CommandCopy;
|
import dan200.computercraft.shared.command.CommandCopy;
|
||||||
import dan200.computercraft.shared.common.BlockGeneric;
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||||
|
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
|
||||||
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
|
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
|
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
||||||
import dan200.computercraft.shared.peripheral.modem.TileModemBase;
|
import dan200.computercraft.shared.util.TickScheduler;
|
||||||
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.text.TextComponentTranslation;
|
import net.minecraft.util.text.TextComponentTranslation;
|
||||||
@@ -37,42 +37,35 @@ import javax.annotation.Nullable;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class TileCable extends TileModemBase
|
public class TileCable extends TileGeneric implements IPeripheralTile
|
||||||
{
|
{
|
||||||
private static class CableElement extends WiredModemElement
|
private class CableElement extends WiredModemElement
|
||||||
{
|
{
|
||||||
private final TileCable m_entity;
|
|
||||||
|
|
||||||
private CableElement( TileCable m_entity )
|
|
||||||
{
|
|
||||||
this.m_entity = m_entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public World getWorld()
|
public World getWorld()
|
||||||
{
|
{
|
||||||
return m_entity.getWorld();
|
return TileCable.this.getWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Vec3d getPosition()
|
public Vec3d getPosition()
|
||||||
{
|
{
|
||||||
BlockPos pos = m_entity.getPos();
|
BlockPos pos = TileCable.this.getPos();
|
||||||
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void attachPeripheral( String name, IPeripheral peripheral )
|
protected void attachPeripheral( String name, IPeripheral peripheral )
|
||||||
{
|
{
|
||||||
((WiredModemPeripheral) m_entity.m_modem).attachPeripheral( name, peripheral );
|
m_modem.attachPeripheral( name, peripheral );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void detachPeripheral( String name )
|
protected void detachPeripheral( String name )
|
||||||
{
|
{
|
||||||
((WiredModemPeripheral) m_entity.m_modem).detachPeripheral( name );
|
m_modem.detachPeripheral( name );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,35 +76,35 @@ public class TileCable extends TileModemBase
|
|||||||
|
|
||||||
private boolean m_destroyed = false;
|
private boolean m_destroyed = false;
|
||||||
|
|
||||||
private boolean m_hasDirection = false;
|
private EnumFacing modemDirection;
|
||||||
|
private boolean hasModemDirection = false;
|
||||||
|
|
||||||
private boolean m_connectionsFormed = false;
|
private boolean m_connectionsFormed = false;
|
||||||
|
|
||||||
private WiredModemElement m_cable;
|
private final WiredModemElement m_cable = new CableElement();
|
||||||
private IWiredNode m_node;
|
private final IWiredNode m_node = m_cable.getNode();
|
||||||
|
private final WiredModemPeripheral m_modem = new WiredModemPeripheral(
|
||||||
@Override
|
new ModemState( () -> TickScheduler.schedule( this ) ),
|
||||||
protected ModemPeripheral createPeripheral()
|
m_cable
|
||||||
|
)
|
||||||
{
|
{
|
||||||
m_cable = new CableElement( this );
|
@Nonnull
|
||||||
m_node = m_cable.getNode();
|
@Override
|
||||||
return new WiredModemPeripheral( new ModemState(), m_cable )
|
protected WiredModemLocalPeripheral getLocalPeripheral()
|
||||||
{
|
{
|
||||||
@Nonnull
|
return m_peripheral;
|
||||||
@Override
|
}
|
||||||
protected WiredModemLocalPeripheral getLocalPeripheral()
|
|
||||||
{
|
|
||||||
return m_peripheral;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Vec3d getPosition()
|
public Vec3d getPosition()
|
||||||
{
|
{
|
||||||
BlockPos pos = getPos().offset( getCachedDirection() );
|
BlockPos pos = getPos().offset( modemDirection );
|
||||||
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
private int m_state = 0;
|
||||||
|
|
||||||
private void remove()
|
private void remove()
|
||||||
{
|
{
|
||||||
@@ -128,9 +121,9 @@ public class TileCable extends TileModemBase
|
|||||||
if( !m_destroyed )
|
if( !m_destroyed )
|
||||||
{
|
{
|
||||||
m_destroyed = true;
|
m_destroyed = true;
|
||||||
|
m_modem.destroy();
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
super.destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -151,26 +144,31 @@ public class TileCable extends TileModemBase
|
|||||||
public void onLoad()
|
public void onLoad()
|
||||||
{
|
{
|
||||||
super.onLoad();
|
super.onLoad();
|
||||||
updateDirection();
|
if( !world.isRemote )
|
||||||
|
{
|
||||||
|
updateDirection();
|
||||||
|
world.scheduleUpdate( pos, getBlockType(), 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateContainingBlockInfo()
|
public void updateContainingBlockInfo()
|
||||||
{
|
{
|
||||||
m_hasDirection = false;
|
super.updateContainingBlockInfo();
|
||||||
|
hasModemDirection = false;
|
||||||
|
if( !world.isRemote ) world.scheduleUpdate( pos, getBlockType(), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDirection()
|
private void updateDirection()
|
||||||
{
|
{
|
||||||
if( !m_hasDirection )
|
if( !hasModemDirection )
|
||||||
{
|
{
|
||||||
m_hasDirection = true;
|
hasModemDirection = true;
|
||||||
m_dir = getDirection();
|
modemDirection = getDirection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private EnumFacing getDirection()
|
||||||
public EnumFacing getDirection()
|
|
||||||
{
|
{
|
||||||
IBlockState state = getBlockState();
|
IBlockState state = getBlockState();
|
||||||
EnumFacing facing = state.getValue( BlockCable.Properties.MODEM ).getFacing();
|
EnumFacing facing = state.getValue( BlockCable.Properties.MODEM ).getFacing();
|
||||||
@@ -178,55 +176,17 @@ public class TileCable extends TileModemBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDirection( EnumFacing dir )
|
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||||
{
|
|
||||||
IBlockState state = getBlockState();
|
|
||||||
BlockCableModemVariant modem = state.getValue( BlockCable.Properties.MODEM );
|
|
||||||
if( modem != BlockCableModemVariant.None )
|
|
||||||
{
|
|
||||||
setBlockState( state.withProperty( BlockCable.Properties.MODEM, BlockCableModemVariant.fromFacing( dir ) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
|
|
||||||
{
|
|
||||||
if( !creative )
|
|
||||||
{
|
|
||||||
PeripheralType type = getPeripheralType();
|
|
||||||
switch( type )
|
|
||||||
{
|
|
||||||
case Cable:
|
|
||||||
case WiredModem:
|
|
||||||
{
|
|
||||||
drops.add( PeripheralItemFactory.create( type, getLabel(), 1 ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WiredModemWithCable:
|
|
||||||
{
|
|
||||||
drops.add( PeripheralItemFactory.create( PeripheralType.WiredModem, getLabel(), 1 ) );
|
|
||||||
drops.add( PeripheralItemFactory.create( PeripheralType.Cable, null, 1 ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNeighbourChange()
|
|
||||||
{
|
{
|
||||||
EnumFacing dir = getDirection();
|
EnumFacing dir = getDirection();
|
||||||
if( !getWorld().isSideSolid(
|
if( neighbour.equals( getPos().offset( dir ) ) && !getWorld().isSideSolid( neighbour, dir.getOpposite() ) )
|
||||||
getPos().offset( dir ),
|
|
||||||
dir.getOpposite()
|
|
||||||
) )
|
|
||||||
{
|
{
|
||||||
switch( getPeripheralType() )
|
switch( getPeripheralType() )
|
||||||
{
|
{
|
||||||
case WiredModem:
|
case WiredModem:
|
||||||
{
|
{
|
||||||
// Drop everything and remove block
|
// Drop everything and remove block
|
||||||
((BlockGeneric) getBlockType()).dropAllItems( getWorld(), getPos(), false );
|
getBlock().dropBlockAsItem( getWorld(), getPos(), getBlockState(), 0 );
|
||||||
getWorld().setBlockToAir( getPos() );
|
getWorld().setBlockToAir( getPos() );
|
||||||
|
|
||||||
// This'll call #destroy(), so we don't need to reset the network here.
|
// This'll call #destroy(), so we don't need to reset the network here.
|
||||||
@@ -235,8 +195,7 @@ public class TileCable extends TileModemBase
|
|||||||
case WiredModemWithCable:
|
case WiredModemWithCable:
|
||||||
{
|
{
|
||||||
// Drop the modem and convert to cable
|
// Drop the modem and convert to cable
|
||||||
((BlockGeneric) getBlockType()).dropItem( getWorld(), getPos(), PeripheralItemFactory.create( PeripheralType.WiredModem, getLabel(), 1 ) );
|
Block.spawnAsEntity( getWorld(), getPos(), PeripheralItemFactory.create( PeripheralType.WiredModem, null, 1 ) );
|
||||||
setLabel( null );
|
|
||||||
setBlockState( getBlockState().withProperty( BlockCable.Properties.MODEM, BlockCableModemVariant.None ) );
|
setBlockState( getBlockState().withProperty( BlockCable.Properties.MODEM, BlockCableModemVariant.None ) );
|
||||||
modemChanged();
|
modemChanged();
|
||||||
connectionsChanged();
|
connectionsChanged();
|
||||||
@@ -328,21 +287,46 @@ public class TileCable extends TileModemBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateAnim()
|
protected void writeDescription( @Nonnull NBTTagCompound nbt )
|
||||||
{
|
{
|
||||||
int anim = 0;
|
super.writeDescription( nbt );
|
||||||
if( m_modem.getModemState().isOpen() ) anim |= 1;
|
nbt.setInteger( "state", m_state );
|
||||||
if( m_peripheralAccessAllowed ) anim |= 2;
|
|
||||||
setAnim( anim );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update()
|
public final void readDescription( @Nonnull NBTTagCompound nbt )
|
||||||
|
{
|
||||||
|
super.readDescription( nbt );
|
||||||
|
m_state = nbt.getInteger( "state" );
|
||||||
|
updateBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getState()
|
||||||
|
{
|
||||||
|
return m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateState()
|
||||||
|
{
|
||||||
|
int state = 0;
|
||||||
|
if( m_modem.getModemState().isOpen() ) state |= 1;
|
||||||
|
if( m_peripheralAccessAllowed ) state |= 2;
|
||||||
|
if( state != m_state )
|
||||||
|
{
|
||||||
|
m_state = state;
|
||||||
|
updateBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateTick()
|
||||||
{
|
{
|
||||||
super.update();
|
|
||||||
updateDirection();
|
|
||||||
if( !getWorld().isRemote )
|
if( !getWorld().isRemote )
|
||||||
{
|
{
|
||||||
|
updateDirection();
|
||||||
|
|
||||||
|
if( m_modem.getModemState().pollChanged() ) updateState();
|
||||||
|
|
||||||
if( !m_connectionsFormed )
|
if( !m_connectionsFormed )
|
||||||
{
|
{
|
||||||
m_connectionsFormed = true;
|
m_connectionsFormed = true;
|
||||||
@@ -350,7 +334,7 @@ public class TileCable extends TileModemBase
|
|||||||
connectionsChanged();
|
connectionsChanged();
|
||||||
if( m_peripheralAccessAllowed )
|
if( m_peripheralAccessAllowed )
|
||||||
{
|
{
|
||||||
m_peripheral.attach( world, pos, m_dir );
|
m_peripheral.attach( world, pos, modemDirection );
|
||||||
updateConnectedPeripherals();
|
updateConnectedPeripherals();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,7 +380,7 @@ public class TileCable extends TileModemBase
|
|||||||
m_peripheral.detach();
|
m_peripheral.detach();
|
||||||
m_node.updatePeripherals( Collections.emptyMap() );
|
m_node.updatePeripherals( Collections.emptyMap() );
|
||||||
markDirty();
|
markDirty();
|
||||||
updateAnim();
|
updateState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,7 +403,7 @@ public class TileCable extends TileModemBase
|
|||||||
m_node.updatePeripherals( Collections.emptyMap() );
|
m_node.updatePeripherals( Collections.emptyMap() );
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAnim();
|
updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateConnectedPeripherals()
|
private void updateConnectedPeripherals()
|
||||||
@@ -429,7 +413,7 @@ public class TileCable extends TileModemBase
|
|||||||
{
|
{
|
||||||
// If there are no peripherals then disable access and update the display state.
|
// If there are no peripherals then disable access and update the display state.
|
||||||
m_peripheralAccessAllowed = false;
|
m_peripheralAccessAllowed = false;
|
||||||
updateAnim();
|
updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_node.updatePeripherals( peripherals );
|
m_node.updatePeripherals( peripherals );
|
||||||
@@ -441,12 +425,14 @@ public class TileCable extends TileModemBase
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IWiredElement capability
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
|
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
|
||||||
{
|
{
|
||||||
if( capability == CapabilityWiredElement.CAPABILITY ) return BlockCable.canConnectIn( getBlockState(), facing );
|
if( capability == CapabilityWiredElement.CAPABILITY )
|
||||||
|
{
|
||||||
|
return !m_destroyed && BlockCable.canConnectIn( getBlockState(), facing );
|
||||||
|
}
|
||||||
|
|
||||||
return super.hasCapability( capability, facing );
|
return super.hasCapability( capability, facing );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,21 +442,23 @@ public class TileCable extends TileModemBase
|
|||||||
{
|
{
|
||||||
if( capability == CapabilityWiredElement.CAPABILITY )
|
if( capability == CapabilityWiredElement.CAPABILITY )
|
||||||
{
|
{
|
||||||
return BlockCable.canConnectIn( getBlockState(), facing ) ? CapabilityWiredElement.CAPABILITY.cast( m_cable ) : null;
|
return !m_destroyed && BlockCable.canConnectIn( getBlockState(), facing )
|
||||||
|
? CapabilityWiredElement.CAPABILITY.cast( m_cable )
|
||||||
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability( capability, facing );
|
return super.getCapability( capability, facing );
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPeripheralTile
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPeripheral getPeripheral( EnumFacing side )
|
public IPeripheral getPeripheral( EnumFacing side )
|
||||||
{
|
{
|
||||||
if( getPeripheralType() != PeripheralType.Cable )
|
return !m_destroyed && getPeripheralType() != PeripheralType.Cable && side == getDirection() ? m_modem : null;
|
||||||
{
|
}
|
||||||
return super.getPeripheral( side );
|
|
||||||
}
|
public PeripheralType getPeripheralType()
|
||||||
return null;
|
{
|
||||||
|
IBlockState state = getBlockState();
|
||||||
|
return ComputerCraft.Blocks.cable.getPeripheralType( state );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,10 @@ import dan200.computercraft.api.network.wired.IWiredElement;
|
|||||||
import dan200.computercraft.api.network.wired.IWiredNode;
|
import dan200.computercraft.api.network.wired.IWiredNode;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.shared.command.CommandCopy;
|
import dan200.computercraft.shared.command.CommandCopy;
|
||||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
|
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
||||||
|
import dan200.computercraft.shared.util.TickScheduler;
|
||||||
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
@@ -30,7 +32,7 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class TileWiredModemFull extends TilePeripheralBase
|
public class TileWiredModemFull extends TileGeneric implements IPeripheralTile
|
||||||
{
|
{
|
||||||
private static class FullElement extends WiredModemElement
|
private static class FullElement extends WiredModemElement
|
||||||
{
|
{
|
||||||
@@ -85,10 +87,12 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
private boolean m_destroyed = false;
|
private boolean m_destroyed = false;
|
||||||
private boolean m_connectionsFormed = false;
|
private boolean m_connectionsFormed = false;
|
||||||
|
|
||||||
private final ModemState m_modemState = new ModemState();
|
private final ModemState m_modemState = new ModemState( () -> TickScheduler.schedule( this ) );
|
||||||
private final WiredModemElement m_element = new FullElement( this );
|
private final WiredModemElement m_element = new FullElement( this );
|
||||||
private final IWiredNode m_node = m_element.getNode();
|
private final IWiredNode m_node = m_element.getNode();
|
||||||
|
|
||||||
|
private int m_state = 0;
|
||||||
|
|
||||||
public TileWiredModemFull()
|
public TileWiredModemFull()
|
||||||
{
|
{
|
||||||
for( int i = 0; i < m_peripherals.length; i++ ) m_peripherals[i] = new WiredModemLocalPeripheral();
|
for( int i = 0; i < m_peripherals.length; i++ ) m_peripherals[i] = new WiredModemLocalPeripheral();
|
||||||
@@ -129,29 +133,9 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EnumFacing getDirection()
|
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||||
{
|
{
|
||||||
return EnumFacing.NORTH;
|
onNeighbourTileEntityChange( neighbour );
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDirection( EnumFacing dir )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNeighbourChange()
|
|
||||||
{
|
|
||||||
if( !world.isRemote && m_peripheralAccessAllowed )
|
|
||||||
{
|
|
||||||
boolean hasChanged = false;
|
|
||||||
for( EnumFacing facing : EnumFacing.VALUES )
|
|
||||||
{
|
|
||||||
hasChanged |= m_peripherals[facing.ordinal()].attach( world, getPos(), facing );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( hasChanged ) updateConnectedPeripherals();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -231,27 +215,51 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
return nbt;
|
return nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateAnim()
|
public int getState()
|
||||||
{
|
{
|
||||||
int anim = 0;
|
return m_state;
|
||||||
if( m_modemState.isOpen() ) anim |= 1;
|
}
|
||||||
if( m_peripheralAccessAllowed ) anim |= 2;
|
|
||||||
setAnim( anim );
|
private void updateState()
|
||||||
|
{
|
||||||
|
int state = 0;
|
||||||
|
if( m_modemState.isOpen() ) state |= 1;
|
||||||
|
if( m_peripheralAccessAllowed ) state |= 2;
|
||||||
|
if( state != m_state )
|
||||||
|
{
|
||||||
|
m_state = state;
|
||||||
|
updateBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeDescription( @Nonnull NBTTagCompound nbt )
|
||||||
|
{
|
||||||
|
super.writeDescription( nbt );
|
||||||
|
nbt.setInteger( "state", m_state );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void readDescription( @Nonnull NBTTagCompound nbt )
|
public final void readDescription( @Nonnull NBTTagCompound nbt )
|
||||||
{
|
{
|
||||||
super.readDescription( nbt );
|
super.readDescription( nbt );
|
||||||
|
m_state = nbt.getInteger( "state" );
|
||||||
updateBlock();
|
updateBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update()
|
public void onLoad()
|
||||||
|
{
|
||||||
|
super.onLoad();
|
||||||
|
if( !world.isRemote ) world.scheduleUpdate( pos, getBlockType(), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateTick()
|
||||||
{
|
{
|
||||||
if( !getWorld().isRemote )
|
if( !getWorld().isRemote )
|
||||||
{
|
{
|
||||||
if( m_modemState.pollChanged() ) updateAnim();
|
if( m_modemState.pollChanged() ) updateState();
|
||||||
|
|
||||||
if( !m_connectionsFormed )
|
if( !m_connectionsFormed )
|
||||||
{
|
{
|
||||||
@@ -268,8 +276,6 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void connectionsChanged()
|
private void connectionsChanged()
|
||||||
@@ -291,7 +297,6 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private stuff
|
|
||||||
private void togglePeripheralAccess()
|
private void togglePeripheralAccess()
|
||||||
{
|
{
|
||||||
if( !m_peripheralAccessAllowed )
|
if( !m_peripheralAccessAllowed )
|
||||||
@@ -317,7 +322,7 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
m_node.updatePeripherals( Collections.emptyMap() );
|
m_node.updatePeripherals( Collections.emptyMap() );
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAnim();
|
updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> getConnectedPeripheralNames()
|
private Set<String> getConnectedPeripheralNames()
|
||||||
@@ -349,7 +354,7 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
{
|
{
|
||||||
// If there are no peripherals then disable access and update the display state.
|
// If there are no peripherals then disable access and update the display state.
|
||||||
m_peripheralAccessAllowed = false;
|
m_peripheralAccessAllowed = false;
|
||||||
updateAnim();
|
updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_node.updatePeripherals( peripherals );
|
m_node.updatePeripherals( peripherals );
|
||||||
@@ -360,7 +365,8 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
@Override
|
@Override
|
||||||
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
|
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
|
||||||
{
|
{
|
||||||
return capability == CapabilityWiredElement.CAPABILITY || super.hasCapability( capability, facing );
|
if( capability == CapabilityWiredElement.CAPABILITY ) return !m_destroyed;
|
||||||
|
return super.hasCapability( capability, facing );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -369,17 +375,18 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
{
|
{
|
||||||
if( capability == CapabilityWiredElement.CAPABILITY )
|
if( capability == CapabilityWiredElement.CAPABILITY )
|
||||||
{
|
{
|
||||||
|
if( m_destroyed ) return null;
|
||||||
return CapabilityWiredElement.CAPABILITY.cast( m_element );
|
return CapabilityWiredElement.CAPABILITY.cast( m_element );
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability( capability, facing );
|
return super.getCapability( capability, facing );
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPeripheralTile
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPeripheral getPeripheral( EnumFacing side )
|
public IPeripheral getPeripheral( EnumFacing side )
|
||||||
{
|
{
|
||||||
|
if( m_destroyed ) return null;
|
||||||
|
|
||||||
WiredModemPeripheral peripheral = m_modems[side.ordinal()];
|
WiredModemPeripheral peripheral = m_modems[side.ordinal()];
|
||||||
if( peripheral == null )
|
if( peripheral == null )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import net.minecraftforge.common.util.Constants;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -66,10 +65,7 @@ public final class WiredModemLocalPeripheral
|
|||||||
else if( id < 0 || !type.equals( this.type ) )
|
else if( id < 0 || !type.equals( this.type ) )
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.id = IDAssigner.getNextIDFromFile( new File(
|
this.id = IDAssigner.getNextIDFromFile( "computer/lastid_" + type + ".txt" );
|
||||||
ComputerCraft.getWorldDir( world ),
|
|
||||||
"computer/lastid_" + type + ".txt"
|
|
||||||
) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldPeripheral == null || !oldPeripheral.equals( peripheral );
|
return oldPeripheral == null || !oldPeripheral.equals( peripheral );
|
||||||
|
|||||||
@@ -7,33 +7,37 @@
|
|||||||
package dan200.computercraft.shared.peripheral.modem.wireless;
|
package dan200.computercraft.shared.peripheral.modem.wireless;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.common.BlockGeneric;
|
||||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheralBase;
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemBounds;
|
import dan200.computercraft.shared.peripheral.modem.ModemBounds;
|
||||||
|
import net.minecraft.block.BlockDirectional;
|
||||||
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.properties.PropertyBool;
|
import net.minecraft.block.properties.PropertyBool;
|
||||||
import net.minecraft.block.properties.PropertyDirection;
|
import net.minecraft.block.properties.PropertyDirection;
|
||||||
import net.minecraft.block.state.BlockFaceShape;
|
import net.minecraft.block.state.BlockFaceShape;
|
||||||
import net.minecraft.block.state.BlockStateContainer;
|
import net.minecraft.block.state.BlockStateContainer;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class BlockAdvancedModem extends BlockPeripheralBase
|
public class BlockAdvancedModem extends BlockGeneric
|
||||||
{
|
{
|
||||||
public static class Properties
|
public static class Properties
|
||||||
{
|
{
|
||||||
public static final PropertyDirection FACING = PropertyDirection.create( "facing" );
|
public static final PropertyDirection FACING = BlockDirectional.FACING;
|
||||||
public static final PropertyBool ON = PropertyBool.create( "on" );
|
public static final PropertyBool ON = PropertyBool.create( "on" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockAdvancedModem()
|
public BlockAdvancedModem()
|
||||||
{
|
{
|
||||||
|
super( Material.ROCK );
|
||||||
setHardness( 2.0f );
|
setHardness( 2.0f );
|
||||||
setTranslationKey( "computercraft:advanced_modem" );
|
setTranslationKey( "computercraft:advanced_modem" );
|
||||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||||
@@ -55,17 +59,13 @@ public class BlockAdvancedModem extends BlockPeripheralBase
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public IBlockState getStateFromMeta( int meta )
|
public IBlockState getStateFromMeta( int meta )
|
||||||
{
|
{
|
||||||
IBlockState state = getDefaultState();
|
return getDefaultState().withProperty( Properties.FACING, EnumFacing.byIndex( meta ) );
|
||||||
state = state.withProperty( Properties.FACING, EnumFacing.byIndex( meta ) );
|
|
||||||
state = state.withProperty( Properties.ON, false );
|
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetaFromState( IBlockState state )
|
public int getMetaFromState( IBlockState state )
|
||||||
{
|
{
|
||||||
EnumFacing dir = state.getValue( Properties.FACING );
|
return state.getValue( Properties.FACING ).getIndex();
|
||||||
return dir.getIndex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@@ -73,47 +73,26 @@ public class BlockAdvancedModem extends BlockPeripheralBase
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess world, BlockPos pos )
|
public IBlockState getActualState( @Nonnull IBlockState state, IBlockAccess world, BlockPos pos )
|
||||||
{
|
{
|
||||||
int anim;
|
|
||||||
EnumFacing dir;
|
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TilePeripheralBase )
|
return state.withProperty( Properties.ON, tile instanceof TileAdvancedModem && ((TileAdvancedModem) tile).isOn() );
|
||||||
{
|
|
||||||
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
|
|
||||||
anim = peripheral.getAnim();
|
|
||||||
dir = peripheral.getDirection();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
anim = 0;
|
|
||||||
dir = state.getValue( Properties.FACING );
|
|
||||||
}
|
|
||||||
|
|
||||||
state = state.withProperty( Properties.FACING, dir );
|
|
||||||
state = state.withProperty( Properties.ON, anim > 0 );
|
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public IBlockState getDefaultBlockState( PeripheralType type, EnumFacing placedSide )
|
@Deprecated
|
||||||
|
public IBlockState getStateForPlacement( World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer )
|
||||||
{
|
{
|
||||||
EnumFacing dir = placedSide.getOpposite();
|
return getDefaultState().withProperty( Properties.FACING, facing.getOpposite() );
|
||||||
return getDefaultState().withProperty( Properties.FACING, dir );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PeripheralType getPeripheralType( int damage )
|
protected TileGeneric createTile( IBlockState state )
|
||||||
{
|
{
|
||||||
return PeripheralType.AdvancedModem;
|
return new TileAdvancedModem();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PeripheralType getPeripheralType( IBlockState state )
|
protected TileGeneric createTile( int damage )
|
||||||
{
|
|
||||||
return PeripheralType.AdvancedModem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TilePeripheralBase createTile( PeripheralType type )
|
|
||||||
{
|
{
|
||||||
return new TileAdvancedModem();
|
return new TileAdvancedModem();
|
||||||
}
|
}
|
||||||
@@ -140,6 +119,7 @@ public class BlockAdvancedModem extends BlockPeripheralBase
|
|||||||
return BlockFaceShape.UNDEFINED;
|
return BlockFaceShape.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess source, BlockPos pos )
|
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess source, BlockPos pos )
|
||||||
|
|||||||
@@ -27,30 +27,6 @@ public class ItemAdvancedModem extends ItemPeripheralBase
|
|||||||
setCreativeTab( ComputerCraft.mainCreativeTab );
|
setCreativeTab( ComputerCraft.mainCreativeTab );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public ItemStack create( PeripheralType type, String label, int quantity )
|
|
||||||
{
|
|
||||||
ItemStack stack;
|
|
||||||
switch( type )
|
|
||||||
{
|
|
||||||
case AdvancedModem:
|
|
||||||
{
|
|
||||||
stack = new ItemStack( this, quantity, 0 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
// Ignore types we can't handle
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( label != null )
|
|
||||||
{
|
|
||||||
stack.setStackDisplayName( label );
|
|
||||||
}
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getSubItems( @Nullable CreativeTabs tabs, @Nonnull NonNullList<ItemStack> list )
|
public void getSubItems( @Nullable CreativeTabs tabs, @Nonnull NonNullList<ItemStack> list )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,116 +6,18 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.peripheral.modem.wireless;
|
package dan200.computercraft.shared.peripheral.modem.wireless;
|
||||||
|
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
|
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
|
||||||
import dan200.computercraft.shared.peripheral.modem.TileModemBase;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
public class TileAdvancedModem extends TileWirelessModemBase
|
||||||
|
|
||||||
public class TileAdvancedModem extends TileModemBase
|
|
||||||
{
|
{
|
||||||
// Statics
|
|
||||||
|
|
||||||
private static class Peripheral extends WirelessModemPeripheral
|
|
||||||
{
|
|
||||||
private TileModemBase m_entity;
|
|
||||||
|
|
||||||
public Peripheral( TileModemBase entity )
|
|
||||||
{
|
|
||||||
super( new ModemState(), true );
|
|
||||||
m_entity = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public World getWorld()
|
|
||||||
{
|
|
||||||
return m_entity.getWorld();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Vec3d getPosition()
|
|
||||||
{
|
|
||||||
BlockPos pos = m_entity.getPos().offset( m_entity.getCachedDirection() );
|
|
||||||
return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals( IPeripheral other )
|
|
||||||
{
|
|
||||||
if( other instanceof Peripheral )
|
|
||||||
{
|
|
||||||
Peripheral otherModem = (Peripheral) other;
|
|
||||||
return otherModem.m_entity == m_entity;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Members
|
|
||||||
private boolean m_hasDirection = false;
|
|
||||||
|
|
||||||
public TileAdvancedModem()
|
public TileAdvancedModem()
|
||||||
{
|
{
|
||||||
m_dir = EnumFacing.DOWN;
|
super( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad()
|
protected EnumFacing getDirection()
|
||||||
{
|
{
|
||||||
super.onLoad();
|
return getBlockState().getValue( BlockAdvancedModem.Properties.FACING );
|
||||||
updateDirection();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateContainingBlockInfo()
|
|
||||||
{
|
|
||||||
m_hasDirection = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update()
|
|
||||||
{
|
|
||||||
super.update();
|
|
||||||
updateDirection();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateDirection()
|
|
||||||
{
|
|
||||||
if( !m_hasDirection )
|
|
||||||
{
|
|
||||||
m_hasDirection = true;
|
|
||||||
m_dir = getDirection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumFacing getDirection()
|
|
||||||
{
|
|
||||||
// Wireless Modem
|
|
||||||
IBlockState state = getBlockState();
|
|
||||||
return state.getValue( BlockAdvancedModem.Properties.FACING );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDirection( EnumFacing dir )
|
|
||||||
{
|
|
||||||
// Wireless Modem
|
|
||||||
setBlockState( getBlockState()
|
|
||||||
.withProperty( BlockAdvancedModem.Properties.FACING, dir )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ModemPeripheral createPeripheral()
|
|
||||||
{
|
|
||||||
return new Peripheral( this );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,98 +7,23 @@
|
|||||||
package dan200.computercraft.shared.peripheral.modem.wireless;
|
package dan200.computercraft.shared.peripheral.modem.wireless;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.shared.common.IDirectionalTile;
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
|
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
|
||||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheralVariant;
|
import dan200.computercraft.shared.peripheral.common.BlockPeripheralVariant;
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
|
import dan200.computercraft.shared.peripheral.common.ITilePeripheral;
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
|
||||||
import dan200.computercraft.shared.peripheral.modem.TileModemBase;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class TileWirelessModem extends TileModemBase
|
public class TileWirelessModem extends TileWirelessModemBase implements IDirectionalTile, ITilePeripheral
|
||||||
{
|
{
|
||||||
// Statics
|
|
||||||
|
|
||||||
private static class Peripheral extends WirelessModemPeripheral
|
|
||||||
{
|
|
||||||
private TileModemBase m_entity;
|
|
||||||
|
|
||||||
public Peripheral( TileModemBase entity )
|
|
||||||
{
|
|
||||||
super( new ModemState(), false );
|
|
||||||
m_entity = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public World getWorld()
|
|
||||||
{
|
|
||||||
return m_entity.getWorld();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Vec3d getPosition()
|
|
||||||
{
|
|
||||||
BlockPos pos = m_entity.getPos().offset( m_entity.getCachedDirection() );
|
|
||||||
return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals( IPeripheral other )
|
|
||||||
{
|
|
||||||
if( other instanceof Peripheral )
|
|
||||||
{
|
|
||||||
Peripheral otherModem = (Peripheral) other;
|
|
||||||
return otherModem.m_entity == m_entity;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Members
|
|
||||||
|
|
||||||
private boolean m_hasDirection = false;
|
|
||||||
|
|
||||||
public TileWirelessModem()
|
public TileWirelessModem()
|
||||||
{
|
{
|
||||||
m_dir = EnumFacing.DOWN;
|
super( false );
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad()
|
|
||||||
{
|
|
||||||
super.onLoad();
|
|
||||||
updateDirection();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateContainingBlockInfo()
|
|
||||||
{
|
|
||||||
m_hasDirection = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update()
|
|
||||||
{
|
|
||||||
super.update();
|
|
||||||
updateDirection();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateDirection()
|
|
||||||
{
|
|
||||||
if( !m_hasDirection )
|
|
||||||
{
|
|
||||||
m_hasDirection = true;
|
|
||||||
m_dir = getDirection();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -110,18 +35,12 @@ public class TileWirelessModem extends TileModemBase
|
|||||||
{
|
{
|
||||||
case WirelessModemDownOff:
|
case WirelessModemDownOff:
|
||||||
case WirelessModemDownOn:
|
case WirelessModemDownOn:
|
||||||
{
|
|
||||||
return EnumFacing.DOWN;
|
return EnumFacing.DOWN;
|
||||||
}
|
|
||||||
case WirelessModemUpOff:
|
case WirelessModemUpOff:
|
||||||
case WirelessModemUpOn:
|
case WirelessModemUpOn:
|
||||||
{
|
|
||||||
return EnumFacing.UP;
|
return EnumFacing.UP;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
{
|
|
||||||
return state.getValue( BlockPeripheral.Properties.FACING );
|
return state.getValue( BlockPeripheral.Properties.FACING );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,15 +71,15 @@ public class TileWirelessModem extends TileModemBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ModemPeripheral createPeripheral()
|
|
||||||
{
|
|
||||||
return new Peripheral( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldRefresh( World world, BlockPos pos, @Nonnull IBlockState oldState, @Nonnull IBlockState newState )
|
public boolean shouldRefresh( World world, BlockPos pos, @Nonnull IBlockState oldState, @Nonnull IBlockState newState )
|
||||||
{
|
{
|
||||||
return super.shouldRefresh( world, pos, oldState, newState ) || ComputerCraft.Blocks.peripheral.getPeripheralType( newState ) != PeripheralType.WirelessModem;
|
return super.shouldRefresh( world, pos, oldState, newState ) || ComputerCraft.Blocks.peripheral.getPeripheralType( newState ) != PeripheralType.WirelessModem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PeripheralType getPeripheralType()
|
||||||
|
{
|
||||||
|
return PeripheralType.WirelessModem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dan200.computercraft.shared.peripheral.modem.wireless;
|
||||||
|
|
||||||
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
|
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
|
||||||
|
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
|
||||||
|
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
||||||
|
import dan200.computercraft.shared.util.TickScheduler;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public abstract class TileWirelessModemBase extends TileGeneric implements IPeripheralTile
|
||||||
|
{
|
||||||
|
protected TileWirelessModemBase( boolean advanced )
|
||||||
|
{
|
||||||
|
this.advanced = advanced;
|
||||||
|
this.modem = new Peripheral( this ); // Needs to be initialised after advanced
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Peripheral extends WirelessModemPeripheral
|
||||||
|
{
|
||||||
|
private final TileWirelessModemBase entity;
|
||||||
|
|
||||||
|
Peripheral( TileWirelessModemBase entity )
|
||||||
|
{
|
||||||
|
super( new ModemState( () -> TickScheduler.schedule( entity ) ), entity.advanced );
|
||||||
|
this.entity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public World getWorld()
|
||||||
|
{
|
||||||
|
return entity.getWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Vec3d getPosition()
|
||||||
|
{
|
||||||
|
BlockPos pos = entity.getPos().offset( entity.modemDirection );
|
||||||
|
return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals( IPeripheral other )
|
||||||
|
{
|
||||||
|
return this == other;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final boolean advanced;
|
||||||
|
private boolean hasModemDirection = false;
|
||||||
|
private EnumFacing modemDirection = EnumFacing.DOWN;
|
||||||
|
private final ModemPeripheral modem;
|
||||||
|
private boolean destroyed = false;
|
||||||
|
|
||||||
|
private boolean on = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad()
|
||||||
|
{
|
||||||
|
super.onLoad();
|
||||||
|
updateDirection();
|
||||||
|
world.scheduleUpdate( getPos(), getBlockType(), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy()
|
||||||
|
{
|
||||||
|
if( !destroyed )
|
||||||
|
{
|
||||||
|
modem.destroy();
|
||||||
|
destroyed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateContainingBlockInfo()
|
||||||
|
{
|
||||||
|
hasModemDirection = false;
|
||||||
|
super.updateContainingBlockInfo();
|
||||||
|
world.scheduleUpdate( getPos(), getBlockType(), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTick()
|
||||||
|
{
|
||||||
|
updateDirection();
|
||||||
|
|
||||||
|
if( modem.getModemState().pollChanged() )
|
||||||
|
{
|
||||||
|
boolean newOn = modem.getModemState().isOpen();
|
||||||
|
if( newOn != on )
|
||||||
|
{
|
||||||
|
on = newOn;
|
||||||
|
updateBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDirection()
|
||||||
|
{
|
||||||
|
if( !hasModemDirection )
|
||||||
|
{
|
||||||
|
hasModemDirection = true;
|
||||||
|
modemDirection = getDirection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract EnumFacing getDirection();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||||
|
{
|
||||||
|
EnumFacing dir = getDirection();
|
||||||
|
if( neighbour.equals( getPos().offset( dir ) ) && !getWorld().isSideSolid( neighbour, dir.getOpposite() ) )
|
||||||
|
{
|
||||||
|
// Drop everything and remove block
|
||||||
|
getBlock().dropBlockAsItem( getWorld(), getPos(), getBlockState(), 0 );
|
||||||
|
getWorld().setBlockToAir( getPos() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeDescription( @Nonnull NBTTagCompound nbt )
|
||||||
|
{
|
||||||
|
super.writeDescription( nbt );
|
||||||
|
nbt.setBoolean( "on", on );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void readDescription( @Nonnull NBTTagCompound nbt )
|
||||||
|
{
|
||||||
|
super.readDescription( nbt );
|
||||||
|
on = nbt.getBoolean( "on" );
|
||||||
|
updateBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOn()
|
||||||
|
{
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPeripheral getPeripheral( EnumFacing side )
|
||||||
|
{
|
||||||
|
return !destroyed && side == getDirection() ? modem : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,8 +28,6 @@ public class MonitorPeripheral implements IPeripheral
|
|||||||
m_monitor = monitor;
|
m_monitor = monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPeripheral implementation
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getType()
|
public String getType()
|
||||||
|
|||||||
@@ -8,12 +8,16 @@ package dan200.computercraft.shared.peripheral.monitor;
|
|||||||
|
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.shared.common.ServerTerminal;
|
import dan200.computercraft.shared.common.ServerTerminal;
|
||||||
|
import dan200.computercraft.shared.util.TickScheduler;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class ServerMonitor extends ServerTerminal
|
public class ServerMonitor extends ServerTerminal
|
||||||
{
|
{
|
||||||
private final TileMonitor origin;
|
private final TileMonitor origin;
|
||||||
private int textScale = 2;
|
private int textScale = 2;
|
||||||
private boolean resized;
|
private final AtomicBoolean resized = new AtomicBoolean( false );
|
||||||
|
private final AtomicBoolean changed = new AtomicBoolean( false );
|
||||||
|
|
||||||
public ServerMonitor( boolean colour, TileMonitor origin )
|
public ServerMonitor( boolean colour, TileMonitor origin )
|
||||||
{
|
{
|
||||||
@@ -41,10 +45,28 @@ public class ServerMonitor extends ServerTerminal
|
|||||||
if( oldWidth != termWidth || oldHeight != termHeight )
|
if( oldWidth != termWidth || oldHeight != termHeight )
|
||||||
{
|
{
|
||||||
getTerminal().clear();
|
getTerminal().clear();
|
||||||
resized = true;
|
resized.set( true );
|
||||||
|
markChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void markTerminalChanged()
|
||||||
|
{
|
||||||
|
super.markTerminalChanged();
|
||||||
|
markChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void markChanged()
|
||||||
|
{
|
||||||
|
if( !changed.getAndSet( true ) ) TickScheduler.schedule( origin );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void clearChanged()
|
||||||
|
{
|
||||||
|
changed.set( false );
|
||||||
|
}
|
||||||
|
|
||||||
public int getTextScale()
|
public int getTextScale()
|
||||||
{
|
{
|
||||||
return textScale;
|
return textScale;
|
||||||
@@ -57,14 +79,14 @@ public class ServerMonitor extends ServerTerminal
|
|||||||
rebuild();
|
rebuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean pollResized()
|
public boolean pollResized()
|
||||||
{
|
{
|
||||||
if( resized )
|
return resized.getAndSet( false );
|
||||||
{
|
}
|
||||||
resized = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
public boolean pollTerminalChanged()
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
return hasTerminalChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
|
|||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.shared.common.ServerTerminal;
|
import dan200.computercraft.shared.common.ServerTerminal;
|
||||||
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||||
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
|
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
|
||||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
|
||||||
|
import dan200.computercraft.shared.peripheral.common.ITilePeripheral;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
@@ -25,13 +27,12 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.HashSet;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class TileMonitor extends TilePeripheralBase
|
public class TileMonitor extends TileGeneric implements ITilePeripheral, IPeripheralTile
|
||||||
{
|
{
|
||||||
// Statics
|
|
||||||
|
|
||||||
public static final double RENDER_BORDER = (2.0 / 16.0);
|
public static final double RENDER_BORDER = (2.0 / 16.0);
|
||||||
public static final double RENDER_MARGIN = (0.5 / 16.0);
|
public static final double RENDER_MARGIN = (0.5 / 16.0);
|
||||||
public static final double RENDER_PIXEL_SCALE = (1.0 / 64.0);
|
public static final double RENDER_PIXEL_SCALE = (1.0 / 64.0);
|
||||||
@@ -39,45 +40,30 @@ public class TileMonitor extends TilePeripheralBase
|
|||||||
private static final int MAX_WIDTH = 8;
|
private static final int MAX_WIDTH = 8;
|
||||||
private static final int MAX_HEIGHT = 6;
|
private static final int MAX_HEIGHT = 6;
|
||||||
|
|
||||||
// Members
|
|
||||||
private ServerMonitor m_serverMonitor;
|
private ServerMonitor m_serverMonitor;
|
||||||
private ClientMonitor m_clientMonitor;
|
private ClientMonitor m_clientMonitor;
|
||||||
private MonitorPeripheral m_peripheral;
|
private MonitorPeripheral m_peripheral;
|
||||||
private final Set<IComputerAccess> m_computers;
|
private final Set<IComputerAccess> m_computers = Collections.newSetFromMap( new ConcurrentHashMap<>() );
|
||||||
|
|
||||||
private boolean m_destroyed;
|
private boolean m_destroyed = false;
|
||||||
private boolean m_ignoreMe;
|
private boolean m_ignoreMe = false;
|
||||||
|
|
||||||
private int m_width;
|
private int m_width = 1;
|
||||||
private int m_height;
|
private int m_height = 1;
|
||||||
private int m_xIndex;
|
private int m_xIndex = 0;
|
||||||
private int m_yIndex;
|
private int m_yIndex = 0;
|
||||||
|
|
||||||
private int m_dir;
|
private int m_dir = 2;
|
||||||
|
|
||||||
private boolean m_advanced;
|
private boolean m_advanced;
|
||||||
|
|
||||||
public TileMonitor()
|
|
||||||
{
|
|
||||||
m_computers = new HashSet<>();
|
|
||||||
|
|
||||||
m_destroyed = false;
|
|
||||||
m_ignoreMe = false;
|
|
||||||
|
|
||||||
m_width = 1;
|
|
||||||
m_height = 1;
|
|
||||||
m_xIndex = 0;
|
|
||||||
m_yIndex = 0;
|
|
||||||
|
|
||||||
m_dir = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad()
|
public void onLoad()
|
||||||
{
|
{
|
||||||
super.onLoad();
|
super.onLoad();
|
||||||
m_advanced = getBlockState().getValue( BlockPeripheral.Properties.VARIANT )
|
m_advanced = getBlockState().getValue( BlockPeripheral.Properties.VARIANT )
|
||||||
.getPeripheralType() == PeripheralType.AdvancedMonitor;
|
.getPeripheralType() == PeripheralType.AdvancedMonitor;
|
||||||
|
world.scheduleUpdate( getPos(), getBlockType(), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -146,44 +132,32 @@ public class TileMonitor extends TilePeripheralBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update()
|
public void updateTick()
|
||||||
{
|
{
|
||||||
super.update();
|
if( m_xIndex != 0 || m_yIndex != 0 || m_serverMonitor == null ) return;
|
||||||
|
|
||||||
if( !getWorld().isRemote )
|
m_serverMonitor.clearChanged();
|
||||||
|
|
||||||
|
if( m_serverMonitor.pollResized() )
|
||||||
{
|
{
|
||||||
if( m_xIndex == 0 && m_yIndex == 0 && m_serverMonitor != null )
|
for( int x = 0; x < m_width; x++ )
|
||||||
{
|
{
|
||||||
if( m_serverMonitor.pollResized() )
|
for( int y = 0; y < m_height; y++ )
|
||||||
{
|
{
|
||||||
for( int x = 0; x < m_width; x++ )
|
TileMonitor monitor = getNeighbour( x, y );
|
||||||
{
|
if( monitor == null ) continue;
|
||||||
for( int y = 0; y < m_height; y++ )
|
|
||||||
{
|
|
||||||
TileMonitor monitor = getNeighbour( x, y );
|
|
||||||
if( monitor == null ) continue;
|
|
||||||
|
|
||||||
for( IComputerAccess computer : monitor.m_computers )
|
for( IComputerAccess computer : monitor.m_computers )
|
||||||
{
|
{
|
||||||
computer.queueEvent( "monitor_resize", new Object[] {
|
computer.queueEvent( "monitor_resize", new Object[] {
|
||||||
computer.getAttachmentName()
|
computer.getAttachmentName()
|
||||||
} );
|
} );
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_serverMonitor.update();
|
if( m_serverMonitor.pollTerminalChanged() ) updateBlock();
|
||||||
if( m_serverMonitor.hasTerminalChanged() ) updateBlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( m_xIndex == 0 && m_yIndex == 0 && m_clientMonitor != null )
|
|
||||||
{
|
|
||||||
m_clientMonitor.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPeripheralTile implementation
|
// IPeripheralTile implementation
|
||||||
@@ -197,6 +171,12 @@ public class TileMonitor extends TilePeripheralBase
|
|||||||
return m_peripheral;
|
return m_peripheral;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PeripheralType getPeripheralType()
|
||||||
|
{
|
||||||
|
return m_advanced ? PeripheralType.AdvancedMonitor : PeripheralType.Monitor;
|
||||||
|
}
|
||||||
|
|
||||||
public ServerMonitor getCachedServerMonitor()
|
public ServerMonitor getCachedServerMonitor()
|
||||||
{
|
{
|
||||||
return m_serverMonitor;
|
return m_serverMonitor;
|
||||||
@@ -319,7 +299,6 @@ public class TileMonitor extends TilePeripheralBase
|
|||||||
}
|
}
|
||||||
// Sizing and placement stuff
|
// Sizing and placement stuff
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumFacing getDirection()
|
public EnumFacing getDirection()
|
||||||
{
|
{
|
||||||
int dir = getDir() % 6;
|
int dir = getDir() % 6;
|
||||||
@@ -444,7 +423,7 @@ public class TileMonitor extends TilePeripheralBase
|
|||||||
return getSimilarMonitorAt( pos.offset( right, xOffset ).offset( down, yOffset ) );
|
return getSimilarMonitorAt( pos.offset( right, xOffset ).offset( down, yOffset ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileMonitor getOrigin()
|
private TileMonitor getOrigin()
|
||||||
{
|
{
|
||||||
return getNeighbour( 0, 0 );
|
return getNeighbour( 0, 0 );
|
||||||
}
|
}
|
||||||
@@ -698,20 +677,14 @@ public class TileMonitor extends TilePeripheralBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addComputer( IComputerAccess computer )
|
void addComputer( IComputerAccess computer )
|
||||||
{
|
{
|
||||||
synchronized( this )
|
m_computers.add( computer );
|
||||||
{
|
|
||||||
m_computers.add( computer );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeComputer( IComputerAccess computer )
|
void removeComputer( IComputerAccess computer )
|
||||||
{
|
{
|
||||||
synchronized( this )
|
m_computers.remove( computer );
|
||||||
{
|
|
||||||
m_computers.remove( computer );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@@ -752,15 +725,10 @@ public class TileMonitor extends TilePeripheralBase
|
|||||||
{
|
{
|
||||||
case Monitor:
|
case Monitor:
|
||||||
case AdvancedMonitor:
|
case AdvancedMonitor:
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ import dan200.computercraft.shared.media.items.ItemPrintout;
|
|||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
||||||
import dan200.computercraft.shared.util.DefaultSidedInventory;
|
import dan200.computercraft.shared.util.DefaultSidedInventory;
|
||||||
import dan200.computercraft.shared.util.InventoryUtil;
|
import dan200.computercraft.shared.util.WorldUtil;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.item.EntityItem;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
@@ -262,6 +261,23 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isItemValidForSlot( int slot, @Nonnull ItemStack stack )
|
||||||
|
{
|
||||||
|
if( slot == 0 )
|
||||||
|
{
|
||||||
|
return isInk( stack );
|
||||||
|
}
|
||||||
|
else if( slot >= topSlots[0] && slot <= topSlots[topSlots.length - 1] )
|
||||||
|
{
|
||||||
|
return isPaper( stack );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasCustomName()
|
public boolean hasCustomName()
|
||||||
{
|
{
|
||||||
@@ -393,15 +409,15 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInk( @Nonnull ItemStack stack )
|
private static boolean isInk( @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
return (stack.getItem() == Items.DYE);
|
return stack.getItem() == Items.DYE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPaper( @Nonnull ItemStack stack )
|
private static boolean isPaper( @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
Item item = stack.getItem();
|
Item item = stack.getItem();
|
||||||
return (item == Items.PAPER || (item instanceof ItemPrintout && ItemPrintout.getType( stack ) == ItemPrintout.Type.Single));
|
return item == Items.PAPER || (item instanceof ItemPrintout && ItemPrintout.getType( stack ) == ItemPrintout.Type.Single);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canInputPage()
|
private boolean canInputPage()
|
||||||
@@ -493,11 +509,14 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
|||||||
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( m_pageTitle, lines, colours );
|
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( m_pageTitle, lines, colours );
|
||||||
synchronized( m_inventory )
|
synchronized( m_inventory )
|
||||||
{
|
{
|
||||||
ItemStack remainder = InventoryUtil.storeItems( stack, m_itemHandlerAll, 7, 6, 7 );
|
for( int slot : bottomSlots )
|
||||||
if( remainder.isEmpty() )
|
|
||||||
{
|
{
|
||||||
m_printing = false;
|
if( m_inventory.get( slot ).isEmpty() )
|
||||||
return true;
|
{
|
||||||
|
m_inventory.set( slot, stack );
|
||||||
|
m_printing = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -521,11 +540,7 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
|||||||
double x = pos.getX() + 0.5;
|
double x = pos.getX() + 0.5;
|
||||||
double y = pos.getY() + 0.75;
|
double y = pos.getY() + 0.75;
|
||||||
double z = pos.getZ() + 0.5;
|
double z = pos.getZ() + 0.5;
|
||||||
EntityItem entityitem = new EntityItem( getWorld(), x, y, z, stack );
|
WorldUtil.dropItemStack( stack, getWorld(), x, y, z );
|
||||||
entityitem.motionX = getWorld().rand.nextFloat() * 0.2 - 0.1;
|
|
||||||
entityitem.motionY = getWorld().rand.nextFloat() * 0.2 - 0.1;
|
|
||||||
entityitem.motionZ = getWorld().rand.nextFloat() * 0.2 - 0.1;
|
|
||||||
getWorld().spawnEntity( entityitem );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user