mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-11-03 23:22:59 +00:00 
			
		
		
		
	Compare commits
	
		
			55 Commits
		
	
	
		
			v1.16.1-1.
			...
			v1.15.2-1.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					74ac5bb3d1 | ||
| 
						 | 
					d13bd2cce8 | ||
| 
						 | 
					cc96e41d3e | ||
| 
						 | 
					741adfa7bb | ||
| 
						 | 
					666e83cf4f | ||
| 
						 | 
					e2a635b6e5 | ||
| 
						 | 
					c58441b29c | ||
| 
						 | 
					a6fcfb6af2 | ||
| 
						 | 
					17a9329207 | ||
| 
						 | 
					f6160bdc57 | ||
| 
						 | 
					6aae4e5766 | ||
| 
						 | 
					84a6bb1cf3 | ||
| 
						 | 
					c334423d42 | ||
| 
						 | 
					113b560a20 | ||
| 
						 | 
					61fb4caaad | ||
| 
						 | 
					6734af6e4a | ||
| 
						 | 
					bf6053906d | ||
| 
						 | 
					01d81cb91d | ||
| 
						 | 
					93068402a2 | ||
| 
						 | 
					34a2c835d4 | ||
| 
						 | 
					30d35883b8 | ||
| 
						 | 
					334ca65482 | ||
| 
						 | 
					8472112fc1 | ||
| 
						 | 
					84036d97d9 | ||
| 
						 | 
					0832974725 | ||
| 
						 | 
					6cee4efcd3 | ||
| 
						 | 
					6f868849ab | ||
| 
						 | 
					275ca58a82 | ||
| 
						 | 
					87393e8aef | ||
| 
						 | 
					86bf57e3cd | ||
| 
						 | 
					748ebbe66b | ||
| 
						 | 
					59de21eae2 | ||
| 
						 | 
					50473afea8 | ||
| 
						 | 
					37f925de0a | ||
| 
						 | 
					cefde3f003 | ||
| 
						 | 
					ae6124d1f4 | ||
| 
						 | 
					7e121ff72f | ||
| 
						 | 
					5155e18de2 | ||
| 
						 | 
					7365741088 | ||
| 
						 | 
					d5368d0719 | ||
| 
						 | 
					04509cefec | ||
| 
						 | 
					74b9f5dcb0 | ||
| 
						 | 
					183b342071 | ||
| 
						 | 
					0bb5515055 | ||
| 
						 | 
					9acfc0316f | ||
| 
						 | 
					29fb0baa09 | ||
| 
						 | 
					d5de39ebd4 | ||
| 
						 | 
					0faf76e4bd | ||
| 
						 | 
					e8e2ed9fe5 | ||
| 
						 | 
					9f72448ecd | ||
| 
						 | 
					3da3f16deb | ||
| 
						 | 
					0e2ce3c634 | ||
| 
						 | 
					fe00e00537 | ||
| 
						 | 
					cd879b067f | ||
| 
						 | 
					053cb1b53c | 
							
								
								
									
										1
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							@@ -12,4 +12,5 @@ labels: bug
 | 
			
		||||
## Useful information to include:
 | 
			
		||||
 - Minecraft version
 | 
			
		||||
 - CC: Tweaked version
 | 
			
		||||
 - Logs: These will be located in the `logs/` directory of your Minecraft instance. Please upload them as a gist or directly into this editor.
 | 
			
		||||
 - 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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/workflows/main-ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/main-ci.yml
									
									
									
									
										vendored
									
									
								
							@@ -34,6 +34,7 @@ jobs:
 | 
			
		||||
 | 
			
		||||
    - name: Upload Coverage
 | 
			
		||||
      run: bash <(curl -s https://codecov.io/bash)
 | 
			
		||||
      continue-on-error: true
 | 
			
		||||
 | 
			
		||||
    - name: Generate Java documentation stubs
 | 
			
		||||
      run: ./gradlew luaJavadoc --no-daemon
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/make-doc.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/make-doc.sh
									
									
									
									
										vendored
									
									
								
							@@ -12,5 +12,5 @@ chmod 600 "$HOME/.ssh/key"
 | 
			
		||||
 | 
			
		||||
# And upload
 | 
			
		||||
rsync -avc -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no -p $SSH_PORT" \
 | 
			
		||||
      "$GITHUB_WORKSPACE/doc/" \
 | 
			
		||||
      "$GITHUB_WORKSPACE/doc/out/" \
 | 
			
		||||
      "$SSH_USER@$SSH_HOST:/var/www/tweaked.cc/$DEST"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -3,9 +3,8 @@
 | 
			
		||||
/logs
 | 
			
		||||
/build
 | 
			
		||||
/out
 | 
			
		||||
/doc/**/*.html
 | 
			
		||||
/doc/out/
 | 
			
		||||
/doc/javadoc/
 | 
			
		||||
/doc/index.json
 | 
			
		||||
 | 
			
		||||
# Runtime directories
 | 
			
		||||
/run
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
# 
 | 
			
		||||
# 
 | 
			
		||||
[](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
 | 
			
		||||
 | 
			
		||||
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
 | 
			
		||||
@@ -50,12 +50,12 @@ I'd generally recommend you don't contact me directly (email, DM, etc...) unless
 | 
			
		||||
report exploits). You'll get a far quicker response if you ask the whole community!
 | 
			
		||||
 | 
			
		||||
## Using
 | 
			
		||||
If you want to depend on CC: Tweaked, we have a maven repo. However, you should be wary that some functionality is only
 | 
			
		||||
exposed by CC:T's API and not vanilla ComputerCraft. If you wish to support all variations of ComputerCraft, I recommend
 | 
			
		||||
using [cc.crzd.me's maven](https://cc.crzd.me/maven/) instead.
 | 
			
		||||
CC: Tweaked is hosted on my maven repo, and so is relatively simple to depend on. You may wish to add a soft (or hard)
 | 
			
		||||
dependency in your `mods.toml` file, with the appropriate version bounds, to ensure that API functionality you depend
 | 
			
		||||
on is present.
 | 
			
		||||
 | 
			
		||||
```groovy
 | 
			
		||||
dependencies {
 | 
			
		||||
repositories {
 | 
			
		||||
  maven { url 'https://squiddev.cc/maven/' }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								build.gradle
									
									
									
									
									
								
							@@ -9,7 +9,7 @@ buildscript {
 | 
			
		||||
    }
 | 
			
		||||
    dependencies {
 | 
			
		||||
        classpath 'com.google.code.gson:gson:2.8.1'
 | 
			
		||||
        classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.181'
 | 
			
		||||
        classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.187'
 | 
			
		||||
        classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2'
 | 
			
		||||
        classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
 | 
			
		||||
    }
 | 
			
		||||
@@ -109,7 +109,7 @@ dependencies {
 | 
			
		||||
    compileOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3:api")
 | 
			
		||||
    compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.15.2:6.0.0.9")
 | 
			
		||||
 | 
			
		||||
    // runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3")
 | 
			
		||||
    runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3")
 | 
			
		||||
 | 
			
		||||
    compileOnly 'com.google.auto.service:auto-service:1.0-rc7'
 | 
			
		||||
    annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'
 | 
			
		||||
@@ -122,7 +122,7 @@ dependencies {
 | 
			
		||||
 | 
			
		||||
    deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
 | 
			
		||||
 | 
			
		||||
    cctJavadoc 'cc.tweaked:cct-javadoc:1.1.0'
 | 
			
		||||
    cctJavadoc 'cc.tweaked:cct-javadoc:1.2.1'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compile tasks
 | 
			
		||||
@@ -409,7 +409,7 @@ curseforge {
 | 
			
		||||
    apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
 | 
			
		||||
    project {
 | 
			
		||||
        id = '282001'
 | 
			
		||||
        releaseType = 'alpha'
 | 
			
		||||
        releaseType = 'release'
 | 
			
		||||
        changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
 | 
			
		||||
 | 
			
		||||
        relations {
 | 
			
		||||
@@ -487,7 +487,7 @@ githubRelease {
 | 
			
		||||
            .takeWhile { it != 'Type "help changelog" to see the full version history.' }
 | 
			
		||||
            .join("\n").trim()
 | 
			
		||||
    }
 | 
			
		||||
    prerelease true
 | 
			
		||||
    prerelease false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def uploadTasks = ["uploadArchives", "curseforge", "githubRelease"]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										55
									
								
								doc/stub/global.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								doc/stub/global.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
--[[-
 | 
			
		||||
Global functions defined by `bios.lua`. This does not include standard Lua
 | 
			
		||||
functions.
 | 
			
		||||
 | 
			
		||||
@module _G
 | 
			
		||||
]]
 | 
			
		||||
 | 
			
		||||
--[[- Pauses execution for the specified number of seconds.
 | 
			
		||||
 | 
			
		||||
As it waits for a fixed amount of world ticks, `time` will automatically be
 | 
			
		||||
rounded up to the nearest multiple of 0.05 seconds. If you are using coroutines
 | 
			
		||||
or the @{parallel|parallel API}, it will only pause execution of the current
 | 
			
		||||
thread, not the whole program.
 | 
			
		||||
 | 
			
		||||
**Note** Because sleep internally uses timers, it is a function that yields.
 | 
			
		||||
This means that you can use it to prevent "Too long without yielding" errors,
 | 
			
		||||
however, as the minimum sleep time is 0.05 seconds, it will slow your program
 | 
			
		||||
down.
 | 
			
		||||
 | 
			
		||||
**Warning** Internally, this function queues and waits for a timer event (using
 | 
			
		||||
@{os.startTimer}), however it does not listen for any other events. This means
 | 
			
		||||
that any event that occurs while sleeping will be entirely discarded. If you
 | 
			
		||||
need to receive events while sleeping, consider using @{os.startTimer|timers},
 | 
			
		||||
or the @{parallel|parallel API}.
 | 
			
		||||
 | 
			
		||||
@tparam number time The number of seconds to sleep for, rounded up to the
 | 
			
		||||
nearest multiple of 0.05.
 | 
			
		||||
 | 
			
		||||
@see os.startTimer
 | 
			
		||||
]]
 | 
			
		||||
function sleep(time) end
 | 
			
		||||
 | 
			
		||||
function write(text) end
 | 
			
		||||
function print(...) end
 | 
			
		||||
function printError(...) end
 | 
			
		||||
 | 
			
		||||
function read(replaceChar, history, completeFn, default) end
 | 
			
		||||
 | 
			
		||||
--- The ComputerCraft and Minecraft version of the current computer environment.
 | 
			
		||||
--
 | 
			
		||||
-- For example, `ComputerCraft 1.93.0 (Minecraft 1.15.2)`.
 | 
			
		||||
_HOST = _HOST
 | 
			
		||||
 | 
			
		||||
--[[- The default computer settings as defined in the ComputerCraft
 | 
			
		||||
configuration.
 | 
			
		||||
 | 
			
		||||
This is a comma-separated list of settings pairs defined by the mod
 | 
			
		||||
configuration or server owner. By default, it is empty.
 | 
			
		||||
 | 
			
		||||
An example value to disable autocompletion:
 | 
			
		||||
 | 
			
		||||
    shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false
 | 
			
		||||
 | 
			
		||||
]]
 | 
			
		||||
_CC_DEFAULT_SETTINGS = _CC_DEFAULT_SETTINGS
 | 
			
		||||
@@ -1,8 +1,6 @@
 | 
			
		||||
--- The http library allows communicating with web servers, sending and
 | 
			
		||||
-- receiving data from them.
 | 
			
		||||
--
 | 
			
		||||
-- #### `http_check` event
 | 
			
		||||
--
 | 
			
		||||
-- @module http
 | 
			
		||||
 | 
			
		||||
--- Asynchronously make a HTTP request to the given url.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										115
									
								
								doc/stub/os.lua
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								doc/stub/os.lua
									
									
									
									
									
								
							@@ -1,6 +1,121 @@
 | 
			
		||||
-- Defined in bios.lua
 | 
			
		||||
 | 
			
		||||
--[[- Loads the given API into the global environment.
 | 
			
		||||
 | 
			
		||||
**Warning** This function is deprecated. Use of this function will pollute the
 | 
			
		||||
global table, use @{require} instead.
 | 
			
		||||
 | 
			
		||||
This function loads and executes the file at the given path, and all global
 | 
			
		||||
variables and functions exported by it will by available through the use of
 | 
			
		||||
`myAPI.<function name>`, where `myAPI` is the base name of the API file.
 | 
			
		||||
 | 
			
		||||
@tparam string path The path of the API to load.
 | 
			
		||||
@treturn boolean Whether or not the API was successfully loaded.
 | 
			
		||||
 | 
			
		||||
@deprecated Use @{require}.
 | 
			
		||||
]]
 | 
			
		||||
function loadAPI(path) end
 | 
			
		||||
 | 
			
		||||
--- Unloads an API which was loaded by @{os.loadAPI}.
 | 
			
		||||
--
 | 
			
		||||
-- This effectively removes the specified table from `_G`.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam string name The name of the API to unload.
 | 
			
		||||
-- @deprecated Use @{require}.
 | 
			
		||||
function unloadAPI(name) end
 | 
			
		||||
 | 
			
		||||
--[[- Pause execution of the current thread and waits for any events matching
 | 
			
		||||
`filter`.
 | 
			
		||||
 | 
			
		||||
This function @{coroutine.yield|yields} the current process and waits for it
 | 
			
		||||
to be resumed with a vararg list where the first element matches `filter`.
 | 
			
		||||
If no `filter` is supplied, this will match all events.
 | 
			
		||||
 | 
			
		||||
Unlike @{os.pullEventRaw}, it will stop the application upon a "terminate"
 | 
			
		||||
event, printing the error "Terminated".
 | 
			
		||||
 | 
			
		||||
@tparam[opt] string filter Event to filter for.
 | 
			
		||||
@treturn string event The name of the event that fired.
 | 
			
		||||
@treturn any param... Optional additional parameters of the event.
 | 
			
		||||
@usage Listen for `mouse_click` events.
 | 
			
		||||
 | 
			
		||||
    while true do
 | 
			
		||||
        local event, button, x, y = os.pullEvent("mouse_click")
 | 
			
		||||
        print("Button", button, "was clicked at", x, ",", y)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@usage Listen for multiple events.
 | 
			
		||||
 | 
			
		||||
    while true do
 | 
			
		||||
        local eventData = {os.pullEvent()}
 | 
			
		||||
        local event = eventData[1]
 | 
			
		||||
 | 
			
		||||
        if event == "mouse_click" then
 | 
			
		||||
            print("Button", eventData[2], "was clicked at", eventData[3], ",", eventData[4])
 | 
			
		||||
        elseif event == "key" then
 | 
			
		||||
            print("Key code", eventData[2], "was pressed")
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@see os.pullEventRaw To pull the terminate event.
 | 
			
		||||
]]
 | 
			
		||||
function pullEvent(filter) end
 | 
			
		||||
 | 
			
		||||
--[[- Pause execution of the current thread and waits for events, including the
 | 
			
		||||
`terminate` event.
 | 
			
		||||
 | 
			
		||||
This behaves almost the same as @{os.pullEvent}, except it allows you to handle
 | 
			
		||||
the `terminate` event yourself - the program will not stop execution when
 | 
			
		||||
<kbd>Ctrl+T</kbd> is pressed.
 | 
			
		||||
 | 
			
		||||
@tparam[opt] string filter Event to filter for.
 | 
			
		||||
@treturn string event The name of the event that fired.
 | 
			
		||||
@treturn any param... Optional additional parameters of the event.
 | 
			
		||||
@usage Listen for `terminate` events.
 | 
			
		||||
 | 
			
		||||
    while true do
 | 
			
		||||
        local event = os.pullEventRaw()
 | 
			
		||||
        if event == "terminate" then
 | 
			
		||||
            print("Caught terminate event!")
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@see os.pullEvent To pull events normally.
 | 
			
		||||
]]
 | 
			
		||||
function pullEventRaw(filter) end
 | 
			
		||||
 | 
			
		||||
--- Pauses execution for the specified number of seconds, alias of @{_G.sleep}.
 | 
			
		||||
function sleep(time) end
 | 
			
		||||
 | 
			
		||||
--- Get the current CraftOS version (for example, `CraftOS 1.8`).
 | 
			
		||||
--
 | 
			
		||||
-- This is defined by `bios.lua`. For the current version of CC:Tweaked, this
 | 
			
		||||
-- should return `CraftOS 1.8`.
 | 
			
		||||
--
 | 
			
		||||
-- @treturn string The current CraftOS version.
 | 
			
		||||
function version() end
 | 
			
		||||
 | 
			
		||||
--[[- Run the program at the given path with the specified environment and
 | 
			
		||||
arguments.
 | 
			
		||||
 | 
			
		||||
This function does not resolve program names like the shell does. This means
 | 
			
		||||
that, for example, `os.run("edit")` will not work. As well as this, it does not
 | 
			
		||||
provide access to the @{shell} API in the environment. For this behaviour, use
 | 
			
		||||
@{shell.run} instead.
 | 
			
		||||
 | 
			
		||||
If the program cannot be found, or failed to run, it will print the error and
 | 
			
		||||
return `false`. If you want to handle this more gracefully, use an alternative
 | 
			
		||||
such as @{loadfile}.
 | 
			
		||||
 | 
			
		||||
@tparam table env The environment to run the program with.
 | 
			
		||||
@tparam string path The exact path of the program to run.
 | 
			
		||||
@param ... The arguments to pass to the program.
 | 
			
		||||
@treturn boolean Whether or not the program ran successfully.
 | 
			
		||||
@usage Run the default shell from within your program:
 | 
			
		||||
 | 
			
		||||
    os.run({}, "/rom/programs/shell")
 | 
			
		||||
 | 
			
		||||
@see shell.run
 | 
			
		||||
@see loadfile
 | 
			
		||||
]]
 | 
			
		||||
function run(env, path, ...) end
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										187
									
								
								doc/styles.css
									
									
									
									
									
								
							
							
						
						
									
										187
									
								
								doc/styles.css
									
									
									
									
									
								
							@@ -1,191 +1,14 @@
 | 
			
		||||
/* Basic reset on elements */
 | 
			
		||||
h1, h2, h3, h4, p, table, div, body {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    border: 0;
 | 
			
		||||
    font-size: 100%;
 | 
			
		||||
    font: inherit;
 | 
			
		||||
    vertical-align: baseline;
 | 
			
		||||
}
 | 
			
		||||
/* Make the page a little more airy */
 | 
			
		||||
body {
 | 
			
		||||
    margin: 20px auto;
 | 
			
		||||
    max-width: 1200px;
 | 
			
		||||
    padding: 0 10px;
 | 
			
		||||
    line-height: 1.6;
 | 
			
		||||
    color: #222;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Try to use system default fonts. */
 | 
			
		||||
body {
 | 
			
		||||
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans",
 | 
			
		||||
                 "Droid Sans", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
code, pre, .parameter, .type, .definition-name, .reference-code {
 | 
			
		||||
    font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Some definitions of basic tags */
 | 
			
		||||
code {
 | 
			
		||||
    color: #c7254e;
 | 
			
		||||
    background-color: #f9f2f4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
p {
 | 
			
		||||
    margin: 0.9em 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 {
 | 
			
		||||
    font-size: 1.5em;
 | 
			
		||||
    font-weight: lighter;
 | 
			
		||||
    border-bottom: solid 1px #aaa;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h2, h3, h4 { margin: 1.4em 0 0.3em;}
 | 
			
		||||
h2 { font-size: 1.25em; }
 | 
			
		||||
h3 { font-size: 1.15em; font-weight: bold; }
 | 
			
		||||
h4 { font-size: 1.06em; }
 | 
			
		||||
 | 
			
		||||
a, a:visited, a:active { font-weight: bold; color: #004080; text-decoration: none; }
 | 
			
		||||
a:hover { text-decoration: underline; }
 | 
			
		||||
 | 
			
		||||
blockquote {
 | 
			
		||||
    padding: 0.3em;
 | 
			
		||||
    margin: 1em 0;
 | 
			
		||||
    background: #f0f0f0;
 | 
			
		||||
    border-left: solid 0.5em #ccc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Stop sublists from having initial vertical space */
 | 
			
		||||
ul ul { margin-top: 0px; }
 | 
			
		||||
ol ul { margin-top: 0px; }
 | 
			
		||||
ol ol { margin-top: 0px; }
 | 
			
		||||
ul ol { margin-top: 0px; }
 | 
			
		||||
 | 
			
		||||
/* Make the target distinct; helps when we're navigating to a function */
 | 
			
		||||
a:target + * { background-color: #FFFF99; }
 | 
			
		||||
 | 
			
		||||
/* Allow linking to any subsection */
 | 
			
		||||
a[name]::before { content: "#"; }
 | 
			
		||||
 | 
			
		||||
/* Layout */
 | 
			
		||||
#main {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-wrap: nowrap;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    min-height: calc(100vh - 100px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#main > nav {
 | 
			
		||||
    flex-basis: 30%;
 | 
			
		||||
    min-width: 150px;
 | 
			
		||||
    max-width: 250px;
 | 
			
		||||
    background-color: #f0f0f0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nav h1, nav ul { padding: 0em 10px; }
 | 
			
		||||
 | 
			
		||||
nav h2 {
 | 
			
		||||
    background-color:#e7e7e7;
 | 
			
		||||
    font-size: 1.1em;
 | 
			
		||||
    color:#000000;
 | 
			
		||||
    padding: 5px 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nav ul {
 | 
			
		||||
    list-style-type: none;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#content {
 | 
			
		||||
    flex-shrink: 1;
 | 
			
		||||
    flex-basis: 80%;
 | 
			
		||||
    padding: 0px 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
footer {
 | 
			
		||||
    text-align: right;
 | 
			
		||||
    font-size: 0.8em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* The definition lists at the top of each page */
 | 
			
		||||
table.definition-list {
 | 
			
		||||
/* Pretty tables, mostly inherited from table.definition-list */
 | 
			
		||||
table.pretty-table {
 | 
			
		||||
    border-collapse: collapse;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.definition-list td, table.definition-list th {
 | 
			
		||||
table.pretty-table td, table.pretty-table th {
 | 
			
		||||
    border: 1px solid #cccccc;
 | 
			
		||||
    padding: 5px;
 | 
			
		||||
    padding: 2px 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.definition-list th {
 | 
			
		||||
table.pretty-table th {
 | 
			
		||||
    background-color: #f0f0f0;
 | 
			
		||||
    min-width: 200px;
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
    text-align: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.definition-list td { width: 100%; }
 | 
			
		||||
 | 
			
		||||
dl.definition dt {
 | 
			
		||||
    border-top: 1px solid #ccc;
 | 
			
		||||
    padding-top: 1em;
 | 
			
		||||
    display: flex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.definition dt .definition-name {
 | 
			
		||||
    padding: 0 0.1em;
 | 
			
		||||
    margin: 0 0.1em;
 | 
			
		||||
    flex-grow: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dl.definition dd {
 | 
			
		||||
    padding-bottom: 1em;
 | 
			
		||||
    margin: 10px 0 0 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.definition h3 {
 | 
			
		||||
    font-size: .95em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Links to source-code */
 | 
			
		||||
.source-link { font-size: 0.8em; }
 | 
			
		||||
.source-link::before { content: '[' }
 | 
			
		||||
.source-link::after  { content: ']' }
 | 
			
		||||
a.source-link, a.source-link:visited, a.source-link:active { color: #505050; }
 | 
			
		||||
 | 
			
		||||
/* Method definitions */
 | 
			
		||||
span.parameter:after { content:":"; padding-left: 0.3em; }
 | 
			
		||||
.optional { text-decoration: underline dotted; }
 | 
			
		||||
 | 
			
		||||
/** Fancy colour display. */
 | 
			
		||||
.colour-ref {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    width: 0.8em;
 | 
			
		||||
    height: 0.8em;
 | 
			
		||||
    margin: 0.1em 0.1em 0.3em 0.1em; /* Terrrible hack to force vertical alignment. */
 | 
			
		||||
    border: solid 1px black;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* styles for prettification of source */
 | 
			
		||||
.highlight .comment { color: #558817; }
 | 
			
		||||
.highlight .constant { color: #a8660d; }
 | 
			
		||||
.highlight .escape { color: #844631; }
 | 
			
		||||
.highlight .keyword { color: #aa5050; font-weight: bold; }
 | 
			
		||||
.highlight .library { color: #0e7c6b; }
 | 
			
		||||
.highlight .marker { color: #512b1e; background: #fedc56; font-weight: bold; }
 | 
			
		||||
.highlight .string { color: #8080ff; }
 | 
			
		||||
.highlight .literal-kw { color: #8080ff; }
 | 
			
		||||
.highlight .number { color: #f8660d; }
 | 
			
		||||
.highlight .operator { color: #2239a8; font-weight: bold; }
 | 
			
		||||
.highlight .preprocessor, pre .prepro { color: #a33243; }
 | 
			
		||||
.highlight .global { color: #800080; }
 | 
			
		||||
.highlight .user-keyword { color: #800080; }
 | 
			
		||||
.highlight .prompt { color: #558817; }
 | 
			
		||||
.highlight .url { color: #272fc2; text-decoration: underline; }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
# Mod properties
 | 
			
		||||
mod_version=1.90.3
 | 
			
		||||
mod_version=1.94.0
 | 
			
		||||
 | 
			
		||||
# Minecraft properties (update mods.toml when changing)
 | 
			
		||||
mc_version=1.16.1
 | 
			
		||||
forge_version=32.0.75
 | 
			
		||||
mappings_version=20200723-1.16.1
 | 
			
		||||
mc_version=1.15.2
 | 
			
		||||
forge_version=31.1.41
 | 
			
		||||
mappings_version=20200429-1.15.1
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,10 @@
 | 
			
		||||
 | 
			
		||||
(doc
 | 
			
		||||
  (title "CC: Tweaked")
 | 
			
		||||
  (destination doc/out)
 | 
			
		||||
  (logo src/main/resources/pack.png)
 | 
			
		||||
  (index doc/index.md)
 | 
			
		||||
  (styles doc/styles.css)
 | 
			
		||||
  (source-link https://github.com/SquidDev-CC/CC-Tweaked/blob/${commit}/${path}#L${line})
 | 
			
		||||
 | 
			
		||||
  (module-kinds
 | 
			
		||||
@@ -50,7 +53,7 @@
 | 
			
		||||
 | 
			
		||||
    ;; colours imports from colors, and we don't handle that right now.
 | 
			
		||||
    ;; keys is entirely dynamic, so we skip it.
 | 
			
		||||
    (dynamic-modules colours keys)
 | 
			
		||||
    (dynamic-modules colours keys _G)
 | 
			
		||||
 | 
			
		||||
    (globals
 | 
			
		||||
      :max
 | 
			
		||||
@@ -79,6 +82,7 @@
 | 
			
		||||
   /doc/stub/http.lua
 | 
			
		||||
   /doc/stub/os.lua
 | 
			
		||||
   /doc/stub/turtle.lua
 | 
			
		||||
   /doc/stub/global.lua
 | 
			
		||||
   ; Java generated APIs
 | 
			
		||||
   /doc/javadoc/turtle.lua
 | 
			
		||||
   ; Peripherals
 | 
			
		||||
@@ -100,7 +104,14 @@
 | 
			
		||||
   /doc/stub/fs.lua)
 | 
			
		||||
  (linters -doc:unresolved-reference))
 | 
			
		||||
 | 
			
		||||
;; Suppress warnings for the BIOS using its own deprecated members for now.
 | 
			
		||||
(at /src/main/resources/*/computercraft/lua/bios.lua
 | 
			
		||||
  (linters -var:deprecated))
 | 
			
		||||
 | 
			
		||||
(at /src/test/resources/test-rom
 | 
			
		||||
  ; We should still be able to test deprecated members.
 | 
			
		||||
  (linters -var:deprecated)
 | 
			
		||||
 | 
			
		||||
  (lint
 | 
			
		||||
    (globals
 | 
			
		||||
      :max sleep write
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "replace": false,
 | 
			
		||||
  "values": [
 | 
			
		||||
    "computercraft:computer_advanced",
 | 
			
		||||
    "computercraft:turtle_advanced",
 | 
			
		||||
    "computercraft:wireless_modem_advanced",
 | 
			
		||||
    "computercraft:pocket_computer_advanced",
 | 
			
		||||
    "computercraft:monitor_advanced"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@@ -39,6 +39,7 @@ public final class ComputerCraft
 | 
			
		||||
    public static final String[] DEFAULT_HTTP_ALLOW = new String[] { "*" };
 | 
			
		||||
    public static final String[] DEFAULT_HTTP_DENY = new String[] {
 | 
			
		||||
        "127.0.0.0/8",
 | 
			
		||||
        "0.0.0.0/8",
 | 
			
		||||
        "10.0.0.0/8",
 | 
			
		||||
        "172.16.0.0/12",
 | 
			
		||||
        "192.168.0.0/16",
 | 
			
		||||
@@ -62,10 +63,10 @@ public final class ComputerCraft
 | 
			
		||||
    public static boolean httpWebsocketEnabled = true;
 | 
			
		||||
    public static List<AddressRule> httpRules = Collections.unmodifiableList( Stream.concat(
 | 
			
		||||
        Stream.of( DEFAULT_HTTP_DENY )
 | 
			
		||||
            .map( x -> AddressRule.parse( x, Action.DENY.toPartial() ) )
 | 
			
		||||
            .map( x -> AddressRule.parse( x, null, Action.DENY.toPartial() ) )
 | 
			
		||||
            .filter( Objects::nonNull ),
 | 
			
		||||
        Stream.of( DEFAULT_HTTP_ALLOW )
 | 
			
		||||
            .map( x -> AddressRule.parse( x, Action.ALLOW.toPartial() ) )
 | 
			
		||||
            .map( x -> AddressRule.parse( x, null, Action.ALLOW.toPartial() ) )
 | 
			
		||||
            .filter( Objects::nonNull )
 | 
			
		||||
    ).collect( Collectors.toList() ) );
 | 
			
		||||
 | 
			
		||||
@@ -89,8 +90,6 @@ public final class ComputerCraft
 | 
			
		||||
    public static boolean turtlesCanPush = true;
 | 
			
		||||
    public static EnumSet<TurtleAction> turtleDisabledActions = EnumSet.noneOf( TurtleAction.class );
 | 
			
		||||
 | 
			
		||||
    public static boolean genericPeripheral = false;
 | 
			
		||||
 | 
			
		||||
    public static int computerTermWidth = 51;
 | 
			
		||||
    public static int computerTermHeight = 19;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
 | 
			
		||||
 | 
			
		||||
    public static InputStream getResourceFile( String domain, String subPath )
 | 
			
		||||
    {
 | 
			
		||||
        IReloadableResourceManager manager = (IReloadableResourceManager) ServerLifecycleHooks.getCurrentServer().getDataPackRegistries().getResourceManager();
 | 
			
		||||
        IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            return manager.getResource( new ResourceLocation( domain, subPath ) ).getInputStream();
 | 
			
		||||
@@ -97,7 +97,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
 | 
			
		||||
    @Override
 | 
			
		||||
    public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
 | 
			
		||||
    {
 | 
			
		||||
        IReloadableResourceManager manager = (IReloadableResourceManager) ServerLifecycleHooks.getCurrentServer().getDataPackRegistries().getResourceManager();
 | 
			
		||||
        IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
 | 
			
		||||
        ResourceMount mount = ResourceMount.get( domain, subPath, manager );
 | 
			
		||||
        return mount.exists( "" ) ? mount : null;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,11 +6,11 @@
 | 
			
		||||
package dan200.computercraft.api.client;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.client.renderer.TransformationMatrix;
 | 
			
		||||
import net.minecraft.client.renderer.model.IBakedModel;
 | 
			
		||||
import net.minecraft.client.renderer.model.ModelManager;
 | 
			
		||||
import net.minecraft.client.renderer.model.ModelResourceLocation;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.util.math.vector.TransformationMatrix;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.api.network;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -29,7 +29,7 @@ public interface IPacketReceiver
 | 
			
		||||
     * @return The receiver's position.
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    Vector3d getPosition();
 | 
			
		||||
    Vec3d getPosition();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the maximum distance this receiver can send and receive messages.
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.api.network;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -29,7 +29,7 @@ public interface IPacketSender
 | 
			
		||||
     * @return The sender's position.
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    Vector3d getPosition();
 | 
			
		||||
    Vec3d getPosition();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get some sort of identification string for this sender. This does not strictly need to be unique, but you
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ import net.minecraft.inventory.IInventory;
 | 
			
		||||
import net.minecraft.nbt.CompoundNBT;
 | 
			
		||||
import net.minecraft.util.Direction;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
import net.minecraftforge.items.IItemHandlerModifiable;
 | 
			
		||||
 | 
			
		||||
@@ -67,7 +67,7 @@ public interface ITurtleAccess
 | 
			
		||||
     * @see #getVisualYaw(float)
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    Vector3d getVisualPosition( float f );
 | 
			
		||||
    Vec3d getVisualPosition( float f );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the yaw the turtle is facing when it is rendered.
 | 
			
		||||
@@ -139,7 +139,7 @@ public interface ITurtleAccess
 | 
			
		||||
     *
 | 
			
		||||
     * @return This turtle's owner.
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Nullable
 | 
			
		||||
    GameProfile getOwningPlayer();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -12,12 +12,14 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
 | 
			
		||||
import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.client.gui.FontRenderer;
 | 
			
		||||
import net.minecraft.client.gui.NewChatGui;
 | 
			
		||||
import net.minecraft.client.gui.RenderComponentsUtil;
 | 
			
		||||
import net.minecraft.util.math.MathHelper;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
import net.minecraft.util.text.TextFormatting;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class ClientTableFormatter implements TableFormatter
 | 
			
		||||
{
 | 
			
		||||
@@ -55,7 +57,7 @@ public class ClientTableFormatter implements TableFormatter
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getWidth( ITextComponent component )
 | 
			
		||||
    {
 | 
			
		||||
        return renderer().func_238414_a_( component );
 | 
			
		||||
        return renderer().getStringWidth( component.getFormattedText() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -64,11 +66,10 @@ public class ClientTableFormatter implements TableFormatter
 | 
			
		||||
        Minecraft mc = Minecraft.getInstance();
 | 
			
		||||
        NewChatGui chat = mc.ingameGUI.getChatGUI();
 | 
			
		||||
 | 
			
		||||
        // TODO: Trim the text if it goes over the allowed length
 | 
			
		||||
        // int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() );
 | 
			
		||||
        // List<ITextProperties> list = RenderComponentsUtil.func_238505_a_( component, maxWidth, mc.fontRenderer );
 | 
			
		||||
        // if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id );
 | 
			
		||||
        chat.printChatMessageWithOptionalDeletion( component, id );
 | 
			
		||||
        // Trim the text if it goes over the allowed length
 | 
			
		||||
        int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() );
 | 
			
		||||
        List<ITextComponent> list = RenderComponentsUtil.splitText( component, maxWidth, mc.fontRenderer, false, false );
 | 
			
		||||
        if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -13,14 +13,10 @@ import dan200.computercraft.core.terminal.TextBuffer;
 | 
			
		||||
import dan200.computercraft.shared.util.Colour;
 | 
			
		||||
import dan200.computercraft.shared.util.Palette;
 | 
			
		||||
import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
 | 
			
		||||
import net.minecraft.client.renderer.RenderState;
 | 
			
		||||
import net.minecraft.client.renderer.RenderType;
 | 
			
		||||
import net.minecraft.client.renderer.*;
 | 
			
		||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
 | 
			
		||||
import net.minecraft.client.renderer.vertex.VertexFormat;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import net.minecraft.util.math.vector.TransformationMatrix;
 | 
			
		||||
import org.lwjgl.opengl.GL11;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.client.gui;
 | 
			
		||||
 | 
			
		||||
import com.mojang.blaze3d.matrix.MatrixStack;
 | 
			
		||||
import com.mojang.blaze3d.systems.RenderSystem;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
 | 
			
		||||
@@ -22,8 +21,6 @@ import net.minecraft.entity.player.PlayerInventory;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
import org.lwjgl.glfw.GLFW;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER;
 | 
			
		||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
 | 
			
		||||
 | 
			
		||||
@@ -91,13 +88,13 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
 | 
			
		||||
        terminalWrapper = new WidgetWrapper( terminal, MARGIN + BORDER + guiLeft, MARGIN + BORDER + guiTop, termPxWidth, termPxHeight );
 | 
			
		||||
 | 
			
		||||
        children.add( terminalWrapper );
 | 
			
		||||
        setListener( terminalWrapper );
 | 
			
		||||
        setFocused( terminalWrapper );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onClose()
 | 
			
		||||
    public void removed()
 | 
			
		||||
    {
 | 
			
		||||
        super.onClose();
 | 
			
		||||
        super.removed();
 | 
			
		||||
        children.remove( terminal );
 | 
			
		||||
        terminal = null;
 | 
			
		||||
        minecraft.keyboardListener.enableRepeatEvents( false );
 | 
			
		||||
@@ -114,16 +111,16 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
 | 
			
		||||
    public boolean keyPressed( int key, int scancode, int modifiers )
 | 
			
		||||
    {
 | 
			
		||||
        // Forward the tab key to the terminal, rather than moving between controls.
 | 
			
		||||
        if( key == GLFW.GLFW_KEY_TAB && getListener() != null && getListener() == terminalWrapper )
 | 
			
		||||
        if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper )
 | 
			
		||||
        {
 | 
			
		||||
            return getListener().keyPressed( key, scancode, modifiers );
 | 
			
		||||
            return getFocused().keyPressed( key, scancode, modifiers );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return super.keyPressed( key, scancode, modifiers );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY )
 | 
			
		||||
    public void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
 | 
			
		||||
    {
 | 
			
		||||
        // Draw terminal
 | 
			
		||||
        terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
 | 
			
		||||
@@ -138,22 +135,17 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks )
 | 
			
		||||
    public void render( int mouseX, int mouseY, float partialTicks )
 | 
			
		||||
    {
 | 
			
		||||
        super.render( stack, mouseX, mouseY, partialTicks );
 | 
			
		||||
        func_230459_a_( stack, mouseX, mouseY );
 | 
			
		||||
        renderBackground();
 | 
			
		||||
        super.render( mouseX, mouseY, partialTicks );
 | 
			
		||||
        renderHoveredToolTip( mouseX, mouseY );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
 | 
			
		||||
    {
 | 
			
		||||
        return (getListener() != null && getListener().mouseDragged( x, y, button, deltaX, deltaY ))
 | 
			
		||||
        return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
 | 
			
		||||
            || super.mouseDragged( x, y, button, deltaX, deltaY );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void drawGuiContainerForegroundLayer( @Nonnull MatrixStack transform, int mouseX, int mouseY )
 | 
			
		||||
    {
 | 
			
		||||
        // Skip rendering labels.
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.client.gui;
 | 
			
		||||
 | 
			
		||||
import com.mojang.blaze3d.matrix.MatrixStack;
 | 
			
		||||
import com.mojang.blaze3d.systems.RenderSystem;
 | 
			
		||||
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
 | 
			
		||||
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
 | 
			
		||||
@@ -13,8 +12,6 @@ import net.minecraft.entity.player.PlayerInventory;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
public class GuiDiskDrive extends ContainerScreen<ContainerDiskDrive>
 | 
			
		||||
{
 | 
			
		||||
    private static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/disk_drive.png" );
 | 
			
		||||
@@ -25,18 +22,26 @@ public class GuiDiskDrive extends ContainerScreen<ContainerDiskDrive>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
 | 
			
		||||
    protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY )
 | 
			
		||||
    {
 | 
			
		||||
        RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
 | 
			
		||||
        minecraft.getTextureManager().bindTexture( BACKGROUND );
 | 
			
		||||
        blit( transform, guiLeft, guiTop, 0, 0, xSize, ySize );
 | 
			
		||||
        String title = this.title.getFormattedText();
 | 
			
		||||
        font.drawString( title, (xSize - font.getStringWidth( title )) / 2.0f, 6, 0x404040 );
 | 
			
		||||
        font.drawString( title, 8, ySize - 96 + 2, 0x404040 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void render( @Nonnull MatrixStack transform, int mouseX, int mouseY, float partialTicks )
 | 
			
		||||
    protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
 | 
			
		||||
    {
 | 
			
		||||
        renderBackground( transform );
 | 
			
		||||
        super.render( transform, mouseX, mouseY, partialTicks );
 | 
			
		||||
        func_230459_a_( transform, mouseX, mouseY );
 | 
			
		||||
        RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
 | 
			
		||||
        minecraft.getTextureManager().bindTexture( BACKGROUND );
 | 
			
		||||
        blit( guiLeft, guiTop, 0, 0, xSize, ySize );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void render( int mouseX, int mouseY, float partialTicks )
 | 
			
		||||
    {
 | 
			
		||||
        renderBackground();
 | 
			
		||||
        super.render( mouseX, mouseY, partialTicks );
 | 
			
		||||
        renderHoveredToolTip( mouseX, mouseY );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,16 +5,14 @@
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.client.gui;
 | 
			
		||||
 | 
			
		||||
import com.mojang.blaze3d.matrix.MatrixStack;
 | 
			
		||||
import com.mojang.blaze3d.systems.RenderSystem;
 | 
			
		||||
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
 | 
			
		||||
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
 | 
			
		||||
import net.minecraft.client.resources.I18n;
 | 
			
		||||
import net.minecraft.entity.player.PlayerInventory;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
public class GuiPrinter extends ContainerScreen<ContainerPrinter>
 | 
			
		||||
{
 | 
			
		||||
    private static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/printer.png" );
 | 
			
		||||
@@ -24,29 +22,29 @@ public class GuiPrinter extends ContainerScreen<ContainerPrinter>
 | 
			
		||||
        super( container, player, title );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*@Override
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY )
 | 
			
		||||
    {
 | 
			
		||||
        String title = getTitle().getFormattedText();
 | 
			
		||||
        font.drawString( title, (xSize - font.getStringWidth( title )) / 2.0f, 6, 0x404040 );
 | 
			
		||||
        font.drawString( I18n.format( "container.inventory" ), 8, ySize - 96 + 2, 0x404040 );
 | 
			
		||||
    }*/
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
 | 
			
		||||
    protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
 | 
			
		||||
    {
 | 
			
		||||
        RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
 | 
			
		||||
        minecraft.getTextureManager().bindTexture( BACKGROUND );
 | 
			
		||||
        blit( transform, guiLeft, guiTop, 0, 0, xSize, ySize );
 | 
			
		||||
        blit( guiLeft, guiTop, 0, 0, xSize, ySize );
 | 
			
		||||
 | 
			
		||||
        if( getContainer().isPrinting() ) blit( transform, guiLeft + 34, guiTop + 21, 176, 0, 25, 45 );
 | 
			
		||||
        if( getContainer().isPrinting() ) blit( guiLeft + 34, guiTop + 21, 176, 0, 25, 45 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks )
 | 
			
		||||
    public void render( int mouseX, int mouseY, float partialTicks )
 | 
			
		||||
    {
 | 
			
		||||
        renderBackground( stack );
 | 
			
		||||
        super.render( stack, mouseX, mouseY, partialTicks );
 | 
			
		||||
        func_230459_a_( stack, mouseX, mouseY );
 | 
			
		||||
        renderBackground();
 | 
			
		||||
        super.render( mouseX, mouseY, partialTicks );
 | 
			
		||||
        renderHoveredToolTip( mouseX, mouseY );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.client.gui;
 | 
			
		||||
 | 
			
		||||
import com.mojang.blaze3d.matrix.MatrixStack;
 | 
			
		||||
import com.mojang.blaze3d.systems.RenderSystem;
 | 
			
		||||
import dan200.computercraft.core.terminal.TextBuffer;
 | 
			
		||||
import dan200.computercraft.shared.common.ContainerHeldItem;
 | 
			
		||||
@@ -13,17 +12,18 @@ import dan200.computercraft.shared.media.items.ItemPrintout;
 | 
			
		||||
import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
 | 
			
		||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
 | 
			
		||||
import net.minecraft.client.renderer.Matrix4f;
 | 
			
		||||
import net.minecraft.client.renderer.TransformationMatrix;
 | 
			
		||||
import net.minecraft.entity.player.PlayerInventory;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
import org.lwjgl.glfw.GLFW;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.client.render.PrintoutRenderer.*;
 | 
			
		||||
 | 
			
		||||
public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
 | 
			
		||||
{
 | 
			
		||||
    private static final Matrix4f IDENTITY = TransformationMatrix.identity().getMatrix();
 | 
			
		||||
 | 
			
		||||
    private final boolean m_book;
 | 
			
		||||
    private final int m_pages;
 | 
			
		||||
    private final TextBuffer[] m_text;
 | 
			
		||||
@@ -91,33 +91,27 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
 | 
			
		||||
    public void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
 | 
			
		||||
    {
 | 
			
		||||
        // Draw the printout
 | 
			
		||||
        RenderSystem.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
 | 
			
		||||
        RenderSystem.enableDepthTest();
 | 
			
		||||
 | 
			
		||||
        IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource();
 | 
			
		||||
        Matrix4f matrix = transform.getLast().getMatrix();
 | 
			
		||||
        drawBorder( matrix, renderer, guiLeft, guiTop, getBlitOffset(), m_page, m_pages, m_book );
 | 
			
		||||
        drawText( matrix, renderer, guiLeft + X_TEXT_MARGIN, guiTop + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
 | 
			
		||||
        drawBorder( IDENTITY, renderer, guiLeft, guiTop, getBlitOffset(), m_page, m_pages, m_book );
 | 
			
		||||
        drawText( IDENTITY, renderer, guiLeft + X_TEXT_MARGIN, guiTop + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
 | 
			
		||||
        renderer.finish();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks )
 | 
			
		||||
    public void render( int mouseX, int mouseY, float partialTicks )
 | 
			
		||||
    {
 | 
			
		||||
        // We must take the background further back in order to not overlap with our printed pages.
 | 
			
		||||
        setBlitOffset( getBlitOffset() - 1 );
 | 
			
		||||
        renderBackground( stack );
 | 
			
		||||
        renderBackground();
 | 
			
		||||
        setBlitOffset( getBlitOffset() + 1 );
 | 
			
		||||
 | 
			
		||||
        super.render( stack, mouseX, mouseY, partialTicks );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void drawGuiContainerForegroundLayer( @Nonnull MatrixStack transform, int mouseX, int mouseY )
 | 
			
		||||
    {
 | 
			
		||||
        // Skip rendering labels.
 | 
			
		||||
        super.render( mouseX, mouseY, partialTicks );
 | 
			
		||||
        renderHoveredToolTip( mouseX, mouseY );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.client.gui;
 | 
			
		||||
 | 
			
		||||
import com.mojang.blaze3d.matrix.MatrixStack;
 | 
			
		||||
import com.mojang.blaze3d.systems.RenderSystem;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
 | 
			
		||||
@@ -19,8 +18,6 @@ import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
import org.lwjgl.glfw.GLFW;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
public class GuiTurtle extends ContainerScreen<ContainerTurtle>
 | 
			
		||||
{
 | 
			
		||||
    private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( "computercraft", "textures/gui/turtle_normal.png" );
 | 
			
		||||
@@ -64,13 +61,13 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
 | 
			
		||||
        terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + guiLeft, 2 + 8 + guiTop, termPxWidth, termPxHeight );
 | 
			
		||||
 | 
			
		||||
        children.add( terminalWrapper );
 | 
			
		||||
        setListener( terminalWrapper );
 | 
			
		||||
        setFocused( terminalWrapper );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onClose()
 | 
			
		||||
    public void removed()
 | 
			
		||||
    {
 | 
			
		||||
        super.onClose();
 | 
			
		||||
        super.removed();
 | 
			
		||||
        children.remove( terminal );
 | 
			
		||||
        terminal = null;
 | 
			
		||||
        minecraft.keyboardListener.enableRepeatEvents( false );
 | 
			
		||||
@@ -87,58 +84,55 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
 | 
			
		||||
    public boolean keyPressed( int key, int scancode, int modifiers )
 | 
			
		||||
    {
 | 
			
		||||
        // Forward the tab key to the terminal, rather than moving between controls.
 | 
			
		||||
        if( key == GLFW.GLFW_KEY_TAB && getListener() != null && getListener() == terminalWrapper )
 | 
			
		||||
        if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper )
 | 
			
		||||
        {
 | 
			
		||||
            return getListener().keyPressed( key, scancode, modifiers );
 | 
			
		||||
            return getFocused().keyPressed( key, scancode, modifiers );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return super.keyPressed( key, scancode, modifiers );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
 | 
			
		||||
    private void drawSelectionSlot( boolean advanced )
 | 
			
		||||
    {
 | 
			
		||||
        // Draw term
 | 
			
		||||
        ResourceLocation texture = m_family == ComputerFamily.ADVANCED ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL;
 | 
			
		||||
        terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
 | 
			
		||||
 | 
			
		||||
        // Draw border/inventory
 | 
			
		||||
        RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
 | 
			
		||||
        minecraft.getTextureManager().bindTexture( texture );
 | 
			
		||||
        blit( transform, guiLeft, guiTop, 0, 0, xSize, ySize );
 | 
			
		||||
 | 
			
		||||
        // Draw selection slot
 | 
			
		||||
        int slot = m_container.getSelectedSlot();
 | 
			
		||||
        if( slot >= 0 )
 | 
			
		||||
        {
 | 
			
		||||
            RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
 | 
			
		||||
            int slotX = slot % 4;
 | 
			
		||||
            int slotY = slot / 4;
 | 
			
		||||
            blit( transform,
 | 
			
		||||
                guiLeft + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18,
 | 
			
		||||
                guiTop + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18,
 | 
			
		||||
                0, 217, 24, 24
 | 
			
		||||
            );
 | 
			
		||||
            minecraft.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
 | 
			
		||||
            blit( guiLeft + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18, guiTop + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18, 0, 217, 24, 24 );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks )
 | 
			
		||||
    protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
 | 
			
		||||
    {
 | 
			
		||||
        renderBackground( stack );
 | 
			
		||||
        super.render( stack, mouseX, mouseY, partialTicks );
 | 
			
		||||
        func_230459_a_( stack, mouseX, mouseY );
 | 
			
		||||
        // Draw term
 | 
			
		||||
        boolean advanced = m_family == ComputerFamily.ADVANCED;
 | 
			
		||||
        terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
 | 
			
		||||
 | 
			
		||||
        // Draw border/inventory
 | 
			
		||||
        RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
 | 
			
		||||
        minecraft.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
 | 
			
		||||
        blit( guiLeft, guiTop, 0, 0, xSize, ySize );
 | 
			
		||||
 | 
			
		||||
        drawSelectionSlot( advanced );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void render( int mouseX, int mouseY, float partialTicks )
 | 
			
		||||
    {
 | 
			
		||||
        renderBackground();
 | 
			
		||||
        super.render( mouseX, mouseY, partialTicks );
 | 
			
		||||
        renderHoveredToolTip( mouseX, mouseY );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
 | 
			
		||||
    {
 | 
			
		||||
        return (getListener() != null && getListener().mouseDragged( x, y, button, deltaX, deltaY ))
 | 
			
		||||
        return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
 | 
			
		||||
            || super.mouseDragged( x, y, button, deltaX, deltaY );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void drawGuiContainerForegroundLayer( @Nonnull MatrixStack transform, int mouseX, int mouseY )
 | 
			
		||||
    {
 | 
			
		||||
        // Skip rendering labels.
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,19 +11,13 @@ import dan200.computercraft.client.render.TileEntityMonitorRenderer;
 | 
			
		||||
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
 | 
			
		||||
import dan200.computercraft.client.render.TurtlePlayerRenderer;
 | 
			
		||||
import dan200.computercraft.shared.Registry;
 | 
			
		||||
import dan200.computercraft.shared.common.IColouredItem;
 | 
			
		||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
 | 
			
		||||
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
 | 
			
		||||
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
 | 
			
		||||
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
 | 
			
		||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
 | 
			
		||||
import net.minecraft.client.gui.ScreenManager;
 | 
			
		||||
import net.minecraft.client.renderer.RenderType;
 | 
			
		||||
import net.minecraft.client.renderer.RenderTypeLookup;
 | 
			
		||||
import net.minecraft.item.IItemPropertyGetter;
 | 
			
		||||
import net.minecraft.item.Item;
 | 
			
		||||
import net.minecraft.item.ItemModelsProperties;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraftforge.api.distmarker.Dist;
 | 
			
		||||
import net.minecraftforge.event.world.WorldEvent;
 | 
			
		||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
			
		||||
@@ -32,8 +26,6 @@ import net.minecraftforge.fml.client.registry.RenderingRegistry;
 | 
			
		||||
import net.minecraftforge.fml.common.Mod;
 | 
			
		||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD )
 | 
			
		||||
public final class ComputerCraftProxyClient
 | 
			
		||||
{
 | 
			
		||||
@@ -58,25 +50,6 @@ public final class ComputerCraftProxyClient
 | 
			
		||||
        // TODO: ClientRegistry.bindTileEntityRenderer( TileCable.FACTORY, x -> new TileEntityCableRenderer() );
 | 
			
		||||
 | 
			
		||||
        RenderingRegistry.registerEntityRenderingHandler( Registry.ModEntities.TURTLE_PLAYER.get(), TurtlePlayerRenderer::new );
 | 
			
		||||
 | 
			
		||||
        registerItemProperty( "state",
 | 
			
		||||
            ( stack, world, player ) -> ItemPocketComputer.getState( stack ).ordinal(),
 | 
			
		||||
            Registry.ModItems.POCKET_COMPUTER_NORMAL, Registry.ModItems.POCKET_COMPUTER_ADVANCED
 | 
			
		||||
        );
 | 
			
		||||
        registerItemProperty( "state",
 | 
			
		||||
            ( stack, world, player ) -> IColouredItem.getColourBasic( stack ) != -1 ? 1 : 0,
 | 
			
		||||
            Registry.ModItems.POCKET_COMPUTER_NORMAL, Registry.ModItems.POCKET_COMPUTER_ADVANCED
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SafeVarargs
 | 
			
		||||
    private static void registerItemProperty( String name, IItemPropertyGetter getter, Supplier<? extends Item>... items )
 | 
			
		||||
    {
 | 
			
		||||
        ResourceLocation id = new ResourceLocation( ComputerCraft.MOD_ID, name );
 | 
			
		||||
        for( Supplier<? extends Item> item : items )
 | 
			
		||||
        {
 | 
			
		||||
            ItemModelsProperties.func_239418_a_( item.get(), id, getter );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void registerContainers()
 | 
			
		||||
 
 | 
			
		||||
@@ -14,14 +14,14 @@ import dan200.computercraft.shared.peripheral.modem.wired.CableShapes;
 | 
			
		||||
import dan200.computercraft.shared.util.WorldUtil;
 | 
			
		||||
import net.minecraft.block.BlockState;
 | 
			
		||||
import net.minecraft.client.renderer.ActiveRenderInfo;
 | 
			
		||||
import net.minecraft.client.renderer.Matrix4f;
 | 
			
		||||
import net.minecraft.client.renderer.RenderType;
 | 
			
		||||
import net.minecraft.client.renderer.WorldRenderer;
 | 
			
		||||
import net.minecraft.entity.Entity;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.math.BlockRayTraceResult;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.util.math.shapes.VoxelShape;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
import net.minecraftforge.api.distmarker.Dist;
 | 
			
		||||
import net.minecraftforge.client.event.DrawHighlightEvent;
 | 
			
		||||
@@ -63,7 +63,7 @@ public final class CableHighlightRenderer
 | 
			
		||||
            ? CableShapes.getModemShape( state )
 | 
			
		||||
            : CableShapes.getCableShape( state );
 | 
			
		||||
 | 
			
		||||
        Vector3d cameraPos = info.getProjectedView();
 | 
			
		||||
        Vec3d cameraPos = info.getProjectedView();
 | 
			
		||||
        double xOffset = pos.getX() - cameraPos.getX();
 | 
			
		||||
        double yOffset = pos.getY() - cameraPos.getY();
 | 
			
		||||
        double zOffset = pos.getZ() - cameraPos.getZ();
 | 
			
		||||
 
 | 
			
		||||
@@ -11,10 +11,10 @@ import com.mojang.blaze3d.vertex.IVertexBuilder;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
			
		||||
import net.minecraft.client.renderer.BufferBuilder;
 | 
			
		||||
import net.minecraft.client.renderer.Matrix4f;
 | 
			
		||||
import net.minecraft.client.renderer.Tessellator;
 | 
			
		||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import org.lwjgl.opengl.GL11;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,12 +10,12 @@ import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.client.entity.player.AbstractClientPlayerEntity;
 | 
			
		||||
import net.minecraft.client.renderer.FirstPersonRenderer;
 | 
			
		||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
 | 
			
		||||
import net.minecraft.client.renderer.Vector3f;
 | 
			
		||||
import net.minecraft.entity.player.PlayerEntity;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.util.Hand;
 | 
			
		||||
import net.minecraft.util.HandSide;
 | 
			
		||||
import net.minecraft.util.math.MathHelper;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3f;
 | 
			
		||||
 | 
			
		||||
public abstract class ItemMapLikeRenderer
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -15,13 +15,9 @@ import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
			
		||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
 | 
			
		||||
import dan200.computercraft.shared.util.Colour;
 | 
			
		||||
import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.client.renderer.BufferBuilder;
 | 
			
		||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
 | 
			
		||||
import net.minecraft.client.renderer.Tessellator;
 | 
			
		||||
import net.minecraft.client.renderer.*;
 | 
			
		||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3f;
 | 
			
		||||
import net.minecraftforge.api.distmarker.Dist;
 | 
			
		||||
import net.minecraftforge.client.event.RenderHandEvent;
 | 
			
		||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
			
		||||
@@ -119,6 +115,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
 | 
			
		||||
 | 
			
		||||
    private static void renderFrame( Matrix4f transform, ComputerFamily family, int colour, int width, int height )
 | 
			
		||||
    {
 | 
			
		||||
        RenderSystem.enableBlend();
 | 
			
		||||
        Minecraft.getInstance().getTextureManager()
 | 
			
		||||
            .bindTexture( colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family ) );
 | 
			
		||||
 | 
			
		||||
@@ -137,7 +134,6 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
 | 
			
		||||
 | 
			
		||||
    private static void renderLight( Matrix4f transform, int colour, int width, int height )
 | 
			
		||||
    {
 | 
			
		||||
        RenderSystem.enableBlend();
 | 
			
		||||
        RenderSystem.disableTexture();
 | 
			
		||||
 | 
			
		||||
        float r = ((colour >>> 16) & 0xFF) / 255.0f;
 | 
			
		||||
 
 | 
			
		||||
@@ -9,9 +9,9 @@ import com.mojang.blaze3d.matrix.MatrixStack;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.shared.media.items.ItemPrintout;
 | 
			
		||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
 | 
			
		||||
import net.minecraft.client.renderer.Matrix4f;
 | 
			
		||||
import net.minecraft.client.renderer.Vector3f;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3f;
 | 
			
		||||
import net.minecraftforge.api.distmarker.Dist;
 | 
			
		||||
import net.minecraftforge.client.event.RenderHandEvent;
 | 
			
		||||
import net.minecraftforge.client.event.RenderItemInFrameEvent;
 | 
			
		||||
 
 | 
			
		||||
@@ -9,12 +9,12 @@ import com.mojang.blaze3d.matrix.MatrixStack;
 | 
			
		||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
 | 
			
		||||
import net.minecraft.client.renderer.Matrix4f;
 | 
			
		||||
import net.minecraft.client.renderer.RenderType;
 | 
			
		||||
import net.minecraft.tileentity.TileEntity;
 | 
			
		||||
import net.minecraft.util.Direction;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
import net.minecraftforge.api.distmarker.Dist;
 | 
			
		||||
import net.minecraftforge.client.event.DrawHighlightEvent;
 | 
			
		||||
@@ -61,7 +61,7 @@ public final class MonitorHighlightRenderer
 | 
			
		||||
        if( monitor.getYIndex() != monitor.getHeight() - 1 ) faces.remove( monitor.getDown() );
 | 
			
		||||
 | 
			
		||||
        MatrixStack transformStack = event.getMatrix();
 | 
			
		||||
        Vector3d cameraPos = event.getInfo().getProjectedView();
 | 
			
		||||
        Vec3d cameraPos = event.getInfo().getProjectedView();
 | 
			
		||||
        transformStack.push();
 | 
			
		||||
        transformStack.translate( pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ() );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -12,8 +12,8 @@ import com.mojang.blaze3d.systems.RenderSystem;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
 | 
			
		||||
import dan200.computercraft.shared.util.Palette;
 | 
			
		||||
import net.minecraft.client.renderer.Matrix4f;
 | 
			
		||||
import net.minecraft.client.renderer.texture.TextureUtil;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import org.lwjgl.BufferUtils;
 | 
			
		||||
import org.lwjgl.opengl.GL13;
 | 
			
		||||
import org.lwjgl.opengl.GL20;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,11 +10,11 @@ import dan200.computercraft.client.gui.FixedWidthFontRenderer;
 | 
			
		||||
import dan200.computercraft.core.terminal.TextBuffer;
 | 
			
		||||
import dan200.computercraft.shared.util.Palette;
 | 
			
		||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
 | 
			
		||||
import net.minecraft.client.renderer.Matrix4f;
 | 
			
		||||
import net.minecraft.client.renderer.RenderState;
 | 
			
		||||
import net.minecraft.client.renderer.RenderType;
 | 
			
		||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import org.lwjgl.opengl.GL11;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
 | 
			
		||||
 
 | 
			
		||||
@@ -17,19 +17,13 @@ import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
 | 
			
		||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
 | 
			
		||||
import dan200.computercraft.shared.util.Colour;
 | 
			
		||||
import dan200.computercraft.shared.util.DirectionUtil;
 | 
			
		||||
import net.minecraft.client.renderer.BufferBuilder;
 | 
			
		||||
import net.minecraft.client.renderer.GLAllocation;
 | 
			
		||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
 | 
			
		||||
import net.minecraft.client.renderer.Tessellator;
 | 
			
		||||
import net.minecraft.client.renderer.*;
 | 
			
		||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
 | 
			
		||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
 | 
			
		||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
 | 
			
		||||
import net.minecraft.client.renderer.vertex.VertexBuffer;
 | 
			
		||||
import net.minecraft.util.Direction;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import net.minecraft.util.math.vector.TransformationMatrix;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3f;
 | 
			
		||||
import org.lwjgl.opengl.GL11;
 | 
			
		||||
import org.lwjgl.opengl.GL13;
 | 
			
		||||
import org.lwjgl.opengl.GL20;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,8 @@ import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.client.gui.FontRenderer;
 | 
			
		||||
import net.minecraft.client.renderer.Atlases;
 | 
			
		||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
 | 
			
		||||
import net.minecraft.client.renderer.Matrix4f;
 | 
			
		||||
import net.minecraft.client.renderer.Vector3f;
 | 
			
		||||
import net.minecraft.client.renderer.model.BakedQuad;
 | 
			
		||||
import net.minecraft.client.renderer.model.IBakedModel;
 | 
			
		||||
import net.minecraft.client.renderer.model.ModelManager;
 | 
			
		||||
@@ -29,9 +31,7 @@ import net.minecraft.util.Direction;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.math.BlockRayTraceResult;
 | 
			
		||||
import net.minecraft.util.math.RayTraceResult;
 | 
			
		||||
import net.minecraft.util.math.vector.Matrix4f;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3f;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraftforge.client.model.data.EmptyModelData;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -99,7 +99,7 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
 | 
			
		||||
        transform.push();
 | 
			
		||||
 | 
			
		||||
        // Setup the transform.
 | 
			
		||||
        Vector3d offset = turtle.getRenderOffset( partialTicks );
 | 
			
		||||
        Vec3d offset = turtle.getRenderOffset( partialTicks );
 | 
			
		||||
        float yaw = turtle.getRenderYaw( partialTicks );
 | 
			
		||||
        transform.translate( offset.x, offset.y, offset.z );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -57,16 +57,16 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public Collection<RenderMaterial> getTextures( IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors )
 | 
			
		||||
        public Collection<Material> getTextures( IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors )
 | 
			
		||||
        {
 | 
			
		||||
            Set<RenderMaterial> materials = new HashSet<>();
 | 
			
		||||
            Set<Material> materials = new HashSet<>();
 | 
			
		||||
            materials.addAll( modelGetter.apply( family ).getTextures( modelGetter, missingTextureErrors ) );
 | 
			
		||||
            materials.addAll( modelGetter.apply( COLOUR_TURTLE_MODEL ).getTextures( modelGetter, missingTextureErrors ) );
 | 
			
		||||
            return materials;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public IBakedModel bake( IModelConfiguration owner, ModelBakery bakery, Function<RenderMaterial, TextureAtlasSprite> spriteGetter, IModelTransform transform, ItemOverrideList overrides, ResourceLocation modelLocation )
 | 
			
		||||
        public IBakedModel bake( IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform transform, ItemOverrideList overrides, ResourceLocation modelLocation )
 | 
			
		||||
        {
 | 
			
		||||
            return new TurtleSmartItemModel(
 | 
			
		||||
                bakery.getBakedModel( family, transform, spriteGetter ),
 | 
			
		||||
 
 | 
			
		||||
@@ -7,12 +7,12 @@ package dan200.computercraft.client.render;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.api.client.TransformedModel;
 | 
			
		||||
import net.minecraft.block.BlockState;
 | 
			
		||||
import net.minecraft.client.renderer.TransformationMatrix;
 | 
			
		||||
import net.minecraft.client.renderer.model.BakedQuad;
 | 
			
		||||
import net.minecraft.client.renderer.model.IBakedModel;
 | 
			
		||||
import net.minecraft.client.renderer.model.ItemOverrideList;
 | 
			
		||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
 | 
			
		||||
import net.minecraft.util.Direction;
 | 
			
		||||
import net.minecraft.util.math.vector.TransformationMatrix;
 | 
			
		||||
import net.minecraftforge.client.model.data.EmptyModelData;
 | 
			
		||||
import net.minecraftforge.client.model.data.IModelData;
 | 
			
		||||
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
 | 
			
		||||
 
 | 
			
		||||
@@ -15,14 +15,14 @@ import dan200.computercraft.shared.util.Holiday;
 | 
			
		||||
import dan200.computercraft.shared.util.HolidayUtil;
 | 
			
		||||
import net.minecraft.block.BlockState;
 | 
			
		||||
import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.client.renderer.TransformationMatrix;
 | 
			
		||||
import net.minecraft.client.renderer.model.*;
 | 
			
		||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
 | 
			
		||||
import net.minecraft.client.world.ClientWorld;
 | 
			
		||||
import net.minecraft.entity.LivingEntity;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.util.Direction;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.math.vector.TransformationMatrix;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
import net.minecraftforge.client.model.data.IModelData;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -109,7 +109,7 @@ public class TurtleSmartItemModel implements IBakedModel
 | 
			
		||||
        {
 | 
			
		||||
            @Nonnull
 | 
			
		||||
            @Override
 | 
			
		||||
            public IBakedModel func_239290_a_( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable ClientWorld world, @Nullable LivingEntity entity )
 | 
			
		||||
            public IBakedModel getModelWithOverrides( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable World world, @Nullable LivingEntity entity )
 | 
			
		||||
            {
 | 
			
		||||
                ItemTurtle turtle = (ItemTurtle) stack.getItem();
 | 
			
		||||
                int colour = turtle.getColour( stack );
 | 
			
		||||
 
 | 
			
		||||
@@ -385,8 +385,8 @@ public class FSAPI implements ILuaAPI
 | 
			
		||||
     *
 | 
			
		||||
     * @param path The path to check the free space for.
 | 
			
		||||
     * @return The amount of free space available, in bytes.
 | 
			
		||||
     * @throws LuaException If the path doesn't exist.
 | 
			
		||||
     * @cc.treturn number|"unlimited" The amount of free space available, in bytes, or "unlimited".
 | 
			
		||||
     * @throws LuaException If the path doesn't exist.
 | 
			
		||||
     */
 | 
			
		||||
    @LuaFunction
 | 
			
		||||
    public final Object getFreeSpace( String path ) throws LuaException
 | 
			
		||||
@@ -479,6 +479,7 @@ public class FSAPI implements ILuaAPI
 | 
			
		||||
            BasicFileAttributes attributes = fileSystem.getAttributes( path );
 | 
			
		||||
            Map<String, Object> result = new HashMap<>();
 | 
			
		||||
            result.put( "modification", getFileTime( attributes.lastModifiedTime() ) );
 | 
			
		||||
            result.put( "modified", getFileTime( attributes.lastModifiedTime() ) );
 | 
			
		||||
            result.put( "created", getFileTime( attributes.creationTime() ) );
 | 
			
		||||
            result.put( "size", attributes.isDirectory() ? 0 : attributes.size() );
 | 
			
		||||
            result.put( "isDir", attributes.isDirectory() );
 | 
			
		||||
 
 | 
			
		||||
@@ -171,12 +171,18 @@ public class OSAPI implements ILuaAPI
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Starts a timer that will run for the specified number of seconds. Once
 | 
			
		||||
     * the timer fires, a timer event will be added to the queue with the ID
 | 
			
		||||
     * returned from this function as the first parameter.
 | 
			
		||||
     * the timer fires, a {@code timer} event will be added to the queue with
 | 
			
		||||
     * the ID returned from this function as the first parameter.
 | 
			
		||||
     *
 | 
			
		||||
     * As with @{os.sleep|sleep}, {@code timer} will automatically be rounded up
 | 
			
		||||
     * to the nearest multiple of 0.05 seconds, as it waits for a fixed amount
 | 
			
		||||
     * of world ticks.
 | 
			
		||||
     *
 | 
			
		||||
     * @param timer The number of seconds until the timer fires.
 | 
			
		||||
     * @return The ID of the new timer.
 | 
			
		||||
     * @return The ID of the new timer. This can be used to filter the
 | 
			
		||||
     *   {@code timer} event, or {@link #cancelTimer cancel the timer}.
 | 
			
		||||
     * @throws LuaException If the time is below zero.
 | 
			
		||||
     * @see #cancelTimer To cancel a timer.
 | 
			
		||||
     */
 | 
			
		||||
    @LuaFunction
 | 
			
		||||
    public final int startTimer( double timer ) throws LuaException
 | 
			
		||||
@@ -199,11 +205,14 @@ public class OSAPI implements ILuaAPI
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets an alarm that will fire at the specified world time. When it fires,
 | 
			
		||||
     * an alarm event will be added to the event queue.
 | 
			
		||||
     * an {@code alarm} event will be added to the event queue with the ID
 | 
			
		||||
     * returned from this function as the first parameter.
 | 
			
		||||
     *
 | 
			
		||||
     * @param time The time at which to fire the alarm, in the range [0.0, 24.0).
 | 
			
		||||
     * @return The ID of the alarm that was set.
 | 
			
		||||
     * @return The ID of the new alarm. This can be used to filter the
 | 
			
		||||
     *   {@code alarm} event, or {@link #cancelAlarm cancel the alarm}.
 | 
			
		||||
     * @throws LuaException If the time is out of range.
 | 
			
		||||
     * @see #cancelAlarm To cancel an alarm.
 | 
			
		||||
     */
 | 
			
		||||
    @LuaFunction
 | 
			
		||||
    public final int setAlarm( double time ) throws LuaException
 | 
			
		||||
@@ -303,10 +312,10 @@ public class OSAPI implements ILuaAPI
 | 
			
		||||
     * always be in the range [0.0, 24.0).
 | 
			
		||||
     *
 | 
			
		||||
     * * If called with {@code ingame}, the current world time will be returned.
 | 
			
		||||
     * This is the default if nothing is passed.
 | 
			
		||||
     *   This is the default if nothing is passed.
 | 
			
		||||
     * * If called with {@code utc}, returns the hour of the day in UTC time.
 | 
			
		||||
     * * If called with {@code local}, returns the hour of the day in the
 | 
			
		||||
     * timezone the server is located in.
 | 
			
		||||
     *   timezone the server is located in.
 | 
			
		||||
     *
 | 
			
		||||
     * This function can also be called with a table returned from {@link #date},
 | 
			
		||||
     * which will convert the date fields into a UNIX timestamp (number of
 | 
			
		||||
@@ -314,9 +323,9 @@ public class OSAPI implements ILuaAPI
 | 
			
		||||
     *
 | 
			
		||||
     * @param args The locale of the time, or a table filled by {@code os.date("*t")} to decode. Defaults to {@code ingame} locale if not specified.
 | 
			
		||||
     * @return The hour of the selected locale, or a UNIX timestamp from the table, depending on the argument passed in.
 | 
			
		||||
     * @throws LuaException If an invalid locale is passed.
 | 
			
		||||
     * @cc.tparam [opt] string|table locale The locale of the time, or a table filled by {@code os.date("*t")} to decode. Defaults to {@code ingame} locale if not specified.
 | 
			
		||||
     * @see #date To get a date table that can be converted with this function.
 | 
			
		||||
     * @throws LuaException If an invalid locale is passed.
 | 
			
		||||
     */
 | 
			
		||||
    @LuaFunction
 | 
			
		||||
    public final Object time( IArguments args ) throws LuaException
 | 
			
		||||
@@ -342,11 +351,11 @@ public class OSAPI implements ILuaAPI
 | 
			
		||||
     * Returns the day depending on the locale specified.
 | 
			
		||||
     *
 | 
			
		||||
     * * If called with {@code ingame}, returns the number of days since the
 | 
			
		||||
     * world was created. This is the default.
 | 
			
		||||
     *   world was created. This is the default.
 | 
			
		||||
     * * If called with {@code utc}, returns the number of days since 1 January
 | 
			
		||||
     * 1970 in the UTC timezone.
 | 
			
		||||
     *   1970 in the UTC timezone.
 | 
			
		||||
     * * If called with {@code local}, returns the number of days since 1
 | 
			
		||||
     * January 1970 in the server's local timezone.
 | 
			
		||||
     *   January 1970 in the server's local timezone.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args The locale to get the day for. Defaults to {@code ingame} if not set.
 | 
			
		||||
     * @return The day depending on the selected locale.
 | 
			
		||||
@@ -372,11 +381,11 @@ public class OSAPI implements ILuaAPI
 | 
			
		||||
     * Returns the number of seconds since an epoch depending on the locale.
 | 
			
		||||
     *
 | 
			
		||||
     * * If called with {@code ingame}, returns the number of seconds since the
 | 
			
		||||
     * world was created. This is the default.
 | 
			
		||||
     *   world was created. This is the default.
 | 
			
		||||
     * * If called with {@code utc}, returns the number of seconds since 1
 | 
			
		||||
     * January 1970 in the UTC timezone.
 | 
			
		||||
     *   January 1970 in the UTC timezone.
 | 
			
		||||
     * * If called with {@code local}, returns the number of seconds since 1
 | 
			
		||||
     * January 1970 in the server's local timezone.
 | 
			
		||||
     *   January 1970 in the server's local timezone.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args The locale to get the seconds for. Defaults to {@code ingame} if not set.
 | 
			
		||||
     * @return The seconds since the epoch depending on the selected locale.
 | 
			
		||||
@@ -426,7 +435,7 @@ public class OSAPI implements ILuaAPI
 | 
			
		||||
     * timestamp (days since 1 January 1970) with {@link #date}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param formatA The format of the string to return. This defaults to {@code %c}, which expands to a string similar to "Sat Dec 24 16:58:00 2011".
 | 
			
		||||
     * @param timeA   The time to convert to a string. This defaults to the current time.
 | 
			
		||||
     * @param timeA The time to convert to a string. This defaults to the current time.
 | 
			
		||||
     * @return The resulting format string.
 | 
			
		||||
     * @throws LuaException If an invalid format is passed.
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -24,14 +24,14 @@ public class CheckUrl extends Resource<CheckUrl>
 | 
			
		||||
 | 
			
		||||
    private final IAPIEnvironment environment;
 | 
			
		||||
    private final String address;
 | 
			
		||||
    private final String host;
 | 
			
		||||
    private final URI uri;
 | 
			
		||||
 | 
			
		||||
    public CheckUrl( ResourceGroup<CheckUrl> limiter, IAPIEnvironment environment, String address, URI uri )
 | 
			
		||||
    {
 | 
			
		||||
        super( limiter );
 | 
			
		||||
        this.environment = environment;
 | 
			
		||||
        this.address = address;
 | 
			
		||||
        host = uri.getHost();
 | 
			
		||||
        this.uri = uri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void run()
 | 
			
		||||
@@ -47,8 +47,9 @@ public class CheckUrl extends Resource<CheckUrl>
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            InetSocketAddress netAddress = NetworkUtils.getAddress( host, 80, false );
 | 
			
		||||
            NetworkUtils.getOptions( host, netAddress );
 | 
			
		||||
            boolean ssl = uri.getScheme().equalsIgnoreCase( "https" );
 | 
			
		||||
            InetSocketAddress netAddress = NetworkUtils.getAddress( uri, ssl );
 | 
			
		||||
            NetworkUtils.getOptions( uri.getHost(), netAddress );
 | 
			
		||||
 | 
			
		||||
            if( tryClose() ) environment.queueEvent( EVENT, address, true );
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ import io.netty.handler.ssl.SslContextBuilder;
 | 
			
		||||
import javax.net.ssl.SSLException;
 | 
			
		||||
import javax.net.ssl.TrustManagerFactory;
 | 
			
		||||
import java.net.InetSocketAddress;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.security.KeyStore;
 | 
			
		||||
import java.util.concurrent.ExecutorService;
 | 
			
		||||
import java.util.concurrent.SynchronousQueue;
 | 
			
		||||
@@ -99,6 +100,21 @@ public final class NetworkUtils
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a {@link InetSocketAddress} from a {@link java.net.URI}.
 | 
			
		||||
     *
 | 
			
		||||
     * Note, this may require a DNS lookup, and so should not be executed on the main CC thread.
 | 
			
		||||
     *
 | 
			
		||||
     * @param uri The URI to fetch.
 | 
			
		||||
     * @param ssl Whether to connect with SSL. This is used to find the default port if not otherwise specified.
 | 
			
		||||
     * @return The resolved address.
 | 
			
		||||
     * @throws HTTPRequestException If the host is not malformed.
 | 
			
		||||
     */
 | 
			
		||||
    public static InetSocketAddress getAddress( URI uri, boolean ssl ) throws HTTPRequestException
 | 
			
		||||
    {
 | 
			
		||||
        return getAddress( uri.getHost(), uri.getPort(), ssl );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a {@link InetSocketAddress} from the resolved {@code host} and port.
 | 
			
		||||
     *
 | 
			
		||||
@@ -128,7 +144,7 @@ public final class NetworkUtils
 | 
			
		||||
     */
 | 
			
		||||
    public static Options getOptions( String host, InetSocketAddress address ) throws HTTPRequestException
 | 
			
		||||
    {
 | 
			
		||||
        Options options = AddressRule.apply( ComputerCraft.httpRules, host, address.getAddress() );
 | 
			
		||||
        Options options = AddressRule.apply( ComputerCraft.httpRules, host, address );
 | 
			
		||||
        if( options.action == Action.DENY ) throw new HTTPRequestException( "Domain not permitted" );
 | 
			
		||||
        return options;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.net.Inet6Address;
 | 
			
		||||
import java.net.InetAddress;
 | 
			
		||||
import java.net.InetSocketAddress;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -52,17 +53,23 @@ public final class AddressRule
 | 
			
		||||
 | 
			
		||||
    private final HostRange ip;
 | 
			
		||||
    private final Pattern domainPattern;
 | 
			
		||||
    private final Integer port;
 | 
			
		||||
    private final PartialOptions partial;
 | 
			
		||||
 | 
			
		||||
    private AddressRule( @Nullable HostRange ip, @Nullable Pattern domainPattern, @Nonnull PartialOptions partial )
 | 
			
		||||
    private AddressRule(
 | 
			
		||||
        @Nullable HostRange ip,
 | 
			
		||||
        @Nullable Pattern domainPattern,
 | 
			
		||||
        @Nullable Integer port,
 | 
			
		||||
        @Nonnull PartialOptions partial )
 | 
			
		||||
    {
 | 
			
		||||
        this.ip = ip;
 | 
			
		||||
        this.domainPattern = domainPattern;
 | 
			
		||||
        this.partial = partial;
 | 
			
		||||
        this.port = port;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public static AddressRule parse( String filter, @Nonnull PartialOptions partial )
 | 
			
		||||
    public static AddressRule parse( String filter, @Nullable Integer port, @Nonnull PartialOptions partial )
 | 
			
		||||
    {
 | 
			
		||||
        int cidr = filter.indexOf( '/' );
 | 
			
		||||
        if( cidr >= 0 )
 | 
			
		||||
@@ -117,24 +124,27 @@ public final class AddressRule
 | 
			
		||||
                size -= 8;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new AddressRule( new HostRange( minBytes, maxBytes ), null, partial );
 | 
			
		||||
            return new AddressRule( new HostRange( minBytes, maxBytes ), null, port, partial );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            Pattern pattern = Pattern.compile( "^\\Q" + filter.replaceAll( "\\*", "\\\\E.*\\\\Q" ) + "\\E$" );
 | 
			
		||||
            return new AddressRule( null, pattern, partial );
 | 
			
		||||
            return new AddressRule( null, pattern, port, partial );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine whether the given address matches a series of patterns.
 | 
			
		||||
     *
 | 
			
		||||
     * @param domain  The domain to match
 | 
			
		||||
     * @param address The address to check.
 | 
			
		||||
     * @param domain        The domain to match
 | 
			
		||||
     * @param socketAddress The address to check.
 | 
			
		||||
     * @return Whether it matches any of these patterns.
 | 
			
		||||
     */
 | 
			
		||||
    private boolean matches( String domain, InetAddress address )
 | 
			
		||||
    private boolean matches( String domain, InetSocketAddress socketAddress )
 | 
			
		||||
    {
 | 
			
		||||
        InetAddress address = socketAddress.getAddress();
 | 
			
		||||
        if( port != null && port != socketAddress.getPort() ) return false;
 | 
			
		||||
 | 
			
		||||
        if( domainPattern != null )
 | 
			
		||||
        {
 | 
			
		||||
            if( domainPattern.matcher( domain ).matches() ) return true;
 | 
			
		||||
@@ -155,7 +165,7 @@ public final class AddressRule
 | 
			
		||||
        return ip != null && ip.contains( address );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Options apply( Iterable<? extends AddressRule> rules, String domain, InetAddress address )
 | 
			
		||||
    public static Options apply( Iterable<? extends AddressRule> rules, String domain, InetSocketAddress address )
 | 
			
		||||
    {
 | 
			
		||||
        PartialOptions options = null;
 | 
			
		||||
        boolean hasMany = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -49,12 +49,14 @@ public class AddressRuleConfig
 | 
			
		||||
    public static boolean checkRule( UnmodifiableConfig builder )
 | 
			
		||||
    {
 | 
			
		||||
        String hostObj = get( builder, "host", String.class ).orElse( null );
 | 
			
		||||
        Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
 | 
			
		||||
        return hostObj != null && checkEnum( builder, "action", Action.class )
 | 
			
		||||
            && check( builder, "port", Number.class )
 | 
			
		||||
            && check( builder, "timeout", Number.class )
 | 
			
		||||
            && check( builder, "max_upload", Number.class )
 | 
			
		||||
            && check( builder, "max_download", Number.class )
 | 
			
		||||
            && check( builder, "websocket_message", Number.class )
 | 
			
		||||
            && AddressRule.parse( hostObj, PartialOptions.DEFAULT ) != null;
 | 
			
		||||
            && AddressRule.parse( hostObj, port, PartialOptions.DEFAULT ) != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
@@ -64,6 +66,7 @@ public class AddressRuleConfig
 | 
			
		||||
        if( hostObj == null ) return null;
 | 
			
		||||
 | 
			
		||||
        Action action = getEnum( builder, "action", Action.class ).orElse( null );
 | 
			
		||||
        Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
 | 
			
		||||
        Integer timeout = get( builder, "timeout", Number.class ).map( Number::intValue ).orElse( null );
 | 
			
		||||
        Long maxUpload = get( builder, "max_upload", Number.class ).map( Number::longValue ).orElse( null );
 | 
			
		||||
        Long maxDownload = get( builder, "max_download", Number.class ).map( Number::longValue ).orElse( null );
 | 
			
		||||
@@ -77,7 +80,7 @@ public class AddressRuleConfig
 | 
			
		||||
            websocketMessage
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return AddressRule.parse( hostObj, options );
 | 
			
		||||
        return AddressRule.parse( hostObj, port, options );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static <T> boolean check( UnmodifiableConfig config, String field, Class<T> klass )
 | 
			
		||||
 
 | 
			
		||||
@@ -136,7 +136,7 @@ public class HttpRequest extends Resource<HttpRequest>
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boolean ssl = uri.getScheme().equalsIgnoreCase( "https" );
 | 
			
		||||
            InetSocketAddress socketAddress = NetworkUtils.getAddress( uri.getHost(), uri.getPort(), ssl );
 | 
			
		||||
            InetSocketAddress socketAddress = NetworkUtils.getAddress( uri, ssl );
 | 
			
		||||
            Options options = NetworkUtils.getOptions( uri.getHost(), socketAddress );
 | 
			
		||||
            SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -129,8 +129,7 @@ public class Websocket extends Resource<Websocket>
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boolean ssl = uri.getScheme().equalsIgnoreCase( "wss" );
 | 
			
		||||
 | 
			
		||||
            InetSocketAddress socketAddress = NetworkUtils.getAddress( uri.getHost(), uri.getPort(), ssl );
 | 
			
		||||
            InetSocketAddress socketAddress = NetworkUtils.getAddress( uri, ssl );
 | 
			
		||||
            Options options = NetworkUtils.getOptions( uri.getHost(), socketAddress );
 | 
			
		||||
            SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -395,14 +395,7 @@ public final class ComputerThread
 | 
			
		||||
                            executor.timeout.hardAbort();
 | 
			
		||||
                            executor.abort();
 | 
			
		||||
 | 
			
		||||
                            if( afterHardAbort >= ABORT_TIMEOUT )
 | 
			
		||||
                            {
 | 
			
		||||
                                // If we've hard aborted but we're still not dead, dump the stack trace and interrupt
 | 
			
		||||
                                // the task.
 | 
			
		||||
                                timeoutTask( executor, runner.owner, afterStart );
 | 
			
		||||
                                runner.owner.interrupt();
 | 
			
		||||
                            }
 | 
			
		||||
                            else if( afterHardAbort >= ABORT_TIMEOUT * 2 )
 | 
			
		||||
                            if( afterHardAbort >= ABORT_TIMEOUT * 2 )
 | 
			
		||||
                            {
 | 
			
		||||
                                // If we've hard aborted and interrupted, and we're still not dead, then mark the runner
 | 
			
		||||
                                // as dead, finish off the task, and spawn a new runner.
 | 
			
		||||
@@ -421,6 +414,13 @@ public final class ComputerThread
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            else if( afterHardAbort >= ABORT_TIMEOUT )
 | 
			
		||||
                            {
 | 
			
		||||
                                // If we've hard aborted but we're still not dead, dump the stack trace and interrupt
 | 
			
		||||
                                // the task.
 | 
			
		||||
                                timeoutTask( executor, runner.owner, afterStart );
 | 
			
		||||
                                runner.owner.interrupt();
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -124,7 +124,7 @@ public class FileSystemWrapperMount implements IFileSystem
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            return m_filesystem.exists( path );
 | 
			
		||||
            return m_filesystem.isDir( path );
 | 
			
		||||
        }
 | 
			
		||||
        catch( FileSystemException e )
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -83,9 +83,9 @@ class VarargArguments implements IArguments
 | 
			
		||||
    public ByteBuffer getBytes( int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        LuaValue value = varargs.arg( index + 1 );
 | 
			
		||||
        if( !(value instanceof LuaString) ) throw LuaValues.badArgument( index, "string", value.typeName() );
 | 
			
		||||
        if( !(value instanceof LuaBaseString) ) throw LuaValues.badArgument( index, "string", value.typeName() );
 | 
			
		||||
 | 
			
		||||
        LuaString str = (LuaString) value;
 | 
			
		||||
        LuaString str = ((LuaBaseString) value).strvalue();
 | 
			
		||||
        return ByteBuffer.wrap( str.bytes, str.offset, str.length ).asReadOnlyBuffer();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -94,9 +94,9 @@ class VarargArguments implements IArguments
 | 
			
		||||
    {
 | 
			
		||||
        LuaValue value = varargs.arg( index + 1 );
 | 
			
		||||
        if( value.isNil() ) return Optional.empty();
 | 
			
		||||
        if( !(value instanceof LuaString) ) throw LuaValues.badArgument( index, "string", value.typeName() );
 | 
			
		||||
        if( !(value instanceof LuaBaseString) ) throw LuaValues.badArgument( index, "string", value.typeName() );
 | 
			
		||||
 | 
			
		||||
        LuaString str = (LuaString) value;
 | 
			
		||||
        LuaString str = ((LuaBaseString) value).strvalue();
 | 
			
		||||
        return Optional.of( ByteBuffer.wrap( str.bytes, str.offset, str.length ).asReadOnlyBuffer() );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@
 | 
			
		||||
package dan200.computercraft.data;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
 | 
			
		||||
import net.minecraft.data.BlockTagsProvider;
 | 
			
		||||
import net.minecraft.data.DataGenerator;
 | 
			
		||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
			
		||||
import net.minecraftforge.fml.common.Mod;
 | 
			
		||||
@@ -24,6 +23,6 @@ public class Generators
 | 
			
		||||
        DataGenerator generator = event.getGenerator();
 | 
			
		||||
        generator.addProvider( new Recipes( generator ) );
 | 
			
		||||
        generator.addProvider( new LootTables( generator ) );
 | 
			
		||||
        generator.addProvider( new Tags( generator, new BlockTagsProvider( generator ) ) );
 | 
			
		||||
        generator.addProvider( new Tags( generator ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,11 +13,11 @@ import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import net.minecraft.data.DataGenerator;
 | 
			
		||||
import net.minecraft.data.DirectoryCache;
 | 
			
		||||
import net.minecraft.data.IDataProvider;
 | 
			
		||||
import net.minecraft.loot.LootParameterSets;
 | 
			
		||||
import net.minecraft.loot.LootTable;
 | 
			
		||||
import net.minecraft.loot.LootTableManager;
 | 
			
		||||
import net.minecraft.loot.ValidationTracker;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootParameterSets;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootTable;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootTableManager;
 | 
			
		||||
import net.minecraft.world.storage.loot.ValidationTracker;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 
 | 
			
		||||
@@ -14,10 +14,10 @@ import dan200.computercraft.shared.data.PlayerCreativeLootCondition;
 | 
			
		||||
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
 | 
			
		||||
import net.minecraft.block.Block;
 | 
			
		||||
import net.minecraft.data.DataGenerator;
 | 
			
		||||
import net.minecraft.loot.*;
 | 
			
		||||
import net.minecraft.loot.conditions.Alternative;
 | 
			
		||||
import net.minecraft.loot.conditions.SurvivesExplosion;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.storage.loot.*;
 | 
			
		||||
import net.minecraft.world.storage.loot.conditions.Alternative;
 | 
			
		||||
import net.minecraft.world.storage.loot.conditions.SurvivesExplosion;
 | 
			
		||||
import net.minecraftforge.fml.RegistryObject;
 | 
			
		||||
 | 
			
		||||
import java.util.function.BiConsumer;
 | 
			
		||||
@@ -77,9 +77,9 @@ public class LootTables extends LootTableProvider
 | 
			
		||||
                .rolls( ConstantRange.of( 1 ) )
 | 
			
		||||
                .addEntry( DynamicLootEntry.func_216162_a( new ResourceLocation( ComputerCraft.MOD_ID, "computer" ) ) )
 | 
			
		||||
                .acceptCondition( Alternative.builder(
 | 
			
		||||
                    BlockNamedEntityLootCondition.BUILDER,
 | 
			
		||||
                    HasComputerIdLootCondition.BUILDER,
 | 
			
		||||
                    PlayerCreativeLootCondition.BUILDER.inverted()
 | 
			
		||||
                    BlockNamedEntityLootCondition.builder(),
 | 
			
		||||
                    HasComputerIdLootCondition.builder(),
 | 
			
		||||
                    PlayerCreativeLootCondition.builder().inverted()
 | 
			
		||||
                ) )
 | 
			
		||||
            ).build() );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ import net.minecraft.advancements.criterion.ItemPredicate;
 | 
			
		||||
import net.minecraft.block.Blocks;
 | 
			
		||||
import net.minecraft.data.*;
 | 
			
		||||
import net.minecraft.item.*;
 | 
			
		||||
import net.minecraft.tags.ITag;
 | 
			
		||||
import net.minecraft.tags.Tag;
 | 
			
		||||
import net.minecraft.util.IItemProvider;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraftforge.common.Tags;
 | 
			
		||||
@@ -309,7 +309,7 @@ public class Recipes extends RecipeProvider
 | 
			
		||||
        return DyeColor.byId( 15 - colour.ordinal() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static InventoryChangeTrigger.Instance inventoryChange( ITag<Item> stack )
 | 
			
		||||
    private static InventoryChangeTrigger.Instance inventoryChange( Tag<Item> stack )
 | 
			
		||||
    {
 | 
			
		||||
        return InventoryChangeTrigger.Instance.forItems( ItemPredicate.Builder.create().tag( stack ).build() );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -8,54 +8,46 @@ package dan200.computercraft.data;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.shared.Registry;
 | 
			
		||||
import net.minecraft.data.BlockTagsProvider;
 | 
			
		||||
import net.minecraft.data.DataGenerator;
 | 
			
		||||
import net.minecraft.data.ItemTagsProvider;
 | 
			
		||||
import net.minecraft.item.Item;
 | 
			
		||||
import net.minecraft.tags.ITag;
 | 
			
		||||
import net.minecraft.tags.ItemTags;
 | 
			
		||||
import net.minecraft.tags.Tag;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.data.Tags.CCTags.*;
 | 
			
		||||
 | 
			
		||||
public class Tags extends ItemTagsProvider
 | 
			
		||||
{
 | 
			
		||||
    private static final ITag.INamedTag<Item> PIGLIN_LOVED = ItemTags.field_232903_N_;
 | 
			
		||||
 | 
			
		||||
    public static class CCTags
 | 
			
		||||
    {
 | 
			
		||||
        public static final ITag.INamedTag<Item> COMPUTER = item( "computer" );
 | 
			
		||||
        public static final ITag.INamedTag<Item> TURTLE = item( "turtle" );
 | 
			
		||||
        public static final ITag.INamedTag<Item> WIRED_MODEM = item( "wired_modem" );
 | 
			
		||||
        public static final ITag.INamedTag<Item> MONITOR = item( "monitor" );
 | 
			
		||||
        public static final Tag<Item> COMPUTER = item( "computer" );
 | 
			
		||||
        public static final Tag<Item> TURTLE = item( "turtle" );
 | 
			
		||||
        public static final Tag<Item> WIRED_MODEM = item( "wired_modem" );
 | 
			
		||||
        public static final Tag<Item> MONITOR = item( "monitor" );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Tags( DataGenerator generator, BlockTagsProvider tags )
 | 
			
		||||
    public Tags( DataGenerator generator )
 | 
			
		||||
    {
 | 
			
		||||
        super( generator, tags );
 | 
			
		||||
        super( generator );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void registerTags()
 | 
			
		||||
    {
 | 
			
		||||
        getOrCreateBuilder( COMPUTER ).add(
 | 
			
		||||
            Registry.ModItems.COMPUTER_NORMAL.get(),
 | 
			
		||||
            Registry.ModItems.COMPUTER_ADVANCED.get(),
 | 
			
		||||
            Registry.ModItems.COMPUTER_COMMAND.get()
 | 
			
		||||
        );
 | 
			
		||||
        getOrCreateBuilder( TURTLE ).add( Registry.ModItems.TURTLE_NORMAL.get(), Registry.ModItems.TURTLE_ADVANCED.get() );
 | 
			
		||||
        getOrCreateBuilder( WIRED_MODEM ).add( Registry.ModItems.WIRED_MODEM.get(), Registry.ModItems.WIRED_MODEM_FULL.get() );
 | 
			
		||||
        getOrCreateBuilder( MONITOR ).add( Registry.ModItems.MONITOR_NORMAL.get(), Registry.ModItems.MONITOR_ADVANCED.get() );
 | 
			
		||||
 | 
			
		||||
        getOrCreateBuilder( PIGLIN_LOVED ).add(
 | 
			
		||||
            Registry.ModItems.COMPUTER_ADVANCED.get(), Registry.ModItems.TURTLE_ADVANCED.get(),
 | 
			
		||||
            Registry.ModItems.WIRELESS_MODEM_ADVANCED.get(), Registry.ModItems.POCKET_COMPUTER_ADVANCED.get(),
 | 
			
		||||
            Registry.ModItems.MONITOR_ADVANCED.get()
 | 
			
		||||
        );
 | 
			
		||||
        getBuilder( COMPUTER )
 | 
			
		||||
            .add( Registry.ModItems.COMPUTER_NORMAL.get() )
 | 
			
		||||
            .add( Registry.ModItems.COMPUTER_ADVANCED.get() )
 | 
			
		||||
            .add( Registry.ModItems.COMPUTER_COMMAND.get() );
 | 
			
		||||
        getBuilder( TURTLE ).add( Registry.ModItems.TURTLE_NORMAL.get(), Registry.ModItems.TURTLE_ADVANCED.get() );
 | 
			
		||||
        getBuilder( WIRED_MODEM ).add( Registry.ModItems.WIRED_MODEM.get(), Registry.ModItems.WIRED_MODEM_FULL.get() );
 | 
			
		||||
        getBuilder( MONITOR )
 | 
			
		||||
            .add( Registry.ModItems.MONITOR_NORMAL.get() )
 | 
			
		||||
            .add( Registry.ModItems.MONITOR_ADVANCED.get() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static ITag.INamedTag<Item> item( String name )
 | 
			
		||||
    private static Tag<Item> item( String name )
 | 
			
		||||
    {
 | 
			
		||||
        return ItemTags.makeWrapperTag( new ResourceLocation( ComputerCraft.MOD_ID, name ).toString() );
 | 
			
		||||
        return new ItemTags.Wrapper( new ResourceLocation( ComputerCraft.MOD_ID, name ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -82,8 +82,6 @@ public final class Config
 | 
			
		||||
    private static final ConfigValue<Integer> monitorWidth;
 | 
			
		||||
    private static final ConfigValue<Integer> monitorHeight;
 | 
			
		||||
 | 
			
		||||
    private static final ConfigValue<Boolean> genericPeripheral;
 | 
			
		||||
 | 
			
		||||
    private static final ConfigValue<MonitorRenderer> monitorRenderer;
 | 
			
		||||
    private static final ConfigValue<Integer> monitorDistance;
 | 
			
		||||
 | 
			
		||||
@@ -294,17 +292,6 @@ public final class Config
 | 
			
		||||
            builder.pop();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            builder.comment( "Options for various experimental features. These are not guaranteed to be stable, and may change or be removed across versions." );
 | 
			
		||||
            builder.push( "experimental" );
 | 
			
		||||
 | 
			
		||||
            genericPeripheral = builder
 | 
			
		||||
                .comment( "Attempt to make any existing block (or tile entity) a peripheral.\n" +
 | 
			
		||||
                    "This provides peripheral methods for any inventory, fluid tank or energy storage block. It will" +
 | 
			
		||||
                    "_not_ provide methods which have an existing peripheral provider." )
 | 
			
		||||
                .define( "generic_peripherals", false );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        serverSpec = builder.build();
 | 
			
		||||
 | 
			
		||||
        Builder clientBuilder = new Builder();
 | 
			
		||||
@@ -379,9 +366,6 @@ public final class Config
 | 
			
		||||
        ComputerCraft.monitorWidth = monitorWidth.get();
 | 
			
		||||
        ComputerCraft.monitorHeight = monitorHeight.get();
 | 
			
		||||
 | 
			
		||||
        // Experimental
 | 
			
		||||
        ComputerCraft.genericPeripheral = genericPeripheral.get();
 | 
			
		||||
 | 
			
		||||
        // Client
 | 
			
		||||
        ComputerCraft.monitorRenderer = monitorRenderer.get();
 | 
			
		||||
        ComputerCraft.monitorDistanceSq = monitorDistance.get() * monitorDistance.get();
 | 
			
		||||
 
 | 
			
		||||
@@ -92,7 +92,7 @@ public final class Registry
 | 
			
		||||
 | 
			
		||||
    public static final class ModBlocks
 | 
			
		||||
    {
 | 
			
		||||
        static final DeferredRegister<Block> BLOCKS = DeferredRegister.create( ForgeRegistries.BLOCKS, ComputerCraft.MOD_ID );
 | 
			
		||||
        static final DeferredRegister<Block> BLOCKS = new DeferredRegister<>( ForgeRegistries.BLOCKS, ComputerCraft.MOD_ID );
 | 
			
		||||
 | 
			
		||||
        private static Block.Properties properties()
 | 
			
		||||
        {
 | 
			
		||||
@@ -145,7 +145,7 @@ public final class Registry
 | 
			
		||||
 | 
			
		||||
    public static class ModTiles
 | 
			
		||||
    {
 | 
			
		||||
        static final DeferredRegister<TileEntityType<?>> TILES = DeferredRegister.create( ForgeRegistries.TILE_ENTITIES, ComputerCraft.MOD_ID );
 | 
			
		||||
        static final DeferredRegister<TileEntityType<?>> TILES = new DeferredRegister<>( ForgeRegistries.TILE_ENTITIES, ComputerCraft.MOD_ID );
 | 
			
		||||
 | 
			
		||||
        private static <T extends TileEntity> RegistryObject<TileEntityType<T>> ofBlock( RegistryObject<? extends Block> block, Function<TileEntityType<T>, T> factory )
 | 
			
		||||
        {
 | 
			
		||||
@@ -183,7 +183,7 @@ public final class Registry
 | 
			
		||||
 | 
			
		||||
    public static final class ModItems
 | 
			
		||||
    {
 | 
			
		||||
        static final DeferredRegister<Item> ITEMS = DeferredRegister.create( ForgeRegistries.ITEMS, ComputerCraft.MOD_ID );
 | 
			
		||||
        static final DeferredRegister<Item> ITEMS = new DeferredRegister<>( ForgeRegistries.ITEMS, ComputerCraft.MOD_ID );
 | 
			
		||||
 | 
			
		||||
        private static Item.Properties properties()
 | 
			
		||||
        {
 | 
			
		||||
@@ -281,7 +281,7 @@ public final class Registry
 | 
			
		||||
 | 
			
		||||
    public static class ModEntities
 | 
			
		||||
    {
 | 
			
		||||
        static final DeferredRegister<EntityType<?>> ENTITIES = DeferredRegister.create( ForgeRegistries.ENTITIES, ComputerCraft.MOD_ID );
 | 
			
		||||
        static final DeferredRegister<EntityType<?>> ENTITIES = new DeferredRegister<>( ForgeRegistries.ENTITIES, ComputerCraft.MOD_ID );
 | 
			
		||||
 | 
			
		||||
        public static final RegistryObject<EntityType<TurtlePlayer>> TURTLE_PLAYER = ENTITIES.register( "turtle_player", () ->
 | 
			
		||||
            EntityType.Builder.<TurtlePlayer>create( EntityClassification.MISC )
 | 
			
		||||
@@ -293,7 +293,7 @@ public final class Registry
 | 
			
		||||
 | 
			
		||||
    public static class ModContainers
 | 
			
		||||
    {
 | 
			
		||||
        static final DeferredRegister<ContainerType<?>> CONTAINERS = DeferredRegister.create( ForgeRegistries.CONTAINERS, ComputerCraft.MOD_ID );
 | 
			
		||||
        static final DeferredRegister<ContainerType<?>> CONTAINERS = new DeferredRegister<>( ForgeRegistries.CONTAINERS, ComputerCraft.MOD_ID );
 | 
			
		||||
 | 
			
		||||
        public static final RegistryObject<ContainerType<ContainerComputer>> COMPUTER = CONTAINERS.register( "computer",
 | 
			
		||||
            () -> ContainerData.toType( ComputerContainerData::new, ContainerComputer::new ) );
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,6 @@ import net.minecraft.entity.player.PlayerEntity;
 | 
			
		||||
import net.minecraft.server.MinecraftServer;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
import net.minecraft.world.server.ServerWorld;
 | 
			
		||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
			
		||||
import net.minecraftforge.fml.common.Mod;
 | 
			
		||||
 | 
			
		||||
@@ -21,12 +20,13 @@ public final class TurtlePermissions
 | 
			
		||||
    public static boolean isBlockEnterable( World world, BlockPos pos, PlayerEntity player )
 | 
			
		||||
    {
 | 
			
		||||
        MinecraftServer server = world.getServer();
 | 
			
		||||
        return server == null || world.isRemote || (world instanceof ServerWorld && !server.isBlockProtected( (ServerWorld) world, pos, player ));
 | 
			
		||||
        return server == null || world.isRemote || !server.isBlockProtected( world, pos, player );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean isBlockEditable( World world, BlockPos pos, PlayerEntity player )
 | 
			
		||||
    {
 | 
			
		||||
        return isBlockEnterable( world, pos, player );
 | 
			
		||||
        MinecraftServer server = world.getServer();
 | 
			
		||||
        return server == null || world.isRemote || !server.isBlockProtected( world, pos, player );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SubscribeEvent
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,6 @@ import net.minecraft.inventory.container.Container;
 | 
			
		||||
import net.minecraft.inventory.container.INamedContainerProvider;
 | 
			
		||||
import net.minecraft.network.play.server.SPlayerPositionLookPacket;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.text.IFormattableTextComponent;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
import net.minecraft.util.text.StringTextComponent;
 | 
			
		||||
import net.minecraft.util.text.TranslationTextComponent;
 | 
			
		||||
@@ -284,16 +283,16 @@ public final class CommandComputerCraft
 | 
			
		||||
 | 
			
		||||
    private static ITextComponent linkComputer( CommandSource source, ServerComputer serverComputer, int computerId )
 | 
			
		||||
    {
 | 
			
		||||
        IFormattableTextComponent out = new StringTextComponent( "" );
 | 
			
		||||
        ITextComponent out = new StringTextComponent( "" );
 | 
			
		||||
 | 
			
		||||
        // Append the computer instance
 | 
			
		||||
        if( serverComputer == null )
 | 
			
		||||
        {
 | 
			
		||||
            out.append( text( "?" ) );
 | 
			
		||||
            out.appendSibling( text( "?" ) );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            out.append( link(
 | 
			
		||||
            out.appendSibling( link(
 | 
			
		||||
                text( Integer.toString( serverComputer.getInstanceID() ) ),
 | 
			
		||||
                "/computercraft dump " + serverComputer.getInstanceID(),
 | 
			
		||||
                translate( "commands.computercraft.dump.action" )
 | 
			
		||||
@@ -301,20 +300,20 @@ public final class CommandComputerCraft
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // And ID
 | 
			
		||||
        out.appendString( " (id " + computerId + ")" );
 | 
			
		||||
        out.appendText( " (id " + computerId + ")" );
 | 
			
		||||
 | 
			
		||||
        // And, if we're a player, some useful links
 | 
			
		||||
        if( serverComputer != null && UserLevel.OP.test( source ) && isPlayer( source ) )
 | 
			
		||||
        {
 | 
			
		||||
            out
 | 
			
		||||
                .appendString( " " )
 | 
			
		||||
                .append( link(
 | 
			
		||||
                .appendText( " " )
 | 
			
		||||
                .appendSibling( link(
 | 
			
		||||
                    text( "\u261b" ),
 | 
			
		||||
                    "/computercraft tp " + serverComputer.getInstanceID(),
 | 
			
		||||
                    translate( "commands.computercraft.tp.action" )
 | 
			
		||||
                ) )
 | 
			
		||||
                .appendString( " " )
 | 
			
		||||
                .append( link(
 | 
			
		||||
                .appendText( " " )
 | 
			
		||||
                .appendSibling( link(
 | 
			
		||||
                    text( "\u20e2" ),
 | 
			
		||||
                    "/computercraft view " + serverComputer.getInstanceID(),
 | 
			
		||||
                    translate( "commands.computercraft.view.action" )
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,6 @@ import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.command.CommandSource;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
import net.minecraft.util.text.StringTextComponent;
 | 
			
		||||
import net.minecraft.util.text.Style;
 | 
			
		||||
import net.minecraft.util.text.TranslationTextComponent;
 | 
			
		||||
import net.minecraft.util.text.event.ClickEvent;
 | 
			
		||||
import net.minecraft.util.text.event.HoverEvent;
 | 
			
		||||
@@ -58,8 +57,10 @@ public final class CommandCopy
 | 
			
		||||
 | 
			
		||||
    public static ITextComponent createCopyText( String text )
 | 
			
		||||
    {
 | 
			
		||||
        return new StringTextComponent( text ).mergeStyle( Style.EMPTY
 | 
			
		||||
        StringTextComponent name = new StringTextComponent( text );
 | 
			
		||||
        name.getStyle()
 | 
			
		||||
            .setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, PREFIX + text ) )
 | 
			
		||||
            .setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new TranslationTextComponent( "gui.computercraft.tooltip.copy" ) ) ) );
 | 
			
		||||
            .setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new TranslationTextComponent( "gui.computercraft.tooltip.copy" ) ) );
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,6 @@ import com.mojang.brigadier.context.CommandContext;
 | 
			
		||||
import com.mojang.brigadier.tree.CommandNode;
 | 
			
		||||
import com.mojang.brigadier.tree.LiteralCommandNode;
 | 
			
		||||
import net.minecraft.command.CommandSource;
 | 
			
		||||
import net.minecraft.util.text.IFormattableTextComponent;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
import net.minecraft.util.text.StringTextComponent;
 | 
			
		||||
import net.minecraft.util.text.TextFormatting;
 | 
			
		||||
@@ -174,12 +173,12 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
 | 
			
		||||
        temp.addChild( node );
 | 
			
		||||
        String usage = dispatcher.getSmartUsage( temp, context.getSource() ).get( node ).substring( node.getName().length() );
 | 
			
		||||
 | 
			
		||||
        IFormattableTextComponent output = new StringTextComponent( "" )
 | 
			
		||||
            .append( coloured( "/" + command + usage, HEADER ) )
 | 
			
		||||
            .appendString( " " )
 | 
			
		||||
            .append( coloured( translate( "commands." + id + ".synopsis" ), SYNOPSIS ) )
 | 
			
		||||
            .appendString( "\n" )
 | 
			
		||||
            .append( translate( "commands." + id + ".desc" ) );
 | 
			
		||||
        ITextComponent output = new StringTextComponent( "" )
 | 
			
		||||
            .appendSibling( coloured( "/" + command + usage, HEADER ) )
 | 
			
		||||
            .appendText( " " )
 | 
			
		||||
            .appendSibling( coloured( translate( "commands." + id + ".synopsis" ), SYNOPSIS ) )
 | 
			
		||||
            .appendText( "\n" )
 | 
			
		||||
            .appendSibling( translate( "commands." + id + ".desc" ) );
 | 
			
		||||
 | 
			
		||||
        for( CommandNode<CommandSource> child : node.getChildren() )
 | 
			
		||||
        {
 | 
			
		||||
@@ -188,16 +187,16 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            output.appendString( "\n" );
 | 
			
		||||
            output.appendText( "\n" );
 | 
			
		||||
 | 
			
		||||
            IFormattableTextComponent component = coloured( child.getName(), NAME );
 | 
			
		||||
            ITextComponent component = coloured( child.getName(), NAME );
 | 
			
		||||
            component.getStyle().setClickEvent( new ClickEvent(
 | 
			
		||||
                ClickEvent.Action.SUGGEST_COMMAND,
 | 
			
		||||
                "/" + command + " " + child.getName()
 | 
			
		||||
            ) );
 | 
			
		||||
            output.append( component );
 | 
			
		||||
            output.appendSibling( component );
 | 
			
		||||
 | 
			
		||||
            output.appendString( " - " ).append( translate( "commands." + id + "." + child.getName() + ".synopsis" ) );
 | 
			
		||||
            output.appendText( " - " ).appendSibling( translate( "commands." + id + "." + child.getName() + ".synopsis" ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return output;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,67 +19,69 @@ public final class ChatHelpers
 | 
			
		||||
 | 
			
		||||
    private ChatHelpers() {}
 | 
			
		||||
 | 
			
		||||
    public static IFormattableTextComponent coloured( String text, TextFormatting colour )
 | 
			
		||||
    public static ITextComponent coloured( String text, TextFormatting colour )
 | 
			
		||||
    {
 | 
			
		||||
        return new StringTextComponent( text == null ? "" : text ).mergeStyle( colour );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends IFormattableTextComponent> T coloured( T component, TextFormatting colour )
 | 
			
		||||
    {
 | 
			
		||||
        component.mergeStyle( colour );
 | 
			
		||||
        ITextComponent component = new StringTextComponent( text == null ? "" : text );
 | 
			
		||||
        component.getStyle().setColor( colour );
 | 
			
		||||
        return component;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IFormattableTextComponent text( String text )
 | 
			
		||||
    public static <T extends ITextComponent> T coloured( T component, TextFormatting colour )
 | 
			
		||||
    {
 | 
			
		||||
        component.getStyle().setColor( colour );
 | 
			
		||||
        return component;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ITextComponent text( String text )
 | 
			
		||||
    {
 | 
			
		||||
        return new StringTextComponent( text == null ? "" : text );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IFormattableTextComponent translate( String text )
 | 
			
		||||
    public static ITextComponent translate( String text )
 | 
			
		||||
    {
 | 
			
		||||
        return new TranslationTextComponent( text == null ? "" : text );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IFormattableTextComponent translate( String text, Object... args )
 | 
			
		||||
    public static ITextComponent translate( String text, Object... args )
 | 
			
		||||
    {
 | 
			
		||||
        return new TranslationTextComponent( text == null ? "" : text, args );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IFormattableTextComponent list( ITextComponent... children )
 | 
			
		||||
    public static ITextComponent list( ITextComponent... children )
 | 
			
		||||
    {
 | 
			
		||||
        IFormattableTextComponent component = new StringTextComponent( "" );
 | 
			
		||||
        ITextComponent component = new StringTextComponent( "" );
 | 
			
		||||
        for( ITextComponent child : children )
 | 
			
		||||
        {
 | 
			
		||||
            component.append( child );
 | 
			
		||||
            component.appendSibling( child );
 | 
			
		||||
        }
 | 
			
		||||
        return component;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IFormattableTextComponent position( BlockPos pos )
 | 
			
		||||
    public static ITextComponent position( BlockPos pos )
 | 
			
		||||
    {
 | 
			
		||||
        if( pos == null ) return translate( "commands.computercraft.generic.no_position" );
 | 
			
		||||
        return translate( "commands.computercraft.generic.position", pos.getX(), pos.getY(), pos.getZ() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IFormattableTextComponent bool( boolean value )
 | 
			
		||||
    public static ITextComponent bool( boolean value )
 | 
			
		||||
    {
 | 
			
		||||
        return value
 | 
			
		||||
            ? coloured( translate( "commands.computercraft.generic.yes" ), TextFormatting.GREEN )
 | 
			
		||||
            : coloured( translate( "commands.computercraft.generic.no" ), TextFormatting.RED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IFormattableTextComponent link( IFormattableTextComponent component, String command, ITextComponent toolTip )
 | 
			
		||||
    public static ITextComponent link( ITextComponent component, String command, ITextComponent toolTip )
 | 
			
		||||
    {
 | 
			
		||||
        Style style = component.getStyle();
 | 
			
		||||
 | 
			
		||||
        if( style.getColor() == null ) style = style.setFormatting( TextFormatting.YELLOW );
 | 
			
		||||
        style = style.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, command ) );
 | 
			
		||||
        style = style.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, toolTip ) );
 | 
			
		||||
        if( style.getColor() == null ) style.setColor( TextFormatting.YELLOW );
 | 
			
		||||
        style.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, command ) );
 | 
			
		||||
        style.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, toolTip ) );
 | 
			
		||||
 | 
			
		||||
        return component.setStyle( style );
 | 
			
		||||
        return component;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IFormattableTextComponent header( String text )
 | 
			
		||||
    public static ITextComponent header( String text )
 | 
			
		||||
    {
 | 
			
		||||
        return coloured( text, HEADER );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -79,12 +79,12 @@ public interface TableFormatter
 | 
			
		||||
            StringTextComponent line = new StringTextComponent( "" );
 | 
			
		||||
            for( int i = 0; i < columns - 1; i++ )
 | 
			
		||||
            {
 | 
			
		||||
                line.append( headers[i] );
 | 
			
		||||
                line.appendSibling( headers[i] );
 | 
			
		||||
                ITextComponent padding = getPadding( headers[i], maxWidths[i] );
 | 
			
		||||
                if( padding != null ) line.append( padding );
 | 
			
		||||
                line.append( SEPARATOR );
 | 
			
		||||
                if( padding != null ) line.appendSibling( padding );
 | 
			
		||||
                line.appendSibling( SEPARATOR );
 | 
			
		||||
            }
 | 
			
		||||
            line.append( headers[columns - 1] );
 | 
			
		||||
            line.appendSibling( headers[columns - 1] );
 | 
			
		||||
 | 
			
		||||
            writeLine( rowId++, line );
 | 
			
		||||
 | 
			
		||||
@@ -100,12 +100,12 @@ public interface TableFormatter
 | 
			
		||||
            StringTextComponent line = new StringTextComponent( "" );
 | 
			
		||||
            for( int i = 0; i < columns - 1; i++ )
 | 
			
		||||
            {
 | 
			
		||||
                line.append( row[i] );
 | 
			
		||||
                line.appendSibling( row[i] );
 | 
			
		||||
                ITextComponent padding = getPadding( row[i], maxWidths[i] );
 | 
			
		||||
                if( padding != null ) line.append( padding );
 | 
			
		||||
                line.append( SEPARATOR );
 | 
			
		||||
                if( padding != null ) line.appendSibling( padding );
 | 
			
		||||
                line.appendSibling( SEPARATOR );
 | 
			
		||||
            }
 | 
			
		||||
            line.append( row[columns - 1] );
 | 
			
		||||
            line.appendSibling( row[columns - 1] );
 | 
			
		||||
            writeLine( rowId++, line );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -105,9 +105,9 @@ public abstract class TileGeneric extends TileEntity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void handleUpdateTag( @Nonnull BlockState state, @Nonnull CompoundNBT tag )
 | 
			
		||||
    public void handleUpdateTag( @Nonnull CompoundNBT tag )
 | 
			
		||||
    {
 | 
			
		||||
        super.handleUpdateTag( state, tag );
 | 
			
		||||
        super.handleUpdateTag( tag );
 | 
			
		||||
        readDescription( tag );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -116,7 +116,6 @@ public class CommandAPI implements ILuaAPI
 | 
			
		||||
     * @param command The command to execute.
 | 
			
		||||
     * @return The "task id". When this command has been executed, it will queue a `task_complete` event with a matching id.
 | 
			
		||||
     * @throws LuaException (hidden) If the task cannot be created.
 | 
			
		||||
     * @cc.tparam string command The command to execute.
 | 
			
		||||
     * @cc.usage Asynchronously sets the block above the computer to stone.
 | 
			
		||||
     * <pre>
 | 
			
		||||
     * commands.execAsync("~ ~1 ~ minecraft:stone")
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,6 @@ import net.minecraft.block.BlockState;
 | 
			
		||||
import net.minecraft.entity.LivingEntity;
 | 
			
		||||
import net.minecraft.entity.player.PlayerEntity;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.loot.LootContext;
 | 
			
		||||
import net.minecraft.loot.LootParameters;
 | 
			
		||||
import net.minecraft.stats.Stats;
 | 
			
		||||
import net.minecraft.tileentity.TileEntity;
 | 
			
		||||
import net.minecraft.tileentity.TileEntityType;
 | 
			
		||||
@@ -26,8 +24,11 @@ import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.math.RayTraceResult;
 | 
			
		||||
import net.minecraft.world.IBlockReader;
 | 
			
		||||
import net.minecraft.world.IWorldReader;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
import net.minecraft.world.server.ServerWorld;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootContext;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootParameters;
 | 
			
		||||
import net.minecraftforge.fml.RegistryObject;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -180,4 +181,10 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
 | 
			
		||||
            if( label != null ) computer.setLabel( label );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean shouldCheckWeakPower( BlockState state, IWorldReader world, BlockPos pos, Direction side )
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,8 @@ import net.minecraft.command.ICommandSource;
 | 
			
		||||
import net.minecraft.entity.player.PlayerEntity;
 | 
			
		||||
import net.minecraft.server.MinecraftServer;
 | 
			
		||||
import net.minecraft.tileentity.TileEntityType;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector2f;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec2f;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
import net.minecraft.util.text.StringTextComponent;
 | 
			
		||||
import net.minecraft.util.text.TranslationTextComponent;
 | 
			
		||||
@@ -25,7 +25,6 @@ import net.minecraft.world.server.ServerWorld;
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
public class TileCommandComputer extends TileComputer
 | 
			
		||||
{
 | 
			
		||||
@@ -49,7 +48,7 @@ public class TileCommandComputer extends TileComputer
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void sendMessage( @Nonnull ITextComponent textComponent, @Nonnull UUID id )
 | 
			
		||||
        public void sendMessage( @Nonnull ITextComponent textComponent )
 | 
			
		||||
        {
 | 
			
		||||
            output.put( output.size() + 1, textComponent.getString() );
 | 
			
		||||
        }
 | 
			
		||||
@@ -97,7 +96,7 @@ public class TileCommandComputer extends TileComputer
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new CommandSource( receiver,
 | 
			
		||||
            new Vector3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ), Vector2f.ZERO,
 | 
			
		||||
            new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ), Vec2f.ZERO,
 | 
			
		||||
            (ServerWorld) getWorld(), 2,
 | 
			
		||||
            name, new StringTextComponent( name ),
 | 
			
		||||
            getWorld().getServer(), null
 | 
			
		||||
 
 | 
			
		||||
@@ -189,9 +189,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void read( @Nonnull BlockState state, @Nonnull CompoundNBT nbt )
 | 
			
		||||
    public void read( @Nonnull CompoundNBT nbt )
 | 
			
		||||
    {
 | 
			
		||||
        super.read( state, nbt );
 | 
			
		||||
        super.read( nbt );
 | 
			
		||||
 | 
			
		||||
        // Load ID, label and power state
 | 
			
		||||
        m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ public enum ComputerState implements IStringSerializable
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getString()
 | 
			
		||||
    public String getName()
 | 
			
		||||
    {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,7 @@ public abstract class ItemComputerBase extends BlockItem implements IComputerIte
 | 
			
		||||
            if( id >= 0 )
 | 
			
		||||
            {
 | 
			
		||||
                list.add( new TranslationTextComponent( "gui.computercraft.tooltip.computer_id", id )
 | 
			
		||||
                    .mergeStyle( TextFormatting.GRAY ) );
 | 
			
		||||
                    .applyTextStyle( TextFormatting.GRAY ) );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -5,13 +5,12 @@
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.shared.data;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.loot.LootConditionType;
 | 
			
		||||
import net.minecraft.loot.LootContext;
 | 
			
		||||
import net.minecraft.loot.LootParameter;
 | 
			
		||||
import net.minecraft.loot.LootParameters;
 | 
			
		||||
import net.minecraft.loot.conditions.ILootCondition;
 | 
			
		||||
import net.minecraft.tileentity.TileEntity;
 | 
			
		||||
import net.minecraft.util.INameable;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootContext;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootParameter;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootParameters;
 | 
			
		||||
import net.minecraft.world.storage.loot.conditions.ILootCondition;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
@@ -23,8 +22,6 @@ import java.util.Set;
 | 
			
		||||
public final class BlockNamedEntityLootCondition implements ILootCondition
 | 
			
		||||
{
 | 
			
		||||
    public static final BlockNamedEntityLootCondition INSTANCE = new BlockNamedEntityLootCondition();
 | 
			
		||||
    public static final LootConditionType TYPE = ConstantLootConditionSerializer.type( INSTANCE );
 | 
			
		||||
    public static final IBuilder BUILDER = () -> INSTANCE;
 | 
			
		||||
 | 
			
		||||
    private BlockNamedEntityLootCondition()
 | 
			
		||||
    {
 | 
			
		||||
@@ -44,10 +41,8 @@ public final class BlockNamedEntityLootCondition implements ILootCondition
 | 
			
		||||
        return Collections.singleton( LootParameters.BLOCK_ENTITY );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public LootConditionType func_230419_b_()
 | 
			
		||||
    public static IBuilder builder()
 | 
			
		||||
    {
 | 
			
		||||
        return TYPE;
 | 
			
		||||
        return () -> INSTANCE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,34 +8,34 @@ package dan200.computercraft.shared.data;
 | 
			
		||||
import com.google.gson.JsonDeserializationContext;
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.gson.JsonSerializationContext;
 | 
			
		||||
import net.minecraft.loot.ILootSerializer;
 | 
			
		||||
import net.minecraft.loot.LootConditionType;
 | 
			
		||||
import net.minecraft.loot.conditions.ILootCondition;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.storage.loot.conditions.ILootCondition;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
public final class ConstantLootConditionSerializer<T extends ILootCondition> implements ILootSerializer<T>
 | 
			
		||||
public final class ConstantLootConditionSerializer<T extends ILootCondition> extends ILootCondition.AbstractSerializer<T>
 | 
			
		||||
{
 | 
			
		||||
    private final T instance;
 | 
			
		||||
 | 
			
		||||
    public ConstantLootConditionSerializer( T instance )
 | 
			
		||||
    private ConstantLootConditionSerializer( ResourceLocation id, Class<T> klass, T instance )
 | 
			
		||||
    {
 | 
			
		||||
        super( id, klass );
 | 
			
		||||
        this.instance = instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T extends ILootCondition> LootConditionType type( T condition )
 | 
			
		||||
    public static <T extends ILootCondition> ILootCondition.AbstractSerializer<T> of( ResourceLocation id, Class<T> klass, T instance )
 | 
			
		||||
    {
 | 
			
		||||
        return new LootConditionType( new ConstantLootConditionSerializer<>( condition ) );
 | 
			
		||||
        return new ConstantLootConditionSerializer<>( id, klass, instance );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void func_230424_a_( @Nonnull JsonObject json, @Nonnull T object, @Nonnull JsonSerializationContext context )
 | 
			
		||||
    public void serialize( @Nonnull JsonObject json, @Nonnull T object, @Nonnull JsonSerializationContext context )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    public T func_230423_a_( @Nonnull JsonObject json, @Nonnull JsonDeserializationContext context )
 | 
			
		||||
    public T deserialize( @Nonnull JsonObject json, @Nonnull JsonDeserializationContext context )
 | 
			
		||||
    {
 | 
			
		||||
        return instance;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,12 +6,11 @@
 | 
			
		||||
package dan200.computercraft.shared.data;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.shared.computer.blocks.IComputerTile;
 | 
			
		||||
import net.minecraft.loot.LootConditionType;
 | 
			
		||||
import net.minecraft.loot.LootContext;
 | 
			
		||||
import net.minecraft.loot.LootParameter;
 | 
			
		||||
import net.minecraft.loot.LootParameters;
 | 
			
		||||
import net.minecraft.loot.conditions.ILootCondition;
 | 
			
		||||
import net.minecraft.tileentity.TileEntity;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootContext;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootParameter;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootParameters;
 | 
			
		||||
import net.minecraft.world.storage.loot.conditions.ILootCondition;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
@@ -23,8 +22,6 @@ import java.util.Set;
 | 
			
		||||
public final class HasComputerIdLootCondition implements ILootCondition
 | 
			
		||||
{
 | 
			
		||||
    public static final HasComputerIdLootCondition INSTANCE = new HasComputerIdLootCondition();
 | 
			
		||||
    public static final LootConditionType TYPE = ConstantLootConditionSerializer.type( INSTANCE );
 | 
			
		||||
    public static final IBuilder BUILDER = () -> INSTANCE;
 | 
			
		||||
 | 
			
		||||
    private HasComputerIdLootCondition()
 | 
			
		||||
    {
 | 
			
		||||
@@ -44,10 +41,8 @@ public final class HasComputerIdLootCondition implements ILootCondition
 | 
			
		||||
        return Collections.singleton( LootParameters.BLOCK_ENTITY );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public LootConditionType func_230419_b_()
 | 
			
		||||
    public static IBuilder builder()
 | 
			
		||||
    {
 | 
			
		||||
        return TYPE;
 | 
			
		||||
        return () -> INSTANCE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,10 @@ package dan200.computercraft.shared.data;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.entity.Entity;
 | 
			
		||||
import net.minecraft.entity.player.PlayerEntity;
 | 
			
		||||
import net.minecraft.loot.LootConditionType;
 | 
			
		||||
import net.minecraft.loot.LootContext;
 | 
			
		||||
import net.minecraft.loot.LootParameter;
 | 
			
		||||
import net.minecraft.loot.LootParameters;
 | 
			
		||||
import net.minecraft.loot.conditions.ILootCondition;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootContext;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootParameter;
 | 
			
		||||
import net.minecraft.world.storage.loot.LootParameters;
 | 
			
		||||
import net.minecraft.world.storage.loot.conditions.ILootCondition;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
@@ -23,8 +22,6 @@ import java.util.Set;
 | 
			
		||||
public final class PlayerCreativeLootCondition implements ILootCondition
 | 
			
		||||
{
 | 
			
		||||
    public static final PlayerCreativeLootCondition INSTANCE = new PlayerCreativeLootCondition();
 | 
			
		||||
    public static final LootConditionType TYPE = ConstantLootConditionSerializer.type( INSTANCE );
 | 
			
		||||
    public static final IBuilder BUILDER = () -> INSTANCE;
 | 
			
		||||
 | 
			
		||||
    private PlayerCreativeLootCondition()
 | 
			
		||||
    {
 | 
			
		||||
@@ -44,10 +41,8 @@ public final class PlayerCreativeLootCondition implements ILootCondition
 | 
			
		||||
        return Collections.singleton( LootParameters.THIS_ENTITY );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public LootConditionType func_230419_b_()
 | 
			
		||||
    public static IBuilder builder()
 | 
			
		||||
    {
 | 
			
		||||
        return TYPE;
 | 
			
		||||
        return () -> INSTANCE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@ public class ItemDisk extends Item implements IMedia, IColouredItem
 | 
			
		||||
            if( id >= 0 )
 | 
			
		||||
            {
 | 
			
		||||
                list.add( new TranslationTextComponent( "gui.computercraft.tooltip.disk_id", id )
 | 
			
		||||
                    .mergeStyle( TextFormatting.GRAY ) );
 | 
			
		||||
                    .applyTextStyle( TextFormatting.GRAY ) );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -19,14 +19,14 @@ import net.minecraft.item.crafting.SpecialRecipe;
 | 
			
		||||
import net.minecraft.item.crafting.SpecialRecipeSerializer;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
import net.minecraftforge.common.Tags;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
public class DiskRecipe extends SpecialRecipe
 | 
			
		||||
{
 | 
			
		||||
    private final Ingredient paper = Ingredient.fromItems( Items.PAPER );
 | 
			
		||||
    private final Ingredient redstone = Ingredient.fromItems( Items.REDSTONE );
 | 
			
		||||
    // TODO: Ingredient.fromTag( Tags.Items.DUSTS_REDSTONE );
 | 
			
		||||
    private final Ingredient redstone = Ingredient.fromTag( Tags.Items.DUSTS_REDSTONE );
 | 
			
		||||
 | 
			
		||||
    public DiskRecipe( ResourceLocation id )
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ import net.minecraft.entity.player.PlayerEntity;
 | 
			
		||||
import net.minecraft.entity.player.ServerPlayerEntity;
 | 
			
		||||
import net.minecraft.network.PacketBuffer;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
import net.minecraft.world.chunk.Chunk;
 | 
			
		||||
import net.minecraftforge.fml.network.NetworkDirection;
 | 
			
		||||
@@ -76,9 +76,9 @@ public final class NetworkHandler
 | 
			
		||||
        network.sendToServer( packet );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sendToAllAround( NetworkMessage packet, World world, Vector3d pos, double range )
 | 
			
		||||
    public static void sendToAllAround( NetworkMessage packet, World world, Vec3d pos, double range )
 | 
			
		||||
    {
 | 
			
		||||
        PacketDistributor.TargetPoint target = new PacketDistributor.TargetPoint( pos.x, pos.y, pos.z, range, world.func_234923_W_() );
 | 
			
		||||
        PacketDistributor.TargetPoint target = new PacketDistributor.TargetPoint( pos.x, pos.y, pos.z, range, world.getDimension().getType() );
 | 
			
		||||
        network.send( PacketDistributor.NEAR.with( () -> target ), packet );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,14 +10,11 @@ import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.network.PacketBuffer;
 | 
			
		||||
import net.minecraft.util.SoundEvent;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.text.StringTextComponent;
 | 
			
		||||
import net.minecraftforge.api.distmarker.Dist;
 | 
			
		||||
import net.minecraftforge.api.distmarker.OnlyIn;
 | 
			
		||||
import net.minecraftforge.fml.network.NetworkEvent;
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Starts or stops a record on the client, depending on if {@link #soundEvent} is {@code null}.
 | 
			
		||||
@@ -52,7 +49,7 @@ public class PlayRecordClientMessage implements NetworkMessage
 | 
			
		||||
        if( buf.readBoolean() )
 | 
			
		||||
        {
 | 
			
		||||
            name = buf.readString( Short.MAX_VALUE );
 | 
			
		||||
            soundEvent = ForgeRegistries.SOUND_EVENTS.getValue( buf.readResourceLocation() );
 | 
			
		||||
            soundEvent = buf.readRegistryIdSafe( SoundEvent.class );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
@@ -73,7 +70,7 @@ public class PlayRecordClientMessage implements NetworkMessage
 | 
			
		||||
        {
 | 
			
		||||
            buf.writeBoolean( true );
 | 
			
		||||
            buf.writeString( name );
 | 
			
		||||
            buf.writeResourceLocation( Objects.requireNonNull( soundEvent.getRegistryName(), "Sound is not registered" ) );
 | 
			
		||||
            buf.writeRegistryId( soundEvent );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -82,7 +79,7 @@ public class PlayRecordClientMessage implements NetworkMessage
 | 
			
		||||
    public void handle( NetworkEvent.Context context )
 | 
			
		||||
    {
 | 
			
		||||
        Minecraft mc = Minecraft.getInstance();
 | 
			
		||||
        mc.worldRenderer.playRecord( soundEvent, pos, null );
 | 
			
		||||
        if( name != null ) mc.ingameGUI.func_238451_a_( new StringTextComponent( name ) );
 | 
			
		||||
        mc.worldRenderer.playRecord( soundEvent, pos );
 | 
			
		||||
        if( name != null ) mc.ingameGUI.setRecordPlayingMessage( name );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -140,7 +140,8 @@ public class DiskDrivePeripheral implements IPeripheral
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the title of the inserted audio disk.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The title of the audio, or {@code nil} if no audio disk is inserted.
 | 
			
		||||
     * @return The title of the audio, or {@code false} if no audio disk is inserted.
 | 
			
		||||
     * @cc.treturn string|nil|false The title of the audio, {@code false} if no disk is inserted, or {@code nil} if the disk has no audio.
 | 
			
		||||
     */
 | 
			
		||||
    @LuaFunction
 | 
			
		||||
    @Nullable
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ public enum DiskDriveState implements IStringSerializable
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public String getString()
 | 
			
		||||
    public String getName()
 | 
			
		||||
    {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -122,10 +122,10 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void read( @Nonnull BlockState state, @Nonnull CompoundNBT nbt )
 | 
			
		||||
    public void read( @Nonnull CompoundNBT nbt )
 | 
			
		||||
    {
 | 
			
		||||
        super.read( state, nbt );
 | 
			
		||||
        customName = nbt.contains( NBT_NAME ) ? ITextComponent.Serializer.func_240643_a_( nbt.getString( NBT_NAME ) ) : null;
 | 
			
		||||
        super.read( nbt );
 | 
			
		||||
        customName = nbt.contains( NBT_NAME ) ? ITextComponent.Serializer.fromJson( nbt.getString( NBT_NAME ) ) : null;
 | 
			
		||||
        if( nbt.contains( NBT_ITEM ) )
 | 
			
		||||
        {
 | 
			
		||||
            CompoundNBT item = nbt.getCompound( NBT_ITEM );
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@
 | 
			
		||||
 | 
			
		||||
package dan200.computercraft.shared.peripheral.generic;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.api.peripheral.IPeripheral;
 | 
			
		||||
import dan200.computercraft.core.asm.NamedMethod;
 | 
			
		||||
import dan200.computercraft.core.asm.PeripheralMethod;
 | 
			
		||||
@@ -35,8 +34,6 @@ public class GenericPeripheralProvider
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static LazyOptional<IPeripheral> getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
 | 
			
		||||
    {
 | 
			
		||||
        if( !ComputerCraft.genericPeripheral ) return LazyOptional.empty();
 | 
			
		||||
 | 
			
		||||
        TileEntity tile = world.getTileEntity( pos );
 | 
			
		||||
        if( tile == null ) return LazyOptional.empty();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ package dan200.computercraft.shared.peripheral.generic.data;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
import net.minecraft.block.BlockState;
 | 
			
		||||
import net.minecraft.state.Property;
 | 
			
		||||
import net.minecraft.state.IProperty;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
@@ -22,9 +22,9 @@ public class BlockData
 | 
			
		||||
        data.put( "name", DataHelpers.getId( state.getBlock() ) );
 | 
			
		||||
 | 
			
		||||
        Map<Object, Object> stateTable = new HashMap<>();
 | 
			
		||||
        for( ImmutableMap.Entry<Property<?>, ? extends Comparable<?>> entry : state.getValues().entrySet() )
 | 
			
		||||
        for( ImmutableMap.Entry<IProperty<?>, ? extends Comparable<?>> entry : state.getValues().entrySet() )
 | 
			
		||||
        {
 | 
			
		||||
            Property<?> property = entry.getKey();
 | 
			
		||||
            IProperty<?> property = entry.getKey();
 | 
			
		||||
            stateTable.put( property.getName(), getPropertyValue( property, entry.getValue() ) );
 | 
			
		||||
        }
 | 
			
		||||
        data.put( "state", stateTable );
 | 
			
		||||
@@ -34,7 +34,7 @@ public class BlockData
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings( { "unchecked", "rawtypes" } )
 | 
			
		||||
    private static Object getPropertyValue( Property property, Comparable value )
 | 
			
		||||
    private static Object getPropertyValue( IProperty property, Comparable value )
 | 
			
		||||
    {
 | 
			
		||||
        if( value instanceof String || value instanceof Number || value instanceof Boolean ) return value;
 | 
			
		||||
        return property.getName( value );
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
package dan200.computercraft.shared.peripheral.generic.data;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonParseException;
 | 
			
		||||
import dan200.computercraft.shared.util.NBTUtil;
 | 
			
		||||
import net.minecraft.enchantment.Enchantment;
 | 
			
		||||
import net.minecraft.enchantment.EnchantmentHelper;
 | 
			
		||||
import net.minecraft.item.EnchantedBookItem;
 | 
			
		||||
@@ -22,13 +23,26 @@ import javax.annotation.Nullable;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Data providers for items.
 | 
			
		||||
 */
 | 
			
		||||
public class ItemData
 | 
			
		||||
{
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static <T extends Map<? super String, Object>> T fillBasic( @Nonnull T data, @Nonnull ItemStack stack )
 | 
			
		||||
    public static <T extends Map<? super String, Object>> T fillBasicSafe( @Nonnull T data, @Nonnull ItemStack stack )
 | 
			
		||||
    {
 | 
			
		||||
        data.put( "name", DataHelpers.getId( stack.getItem() ) );
 | 
			
		||||
        data.put( "count", stack.getCount() );
 | 
			
		||||
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static <T extends Map<? super String, Object>> T fillBasic( @Nonnull T data, @Nonnull ItemStack stack )
 | 
			
		||||
    {
 | 
			
		||||
        fillBasicSafe( data, stack );
 | 
			
		||||
        String hash = NBTUtil.getNBTHash( stack.getTag() );
 | 
			
		||||
        if( hash != null ) data.put( "nbt", hash );
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -93,7 +107,7 @@ public class ItemData
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            return ITextComponent.Serializer.func_240643_a_( x.getString() );
 | 
			
		||||
            return ITextComponent.Serializer.fromJson( x.getString() );
 | 
			
		||||
        }
 | 
			
		||||
        catch( JsonParseException e )
 | 
			
		||||
        {
 | 
			
		||||
@@ -144,7 +158,7 @@ public class ItemData
 | 
			
		||||
 | 
			
		||||
        enchants.ensureCapacity( enchants.size() + rawEnchants.size() );
 | 
			
		||||
 | 
			
		||||
        for( Map.Entry<Enchantment, Integer> entry : EnchantmentHelper.deserializeEnchantments( rawEnchants ).entrySet() )
 | 
			
		||||
        for( Map.Entry<Enchantment, Integer> entry : EnchantmentHelper.func_226652_a_( rawEnchants ).entrySet() )
 | 
			
		||||
        {
 | 
			
		||||
            Enchantment enchantment = entry.getKey();
 | 
			
		||||
            Integer level = entry.getValue();
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ import dan200.computercraft.api.network.IPacketSender;
 | 
			
		||||
import dan200.computercraft.api.network.Packet;
 | 
			
		||||
import dan200.computercraft.api.peripheral.IComputerAccess;
 | 
			
		||||
import dan200.computercraft.api.peripheral.IPeripheral;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -171,7 +171,7 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
 | 
			
		||||
        parseChannel( replyChannel );
 | 
			
		||||
 | 
			
		||||
        World world = getWorld();
 | 
			
		||||
        Vector3d position = getPosition();
 | 
			
		||||
        Vec3d position = getPosition();
 | 
			
		||||
        IPacketNetwork network = m_network;
 | 
			
		||||
 | 
			
		||||
        if( world == null || position == null || network == null ) return;
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ import net.minecraft.block.BlockState;
 | 
			
		||||
import net.minecraft.block.IWaterLoggable;
 | 
			
		||||
import net.minecraft.entity.LivingEntity;
 | 
			
		||||
import net.minecraft.entity.player.PlayerEntity;
 | 
			
		||||
import net.minecraft.fluid.FluidState;
 | 
			
		||||
import net.minecraft.fluid.IFluidState;
 | 
			
		||||
import net.minecraft.item.BlockItemUseContext;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.state.BooleanProperty;
 | 
			
		||||
@@ -100,7 +100,7 @@ public class BlockCable extends BlockGeneric implements IWaterLoggable
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean removedByPlayer( BlockState state, World world, BlockPos pos, PlayerEntity player, boolean willHarvest, FluidState fluid )
 | 
			
		||||
    public boolean removedByPlayer( BlockState state, World world, BlockPos pos, PlayerEntity player, boolean willHarvest, IFluidState fluid )
 | 
			
		||||
    {
 | 
			
		||||
        if( state.get( CABLE ) && state.get( MODEM ).getFacing() != null )
 | 
			
		||||
        {
 | 
			
		||||
@@ -180,7 +180,7 @@ public class BlockCable extends BlockGeneric implements IWaterLoggable
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public FluidState getFluidState( @Nonnull BlockState state )
 | 
			
		||||
    public IFluidState getFluidState( @Nonnull BlockState state )
 | 
			
		||||
    {
 | 
			
		||||
        return getWaterloggedFluidState( state );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ public enum CableModemVariant implements IStringSerializable
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getString()
 | 
			
		||||
    public String getName()
 | 
			
		||||
    {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ import net.minecraft.util.Direction;
 | 
			
		||||
import net.minecraft.util.Hand;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.math.BlockRayTraceResult;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.util.text.TranslationTextComponent;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
import net.minecraftforge.common.capabilities.Capability;
 | 
			
		||||
@@ -58,10 +58,10 @@ public class TileCable extends TileGeneric
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public Vector3d getPosition()
 | 
			
		||||
        public Vec3d getPosition()
 | 
			
		||||
        {
 | 
			
		||||
            BlockPos pos = getPos();
 | 
			
		||||
            return new Vector3d( 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
 | 
			
		||||
@@ -103,10 +103,10 @@ public class TileCable extends TileGeneric
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public Vector3d getPosition()
 | 
			
		||||
        public Vec3d getPosition()
 | 
			
		||||
        {
 | 
			
		||||
            BlockPos pos = getPos().offset( modemDirection );
 | 
			
		||||
            return new Vector3d( 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 );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
@@ -281,9 +281,9 @@ public class TileCable extends TileGeneric
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void read( @Nonnull BlockState state, @Nonnull CompoundNBT nbt )
 | 
			
		||||
    public void read( @Nonnull CompoundNBT nbt )
 | 
			
		||||
    {
 | 
			
		||||
        super.read( state, nbt );
 | 
			
		||||
        super.read( nbt );
 | 
			
		||||
        m_peripheralAccessAllowed = nbt.getBoolean( NBT_PERIPHERAL_ENABLED );
 | 
			
		||||
        m_peripheral.read( nbt, "" );
 | 
			
		||||
    }
 | 
			
		||||
@@ -422,6 +422,12 @@ public class TileCable extends TileGeneric
 | 
			
		||||
        m_node.updatePeripherals( peripherals );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean canRenderBreaking()
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    public <T> LazyOptional<T> getCapability( @Nonnull Capability<T> capability, @Nullable Direction side )
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ import net.minecraft.util.Direction;
 | 
			
		||||
import net.minecraft.util.Hand;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.math.BlockRayTraceResult;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.util.text.StringTextComponent;
 | 
			
		||||
import net.minecraft.util.text.TranslationTextComponent;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
@@ -85,10 +85,10 @@ public class TileWiredModemFull extends TileGeneric
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public Vector3d getPosition()
 | 
			
		||||
        public Vec3d getPosition()
 | 
			
		||||
        {
 | 
			
		||||
            BlockPos pos = m_entity.getPos();
 | 
			
		||||
            return new Vector3d( 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 );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -217,17 +217,17 @@ public class TileWiredModemFull extends TileGeneric
 | 
			
		||||
        StringTextComponent base = new StringTextComponent( "" );
 | 
			
		||||
        for( int i = 0; i < names.size(); i++ )
 | 
			
		||||
        {
 | 
			
		||||
            if( i > 0 ) base.appendString( ", " );
 | 
			
		||||
            base.append( CommandCopy.createCopyText( names.get( i ) ) );
 | 
			
		||||
            if( i > 0 ) base.appendText( ", " );
 | 
			
		||||
            base.appendSibling( CommandCopy.createCopyText( names.get( i ) ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        player.sendStatusMessage( new TranslationTextComponent( kind, base ), false );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void read( @Nonnull BlockState state, @Nonnull CompoundNBT nbt )
 | 
			
		||||
    public void read( @Nonnull CompoundNBT nbt )
 | 
			
		||||
    {
 | 
			
		||||
        super.read( state, nbt );
 | 
			
		||||
        super.read( nbt );
 | 
			
		||||
        m_peripheralAccessAllowed = nbt.getBoolean( NBT_PERIPHERAL_ENABLED );
 | 
			
		||||
        for( int i = 0; i < m_peripherals.length; i++ ) m_peripherals[i].read( nbt, Integer.toString( i ) );
 | 
			
		||||
    }
 | 
			
		||||
@@ -399,10 +399,10 @@ public class TileWiredModemFull extends TileGeneric
 | 
			
		||||
 | 
			
		||||
            @Nonnull
 | 
			
		||||
            @Override
 | 
			
		||||
            public Vector3d getPosition()
 | 
			
		||||
            public Vec3d getPosition()
 | 
			
		||||
            {
 | 
			
		||||
                BlockPos pos = getPos().offset( side );
 | 
			
		||||
                return new Vector3d( 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 );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Nonnull
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ import dan200.computercraft.shared.peripheral.modem.ModemShapes;
 | 
			
		||||
import net.minecraft.block.Block;
 | 
			
		||||
import net.minecraft.block.BlockState;
 | 
			
		||||
import net.minecraft.block.IWaterLoggable;
 | 
			
		||||
import net.minecraft.fluid.FluidState;
 | 
			
		||||
import net.minecraft.fluid.IFluidState;
 | 
			
		||||
import net.minecraft.item.BlockItemUseContext;
 | 
			
		||||
import net.minecraft.state.BooleanProperty;
 | 
			
		||||
import net.minecraft.state.DirectionProperty;
 | 
			
		||||
@@ -62,7 +62,7 @@ public class BlockWirelessModem extends BlockGeneric implements IWaterLoggable
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public FluidState getFluidState( @Nonnull BlockState state )
 | 
			
		||||
    public IFluidState getFluidState( @Nonnull BlockState state )
 | 
			
		||||
    {
 | 
			
		||||
        return getWaterloggedFluidState( state );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ import net.minecraft.block.BlockState;
 | 
			
		||||
import net.minecraft.tileentity.TileEntityType;
 | 
			
		||||
import net.minecraft.util.Direction;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
import net.minecraftforge.common.capabilities.Capability;
 | 
			
		||||
import net.minecraftforge.common.util.LazyOptional;
 | 
			
		||||
@@ -46,10 +46,10 @@ public class TileWirelessModem extends TileGeneric
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public Vector3d getPosition()
 | 
			
		||||
        public Vec3d getPosition()
 | 
			
		||||
        {
 | 
			
		||||
            BlockPos pos = entity.getPos().offset( entity.modemDirection );
 | 
			
		||||
            return new Vector3d( pos.getX(), pos.getY(), pos.getZ() );
 | 
			
		||||
            return new Vec3d( pos.getX(), pos.getY(), pos.getZ() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.api.network.IPacketNetwork;
 | 
			
		||||
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
 | 
			
		||||
import dan200.computercraft.shared.peripheral.modem.ModemState;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
 | 
			
		||||
public abstract class WirelessModemPeripheral extends ModemPeripheral
 | 
			
		||||
@@ -40,7 +40,7 @@ public abstract class WirelessModemPeripheral extends ModemPeripheral
 | 
			
		||||
            World world = getWorld();
 | 
			
		||||
            if( world != null )
 | 
			
		||||
            {
 | 
			
		||||
                Vector3d position = getPosition();
 | 
			
		||||
                Vec3d position = getPosition();
 | 
			
		||||
                double minRange = ComputerCraft.modemRange;
 | 
			
		||||
                double maxRange = ComputerCraft.modemHighAltitudeRange;
 | 
			
		||||
                if( world.isRaining() && world.isThundering() )
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@ public final class ClientMonitor extends ClientTerminal
 | 
			
		||||
                GL15.glBufferData( GL31.GL_TEXTURE_BUFFER, 0, GL15.GL_STATIC_DRAW );
 | 
			
		||||
                tboTexture = GlStateManager.genTexture();
 | 
			
		||||
                GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, tboTexture );
 | 
			
		||||
                GL31.glTexBuffer( GL31.GL_TEXTURE_BUFFER, GL30.GL_R8, tboBuffer );
 | 
			
		||||
                GL31.glTexBuffer( GL31.GL_TEXTURE_BUFFER, GL30.GL_R8UI, tboBuffer );
 | 
			
		||||
                GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, 0 );
 | 
			
		||||
 | 
			
		||||
                GlStateManager.bindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ public enum MonitorEdgeState implements IStringSerializable
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getString()
 | 
			
		||||
    public String getName()
 | 
			
		||||
    {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,6 @@ import dan200.computercraft.shared.common.TileGeneric;
 | 
			
		||||
import dan200.computercraft.shared.network.client.TerminalState;
 | 
			
		||||
import dan200.computercraft.shared.util.CapabilityUtil;
 | 
			
		||||
import dan200.computercraft.shared.util.TickScheduler;
 | 
			
		||||
import net.minecraft.block.BlockState;
 | 
			
		||||
import net.minecraft.entity.player.PlayerEntity;
 | 
			
		||||
import net.minecraft.nbt.CompoundNBT;
 | 
			
		||||
import net.minecraft.tileentity.TileEntity;
 | 
			
		||||
@@ -135,14 +134,13 @@ public class TileMonitor extends TileGeneric
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void read( @Nonnull BlockState state, @Nonnull CompoundNBT nbt )
 | 
			
		||||
    public void read( @Nonnull CompoundNBT tag )
 | 
			
		||||
    {
 | 
			
		||||
        super.read( state, nbt );
 | 
			
		||||
 | 
			
		||||
        m_xIndex = nbt.getInt( NBT_X );
 | 
			
		||||
        m_yIndex = nbt.getInt( NBT_Y );
 | 
			
		||||
        m_width = nbt.getInt( NBT_WIDTH );
 | 
			
		||||
        m_height = nbt.getInt( NBT_HEIGHT );
 | 
			
		||||
        super.read( tag );
 | 
			
		||||
        m_xIndex = tag.getInt( NBT_X );
 | 
			
		||||
        m_yIndex = tag.getInt( NBT_Y );
 | 
			
		||||
        m_width = tag.getInt( NBT_WIDTH );
 | 
			
		||||
        m_height = tag.getInt( NBT_HEIGHT );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,6 @@ import net.minecraft.inventory.IInventory;
 | 
			
		||||
import net.minecraft.inventory.Inventory;
 | 
			
		||||
import net.minecraft.inventory.container.Container;
 | 
			
		||||
import net.minecraft.inventory.container.Slot;
 | 
			
		||||
import net.minecraft.item.DyeItem;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.util.IIntArray;
 | 
			
		||||
import net.minecraft.util.IntArray;
 | 
			
		||||
@@ -95,7 +94,7 @@ public class ContainerPrinter extends Container
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // Transfer from inventory to printer
 | 
			
		||||
            if( stack.getItem() instanceof DyeItem )
 | 
			
		||||
            if( TilePrinter.isInk( stack ) )
 | 
			
		||||
            {
 | 
			
		||||
                if( !mergeItemStack( stack, 0, 1, false ) ) return ItemStack.EMPTY;
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -46,8 +46,8 @@ public class PrinterPeripheral implements IPeripheral
 | 
			
		||||
     * Writes text to the current page.
 | 
			
		||||
     *
 | 
			
		||||
     * @param arguments The values to write to the page.
 | 
			
		||||
     * @throws LuaException If any values couldn't be converted to a string, or if no page is started.
 | 
			
		||||
     * @cc.tparam string|number ... The values to write to the page.
 | 
			
		||||
     * @throws LuaException If any values couldn't be converted to a string, or if no page is started.
 | 
			
		||||
     */
 | 
			
		||||
    @LuaFunction
 | 
			
		||||
    public final void write( IArguments arguments ) throws LuaException
 | 
			
		||||
@@ -62,9 +62,9 @@ public class PrinterPeripheral implements IPeripheral
 | 
			
		||||
     * Returns the current position of the cursor on the page.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The position of the cursor.
 | 
			
		||||
     * @throws LuaException If a page isn't being printed.
 | 
			
		||||
     * @cc.treturn number The X position of the cursor.
 | 
			
		||||
     * @cc.treturn number The Y position of the cursor.
 | 
			
		||||
     * @throws LuaException If a page isn't being printed.
 | 
			
		||||
     */
 | 
			
		||||
    @LuaFunction
 | 
			
		||||
    public final Object[] getCursorPos() throws LuaException
 | 
			
		||||
@@ -93,9 +93,9 @@ public class PrinterPeripheral implements IPeripheral
 | 
			
		||||
     * Returns the size of the current page.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The size of the page.
 | 
			
		||||
     * @throws LuaException If a page isn't being printed.
 | 
			
		||||
     * @cc.treturn number The width of the page.
 | 
			
		||||
     * @cc.treturn number The height of the page.
 | 
			
		||||
     * @throws LuaException If a page isn't being printed.
 | 
			
		||||
     */
 | 
			
		||||
    @LuaFunction
 | 
			
		||||
    public final Object[] getPageSize() throws LuaException
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ import net.minecraft.nbt.CompoundNBT;
 | 
			
		||||
import net.minecraft.tileentity.TileEntityType;
 | 
			
		||||
import net.minecraft.util.*;
 | 
			
		||||
import net.minecraft.util.math.BlockRayTraceResult;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
import net.minecraft.util.text.TranslationTextComponent;
 | 
			
		||||
import net.minecraftforge.common.capabilities.Capability;
 | 
			
		||||
@@ -91,11 +91,11 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void read( @Nonnull BlockState state, @Nonnull CompoundNBT nbt )
 | 
			
		||||
    public void read( @Nonnull CompoundNBT nbt )
 | 
			
		||||
    {
 | 
			
		||||
        super.read( state, nbt );
 | 
			
		||||
        super.read( nbt );
 | 
			
		||||
 | 
			
		||||
        customName = nbt.contains( NBT_NAME ) ? ITextComponent.Serializer.func_240643_a_( nbt.getString( NBT_NAME ) ) : null;
 | 
			
		||||
        customName = nbt.contains( NBT_NAME ) ? ITextComponent.Serializer.fromJson( nbt.getString( NBT_NAME ) ) : null;
 | 
			
		||||
 | 
			
		||||
        // Read page
 | 
			
		||||
        synchronized( m_page )
 | 
			
		||||
@@ -300,9 +300,9 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static boolean isInk( @Nonnull ItemStack stack )
 | 
			
		||||
    static boolean isInk( @Nonnull ItemStack stack )
 | 
			
		||||
    {
 | 
			
		||||
        return stack.getItem() instanceof DyeItem;
 | 
			
		||||
        return ColourUtils.getStackColour( stack ) != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static boolean isPaper( @Nonnull ItemStack stack )
 | 
			
		||||
@@ -321,7 +321,8 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
 | 
			
		||||
    private boolean inputPage()
 | 
			
		||||
    {
 | 
			
		||||
        ItemStack inkStack = m_inventory.get( 0 );
 | 
			
		||||
        if( !isInk( inkStack ) ) return false;
 | 
			
		||||
        DyeColor dye = ColourUtils.getStackColour( inkStack );
 | 
			
		||||
        if( dye == null ) return false;
 | 
			
		||||
 | 
			
		||||
        for( int i = 1; i < 7; i++ )
 | 
			
		||||
        {
 | 
			
		||||
@@ -329,8 +330,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
 | 
			
		||||
            if( paperStack.isEmpty() || !isPaper( paperStack ) ) continue;
 | 
			
		||||
 | 
			
		||||
            // Setup the new page
 | 
			
		||||
            DyeColor dye = ColourUtils.getStackColour( inkStack );
 | 
			
		||||
            m_page.setTextColour( dye != null ? dye.getId() : 15 );
 | 
			
		||||
            m_page.setTextColour( dye.getId() );
 | 
			
		||||
 | 
			
		||||
            m_page.clear();
 | 
			
		||||
            if( paperStack.getItem() instanceof ItemPrintout )
 | 
			
		||||
@@ -403,7 +403,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
 | 
			
		||||
                setInventorySlotContents( i, ItemStack.EMPTY );
 | 
			
		||||
 | 
			
		||||
                // Spawn the item in the world
 | 
			
		||||
                WorldUtil.dropItemStack( stack, getWorld(), Vector3d.copy( getPos() ).add( 0.5, 0.75, 0.5 ) );
 | 
			
		||||
                WorldUtil.dropItemStack( stack, getWorld(), new Vec3d( getPos() ).add( 0.5, 0.75, 0.5 ) );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ import net.minecraft.state.properties.NoteBlockInstrument;
 | 
			
		||||
import net.minecraft.util.ResourceLocation;
 | 
			
		||||
import net.minecraft.util.ResourceLocationException;
 | 
			
		||||
import net.minecraft.util.SoundCategory;
 | 
			
		||||
import net.minecraft.util.math.vector.Vector3d;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.world.World;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -44,7 +44,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
 | 
			
		||||
 | 
			
		||||
    public abstract World getWorld();
 | 
			
		||||
 | 
			
		||||
    public abstract Vector3d getPosition();
 | 
			
		||||
    public abstract Vec3d getPosition();
 | 
			
		||||
 | 
			
		||||
    public boolean madeSound( long ticks )
 | 
			
		||||
    {
 | 
			
		||||
@@ -66,9 +66,9 @@ public abstract class SpeakerPeripheral implements IPeripheral
 | 
			
		||||
     * with an optional volume and speed multiplier, and plays it through the speaker.
 | 
			
		||||
     *
 | 
			
		||||
     * @param context The Lua context
 | 
			
		||||
     * @param name    The name of the sound to play.
 | 
			
		||||
     * @param name The name of the sound to play.
 | 
			
		||||
     * @param volumeA The volume to play the sound at, from 0.0 to 3.0. Defaults to 1.0.
 | 
			
		||||
     * @param pitchA  The speed to play the sound at, from 0.5 to 2.0. Defaults to 1.0.
 | 
			
		||||
     * @param pitchA The speed to play the sound at, from 0.5 to 2.0. Defaults to 1.0.
 | 
			
		||||
     * @return Whether the sound could be played.
 | 
			
		||||
     * @throws LuaException If the sound name couldn't be decoded.
 | 
			
		||||
     */
 | 
			
		||||
@@ -102,9 +102,9 @@ public abstract class SpeakerPeripheral implements IPeripheral
 | 
			
		||||
     * and 6 and 18 map to C.
 | 
			
		||||
     *
 | 
			
		||||
     * @param context The Lua context
 | 
			
		||||
     * @param name    The name of the note to play.
 | 
			
		||||
     * @param name The name of the note to play.
 | 
			
		||||
     * @param volumeA The volume to play the note at, from 0.0 to 3.0. Defaults to 1.0.
 | 
			
		||||
     * @param pitchA  The pitch to play the note at in semitones, from 0 to 24. Defaults to 12.
 | 
			
		||||
     * @param pitchA The pitch to play the note at in semitones, from 0 to 24. Defaults to 12.
 | 
			
		||||
     * @return Whether the note could be played.
 | 
			
		||||
     * @throws LuaException If the instrument doesn't exist.
 | 
			
		||||
     */
 | 
			
		||||
@@ -117,7 +117,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
 | 
			
		||||
        NoteBlockInstrument instrument = null;
 | 
			
		||||
        for( NoteBlockInstrument testInstrument : NoteBlockInstrument.values() )
 | 
			
		||||
        {
 | 
			
		||||
            if( testInstrument.getString().equalsIgnoreCase( name ) )
 | 
			
		||||
            if( testInstrument.getName().equalsIgnoreCase( name ) )
 | 
			
		||||
            {
 | 
			
		||||
                instrument = testInstrument;
 | 
			
		||||
                break;
 | 
			
		||||
@@ -144,7 +144,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        World world = getWorld();
 | 
			
		||||
        Vector3d pos = getPosition();
 | 
			
		||||
        Vec3d pos = getPosition();
 | 
			
		||||
 | 
			
		||||
        context.issueMainThreadTask( () -> {
 | 
			
		||||
            MinecraftServer server = world.getServer();
 | 
			
		||||
@@ -152,7 +152,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
 | 
			
		||||
 | 
			
		||||
            float adjVolume = Math.min( volume, 3.0f );
 | 
			
		||||
            server.getPlayerList().sendToAllNearExcept(
 | 
			
		||||
                null, pos.x, pos.y, pos.z, adjVolume > 1.0f ? 16 * adjVolume : 16.0, world.func_234923_W_(),
 | 
			
		||||
                null, pos.x, pos.y, pos.z, adjVolume > 1.0f ? 16 * adjVolume : 16.0, world.dimension.getType(),
 | 
			
		||||
                new SPlaySoundPacket( name, SoundCategory.RECORDS, pos, adjVolume, pitch )
 | 
			
		||||
            );
 | 
			
		||||
            return null;
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user