mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-18 15:37:38 +00:00
Compare commits
60 Commits
v1.19.3-1.
...
v1.19.3-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9e6e0c8b88 | ||
![]() |
5502412181 | ||
![]() |
62e3c5f9aa | ||
![]() |
7e54a40fa9 | ||
![]() |
8ac42566ec | ||
![]() |
66b20d2bdb | ||
![]() |
81dad421d5 | ||
![]() |
3075d3cea8 | ||
![]() |
cdab8f429e | ||
![]() |
2e5cd29e12 | ||
![]() |
22cadd6730 | ||
![]() |
366052ec48 | ||
![]() |
3224e0bf8b | ||
![]() |
fb4b097a66 | ||
![]() |
67f3d91850 | ||
![]() |
1e3a930543 | ||
![]() |
b21e2f4e63 | ||
![]() |
a12b405acf | ||
![]() |
e076818b29 | ||
![]() |
1554c7b397 | ||
![]() |
6cd32a6368 | ||
![]() |
7335a892b5 | ||
![]() |
83eddc6636 | ||
![]() |
d066d175bf | ||
![]() |
9873ccfa0d | ||
![]() |
da7a50368d | ||
![]() |
8cfbfe7ceb | ||
![]() |
67244b17af | ||
![]() |
9e1de23f4a | ||
![]() |
86b60855d6 | ||
![]() |
db6b6fd173 | ||
![]() |
2014e9527e | ||
![]() |
f43b839056 | ||
![]() |
f561572509 | ||
![]() |
edb21f33be | ||
![]() |
02b68b259e | ||
![]() |
28a55349a9 | ||
![]() |
2457a31728 | ||
![]() |
cdc91a8e5d | ||
![]() |
8024017f53 | ||
![]() |
592ff84aea | ||
![]() |
4360458416 | ||
![]() |
717e096b94 | ||
![]() |
34a31abd9c | ||
![]() |
bdecb88cca | ||
![]() |
af15030fa4 | ||
![]() |
3a883db49e | ||
![]() |
8ea5b64f64 | ||
![]() |
7b6caf76e4 | ||
![]() |
230c7ee904 | ||
![]() |
aa203802c6 | ||
![]() |
1259e29f21 | ||
![]() |
77f62dac94 | ||
![]() |
7f34aff6bb | ||
![]() |
3047e3cdf4 | ||
![]() |
7a83a403f0 | ||
![]() |
a1d5c76d00 | ||
![]() |
bcdfa7c5ff | ||
![]() |
2c59b9122b | ||
![]() |
d2c7b944ab |
8
.github/workflows/main-ci.yml
vendored
8
.github/workflows/main-ci.yml
vendored
@@ -38,11 +38,17 @@ jobs:
|
|||||||
# These are a little flaky on GH actions: its useful to run them, but don't break the build.
|
# These are a little flaky on GH actions: its useful to run them, but don't break the build.
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Prepare Jars
|
||||||
|
run: |
|
||||||
|
# Find the main jar and append the git hash onto it.
|
||||||
|
mkdir -p jars
|
||||||
|
find projects/forge/build/libs projects/fabric/build/libs -type f -regex '.*[0-9.]+\(-SNAPSHOT\)?\.jar$' -exec bash -c 'cp {} "jars/$(basename {} .jar)-$(git rev-parse HEAD).jar"' \;
|
||||||
|
|
||||||
- name: Upload Jar
|
- name: Upload Jar
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: CC-Tweaked
|
name: CC-Tweaked
|
||||||
path: projects/forge/build/libs
|
path: ./jars
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v3
|
uses: codecov/codecov-action@v3
|
||||||
|
@@ -80,7 +80,7 @@ sourceSets.all {
|
|||||||
check("FutureReturnValueIgnored", CheckSeverity.OFF) // Too many false positives with Netty
|
check("FutureReturnValueIgnored", CheckSeverity.OFF) // Too many false positives with Netty
|
||||||
|
|
||||||
check("NullAway", CheckSeverity.ERROR)
|
check("NullAway", CheckSeverity.ERROR)
|
||||||
option("NullAway:AnnotatedPackages", listOf("dan200.computercraft").joinToString(","))
|
option("NullAway:AnnotatedPackages", listOf("dan200.computercraft", "net.fabricmc.fabric.api").joinToString(","))
|
||||||
option("NullAway:ExcludedFieldAnnotations", listOf("org.spongepowered.asm.mixin.Shadow").joinToString(","))
|
option("NullAway:ExcludedFieldAnnotations", listOf("org.spongepowered.asm.mixin.Shadow").joinToString(","))
|
||||||
option("NullAway:CastToNonNullMethod", "dan200.computercraft.core.util.Nullability.assertNonNull")
|
option("NullAway:CastToNonNullMethod", "dan200.computercraft.core.util.Nullability.assertNonNull")
|
||||||
option("NullAway:CheckOptionalEmptiness")
|
option("NullAway:CheckOptionalEmptiness")
|
||||||
|
@@ -34,7 +34,7 @@ abstract class CheckChangelog : DefaultTask() {
|
|||||||
|
|
||||||
var ok = true
|
var ok = true
|
||||||
|
|
||||||
// Check we're targetting the current version
|
// Check we're targeting the current version
|
||||||
var whatsNew = whatsNew.get().asFile.readLines()
|
var whatsNew = whatsNew.get().asFile.readLines()
|
||||||
if (whatsNew[0] != "New features in CC: Tweaked $version") {
|
if (whatsNew[0] != "New features in CC: Tweaked $version") {
|
||||||
ok = false
|
ok = false
|
||||||
|
@@ -3,19 +3,20 @@ module: [kind=event] alarm
|
|||||||
see: os.setAlarm To start an alarm.
|
see: os.setAlarm To start an alarm.
|
||||||
---
|
---
|
||||||
|
|
||||||
The @{timer} event is fired when an alarm started with @{os.setAlarm} completes.
|
The @{alarm} event is fired when an alarm started with @{os.setAlarm} completes.
|
||||||
|
|
||||||
## Return Values
|
## Return Values
|
||||||
1. @{string}: The event name.
|
1. @{string}: The event name.
|
||||||
2. @{number}: The ID of the alarm that finished.
|
2. @{number}: The ID of the alarm that finished.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Starts a timer and then prints its ID:
|
Starts a timer and then waits for it to complete.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
local alarmID = os.setAlarm(os.time() + 0.05)
|
local alarm_id = os.setAlarm(os.time() + 0.05)
|
||||||
local event, id
|
local event, id
|
||||||
repeat
|
repeat
|
||||||
event, id = os.pullEvent("alarm")
|
event, id = os.pullEvent("alarm")
|
||||||
until id == alarmID
|
until id == alarm_id
|
||||||
print("Alarm with ID " .. id .. " was fired")
|
print("Alarm with ID " .. id .. " was fired")
|
||||||
```
|
```
|
||||||
|
@@ -3,7 +3,7 @@ module: [kind=event] char
|
|||||||
see: key To listen to any key press.
|
see: key To listen to any key press.
|
||||||
---
|
---
|
||||||
|
|
||||||
The @{char} event is fired when a character is _typed_ on the keyboard.
|
The @{char} event is fired when a character is typed on the keyboard.
|
||||||
|
|
||||||
The @{char} event is different to a key press. Sometimes multiple key presses may result in one character being
|
The @{char} event is different to a key press. Sometimes multiple key presses may result in one character being
|
||||||
typed (for instance, on some European keyboards). Similarly, some keys (e.g. <kbd>Ctrl</kbd>) do not have any
|
typed (for instance, on some European keyboards). Similarly, some keys (e.g. <kbd>Ctrl</kbd>) do not have any
|
||||||
@@ -16,9 +16,10 @@ corresponding character. The @{key} should be used if you want to listen to key
|
|||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints each character the user presses:
|
Prints each character the user presses:
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
while true do
|
while true do
|
||||||
local event, character = os.pullEvent("char")
|
local event, character = os.pullEvent("char")
|
||||||
print(character .. " was pressed.")
|
print(character .. " was pressed.")
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
@@ -6,7 +6,7 @@ The @{computer_command} event is fired when the `/computercraft queue` command i
|
|||||||
|
|
||||||
## Return Values
|
## Return Values
|
||||||
1. @{string}: The event name.
|
1. @{string}: The event name.
|
||||||
... @{string}: The arguments passed to the command.
|
2. @{string}<abbr title="Variable number of arguments">…</abbr>: The arguments passed to the command.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints the contents of messages sent:
|
Prints the contents of messages sent:
|
||||||
|
@@ -5,9 +5,9 @@ since: 1.101.0
|
|||||||
|
|
||||||
The @{file_transfer} event is queued when a user drags-and-drops a file on an open computer.
|
The @{file_transfer} event is queued when a user drags-and-drops a file on an open computer.
|
||||||
|
|
||||||
This event contains a single argument, that in turn has a single method @{TransferredFiles.getFiles|getFiles}. This
|
This event contains a single argument of type @{TransferredFiles}, which can be used to @{TransferredFiles.getFiles|get
|
||||||
returns the list of files that are being transferred. Each file is a @{fs.BinaryReadHandle|binary file handle} with an
|
the files to be transferred}. Each file returned is a @{fs.BinaryReadHandle|binary file handle} with an additional
|
||||||
additional @{TransferredFile.getName|getName} method.
|
@{TransferredFile.getName|getName} method.
|
||||||
|
|
||||||
## Return values
|
## Return values
|
||||||
1. @{string}: The event name
|
1. @{string}: The event name
|
||||||
|
@@ -11,4 +11,4 @@ This event is normally handled inside @{http.checkURL}, but it can still be seen
|
|||||||
1. @{string}: The event name.
|
1. @{string}: The event name.
|
||||||
2. @{string}: The URL requested to be checked.
|
2. @{string}: The URL requested to be checked.
|
||||||
3. @{boolean}: Whether the check succeeded.
|
3. @{boolean}: Whether the check succeeded.
|
||||||
4. @{string|nil}: If the check failed, a reason explaining why the check failed.
|
4. <span class="type">@{string}|@{nil}</span>: If the check failed, a reason explaining why the check failed.
|
||||||
|
@@ -11,7 +11,8 @@ This event is normally handled inside @{http.get} and @{http.post}, but it can s
|
|||||||
1. @{string}: The event name.
|
1. @{string}: The event name.
|
||||||
2. @{string}: The URL of the site requested.
|
2. @{string}: The URL of the site requested.
|
||||||
3. @{string}: An error describing the failure.
|
3. @{string}: An error describing the failure.
|
||||||
4. @{http.Response|nil}: A response handle if the connection succeeded, but the server's response indicated failure.
|
4. <span class="type">@{http.Response}|@{nil}</span>: A response handle if the connection succeeded, but the server's
|
||||||
|
response indicated failure.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints an error why the website cannot be contacted:
|
Prints an error why the website cannot be contacted:
|
||||||
|
@@ -10,7 +10,7 @@ This event is normally handled inside @{http.get} and @{http.post}, but it can s
|
|||||||
## Return Values
|
## Return Values
|
||||||
1. @{string}: The event name.
|
1. @{string}: The event name.
|
||||||
2. @{string}: The URL of the site requested.
|
2. @{string}: The URL of the site requested.
|
||||||
3. @{http.Response}: The handle for the response text.
|
3. @{http.Response}: The successful HTTP response.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints the content of a website (this may fail if the request fails):
|
Prints the content of a website (this may fail if the request fails):
|
||||||
|
@@ -10,7 +10,7 @@ The @{modem_message} event is fired when a message is received on an open channe
|
|||||||
3. @{number}: The channel that the message was sent on.
|
3. @{number}: The channel that the message was sent on.
|
||||||
4. @{number}: The reply channel set by the sender.
|
4. @{number}: The reply channel set by the sender.
|
||||||
5. @{any}: The message as sent by the sender.
|
5. @{any}: The message as sent by the sender.
|
||||||
6. @{number}: The distance between the sender and the receiver, in blocks.
|
6. <span class="type">@{number}|@{nil}</span>: The distance between the sender and the receiver in blocks, or @{nil} if the message was sent between dimensions.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Wraps a @{modem} peripheral, opens channel 0 for listening, and prints all received messages.
|
Wraps a @{modem} peripheral, opens channel 0 for listening, and prints all received messages.
|
||||||
@@ -20,7 +20,9 @@ local modem = peripheral.find("modem") or error("No modem attached", 0)
|
|||||||
modem.open(0)
|
modem.open(0)
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
|
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
|
||||||
print(("Message received on side %s on channel %d (reply to %d) from %f blocks away with message %s"):format(side, channel, replyChannel, distance, tostring(message)))
|
print(("Message received on side %s on channel %d (reply to %d) from %f blocks away with message %s"):format(
|
||||||
|
side, channel, replyChannel, distance, tostring(message)
|
||||||
|
))
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
@@ -6,10 +6,11 @@ The @{monitor_resize} event is fired when an adjacent or networked monitor's siz
|
|||||||
|
|
||||||
## Return Values
|
## Return Values
|
||||||
1. @{string}: The event name.
|
1. @{string}: The event name.
|
||||||
2. @{string}: The side or network ID of the monitor that resized.
|
2. @{string}: The side or network ID of the monitor that was resized.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints a message when a monitor is resized:
|
Prints a message when a monitor is resized:
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
while true do
|
while true do
|
||||||
local event, side = os.pullEvent("monitor_resize")
|
local event, side = os.pullEvent("monitor_resize")
|
||||||
|
@@ -14,7 +14,7 @@ This event is usually handled by @{rednet.receive}, but it can also be pulled ma
|
|||||||
1. @{string}: The event name.
|
1. @{string}: The event name.
|
||||||
2. @{number}: The ID of the sending computer.
|
2. @{number}: The ID of the sending computer.
|
||||||
3. @{any}: The message sent.
|
3. @{any}: The message sent.
|
||||||
4. @{string|nil}: The protocol of the message, if provided.
|
4. <span class="type">@{string}|@{nil}</span>: The protocol of the message, if provided.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints a message when one is sent:
|
Prints a message when one is sent:
|
||||||
|
@@ -4,6 +4,9 @@ module: [kind=event] redstone
|
|||||||
|
|
||||||
The @{event!redstone} event is fired whenever any redstone inputs on the computer change.
|
The @{event!redstone} event is fired whenever any redstone inputs on the computer change.
|
||||||
|
|
||||||
|
## Return values
|
||||||
|
1. @{string}: The event name.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints a message when a redstone input changes:
|
Prints a message when a redstone input changes:
|
||||||
```lua
|
```lua
|
||||||
|
@@ -10,7 +10,7 @@ The @{task_complete} event is fired when an asynchronous task completes. This is
|
|||||||
2. @{number}: The ID of the task that completed.
|
2. @{number}: The ID of the task that completed.
|
||||||
3. @{boolean}: Whether the command succeeded.
|
3. @{boolean}: Whether the command succeeded.
|
||||||
4. @{string}: If the command failed, an error message explaining the failure. (This is not present if the command succeeded.)
|
4. @{string}: If the command failed, an error message explaining the failure. (This is not present if the command succeeded.)
|
||||||
...: Any parameters returned from the command.
|
5. <abbr title="Variable number of arguments">…</abbr>: Any parameters returned from the command.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints the results of an asynchronous command:
|
Prints the results of an asynchronous command:
|
||||||
|
@@ -9,8 +9,12 @@ The @{term_resize} event is fired when the main terminal is resized. For instanc
|
|||||||
When this event fires, some parts of the terminal may have been moved or deleted. Simple terminal programs (those
|
When this event fires, some parts of the terminal may have been moved or deleted. Simple terminal programs (those
|
||||||
not using @{term.setCursorPos}) can ignore this event, but more complex GUI programs should redraw the entire screen.
|
not using @{term.setCursorPos}) can ignore this event, but more complex GUI programs should redraw the entire screen.
|
||||||
|
|
||||||
|
## Return values
|
||||||
|
1. @{string}: The event name.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints :
|
Print a message each time the terminal is resized.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
while true do
|
while true do
|
||||||
os.pullEvent("term_resize")
|
os.pullEvent("term_resize")
|
||||||
|
@@ -8,6 +8,9 @@ This event is normally handled by @{os.pullEvent}, and will not be returned. How
|
|||||||
|
|
||||||
@{terminate} will be sent even when a filter is provided to @{os.pullEventRaw}. When using @{os.pullEventRaw} with a filter, make sure to check that the event is not @{terminate}.
|
@{terminate} will be sent even when a filter is provided to @{os.pullEventRaw}. When using @{os.pullEventRaw} with a filter, make sure to check that the event is not @{terminate}.
|
||||||
|
|
||||||
|
## Return values
|
||||||
|
1. @{string}: The event name.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints a message when Ctrl-T is held:
|
Prints a message when Ctrl-T is held:
|
||||||
```lua
|
```lua
|
||||||
|
@@ -10,12 +10,12 @@ The @{timer} event is fired when a timer started with @{os.startTimer} completes
|
|||||||
2. @{number}: The ID of the timer that finished.
|
2. @{number}: The ID of the timer that finished.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Starts a timer and then prints its ID:
|
Start and wait for a timer to finish.
|
||||||
```lua
|
```lua
|
||||||
local timerID = os.startTimer(2)
|
local timer_id = os.startTimer(2)
|
||||||
local event, id
|
local event, id
|
||||||
repeat
|
repeat
|
||||||
event, id = os.pullEvent("timer")
|
event, id = os.pullEvent("timer")
|
||||||
until id == timerID
|
until id == timer_id
|
||||||
print("Timer with ID " .. id .. " was fired")
|
print("Timer with ID " .. id .. " was fired")
|
||||||
```
|
```
|
||||||
|
@@ -4,6 +4,9 @@ module: [kind=event] turtle_inventory
|
|||||||
|
|
||||||
The @{turtle_inventory} event is fired when a turtle's inventory is changed.
|
The @{turtle_inventory} event is fired when a turtle's inventory is changed.
|
||||||
|
|
||||||
|
## Return values
|
||||||
|
1. @{string}: The event name.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints a message when the inventory is changed:
|
Prints a message when the inventory is changed:
|
||||||
```lua
|
```lua
|
||||||
|
@@ -25,7 +25,7 @@ single-player or multiplayer. Look for lines that look like this:
|
|||||||
```
|
```
|
||||||
|
|
||||||
On 1.95.0 and later, this will be a single entry with `host = "$private"`. On earlier versions, this will be a number of
|
On 1.95.0 and later, this will be a single entry with `host = "$private"`. On earlier versions, this will be a number of
|
||||||
`[[http.rules]]` with various IP addresses. You will want to remove all of the `[[http.rules]]` entires that have
|
`[[http.rules]]` with various IP addresses. You will want to remove all of the `[[http.rules]]` entries that have
|
||||||
`action = "deny"`. Then save the file and relaunch Minecraft (Server).
|
`action = "deny"`. Then save the file and relaunch Minecraft (Server).
|
||||||
|
|
||||||
Here's what it should look like after removing:
|
Here's what it should look like after removing:
|
||||||
@@ -54,7 +54,7 @@ like this:
|
|||||||
```toml
|
```toml
|
||||||
#A list of wildcards for domains or IP ranges that cannot be accessed through the "http" API on Computers.
|
#A list of wildcards for domains or IP ranges that cannot be accessed through the "http" API on Computers.
|
||||||
#If this is empty then all whitelisted domains will be accessible. Example: "*.github.com" will block access to all subdomains of github.com.
|
#If this is empty then all whitelisted domains will be accessible. Example: "*.github.com" will block access to all subdomains of github.com.
|
||||||
#You can use domain names ("pastebin.com"), wilcards ("*.pastebin.com") or CIDR notation ("127.0.0.0/8").
|
#You can use domain names ("pastebin.com"), wildcards ("*.pastebin.com") or CIDR notation ("127.0.0.0/8").
|
||||||
blacklist = ["127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fd00::/8"]
|
blacklist = ["127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fd00::/8"]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ Here's what it should look like after removing:
|
|||||||
```toml
|
```toml
|
||||||
#A list of wildcards for domains or IP ranges that cannot be accessed through the "http" API on Computers.
|
#A list of wildcards for domains or IP ranges that cannot be accessed through the "http" API on Computers.
|
||||||
#If this is empty then all whitelisted domains will be accessible. Example: "*.github.com" will block access to all subdomains of github.com.
|
#If this is empty then all whitelisted domains will be accessible. Example: "*.github.com" will block access to all subdomains of github.com.
|
||||||
#You can use domain names ("pastebin.com"), wilcards ("*.pastebin.com") or CIDR notation ("127.0.0.0/8").
|
#You can use domain names ("pastebin.com"), wildcards ("*.pastebin.com") or CIDR notation ("127.0.0.0/8").
|
||||||
blacklist = []
|
blacklist = []
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@@ -5,8 +5,8 @@ kotlin.stdlib.default.dependency=false
|
|||||||
kotlin.jvm.target.validation.mode=error
|
kotlin.jvm.target.validation.mode=error
|
||||||
|
|
||||||
# Mod properties
|
# Mod properties
|
||||||
isUnstable=true
|
isUnstable=false
|
||||||
modVersion=1.102.0
|
modVersion=1.103.0
|
||||||
|
|
||||||
# Minecraft properties: We want to configure this here so we can read it in settings.gradle
|
# Minecraft properties: We want to configure this here so we can read it in settings.gradle
|
||||||
mcVersion=1.19.3
|
mcVersion=1.19.3
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
# MC version is specified in gradle.properties, as we need that in settings.gradle.
|
# MC version is specified in gradle.properties, as we need that in settings.gradle.
|
||||||
fabric-api = "0.68.1+1.19.3"
|
fabric-api = "0.68.1+1.19.3"
|
||||||
fabric-loader = "0.14.11"
|
fabric-loader = "0.14.11"
|
||||||
forge = "44.0.18"
|
forge = "44.1.0"
|
||||||
forgeSpi = "6.0.0"
|
forgeSpi = "6.0.0"
|
||||||
mixin = "0.8.5"
|
mixin = "0.8.5"
|
||||||
parchment = "2022.11.27"
|
parchment = "2022.11.27"
|
||||||
@@ -14,19 +14,19 @@ parchmentMc = "1.19.2"
|
|||||||
asm = "9.3"
|
asm = "9.3"
|
||||||
autoService = "1.0.1"
|
autoService = "1.0.1"
|
||||||
checkerFramework = "3.12.0"
|
checkerFramework = "3.12.0"
|
||||||
cobalt = "0.5.9"
|
cobalt = "0.6.0"
|
||||||
fastutil = "8.5.9"
|
fastutil = "8.5.9"
|
||||||
guava = "31.1-jre"
|
guava = "31.1-jre"
|
||||||
jetbrainsAnnotations = "23.0.0"
|
jetbrainsAnnotations = "23.0.0"
|
||||||
jsr305 = "3.0.2"
|
jsr305 = "3.0.2"
|
||||||
kotlin = "1.7.10"
|
kotlin = "1.8.0"
|
||||||
kotlin-coroutines = "1.6.0"
|
kotlin-coroutines = "1.6.4"
|
||||||
netty = "4.1.82.Final"
|
netty = "4.1.82.Final"
|
||||||
nightConfig = "3.6.5"
|
nightConfig = "3.6.5"
|
||||||
slf4j = "1.7.36"
|
slf4j = "1.7.36"
|
||||||
|
|
||||||
# Minecraft mods
|
# Minecraft mods
|
||||||
forgeConfig = "5.0.3"
|
forgeConfig = "5.0.4"
|
||||||
iris = "1.19.3-v1.4.6"
|
iris = "1.19.3-v1.4.6"
|
||||||
jei = "11.3.0.262"
|
jei = "11.3.0.262"
|
||||||
modmenu = "5.0.1"
|
modmenu = "5.0.1"
|
||||||
@@ -42,7 +42,7 @@ jqwik = "1.7.0"
|
|||||||
junit = "5.9.1"
|
junit = "5.9.1"
|
||||||
|
|
||||||
# Build tools
|
# Build tools
|
||||||
cctJavadoc = "1.5.3"
|
cctJavadoc = "1.6.0"
|
||||||
checkstyle = "10.3.4"
|
checkstyle = "10.3.4"
|
||||||
curseForgeGradle = "1.0.11"
|
curseForgeGradle = "1.0.11"
|
||||||
errorProne-core = "2.14.0"
|
errorProne-core = "2.14.0"
|
||||||
@@ -51,7 +51,7 @@ fabric-loom = "1.0-SNAPSHOT"
|
|||||||
forgeGradle = "5.1.+"
|
forgeGradle = "5.1.+"
|
||||||
githubRelease = "2.2.12"
|
githubRelease = "2.2.12"
|
||||||
ideaExt = "1.1.6"
|
ideaExt = "1.1.6"
|
||||||
illuaminate = "0.1.0-7-g2a5a89c"
|
illuaminate = "0.1.0-13-g689d73d"
|
||||||
librarian = "1.+"
|
librarian = "1.+"
|
||||||
minotaur = "2.+"
|
minotaur = "2.+"
|
||||||
mixinGradle = "0.7.+"
|
mixinGradle = "0.7.+"
|
||||||
@@ -73,8 +73,9 @@ forgeSpi = { module = "net.minecraftforge:forgespi", version.ref = "forgeSpi" }
|
|||||||
guava = { module = "com.google.guava:guava", version.ref = "guava" }
|
guava = { module = "com.google.guava:guava", version.ref = "guava" }
|
||||||
jetbrainsAnnotations = { module = "org.jetbrains:annotations", version.ref = "jetbrainsAnnotations" }
|
jetbrainsAnnotations = { module = "org.jetbrains:annotations", version.ref = "jetbrainsAnnotations" }
|
||||||
jsr305 = { module = "com.google.code.findbugs:jsr305", version.ref = "jsr305" }
|
jsr305 = { module = "com.google.code.findbugs:jsr305", version.ref = "jsr305" }
|
||||||
|
kotlin-platform = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
|
||||||
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" }
|
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" }
|
||||||
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
|
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
|
||||||
netty-http = { module = "io.netty:netty-codec-http", version.ref = "netty" }
|
netty-http = { module = "io.netty:netty-codec-http", version.ref = "netty" }
|
||||||
nightConfig-core = { module = "com.electronwill.night-config:core", version.ref = "nightConfig" }
|
nightConfig-core = { module = "com.electronwill.night-config:core", version.ref = "nightConfig" }
|
||||||
nightConfig-toml = { module = "com.electronwill.night-config:toml", version.ref = "nightConfig" }
|
nightConfig-toml = { module = "com.electronwill.night-config:toml", version.ref = "nightConfig" }
|
||||||
|
@@ -8,7 +8,11 @@ package dan200.computercraft.api;
|
|||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.context.UseOnContext;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,6 +25,15 @@ public class ComputerCraftTags {
|
|||||||
public static final TagKey<Item> WIRED_MODEM = make("wired_modem");
|
public static final TagKey<Item> WIRED_MODEM = make("wired_modem");
|
||||||
public static final TagKey<Item> MONITOR = make("monitor");
|
public static final TagKey<Item> MONITOR = make("monitor");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Items which can be {@linkplain Item#use(Level, Player, InteractionHand) used} when calling
|
||||||
|
* {@code turtle.place()}.
|
||||||
|
* <p>
|
||||||
|
* This does not cover items who handle placing inside {@link Item#useOn(UseOnContext)}, as that is always
|
||||||
|
* called.
|
||||||
|
*/
|
||||||
|
public static final TagKey<Item> TURTLE_CAN_PLACE = make("turtle_can_place");
|
||||||
|
|
||||||
private static TagKey<Item> make(String name) {
|
private static TagKey<Item> make(String name) {
|
||||||
return TagKey.create(Registries.ITEM, new ResourceLocation(ComputerCraftAPI.MOD_ID, name));
|
return TagKey.create(Registries.ITEM, new ResourceLocation(ComputerCraftAPI.MOD_ID, name));
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,8 @@ public interface DetailRegistry<T> {
|
|||||||
/**
|
/**
|
||||||
* Compute basic details about an object. This is cheaper than computing all details operation, and so is suitable
|
* Compute basic details about an object. This is cheaper than computing all details operation, and so is suitable
|
||||||
* for when you need to compute the details for a large number of values.
|
* for when you need to compute the details for a large number of values.
|
||||||
|
* <p>
|
||||||
|
* This method <em>MAY</em> be thread safe: consult the instance's documentation for details.
|
||||||
*
|
*
|
||||||
* @param object The object to get details for.
|
* @param object The object to get details for.
|
||||||
* @return The basic details.
|
* @return The basic details.
|
||||||
@@ -40,6 +42,8 @@ public interface DetailRegistry<T> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute all details about an object, using {@link #getBasicDetails(Object)} and any registered providers.
|
* Compute all details about an object, using {@link #getBasicDetails(Object)} and any registered providers.
|
||||||
|
* <p>
|
||||||
|
* This method is <em>NOT</em> thread safe. It should only be called from the computer thread.
|
||||||
*
|
*
|
||||||
* @param object The object to get details for.
|
* @param object The object to get details for.
|
||||||
* @return The computed details.
|
* @return The computed details.
|
||||||
|
@@ -15,12 +15,17 @@ import net.minecraft.world.level.block.Block;
|
|||||||
public class VanillaDetailRegistries {
|
public class VanillaDetailRegistries {
|
||||||
/**
|
/**
|
||||||
* Provides details for {@link ItemStack}s.
|
* Provides details for {@link ItemStack}s.
|
||||||
|
* <p>
|
||||||
|
* This instance's {@link DetailRegistry#getBasicDetails(Object)} is thread safe (assuming the stack is immutable)
|
||||||
|
* and may be called from the computer thread.
|
||||||
*/
|
*/
|
||||||
public static final DetailRegistry<ItemStack> ITEM_STACK = ComputerCraftAPIService.get().getItemStackDetailRegistry();
|
public static final DetailRegistry<ItemStack> ITEM_STACK = ComputerCraftAPIService.get().getItemStackDetailRegistry();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides details for {@link BlockReference}, a reference to a {@link Block} in the world.
|
* Provides details for {@link BlockReference}, a reference to a {@link Block} in the world.
|
||||||
|
* <p>
|
||||||
|
* This instance's {@link DetailRegistry#getBasicDetails(Object)} is thread safe and may be called from the computer
|
||||||
|
* thread.
|
||||||
*/
|
*/
|
||||||
public static final DetailRegistry<BlockReference> BLOCK_IN_WORLD = ComputerCraftAPIService.get().getBlockInWorldDetailRegistry();
|
public static final DetailRegistry<BlockReference> BLOCK_IN_WORLD = ComputerCraftAPIService.get().getBlockInWorldDetailRegistry();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ import net.minecraft.nbt.CompoundTag;
|
|||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@@ -24,6 +25,7 @@ import javax.annotation.Nullable;
|
|||||||
* This should not be implemented by your classes. Do not interact with turtles except via this interface and
|
* This should not be implemented by your classes. Do not interact with turtles except via this interface and
|
||||||
* {@link ITurtleUpgrade}.
|
* {@link ITurtleUpgrade}.
|
||||||
*/
|
*/
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
public interface ITurtleAccess {
|
public interface ITurtleAccess {
|
||||||
/**
|
/**
|
||||||
* Returns the world in which the turtle resides.
|
* Returns the world in which the turtle resides.
|
||||||
|
@@ -98,7 +98,7 @@ public abstract class TurtleUpgradeDataProvider extends UpgradeDataProvider<ITur
|
|||||||
* get the final damage.
|
* get the final damage.
|
||||||
*
|
*
|
||||||
* @param damageMultiplier The damage multiplier.
|
* @param damageMultiplier The damage multiplier.
|
||||||
* @return The tool builder, for futher use.
|
* @return The tool builder, for further use.
|
||||||
*/
|
*/
|
||||||
public ToolBuilder damageMultiplier(float damageMultiplier) {
|
public ToolBuilder damageMultiplier(float damageMultiplier) {
|
||||||
this.damageMultiplier = damageMultiplier;
|
this.damageMultiplier = damageMultiplier;
|
||||||
|
@@ -144,7 +144,7 @@ public abstract class UpgradeDataProvider<T extends UpgradeBase, R extends Upgra
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<T> getGeneratedUpgrades() {
|
public List<T> getGeneratedUpgrades() {
|
||||||
if (upgrades == null) throw new IllegalStateException("Upgrades have not beeen generated yet");
|
if (upgrades == null) throw new IllegalStateException("Upgrades have not been generated yet");
|
||||||
return upgrades;
|
return upgrades;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -105,6 +105,16 @@ public abstract class AbstractComputerScreen<T extends AbstractComputerMenu> ext
|
|||||||
return super.keyPressed(key, scancode, modifiers);
|
return super.keyPressed(key, scancode, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseReleased(double x, double y, int button) {
|
||||||
|
// Reimplement ContainerEventHandler.mouseReleased, as it's not called in vanilla (it is in Forge, but that
|
||||||
|
// shouldn't matter).
|
||||||
|
setDragging(false);
|
||||||
|
var child = getChildAt(x, y);
|
||||||
|
if (child.isPresent() && child.get().mouseReleased(x, y, button)) return true;
|
||||||
|
|
||||||
|
return super.mouseReleased(x, y, button);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) {
|
public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
@@ -30,6 +30,7 @@ public class TerminalWidget extends AbstractWidget {
|
|||||||
private static final Component DESCRIPTION = Component.translatable("gui.computercraft.terminal");
|
private static final Component DESCRIPTION = Component.translatable("gui.computercraft.terminal");
|
||||||
|
|
||||||
private static final float TERMINATE_TIME = 0.5f;
|
private static final float TERMINATE_TIME = 0.5f;
|
||||||
|
private static final float KEY_SUPPRESS_DELAY = 0.2f;
|
||||||
|
|
||||||
private final Terminal terminal;
|
private final Terminal terminal;
|
||||||
private final InputHandler computer;
|
private final InputHandler computer;
|
||||||
@@ -79,15 +80,12 @@ public class TerminalWidget extends AbstractWidget {
|
|||||||
switch (key) {
|
switch (key) {
|
||||||
case GLFW.GLFW_KEY_T -> {
|
case GLFW.GLFW_KEY_T -> {
|
||||||
if (terminateTimer < 0) terminateTimer = 0;
|
if (terminateTimer < 0) terminateTimer = 0;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
case GLFW.GLFW_KEY_S -> {
|
case GLFW.GLFW_KEY_S -> {
|
||||||
if (shutdownTimer < 0) shutdownTimer = 0;
|
if (shutdownTimer < 0) shutdownTimer = 0;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
case GLFW.GLFW_KEY_R -> {
|
case GLFW.GLFW_KEY_R -> {
|
||||||
if (rebootTimer < 0) rebootTimer = 0;
|
if (rebootTimer < 0) rebootTimer = 0;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
case GLFW.GLFW_KEY_V -> {
|
case GLFW.GLFW_KEY_V -> {
|
||||||
// Ctrl+V for paste
|
// Ctrl+V for paste
|
||||||
@@ -118,7 +116,7 @@ public class TerminalWidget extends AbstractWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key >= 0 && terminateTimer < 0 && rebootTimer < 0 && shutdownTimer < 0) {
|
if (key >= 0 && terminateTimer < KEY_SUPPRESS_DELAY && rebootTimer < KEY_SUPPRESS_DELAY && shutdownTimer < KEY_SUPPRESS_DELAY) {
|
||||||
// Queue the "key" event and add to the down set
|
// Queue the "key" event and add to the down set
|
||||||
var repeat = keysDown.get(key);
|
var repeat = keysDown.get(key);
|
||||||
keysDown.set(key);
|
keysDown.set(key);
|
||||||
@@ -184,7 +182,7 @@ public class TerminalWidget extends AbstractWidget {
|
|||||||
lastMouseX = charX;
|
lastMouseX = charX;
|
||||||
lastMouseY = charY;
|
lastMouseY = charY;
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -203,7 +201,7 @@ public class TerminalWidget extends AbstractWidget {
|
|||||||
lastMouseY = charY;
|
lastMouseY = charY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -15,7 +15,6 @@ import dan200.computercraft.client.render.TurtleBlockEntityRenderer;
|
|||||||
import dan200.computercraft.client.turtle.TurtleUpgradeModellers;
|
import dan200.computercraft.client.turtle.TurtleUpgradeModellers;
|
||||||
import dan200.computercraft.shared.turtle.items.TurtleItem;
|
import dan200.computercraft.shared.turtle.items.TurtleItem;
|
||||||
import dan200.computercraft.shared.util.Holiday;
|
import dan200.computercraft.shared.util.Holiday;
|
||||||
import dan200.computercraft.shared.util.HolidayUtil;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
@@ -71,13 +70,16 @@ public final class TurtleModelParts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Combination getCombination(ItemStack stack) {
|
public Combination getCombination(ItemStack stack) {
|
||||||
var turtle = (TurtleItem) stack.getItem();
|
var christmas = Holiday.getCurrent() == Holiday.CHRISTMAS;
|
||||||
|
|
||||||
|
if (!(stack.getItem() instanceof TurtleItem turtle)) {
|
||||||
|
return new Combination(false, null, null, null, christmas, false);
|
||||||
|
}
|
||||||
|
|
||||||
var colour = turtle.getColour(stack);
|
var colour = turtle.getColour(stack);
|
||||||
var leftUpgrade = turtle.getUpgrade(stack, TurtleSide.LEFT);
|
var leftUpgrade = turtle.getUpgrade(stack, TurtleSide.LEFT);
|
||||||
var rightUpgrade = turtle.getUpgrade(stack, TurtleSide.RIGHT);
|
var rightUpgrade = turtle.getUpgrade(stack, TurtleSide.RIGHT);
|
||||||
var overlay = turtle.getOverlay(stack);
|
var overlay = turtle.getOverlay(stack);
|
||||||
var christmas = HolidayUtil.getCurrentHoliday() == Holiday.CHRISTMAS;
|
|
||||||
var label = turtle.getLabel(stack);
|
var label = turtle.getLabel(stack);
|
||||||
var flip = label != null && (label.equals("Dinnerbone") || label.equals("Grumm"));
|
var flip = label != null && (label.equals("Dinnerbone") || label.equals("Grumm"));
|
||||||
|
|
||||||
|
@@ -17,7 +17,6 @@ import dan200.computercraft.shared.computer.core.ComputerFamily;
|
|||||||
import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity;
|
import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity;
|
||||||
import dan200.computercraft.shared.util.DirectionUtil;
|
import dan200.computercraft.shared.util.DirectionUtil;
|
||||||
import dan200.computercraft.shared.util.Holiday;
|
import dan200.computercraft.shared.util.Holiday;
|
||||||
import dan200.computercraft.shared.util.HolidayUtil;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.Font;
|
import net.minecraft.client.gui.Font;
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
@@ -112,7 +111,7 @@ public class TurtleBlockEntityRenderer implements BlockEntityRenderer<TurtleBloc
|
|||||||
renderModel(transform, buffer, lightmapCoord, overlayLight, getTurtleModel(family, colour != -1), colour == -1 ? null : new int[]{ colour });
|
renderModel(transform, buffer, lightmapCoord, overlayLight, getTurtleModel(family, colour != -1), colour == -1 ? null : new int[]{ colour });
|
||||||
|
|
||||||
// Render the overlay
|
// Render the overlay
|
||||||
var overlayModel = getTurtleOverlayModel(overlay, HolidayUtil.getCurrentHoliday() == Holiday.CHRISTMAS);
|
var overlayModel = getTurtleOverlayModel(overlay, Holiday.getCurrent() == Holiday.CHRISTMAS);
|
||||||
if (overlayModel != null) {
|
if (overlayModel != null) {
|
||||||
renderModel(transform, buffer, lightmapCoord, overlayLight, overlayModel, null);
|
renderModel(transform, buffer, lightmapCoord, overlayLight, overlayModel, null);
|
||||||
}
|
}
|
||||||
|
@@ -65,6 +65,7 @@ class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider {
|
|||||||
addSpecial(add, ModRegistry.RecipeSerializers.PRINTOUT.get());
|
addSpecial(add, ModRegistry.RecipeSerializers.PRINTOUT.get());
|
||||||
addSpecial(add, ModRegistry.RecipeSerializers.DISK.get());
|
addSpecial(add, ModRegistry.RecipeSerializers.DISK.get());
|
||||||
addSpecial(add, ModRegistry.RecipeSerializers.DYEABLE_ITEM.get());
|
addSpecial(add, ModRegistry.RecipeSerializers.DYEABLE_ITEM.get());
|
||||||
|
addSpecial(add, ModRegistry.RecipeSerializers.DYEABLE_ITEM_CLEAR.get());
|
||||||
addSpecial(add, ModRegistry.RecipeSerializers.TURTLE_UPGRADE.get());
|
addSpecial(add, ModRegistry.RecipeSerializers.TURTLE_UPGRADE.get());
|
||||||
addSpecial(add, ModRegistry.RecipeSerializers.POCKET_COMPUTER_UPGRADE.get());
|
addSpecial(add, ModRegistry.RecipeSerializers.POCKET_COMPUTER_UPGRADE.get());
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ import net.minecraft.tags.ItemTags;
|
|||||||
import net.minecraft.tags.TagBuilder;
|
import net.minecraft.tags.TagBuilder;
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
|
||||||
@@ -85,6 +86,10 @@ class TagProvider {
|
|||||||
ModRegistry.Items.WIRELESS_MODEM_ADVANCED.get(), ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get(),
|
ModRegistry.Items.WIRELESS_MODEM_ADVANCED.get(), ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get(),
|
||||||
ModRegistry.Items.MONITOR_ADVANCED.get()
|
ModRegistry.Items.MONITOR_ADVANCED.get()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
tags.tag(ComputerCraftTags.Items.TURTLE_CAN_PLACE)
|
||||||
|
.add(Items.GLASS_BOTTLE)
|
||||||
|
.addTag(ItemTags.BOATS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -114,8 +114,9 @@ public class UpgradeManager<R extends UpgradeSerialiser<? extends T>, T extends
|
|||||||
|
|
||||||
private void loadUpgrade(Map<String, UpgradeWrapper<R, T>> current, ResourceLocation id, JsonElement json) {
|
private void loadUpgrade(Map<String, UpgradeWrapper<R, T>> current, ResourceLocation id, JsonElement json) {
|
||||||
var root = GsonHelper.convertToJsonObject(json, "top element");
|
var root = GsonHelper.convertToJsonObject(json, "top element");
|
||||||
var serialiserId = new ResourceLocation(GsonHelper.getAsString(root, "type"));
|
if (!PlatformHelper.get().shouldLoadResource(root)) return;
|
||||||
|
|
||||||
|
var serialiserId = new ResourceLocation(GsonHelper.getAsString(root, "type"));
|
||||||
var serialiser = PlatformHelper.get().tryGetRegistryObject(registry, serialiserId);
|
var serialiser = PlatformHelper.get().tryGetRegistryObject(registry, serialiserId);
|
||||||
if (serialiser == null) throw new JsonSyntaxException("Unknown upgrade type '" + serialiserId + "'");
|
if (serialiser == null) throw new JsonSyntaxException("Unknown upgrade type '" + serialiserId + "'");
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ import dan200.computercraft.shared.command.arguments.ComputerArgumentType;
|
|||||||
import dan200.computercraft.shared.command.arguments.ComputersArgumentType;
|
import dan200.computercraft.shared.command.arguments.ComputersArgumentType;
|
||||||
import dan200.computercraft.shared.command.arguments.RepeatArgumentType;
|
import dan200.computercraft.shared.command.arguments.RepeatArgumentType;
|
||||||
import dan200.computercraft.shared.command.arguments.TrackingFieldArgumentType;
|
import dan200.computercraft.shared.command.arguments.TrackingFieldArgumentType;
|
||||||
|
import dan200.computercraft.shared.common.ClearColourRecipe;
|
||||||
import dan200.computercraft.shared.common.ColourableRecipe;
|
import dan200.computercraft.shared.common.ColourableRecipe;
|
||||||
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
|
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
|
||||||
import dan200.computercraft.shared.common.HeldItemMenu;
|
import dan200.computercraft.shared.common.HeldItemMenu;
|
||||||
@@ -351,6 +352,7 @@ public final class ModRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final RegistryEntry<SimpleCraftingRecipeSerializer<ColourableRecipe>> DYEABLE_ITEM = simple("colour", ColourableRecipe::new);
|
public static final RegistryEntry<SimpleCraftingRecipeSerializer<ColourableRecipe>> DYEABLE_ITEM = simple("colour", ColourableRecipe::new);
|
||||||
|
public static final RegistryEntry<SimpleCraftingRecipeSerializer<ClearColourRecipe>> DYEABLE_ITEM_CLEAR = simple("clear_colour", ClearColourRecipe::new);
|
||||||
public static final RegistryEntry<TurtleRecipe.Serializer> TURTLE = REGISTRY.register("turtle", TurtleRecipe.Serializer::new);
|
public static final RegistryEntry<TurtleRecipe.Serializer> TURTLE = REGISTRY.register("turtle", TurtleRecipe.Serializer::new);
|
||||||
public static final RegistryEntry<SimpleCraftingRecipeSerializer<TurtleUpgradeRecipe>> TURTLE_UPGRADE = simple("turtle_upgrade", TurtleUpgradeRecipe::new);
|
public static final RegistryEntry<SimpleCraftingRecipeSerializer<TurtleUpgradeRecipe>> TURTLE_UPGRADE = simple("turtle_upgrade", TurtleUpgradeRecipe::new);
|
||||||
public static final RegistryEntry<SimpleCraftingRecipeSerializer<PocketComputerUpgradeRecipe>> POCKET_COMPUTER_UPGRADE = simple("pocket_computer_upgrade", PocketComputerUpgradeRecipe::new);
|
public static final RegistryEntry<SimpleCraftingRecipeSerializer<PocketComputerUpgradeRecipe>> POCKET_COMPUTER_UPGRADE = simple("pocket_computer_upgrade", PocketComputerUpgradeRecipe::new);
|
||||||
|
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.common;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.ModRegistry;
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.inventory.CraftingContainer;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import net.minecraft.world.item.crafting.CraftingBookCategory;
|
||||||
|
import net.minecraft.world.item.crafting.CustomRecipe;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Craft a wet sponge with a {@linkplain IColouredItem dyable item} to remove its dye.
|
||||||
|
*/
|
||||||
|
public final class ClearColourRecipe extends CustomRecipe {
|
||||||
|
public ClearColourRecipe(ResourceLocation id, CraftingBookCategory category) {
|
||||||
|
super(id, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(CraftingContainer inv, Level world) {
|
||||||
|
var hasColourable = false;
|
||||||
|
var hasSponge = false;
|
||||||
|
for (var i = 0; i < inv.getContainerSize(); i++) {
|
||||||
|
var stack = inv.getItem(i);
|
||||||
|
if (stack.isEmpty()) continue;
|
||||||
|
|
||||||
|
if (stack.getItem() instanceof IColouredItem colourable) {
|
||||||
|
if (hasColourable) return false;
|
||||||
|
if (colourable.getColour(stack) == -1) return false;
|
||||||
|
hasColourable = true;
|
||||||
|
} else if (stack.getItem() == Items.WET_SPONGE) {
|
||||||
|
if (hasSponge) return false;
|
||||||
|
hasSponge = true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasColourable && hasSponge;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack assemble(CraftingContainer inv) {
|
||||||
|
var colourable = ItemStack.EMPTY;
|
||||||
|
|
||||||
|
for (var i = 0; i < inv.getContainerSize(); i++) {
|
||||||
|
var stack = inv.getItem(i);
|
||||||
|
if (stack.getItem() instanceof IColouredItem) colourable = stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colourable.isEmpty()) return ItemStack.EMPTY;
|
||||||
|
|
||||||
|
var stack = ((IColouredItem) colourable.getItem()).withColour(colourable, -1);
|
||||||
|
stack.setCount(1);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NonNullList<ItemStack> getRemainingItems(CraftingContainer container) {
|
||||||
|
var remaining = NonNullList.withSize(container.getContainerSize(), ItemStack.EMPTY);
|
||||||
|
for (var i = 0; i < remaining.size(); i++) {
|
||||||
|
if (container.getItem(i).getItem() == Items.WET_SPONGE) remaining.set(i, new ItemStack(Items.WET_SPONGE));
|
||||||
|
}
|
||||||
|
return remaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCraftInDimensions(int x, int y) {
|
||||||
|
return x * y >= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeSerializer<ClearColourRecipe> getSerializer() {
|
||||||
|
return ModRegistry.RecipeSerializers.DYEABLE_ITEM_CLEAR.get();
|
||||||
|
}
|
||||||
|
}
|
@@ -74,7 +74,7 @@ public final class ColourableRecipe extends CustomRecipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RecipeSerializer<?> getSerializer() {
|
public RecipeSerializer<ColourableRecipe> getSerializer() {
|
||||||
return ModRegistry.RecipeSerializers.DYEABLE_ITEM.get();
|
return ModRegistry.RecipeSerializers.DYEABLE_ITEM.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,7 @@ import dan200.computercraft.core.lua.ILuaMachine;
|
|||||||
import dan200.computercraft.impl.AbstractComputerCraftAPI;
|
import dan200.computercraft.impl.AbstractComputerCraftAPI;
|
||||||
import dan200.computercraft.shared.CommonHooks;
|
import dan200.computercraft.shared.CommonHooks;
|
||||||
import dan200.computercraft.shared.computer.metrics.GlobalMetrics;
|
import dan200.computercraft.shared.computer.metrics.GlobalMetrics;
|
||||||
import dan200.computercraft.shared.config.Config;
|
import dan200.computercraft.shared.config.ConfigSpec;
|
||||||
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
|
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
|
||||||
import dan200.computercraft.shared.util.IDAssigner;
|
import dan200.computercraft.shared.util.IDAssigner;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
@@ -69,7 +69,7 @@ public final class ServerContext {
|
|||||||
mainThread = new MainThread();
|
mainThread = new MainThread();
|
||||||
context = new ComputerContext(
|
context = new ComputerContext(
|
||||||
new Environment(server),
|
new Environment(server),
|
||||||
new ComputerThread(Config.computerThreads),
|
new ComputerThread(ConfigSpec.computerThreads.get()),
|
||||||
mainThread, luaMachine
|
mainThread, luaMachine
|
||||||
);
|
);
|
||||||
idAssigner = new IDAssigner(storageDir.resolve("ids.json"));
|
idAssigner = new IDAssigner(storageDir.resolve("ids.json"));
|
||||||
|
@@ -17,8 +17,6 @@ public final class Config {
|
|||||||
public static int floppySpaceLimit = 125 * 1000;
|
public static int floppySpaceLimit = 125 * 1000;
|
||||||
public static boolean commandRequireCreative = true;
|
public static boolean commandRequireCreative = true;
|
||||||
|
|
||||||
public static int computerThreads = 1;
|
|
||||||
|
|
||||||
public static boolean enableCommandBlock = false;
|
public static boolean enableCommandBlock = false;
|
||||||
public static int modemRange = 64;
|
public static int modemRange = 64;
|
||||||
public static int modemHighAltitudeRange = 384;
|
public static int modemHighAltitudeRange = 384;
|
||||||
|
@@ -142,7 +142,7 @@ public final class ConfigSpec {
|
|||||||
computers can run at once, but may induce lag. Please note that some mods may
|
computers can run at once, but may induce lag. Please note that some mods may
|
||||||
not work with a thread count higher than 1. Use with caution.""")
|
not work with a thread count higher than 1. Use with caution.""")
|
||||||
.worldRestart()
|
.worldRestart()
|
||||||
.defineInRange("computer_threads", Config.computerThreads, 1, Integer.MAX_VALUE);
|
.defineInRange("computer_threads", 1, 1, Integer.MAX_VALUE);
|
||||||
|
|
||||||
maxMainGlobalTime = builder
|
maxMainGlobalTime = builder
|
||||||
.comment("""
|
.comment("""
|
||||||
@@ -342,11 +342,9 @@ public final class ConfigSpec {
|
|||||||
CoreConfig.maximumFilesOpen = maximumFilesOpen.get();
|
CoreConfig.maximumFilesOpen = maximumFilesOpen.get();
|
||||||
CoreConfig.disableLua51Features = disableLua51Features.get();
|
CoreConfig.disableLua51Features = disableLua51Features.get();
|
||||||
CoreConfig.defaultComputerSettings = defaultComputerSettings.get();
|
CoreConfig.defaultComputerSettings = defaultComputerSettings.get();
|
||||||
Config.computerThreads = computerThreads.get();
|
|
||||||
Config.commandRequireCreative = commandRequireCreative.get();
|
Config.commandRequireCreative = commandRequireCreative.get();
|
||||||
|
|
||||||
// Execution
|
// Execution
|
||||||
Config.computerThreads = computerThreads.get();
|
|
||||||
CoreConfig.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(maxMainGlobalTime.get());
|
CoreConfig.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(maxMainGlobalTime.get());
|
||||||
CoreConfig.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(maxMainComputerTime.get());
|
CoreConfig.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(maxMainComputerTime.get());
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@ import dan200.computercraft.shared.util.NBTUtil;
|
|||||||
import net.minecraft.nbt.ListTag;
|
import net.minecraft.nbt.ListTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.item.CreativeModeTab;
|
||||||
import net.minecraft.world.item.CreativeModeTabs;
|
import net.minecraft.world.item.CreativeModeTabs;
|
||||||
import net.minecraft.world.item.EnchantedBookItem;
|
import net.minecraft.world.item.EnchantedBookItem;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
@@ -24,14 +25,9 @@ import java.util.*;
|
|||||||
* Data providers for items.
|
* Data providers for items.
|
||||||
*/
|
*/
|
||||||
public class ItemDetails {
|
public class ItemDetails {
|
||||||
public static <T extends Map<? super String, Object>> T fillBasicSafe(T data, ItemStack stack) {
|
public static void fillBasic(Map<? super String, Object> data, ItemStack stack) {
|
||||||
data.put("name", DetailHelpers.getId(RegistryWrappers.ITEMS, stack.getItem()));
|
data.put("name", DetailHelpers.getId(RegistryWrappers.ITEMS, stack.getItem()));
|
||||||
data.put("count", stack.getCount());
|
data.put("count", stack.getCount());
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void fillBasic(Map<? super String, Object> data, ItemStack stack) {
|
|
||||||
fillBasicSafe(data, stack);
|
|
||||||
var hash = NBTUtil.getNBTHash(stack.getTag());
|
var hash = NBTUtil.getNBTHash(stack.getTag());
|
||||||
if (hash != null) data.put("nbt", hash);
|
if (hash != null) data.put("nbt", hash);
|
||||||
}
|
}
|
||||||
@@ -96,19 +92,18 @@ public class ItemDetails {
|
|||||||
* @return A filled list that contains pairs of item group IDs and their display names.
|
* @return A filled list that contains pairs of item group IDs and their display names.
|
||||||
*/
|
*/
|
||||||
private static List<Map<String, Object>> getItemGroups(ItemStack stack) {
|
private static List<Map<String, Object>> getItemGroups(ItemStack stack) {
|
||||||
List<Map<String, Object>> groups = new ArrayList<>(1);
|
return CreativeModeTabs.allTabs().stream()
|
||||||
|
.filter(x -> x.shouldDisplay() && x.getType() == CreativeModeTab.Type.CATEGORY && x.contains(stack))
|
||||||
|
.map(group -> {
|
||||||
|
Map<String, Object> groupData = new HashMap<>(2);
|
||||||
|
|
||||||
CreativeModeTabs.tabs().stream().filter(x -> x.contains(stack)).forEach(group -> {
|
var id = PlatformHelper.get().getCreativeTabId(group);
|
||||||
Map<String, Object> groupData = new HashMap<>(2);
|
if (id != null) groupData.put("id", id.toString());
|
||||||
|
|
||||||
var id = PlatformHelper.get().getCreativeTabId(group);
|
groupData.put("displayName", group.getDisplayName().getString());
|
||||||
if (id != null) groupData.put("id", id.toString());
|
return groupData;
|
||||||
|
})
|
||||||
groupData.put("displayName", group.getDisplayName().getString());
|
.toList();
|
||||||
groups.add(groupData);
|
|
||||||
});
|
|
||||||
|
|
||||||
return groups;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -82,10 +82,10 @@ public class UpgradesLoadedMessage implements NetworkMessage<ClientNetworkContex
|
|||||||
|
|
||||||
var serialiser = entry.getValue().serialiser();
|
var serialiser = entry.getValue().serialiser();
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
var unwrapedSerialiser = (UpgradeSerialiser<T>) serialiser;
|
var unwrappedSerialiser = (UpgradeSerialiser<T>) serialiser;
|
||||||
|
|
||||||
buf.writeResourceLocation(Objects.requireNonNull(registry.getKey(serialiser), "Serialiser is not registered!"));
|
buf.writeResourceLocation(Objects.requireNonNull(registry.getKey(serialiser), "Serialiser is not registered!"));
|
||||||
unwrapedSerialiser.toNetwork(buf, entry.getValue().upgrade());
|
unwrappedSerialiser.toNetwork(buf, entry.getValue().upgrade());
|
||||||
|
|
||||||
buf.writeUtf(entry.getValue().modId());
|
buf.writeUtf(entry.getValue().modId());
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
package dan200.computercraft.shared.peripheral.diskdrive;
|
package dan200.computercraft.shared.peripheral.diskdrive;
|
||||||
|
|
||||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||||
|
import dan200.computercraft.api.filesystem.Mount;
|
||||||
import dan200.computercraft.api.filesystem.WritableMount;
|
import dan200.computercraft.api.filesystem.WritableMount;
|
||||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
@@ -47,11 +48,14 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
|||||||
private final NonNullList<ItemStack> inventory = NonNullList.withSize(1, ItemStack.EMPTY);
|
private final NonNullList<ItemStack> inventory = NonNullList.withSize(1, ItemStack.EMPTY);
|
||||||
|
|
||||||
private MediaStack media = MediaStack.EMPTY;
|
private MediaStack media = MediaStack.EMPTY;
|
||||||
|
private @Nullable Mount mount;
|
||||||
|
|
||||||
private boolean recordPlaying = false;
|
private boolean recordPlaying = false;
|
||||||
// In order to avoid main-thread calls in the peripheral, we set flags to mark which operation should be performed,
|
// In order to avoid main-thread calls in the peripheral, we set flags to mark which operation should be performed,
|
||||||
// then read them when ticking.
|
// then read them when ticking.
|
||||||
private final AtomicReference<RecordCommand> recordQueued = new AtomicReference<>(null);
|
private final AtomicReference<RecordCommand> recordQueued = new AtomicReference<>(null);
|
||||||
private final AtomicBoolean ejectQueued = new AtomicBoolean(false);
|
private final AtomicBoolean ejectQueued = new AtomicBoolean(false);
|
||||||
|
private final AtomicBoolean mountQueued = new AtomicBoolean(false);
|
||||||
|
|
||||||
public DiskDriveBlockEntity(BlockEntityType<DiskDriveBlockEntity> type, BlockPos pos, BlockState state) {
|
public DiskDriveBlockEntity(BlockEntityType<DiskDriveBlockEntity> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
@@ -109,6 +113,12 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mountQueued.get()) {
|
||||||
|
synchronized (this) {
|
||||||
|
mountAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -124,9 +134,9 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
|||||||
|
|
||||||
private void updateItem() {
|
private void updateItem() {
|
||||||
var newDisk = getDiskStack();
|
var newDisk = getDiskStack();
|
||||||
if (ItemStack.isSame(newDisk, media.stack)) return;
|
if (ItemStack.isSameItemSameTags(newDisk, media.stack)) return;
|
||||||
|
|
||||||
var media = new MediaStack(newDisk.copy());
|
var media = MediaStack.of(newDisk);
|
||||||
|
|
||||||
if (newDisk.isEmpty()) {
|
if (newDisk.isEmpty()) {
|
||||||
updateBlockState(DiskDriveState.EMPTY);
|
updateBlockState(DiskDriveState.EMPTY);
|
||||||
@@ -146,12 +156,10 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
|||||||
recordPlaying = false;
|
recordPlaying = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mount = null;
|
||||||
this.media = media;
|
this.media = media;
|
||||||
|
|
||||||
// Mount new disk
|
mountAll();
|
||||||
if (!this.media.stack.isEmpty()) {
|
|
||||||
for (var computer : computers.entrySet()) mountDisk(computer.getKey(), computer.getValue(), this.media);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,11 +171,30 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
|||||||
return media;
|
return media;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current disk stack, mounting/unmounting if needed.
|
||||||
|
*
|
||||||
|
* @param stack The new disk stack.
|
||||||
|
*/
|
||||||
void setDiskStack(ItemStack stack) {
|
void setDiskStack(ItemStack stack) {
|
||||||
setItem(0, stack);
|
setItem(0, stack);
|
||||||
setChanged();
|
setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the current disk stack, assuming the underlying item does not change. Unlike
|
||||||
|
* {@link #setDiskStack(ItemStack)} this will not change any mounts.
|
||||||
|
*
|
||||||
|
* @param stack The new disk stack.
|
||||||
|
*/
|
||||||
|
void updateDiskStack(ItemStack stack) {
|
||||||
|
setItem(0, stack);
|
||||||
|
if (!ItemStack.isSameItemSameTags(stack, media.stack)) {
|
||||||
|
media = MediaStack.of(stack);
|
||||||
|
super.setChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
String getDiskMountPath(IComputerAccess computer) {
|
String getDiskMountPath(IComputerAccess computer) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
@@ -176,15 +203,21 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mount(IComputerAccess computer) {
|
/**
|
||||||
|
* Attach a computer to this disk drive. This sets up the {@link MountInfo} map and flags us to mount next tick. We
|
||||||
|
* don't mount here, as that might require mutating the current stack.
|
||||||
|
*
|
||||||
|
* @param computer The computer to attach.
|
||||||
|
*/
|
||||||
|
void attach(IComputerAccess computer) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
var info = new MountInfo();
|
var info = new MountInfo();
|
||||||
computers.put(computer, info);
|
computers.put(computer, info);
|
||||||
mountDisk(computer, info, media);
|
mountQueued.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmount(IComputerAccess computer) {
|
void detach(IComputerAccess computer) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
unmountDisk(computer, computers.remove(computer));
|
unmountDisk(computer, computers.remove(computer));
|
||||||
}
|
}
|
||||||
@@ -202,10 +235,35 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
|||||||
ejectQueued.set(true);
|
ejectQueued.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add our mount to all computers.
|
||||||
|
*/
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private void mountDisk(IComputerAccess computer, MountInfo info, MediaStack disk) {
|
private void mountAll() {
|
||||||
var mount = disk.getMount((ServerLevel) getLevel());
|
doMountAll();
|
||||||
if (mount != null) {
|
mountQueued.set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The worker for {@link #mountAll()}. This is responsible for creating the mount and placing it on all computers.
|
||||||
|
*/
|
||||||
|
@GuardedBy("this")
|
||||||
|
private void doMountAll() {
|
||||||
|
if (computers.isEmpty() || media.media == null) return;
|
||||||
|
|
||||||
|
if (mount == null) {
|
||||||
|
var stack = getDiskStack();
|
||||||
|
mount = media.media.createDataMount(stack, (ServerLevel) level);
|
||||||
|
setDiskStack(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mount == null) return;
|
||||||
|
|
||||||
|
for (var entry : computers.entrySet()) {
|
||||||
|
var computer = entry.getKey();
|
||||||
|
var info = entry.getValue();
|
||||||
|
if (info.mountPath != null) continue;
|
||||||
|
|
||||||
if (mount instanceof WritableMount writable) {
|
if (mount instanceof WritableMount writable) {
|
||||||
// Try mounting at the lowest numbered "disk" name we can
|
// Try mounting at the lowest numbered "disk" name we can
|
||||||
var n = 1;
|
var n = 1;
|
||||||
@@ -221,11 +279,9 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
|||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
info.mountPath = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
computer.queueEvent("disk", computer.getAttachmentName());
|
computer.queueEvent("disk", computer.getAttachmentName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void unmountDisk(IComputerAccess computer, MountInfo info) {
|
private static void unmountDisk(IComputerAccess computer, MountInfo info) {
|
||||||
@@ -251,7 +307,7 @@ public final class DiskDriveBlockEntity extends AbstractContainerBlockEntity {
|
|||||||
if (stack.isEmpty()) return;
|
if (stack.isEmpty()) return;
|
||||||
setDiskStack(ItemStack.EMPTY);
|
setDiskStack(ItemStack.EMPTY);
|
||||||
|
|
||||||
WorldUtil.dropItemStack(stack, getLevel(), getBlockPos(), getDirection());
|
WorldUtil.dropItemStack(getLevel(), getBlockPos(), getDirection(), stack);
|
||||||
getLevel().levelEvent(LevelEvent.SOUND_DISPENSER_DISPENSE, getBlockPos(), 0);
|
getLevel().levelEvent(LevelEvent.SOUND_DISPENSER_DISPENSE, getBlockPos(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -84,11 +84,12 @@ public class DiskDrivePeripheral implements IPeripheral {
|
|||||||
var media = diskDrive.getMedia();
|
var media = diskDrive.getMedia();
|
||||||
if (media.media == null) return;
|
if (media.media == null) return;
|
||||||
|
|
||||||
var stack = media.stack.copy();
|
// We're on the main thread so the stack and media should be in sync.
|
||||||
|
var stack = diskDrive.getDiskStack();
|
||||||
if (!media.media.setLabel(stack, label.map(StringUtil::normaliseLabel).orElse(null))) {
|
if (!media.media.setLabel(stack, label.map(StringUtil::normaliseLabel).orElse(null))) {
|
||||||
throw new LuaException("Disk label cannot be changed");
|
throw new LuaException("Disk label cannot be changed");
|
||||||
}
|
}
|
||||||
diskDrive.setDiskStack(stack);
|
diskDrive.updateDiskStack(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -178,12 +179,12 @@ public class DiskDrivePeripheral implements IPeripheral {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void attach(IComputerAccess computer) {
|
public void attach(IComputerAccess computer) {
|
||||||
diskDrive.mount(computer);
|
diskDrive.attach(computer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void detach(IComputerAccess computer) {
|
public void detach(IComputerAccess computer) {
|
||||||
diskDrive.unmount(computer);
|
diskDrive.detach(computer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -5,10 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.peripheral.diskdrive;
|
package dan200.computercraft.shared.peripheral.diskdrive;
|
||||||
|
|
||||||
import dan200.computercraft.api.filesystem.Mount;
|
|
||||||
import dan200.computercraft.api.media.IMedia;
|
import dan200.computercraft.api.media.IMedia;
|
||||||
import dan200.computercraft.impl.MediaProviders;
|
import dan200.computercraft.impl.MediaProviders;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.sounds.SoundEvent;
|
import net.minecraft.sounds.SoundEvent;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
@@ -17,18 +15,22 @@ import javax.annotation.Nullable;
|
|||||||
/**
|
/**
|
||||||
* An immutable snapshot of the current disk. This allows us to read the stack in a thread-safe manner.
|
* An immutable snapshot of the current disk. This allows us to read the stack in a thread-safe manner.
|
||||||
*/
|
*/
|
||||||
class MediaStack {
|
final class MediaStack {
|
||||||
static final MediaStack EMPTY = new MediaStack(ItemStack.EMPTY);
|
static final MediaStack EMPTY = new MediaStack(ItemStack.EMPTY, null);
|
||||||
|
|
||||||
final ItemStack stack;
|
final ItemStack stack;
|
||||||
final @Nullable IMedia media;
|
final @Nullable IMedia media;
|
||||||
|
|
||||||
@Nullable
|
private MediaStack(ItemStack stack, @Nullable IMedia media) {
|
||||||
private Mount mount;
|
|
||||||
|
|
||||||
MediaStack(ItemStack stack) {
|
|
||||||
this.stack = stack;
|
this.stack = stack;
|
||||||
media = MediaProviders.get(stack);
|
this.media = media;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MediaStack of(ItemStack stack) {
|
||||||
|
if (stack.isEmpty()) return EMPTY;
|
||||||
|
|
||||||
|
var freshStack = stack.copy();
|
||||||
|
return new MediaStack(freshStack, MediaProviders.get(freshStack));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -40,12 +42,4 @@ class MediaStack {
|
|||||||
String getAudioTitle() {
|
String getAudioTitle() {
|
||||||
return media != null ? media.getAudioTitle(stack) : null;
|
return media != null ? media.getAudioTitle(stack) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Mount getMount(ServerLevel level) {
|
|
||||||
if (media == null) return null;
|
|
||||||
|
|
||||||
if (mount == null) mount = media.createDataMount(stack, level);
|
|
||||||
return mount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -52,6 +52,15 @@ import java.util.Set;
|
|||||||
* <li><strong>Wired modems:</strong> These send messages to other any other wired modems connected to the same network
|
* <li><strong>Wired modems:</strong> These send messages to other any other wired modems connected to the same network
|
||||||
* (using <em>Networking Cable</em>). They also can be used to attach additional peripherals to a computer.</li></ul>
|
* (using <em>Networking Cable</em>). They also can be used to attach additional peripherals to a computer.</li></ul>
|
||||||
*
|
*
|
||||||
|
* ## Recipes
|
||||||
|
* <div class="recipe-container">
|
||||||
|
* <mc-recipe recipe="computercraft:wireless_modem_normal"></mc-recipe>
|
||||||
|
* <mc-recipe recipe="computercraft:wireless_modem_advanced"></mc-recipe>
|
||||||
|
* <mc-recipe recipe="computercraft:wired_modem"></mc-recipe>
|
||||||
|
* <mc-recipe recipe="computercraft:cable"></mc-recipe>
|
||||||
|
* <mc-recipe recipe="computercraft:wired_modem_full_from"></mc-recipe>
|
||||||
|
* </div>
|
||||||
|
*
|
||||||
* @cc.module modem
|
* @cc.module modem
|
||||||
* @cc.see modem_message Queued when a modem receives a message on an {@link #open(int) open channel}.
|
* @cc.see modem_message Queued when a modem receives a message on an {@link #open(int) open channel}.
|
||||||
* @cc.see rednet A networking API built on top of the modem peripheral.
|
* @cc.see rednet A networking API built on top of the modem peripheral.
|
||||||
@@ -74,14 +83,6 @@ import java.util.Set;
|
|||||||
* print("Received a reply: " .. tostring(message))
|
* print("Received a reply: " .. tostring(message))
|
||||||
* }</pre>
|
* }</pre>
|
||||||
* <p>
|
* <p>
|
||||||
* ## Recipes
|
|
||||||
* <div class="recipe-container">
|
|
||||||
* <mc-recipe recipe="computercraft:wireless_modem_normal"></mc-recipe>
|
|
||||||
* <mc-recipe recipe="computercraft:wireless_modem_advanced"></mc-recipe>
|
|
||||||
* <mc-recipe recipe="computercraft:wired_modem"></mc-recipe>
|
|
||||||
* <mc-recipe recipe="computercraft:cable"></mc-recipe>
|
|
||||||
* <mc-recipe recipe="computercraft:wired_modem_full_from"></mc-recipe>
|
|
||||||
* </div>
|
|
||||||
*/
|
*/
|
||||||
public abstract class ModemPeripheral implements IPeripheral, PacketSender, PacketReceiver {
|
public abstract class ModemPeripheral implements IPeripheral, PacketSender, PacketReceiver {
|
||||||
private @Nullable PacketNetwork network;
|
private @Nullable PacketNetwork network;
|
||||||
|
@@ -97,45 +97,46 @@ public class CableBlock extends Block implements SimpleWaterloggedBlock, EntityB
|
|||||||
@ForgeOverride
|
@ForgeOverride
|
||||||
public boolean onDestroyedByPlayer(BlockState state, Level world, BlockPos pos, Player player, boolean willHarvest, FluidState fluid) {
|
public boolean onDestroyedByPlayer(BlockState state, Level world, BlockPos pos, Player player, boolean willHarvest, FluidState fluid) {
|
||||||
playerWillDestroy(world, pos, state, player);
|
playerWillDestroy(world, pos, state, player);
|
||||||
return onDestroyedByPlayer(state, world, pos, player, fluid);
|
if (onCustomDestroyBlock(state, world, pos, player)) {
|
||||||
}
|
return false;
|
||||||
|
|
||||||
public boolean onDestroyedByPlayer(BlockState state, Level world, BlockPos pos, Player player, FluidState fluid) {
|
|
||||||
if (state.getValue(CABLE) && state.getValue(MODEM).getFacing() != null) {
|
|
||||||
var hit = world.clip(new ClipContext(
|
|
||||||
WorldUtil.getRayStart(player), WorldUtil.getRayEnd(player),
|
|
||||||
ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, player
|
|
||||||
));
|
|
||||||
if (hit.getType() == HitResult.Type.BLOCK) {
|
|
||||||
var tile = world.getBlockEntity(pos);
|
|
||||||
if (tile instanceof CableBlockEntity cable && tile.hasLevel()) {
|
|
||||||
ItemStack item;
|
|
||||||
BlockState newState;
|
|
||||||
|
|
||||||
if (WorldUtil.isVecInside(CableShapes.getModemShape(state), hit.getLocation().subtract(pos.getX(), pos.getY(), pos.getZ()))) {
|
|
||||||
newState = state.setValue(MODEM, CableModemVariant.None);
|
|
||||||
item = new ItemStack(ModRegistry.Items.WIRED_MODEM.get());
|
|
||||||
} else {
|
|
||||||
newState = state.setValue(CABLE, false);
|
|
||||||
item = new ItemStack(ModRegistry.Items.CABLE.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
world.setBlock(pos, correctConnections(world, pos, newState), 3);
|
|
||||||
|
|
||||||
cable.modemChanged();
|
|
||||||
cable.connectionsChanged();
|
|
||||||
if (!world.isClientSide && !player.getAbilities().instabuild) {
|
|
||||||
Block.popResource(world, pos, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return world.setBlock(pos, fluid.createLegacyBlock(), world.isClientSide ? UPDATE_ALL_IMMEDIATE : UPDATE_ALL);
|
return world.setBlock(pos, fluid.createLegacyBlock(), world.isClientSide ? UPDATE_ALL_IMMEDIATE : UPDATE_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean onCustomDestroyBlock(BlockState state, Level world, BlockPos pos, Player player) {
|
||||||
|
if (!state.getValue(CABLE) || state.getValue(MODEM).getFacing() == null) return false;
|
||||||
|
|
||||||
|
var hit = world.clip(new ClipContext(
|
||||||
|
WorldUtil.getRayStart(player), WorldUtil.getRayEnd(player),
|
||||||
|
ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, player
|
||||||
|
));
|
||||||
|
if (hit.getType() != HitResult.Type.BLOCK) return false;
|
||||||
|
|
||||||
|
var tile = world.getBlockEntity(pos);
|
||||||
|
if (!(tile instanceof CableBlockEntity cable) || !tile.hasLevel()) return false;
|
||||||
|
|
||||||
|
ItemStack item;
|
||||||
|
BlockState newState;
|
||||||
|
if (WorldUtil.isVecInside(CableShapes.getModemShape(state), hit.getLocation().subtract(pos.getX(), pos.getY(), pos.getZ()))) {
|
||||||
|
newState = state.setValue(MODEM, CableModemVariant.None);
|
||||||
|
item = new ItemStack(ModRegistry.Items.WIRED_MODEM.get());
|
||||||
|
} else {
|
||||||
|
newState = state.setValue(CABLE, false);
|
||||||
|
item = new ItemStack(ModRegistry.Items.CABLE.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
world.setBlock(pos, correctConnections(world, pos, newState), 3);
|
||||||
|
|
||||||
|
cable.modemChanged();
|
||||||
|
cable.connectionsChanged();
|
||||||
|
if (!world.isClientSide && !player.getAbilities().instabuild) {
|
||||||
|
Block.popResource(world, pos, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) {
|
public ItemStack getCloneItemStack(BlockGetter world, BlockPos pos, BlockState state) {
|
||||||
|
@@ -219,7 +219,7 @@ public class WiredModemFullBlockEntity extends BlockEntity {
|
|||||||
if (!world.isLoaded(offset)) continue;
|
if (!world.isLoaded(offset)) continue;
|
||||||
|
|
||||||
var element = connectedElements.get((ServerLevel) getLevel(), getBlockPos(), facing);
|
var element = connectedElements.get((ServerLevel) getLevel(), getBlockPos(), facing);
|
||||||
if (element == null) return;
|
if (element == null) continue;
|
||||||
|
|
||||||
node.connectTo(element.getNode());
|
node.connectTo(element.getNode());
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,6 @@ package dan200.computercraft.shared.peripheral.speaker;
|
|||||||
import dan200.computercraft.api.lua.LuaException;
|
import dan200.computercraft.api.lua.LuaException;
|
||||||
import dan200.computercraft.api.lua.LuaTable;
|
import dan200.computercraft.api.lua.LuaTable;
|
||||||
import dan200.computercraft.shared.util.PauseAwareTimer;
|
import dan200.computercraft.shared.util.PauseAwareTimer;
|
||||||
import net.minecraft.util.Mth;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@@ -16,6 +15,7 @@ import java.util.Optional;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static dan200.computercraft.shared.peripheral.speaker.SpeakerPeripheral.SAMPLE_RATE;
|
import static dan200.computercraft.shared.peripheral.speaker.SpeakerPeripheral.SAMPLE_RATE;
|
||||||
|
import static dan200.computercraft.shared.peripheral.speaker.SpeakerPeripheral.clampVolume;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal state of the DFPWM decoder and the state of playback.
|
* Internal state of the DFPWM decoder and the state of playback.
|
||||||
@@ -82,7 +82,7 @@ class DfpwmState {
|
|||||||
buffer.flip();
|
buffer.flip();
|
||||||
|
|
||||||
pendingAudio = buffer;
|
pendingAudio = buffer;
|
||||||
pendingVolume = Mth.clamp(volume.orElse((double) pendingVolume).floatValue(), 0.0f, 3.0f);
|
pendingVolume = (float) clampVolume(volume.orElse((double) pendingVolume));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@ import net.minecraft.resources.ResourceLocation;
|
|||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.sounds.SoundEvent;
|
import net.minecraft.sounds.SoundEvent;
|
||||||
import net.minecraft.sounds.SoundSource;
|
import net.minecraft.sounds.SoundSource;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
|
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -203,7 +204,7 @@ public abstract class SpeakerPeripheral implements IPeripheral {
|
|||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final boolean playNote(ILuaContext context, String instrumentA, Optional<Double> volumeA, Optional<Double> pitchA) throws LuaException {
|
public final boolean playNote(ILuaContext context, String instrumentA, Optional<Double> volumeA, Optional<Double> pitchA) throws LuaException {
|
||||||
var volume = (float) checkFinite(1, volumeA.orElse(1.0));
|
var volume = (float) clampVolume(checkFinite(1, volumeA.orElse(1.0)));
|
||||||
var pitch = (float) checkFinite(2, pitchA.orElse(1.0));
|
var pitch = (float) checkFinite(2, pitchA.orElse(1.0));
|
||||||
|
|
||||||
NoteBlockInstrument instrument = null;
|
NoteBlockInstrument instrument = null;
|
||||||
@@ -241,14 +242,14 @@ public abstract class SpeakerPeripheral implements IPeripheral {
|
|||||||
* @throws LuaException If the sound name was invalid.
|
* @throws LuaException If the sound name was invalid.
|
||||||
* @cc.usage Play a creeper hiss with the speaker.
|
* @cc.usage Play a creeper hiss with the speaker.
|
||||||
*
|
*
|
||||||
* <pre>{@code
|
* <pre data-peripheral="speaker">{@code
|
||||||
* local speaker = peripheral.find("speaker")
|
* local speaker = peripheral.find("speaker")
|
||||||
* speaker.playSound("entity.creeper.primed")
|
* speaker.playSound("entity.creeper.primed")
|
||||||
* }</pre>
|
* }</pre>
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final boolean playSound(ILuaContext context, String name, Optional<Double> volumeA, Optional<Double> pitchA) throws LuaException {
|
public final boolean playSound(ILuaContext context, String name, Optional<Double> volumeA, Optional<Double> pitchA) throws LuaException {
|
||||||
var volume = (float) checkFinite(1, volumeA.orElse(1.0));
|
var volume = (float) clampVolume(checkFinite(1, volumeA.orElse(1.0)));
|
||||||
var pitch = (float) checkFinite(2, pitchA.orElse(1.0));
|
var pitch = (float) checkFinite(2, pitchA.orElse(1.0));
|
||||||
|
|
||||||
ResourceLocation identifier;
|
ResourceLocation identifier;
|
||||||
@@ -293,7 +294,7 @@ public abstract class SpeakerPeripheral implements IPeripheral {
|
|||||||
* @cc.since 1.100
|
* @cc.since 1.100
|
||||||
* @cc.usage Read an audio file, decode it using @{cc.audio.dfpwm}, and play it using the speaker.
|
* @cc.usage Read an audio file, decode it using @{cc.audio.dfpwm}, and play it using the speaker.
|
||||||
*
|
*
|
||||||
* <pre>{@code
|
* <pre data-peripheral="speaker">{@code
|
||||||
* local dfpwm = require("cc.audio.dfpwm")
|
* local dfpwm = require("cc.audio.dfpwm")
|
||||||
* local speaker = peripheral.find("speaker")
|
* local speaker = peripheral.find("speaker")
|
||||||
*
|
*
|
||||||
@@ -361,6 +362,10 @@ public abstract class SpeakerPeripheral implements IPeripheral {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double clampVolume(double volume) {
|
||||||
|
return Mth.clamp(volume, 0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
private record PendingSound<T>(T sound, float volume, float pitch) {
|
private record PendingSound<T>(T sound, float volume, float pitch) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.platform;
|
package dan200.computercraft.shared.platform;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.brigadier.arguments.ArgumentType;
|
import com.mojang.brigadier.arguments.ArgumentType;
|
||||||
import dan200.computercraft.api.network.wired.WiredElement;
|
import dan200.computercraft.api.network.wired.WiredElement;
|
||||||
@@ -96,6 +97,16 @@ public interface PlatformHelper extends dan200.computercraft.impl.PlatformHelper
|
|||||||
@Nullable
|
@Nullable
|
||||||
<T> T tryGetRegistryObject(ResourceKey<Registry<T>> registry, ResourceLocation id);
|
<T> T tryGetRegistryObject(ResourceKey<Registry<T>> registry, ResourceLocation id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if this resource should be loaded, based on platform-specific loot conditions.
|
||||||
|
* <p>
|
||||||
|
* This should only be called from the {@code apply} stage of a reload listener.
|
||||||
|
*
|
||||||
|
* @param object The root JSON object of this resource.
|
||||||
|
* @return If this resource should be loaded.
|
||||||
|
*/
|
||||||
|
boolean shouldLoadResource(JsonObject object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new block entity type which serves a particular block.
|
* Create a new block entity type which serves a particular block.
|
||||||
*
|
*
|
||||||
|
@@ -69,7 +69,7 @@ public class PocketAPI implements ILuaAPI {
|
|||||||
if (newUpgrade == null) return new Object[]{ false, "Cannot find a valid upgrade" };
|
if (newUpgrade == null) return new Object[]{ false, "Cannot find a valid upgrade" };
|
||||||
|
|
||||||
// Remove the current upgrade
|
// Remove the current upgrade
|
||||||
if (previousUpgrade != null) storeItem(player, previousUpgrade.getCraftingItem());
|
if (previousUpgrade != null) storeItem(player, previousUpgrade.getCraftingItem().copy());
|
||||||
|
|
||||||
// Set the new upgrade
|
// Set the new upgrade
|
||||||
computer.setUpgrade(newUpgrade);
|
computer.setUpgrade(newUpgrade);
|
||||||
@@ -88,14 +88,13 @@ public class PocketAPI implements ILuaAPI {
|
|||||||
public final Object[] unequipBack() {
|
public final Object[] unequipBack() {
|
||||||
var entity = computer.getEntity();
|
var entity = computer.getEntity();
|
||||||
if (!(entity instanceof Player player)) return new Object[]{ false, "Cannot find player" };
|
if (!(entity instanceof Player player)) return new Object[]{ false, "Cannot find player" };
|
||||||
var inventory = player.getInventory();
|
|
||||||
var previousUpgrade = computer.getUpgrade();
|
var previousUpgrade = computer.getUpgrade();
|
||||||
|
|
||||||
if (previousUpgrade == null) return new Object[]{ false, "Nothing to unequip" };
|
if (previousUpgrade == null) return new Object[]{ false, "Nothing to unequip" };
|
||||||
|
|
||||||
computer.setUpgrade(null);
|
computer.setUpgrade(null);
|
||||||
|
|
||||||
storeItem(player, previousUpgrade.getCraftingItem());
|
storeItem(player, previousUpgrade.getCraftingItem().copy());
|
||||||
|
|
||||||
return new Object[]{ true };
|
return new Object[]{ true };
|
||||||
}
|
}
|
||||||
|
@@ -25,16 +25,14 @@ public class PocketModem extends AbstractPocketUpgrade {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IPeripheral createPeripheral(IPocketAccess access) {
|
public IPeripheral createPeripheral(IPocketAccess access) {
|
||||||
return new PocketModemPeripheral(advanced);
|
return new PocketModemPeripheral(advanced, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(IPocketAccess access, @Nullable IPeripheral peripheral) {
|
public void update(IPocketAccess access, @Nullable IPeripheral peripheral) {
|
||||||
if (!(peripheral instanceof PocketModemPeripheral modem)) return;
|
if (!(peripheral instanceof PocketModemPeripheral modem)) return;
|
||||||
|
|
||||||
var entity = access.getEntity();
|
modem.setLocation(access);
|
||||||
|
|
||||||
if (entity != null) modem.setLocation(entity.getCommandSenderWorld(), entity.getEyePosition(1));
|
|
||||||
|
|
||||||
var state = modem.getModemState();
|
var state = modem.getModemState();
|
||||||
if (state.pollChanged()) access.setLight(state.isOpen() ? 0xBA0000 : -1);
|
if (state.pollChanged()) access.setLight(state.isOpen() ? 0xBA0000 : -1);
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
package dan200.computercraft.shared.pocket.peripherals;
|
package dan200.computercraft.shared.pocket.peripherals;
|
||||||
|
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
import dan200.computercraft.api.pocket.IPocketAccess;
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
||||||
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemPeripheral;
|
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemPeripheral;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
@@ -17,13 +18,17 @@ public class PocketModemPeripheral extends WirelessModemPeripheral {
|
|||||||
private @Nullable Level level = null;
|
private @Nullable Level level = null;
|
||||||
private Vec3 position = Vec3.ZERO;
|
private Vec3 position = Vec3.ZERO;
|
||||||
|
|
||||||
public PocketModemPeripheral(boolean advanced) {
|
public PocketModemPeripheral(boolean advanced, IPocketAccess access) {
|
||||||
super(new ModemState(), advanced);
|
super(new ModemState(), advanced);
|
||||||
|
setLocation(access);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLocation(Level level, Vec3 position) {
|
void setLocation(IPocketAccess access) {
|
||||||
this.position = position;
|
var entity = access.getEntity();
|
||||||
this.level = level;
|
if (entity != null) {
|
||||||
|
level = entity.getCommandSenderWorld();
|
||||||
|
position = entity.getEyePosition(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -46,7 +46,7 @@ public class TurtleUtil {
|
|||||||
public static void storeItemOrDrop(ITurtleAccess turtle, ItemStack stack) {
|
public static void storeItemOrDrop(ITurtleAccess turtle, ItemStack stack) {
|
||||||
if (stack.isEmpty()) return;
|
if (stack.isEmpty()) return;
|
||||||
if (turtle.isRemoved()) {
|
if (turtle.isRemoved()) {
|
||||||
WorldUtil.dropItemStack(stack, turtle.getLevel(), turtle.getPosition(), null);
|
WorldUtil.dropItemStack(turtle.getLevel(), turtle.getPosition(), null, stack);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ public class TurtleUtil {
|
|||||||
var remainder = InventoryUtil.storeItemsFromOffset(turtle.getInventory(), stack, turtle.getSelectedSlot());
|
var remainder = InventoryUtil.storeItemsFromOffset(turtle.getInventory(), stack, turtle.getSelectedSlot());
|
||||||
if (remainder.isEmpty()) return;
|
if (remainder.isEmpty()) return;
|
||||||
|
|
||||||
WorldUtil.dropItemStack(remainder, turtle.getLevel(), turtle.getPosition(), turtle.getDirection().getOpposite());
|
WorldUtil.dropItemStack(turtle.getLevel(), turtle.getPosition(), turtle.getDirection().getOpposite(), remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Function<ItemStack, ItemStack> dropConsumer(ITurtleAccess turtle) {
|
public static Function<ItemStack, ItemStack> dropConsumer(ITurtleAccess turtle) {
|
||||||
|
@@ -7,16 +7,13 @@ package dan200.computercraft.shared.turtle.apis;
|
|||||||
|
|
||||||
import dan200.computercraft.api.detail.VanillaDetailRegistries;
|
import dan200.computercraft.api.detail.VanillaDetailRegistries;
|
||||||
import dan200.computercraft.api.lua.*;
|
import dan200.computercraft.api.lua.*;
|
||||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
|
||||||
import dan200.computercraft.api.turtle.TurtleCommand;
|
import dan200.computercraft.api.turtle.TurtleCommand;
|
||||||
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
import dan200.computercraft.api.turtle.TurtleCommandResult;
|
||||||
import dan200.computercraft.api.turtle.TurtleSide;
|
import dan200.computercraft.api.turtle.TurtleSide;
|
||||||
import dan200.computercraft.core.apis.IAPIEnvironment;
|
import dan200.computercraft.core.apis.IAPIEnvironment;
|
||||||
import dan200.computercraft.core.metrics.Metrics;
|
import dan200.computercraft.core.metrics.Metrics;
|
||||||
import dan200.computercraft.shared.details.ItemDetails;
|
|
||||||
import dan200.computercraft.shared.turtle.core.*;
|
import dan200.computercraft.shared.turtle.core.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,9 +67,9 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public class TurtleAPI implements ILuaAPI {
|
public class TurtleAPI implements ILuaAPI {
|
||||||
private final IAPIEnvironment environment;
|
private final IAPIEnvironment environment;
|
||||||
private final ITurtleAccess turtle;
|
private final TurtleAccessInternal turtle;
|
||||||
|
|
||||||
public TurtleAPI(IAPIEnvironment environment, ITurtleAccess turtle) {
|
public TurtleAPI(IAPIEnvironment environment, TurtleAccessInternal turtle) {
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
this.turtle = turtle;
|
this.turtle = turtle;
|
||||||
}
|
}
|
||||||
@@ -136,7 +133,7 @@ public class TurtleAPI implements ILuaAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotate the turtle 90 degress to the left.
|
* Rotate the turtle 90 degrees to the left.
|
||||||
*
|
*
|
||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether the turtle could successfully turn.
|
* @cc.treturn boolean Whether the turtle could successfully turn.
|
||||||
@@ -148,7 +145,7 @@ public class TurtleAPI implements ILuaAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotate the turtle 90 degress to the right.
|
* Rotate the turtle 90 degrees to the right.
|
||||||
*
|
*
|
||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether the turtle could successfully turn.
|
* @cc.treturn boolean Whether the turtle could successfully turn.
|
||||||
@@ -555,7 +552,7 @@ public class TurtleAPI implements ILuaAPI {
|
|||||||
* @throws LuaException If the refuel count is out of range.
|
* @throws LuaException If the refuel count is out of range.
|
||||||
* @cc.treturn [1] true If the turtle was refuelled.
|
* @cc.treturn [1] true If the turtle was refuelled.
|
||||||
* @cc.treturn [2] false If the turtle was not refuelled.
|
* @cc.treturn [2] false If the turtle was not refuelled.
|
||||||
* @cc.treturn [2] string The reason the turtle was not refuelled (
|
* @cc.treturn [2] string The reason the turtle was not refuelled.
|
||||||
* @cc.usage Refuel a turtle from the currently selected slot.
|
* @cc.usage Refuel a turtle from the currently selected slot.
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* local level = turtle.getFuelLevel()
|
* local level = turtle.getFuelLevel()
|
||||||
@@ -652,7 +649,7 @@ public class TurtleAPI implements ILuaAPI {
|
|||||||
* previous upgrade is removed and placed into the turtle's inventory. If there is no item in the slot, the previous
|
* previous upgrade is removed and placed into the turtle's inventory. If there is no item in the slot, the previous
|
||||||
* upgrade is removed, but no new one is equipped.
|
* upgrade is removed, but no new one is equipped.
|
||||||
*
|
*
|
||||||
* @return Whether an item was equiped or not.
|
* @return Whether an item was equipped or not.
|
||||||
* @cc.treturn [1] true If the item was equipped.
|
* @cc.treturn [1] true If the item was equipped.
|
||||||
* @cc.treturn [2] false If we could not equip the item.
|
* @cc.treturn [2] false If we could not equip the item.
|
||||||
* @cc.treturn [2] string The reason equipping this item failed.
|
* @cc.treturn [2] string The reason equipping this item failed.
|
||||||
@@ -671,7 +668,7 @@ public class TurtleAPI implements ILuaAPI {
|
|||||||
* previous upgrade is removed and placed into the turtle's inventory. If there is no item in the slot, the previous
|
* previous upgrade is removed and placed into the turtle's inventory. If there is no item in the slot, the previous
|
||||||
* upgrade is removed, but no new one is equipped.
|
* upgrade is removed, but no new one is equipped.
|
||||||
*
|
*
|
||||||
* @return Whether an item was equiped or not.
|
* @return Whether an item was equipped or not.
|
||||||
* @cc.treturn [1] true If the item was equipped.
|
* @cc.treturn [1] true If the item was equipped.
|
||||||
* @cc.treturn [2] false If we could not equip the item.
|
* @cc.treturn [2] false If we could not equip the item.
|
||||||
* @cc.treturn [2] string The reason equipping this item failed.
|
* @cc.treturn [2] string The reason equipping this item failed.
|
||||||
@@ -760,20 +757,15 @@ public class TurtleAPI implements ILuaAPI {
|
|||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult getItemDetail(ILuaContext context, Optional<Integer> slot, Optional<Boolean> detailed) throws LuaException {
|
public final MethodResult getItemDetail(ILuaContext context, Optional<Integer> slot, Optional<Boolean> detailed) throws LuaException {
|
||||||
int actualSlot = checkSlot(slot).orElse(turtle.getSelectedSlot());
|
int actualSlot = checkSlot(slot).orElse(turtle.getSelectedSlot());
|
||||||
return detailed.orElse(false)
|
if (detailed.orElse(false)) {
|
||||||
? context.executeMainThreadTask(() -> getItemDetail(actualSlot, true))
|
return context.executeMainThreadTask(() -> {
|
||||||
: MethodResult.of(getItemDetail(actualSlot, false));
|
var stack = turtle.getInventory().getItem(actualSlot);
|
||||||
}
|
return new Object[]{ stack.isEmpty() ? null : VanillaDetailRegistries.ITEM_STACK.getDetails(stack) };
|
||||||
|
});
|
||||||
private Object[] getItemDetail(int slot, boolean detailed) {
|
} else {
|
||||||
var stack = turtle.getInventory().getItem(slot);
|
var stack = turtle.getItemSnapshot(actualSlot);
|
||||||
if (stack.isEmpty()) return new Object[]{ null };
|
return MethodResult.of(stack.isEmpty() ? null : VanillaDetailRegistries.ITEM_STACK.getBasicDetails(stack));
|
||||||
|
}
|
||||||
var table = detailed
|
|
||||||
? VanillaDetailRegistries.ITEM_STACK.getDetails(stack)
|
|
||||||
: ItemDetails.fillBasicSafe(new HashMap<>(), stack);
|
|
||||||
|
|
||||||
return new Object[]{ table };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -113,9 +113,8 @@ public class TurtleBlock extends AbstractComputerBlock<TurtleBlockEntity> implem
|
|||||||
public final void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
public final void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
if (state.is(newState.getBlock())) return;
|
if (state.is(newState.getBlock())) return;
|
||||||
|
|
||||||
if (level.getBlockEntity(pos) instanceof TurtleBlockEntity turtle) {
|
if (!level.isClientSide && level.getBlockEntity(pos) instanceof TurtleBlockEntity turtle && !turtle.hasMoved()) {
|
||||||
if (!level.isClientSide) Containers.dropContents(level, pos, turtle);
|
Containers.dropContents(level, pos, turtle);
|
||||||
level.updateNeighbourForOutputSignal(pos, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onRemove(state, level, pos, newState, isMoving);
|
super.onRemove(state, level, pos, newState, isMoving);
|
||||||
|
@@ -29,14 +29,10 @@ import net.minecraft.nbt.ListTag;
|
|||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.InteractionHand;
|
|
||||||
import net.minecraft.world.InteractionResult;
|
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
import net.minecraft.world.item.DyeItem;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
@@ -56,7 +52,7 @@ public class TurtleBlockEntity extends AbstractComputerBlockEntity implements Ba
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final NonNullList<ItemStack> inventory = NonNullList.withSize(INVENTORY_SIZE, ItemStack.EMPTY);
|
private final NonNullList<ItemStack> inventory = NonNullList.withSize(INVENTORY_SIZE, ItemStack.EMPTY);
|
||||||
private final NonNullList<ItemStack> previousInventory = NonNullList.withSize(INVENTORY_SIZE, ItemStack.EMPTY);
|
private final NonNullList<ItemStack> inventorySnapshot = NonNullList.withSize(INVENTORY_SIZE, ItemStack.EMPTY);
|
||||||
private boolean inventoryChanged = false;
|
private boolean inventoryChanged = false;
|
||||||
private TurtleBrain brain = new TurtleBrain(this);
|
private TurtleBrain brain = new TurtleBrain(this);
|
||||||
private MoveState moveState = MoveState.NOT_MOVED;
|
private MoveState moveState = MoveState.NOT_MOVED;
|
||||||
@@ -67,7 +63,7 @@ public class TurtleBlockEntity extends AbstractComputerBlockEntity implements Ba
|
|||||||
super(type, pos, state, family);
|
super(type, pos, state, family);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasMoved() {
|
boolean hasMoved() {
|
||||||
return moveState == MoveState.MOVED;
|
return moveState == MoveState.MOVED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +74,7 @@ public class TurtleBlockEntity extends AbstractComputerBlockEntity implements Ba
|
|||||||
getFamily(), Config.turtleTermWidth,
|
getFamily(), Config.turtleTermWidth,
|
||||||
Config.turtleTermHeight
|
Config.turtleTermHeight
|
||||||
);
|
);
|
||||||
computer.addAPI(new TurtleAPI(computer.getAPIEnvironment(), getAccess()));
|
computer.addAPI(new TurtleAPI(computer.getAPIEnvironment(), brain));
|
||||||
brain.setupComputer(computer);
|
brain.setupComputer(computer);
|
||||||
return computer;
|
return computer;
|
||||||
}
|
}
|
||||||
@@ -88,42 +84,6 @@ public class TurtleBlockEntity extends AbstractComputerBlockEntity implements Ba
|
|||||||
if (!hasMoved()) super.unload();
|
if (!hasMoved()) super.unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public InteractionResult use(Player player, InteractionHand hand) {
|
|
||||||
// Apply dye
|
|
||||||
var currentItem = player.getItemInHand(hand);
|
|
||||||
if (!currentItem.isEmpty()) {
|
|
||||||
if (currentItem.getItem() instanceof DyeItem dyeItem) {
|
|
||||||
// Dye to change turtle colour
|
|
||||||
if (!getLevel().isClientSide) {
|
|
||||||
var dye = dyeItem.getDyeColor();
|
|
||||||
if (brain.getDyeColour() != dye) {
|
|
||||||
brain.setDyeColour(dye);
|
|
||||||
if (!player.isCreative()) {
|
|
||||||
currentItem.shrink(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return InteractionResult.sidedSuccess(getLevel().isClientSide);
|
|
||||||
} else if (currentItem.getItem() == Items.WATER_BUCKET && brain.getColour() != -1) {
|
|
||||||
// Water to remove turtle colour
|
|
||||||
if (!getLevel().isClientSide) {
|
|
||||||
if (brain.getColour() != -1) {
|
|
||||||
brain.setColour(-1);
|
|
||||||
if (!player.isCreative()) {
|
|
||||||
player.setItemInHand(hand, new ItemStack(Items.BUCKET));
|
|
||||||
player.getInventory().setChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return InteractionResult.sidedSuccess(getLevel().isClientSide);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open GUI or whatever
|
|
||||||
return super.use(player, hand);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canNameWithTag(Player player) {
|
protected boolean canNameWithTag(Player player) {
|
||||||
return true;
|
return true;
|
||||||
@@ -141,11 +101,7 @@ public class TurtleBlockEntity extends AbstractComputerBlockEntity implements Ba
|
|||||||
if (inventoryChanged) {
|
if (inventoryChanged) {
|
||||||
var computer = getServerComputer();
|
var computer = getServerComputer();
|
||||||
if (computer != null) computer.queueEvent("turtle_inventory");
|
if (computer != null) computer.queueEvent("turtle_inventory");
|
||||||
|
|
||||||
inventoryChanged = false;
|
inventoryChanged = false;
|
||||||
for (var n = 0; n < getContainerSize(); n++) {
|
|
||||||
previousInventory.set(n, getItem(n).copy());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,13 +134,13 @@ public class TurtleBlockEntity extends AbstractComputerBlockEntity implements Ba
|
|||||||
// Read inventory
|
// Read inventory
|
||||||
var nbttaglist = nbt.getList("Items", Tag.TAG_COMPOUND);
|
var nbttaglist = nbt.getList("Items", Tag.TAG_COMPOUND);
|
||||||
inventory.clear();
|
inventory.clear();
|
||||||
previousInventory.clear();
|
inventorySnapshot.clear();
|
||||||
for (var i = 0; i < nbttaglist.size(); i++) {
|
for (var i = 0; i < nbttaglist.size(); i++) {
|
||||||
var tag = nbttaglist.getCompound(i);
|
var tag = nbttaglist.getCompound(i);
|
||||||
var slot = tag.getByte("Slot") & 0xff;
|
var slot = tag.getByte("Slot") & 0xff;
|
||||||
if (slot < getContainerSize()) {
|
if (slot < getContainerSize()) {
|
||||||
inventory.set(slot, ItemStack.of(tag));
|
inventory.set(slot, ItemStack.of(tag));
|
||||||
previousInventory.set(slot, inventory.get(slot).copy());
|
inventorySnapshot.set(slot, inventory.get(slot).copy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +229,7 @@ public class TurtleBlockEntity extends AbstractComputerBlockEntity implements Ba
|
|||||||
|
|
||||||
void setOwningPlayer(GameProfile player) {
|
void setOwningPlayer(GameProfile player) {
|
||||||
brain.setOwningPlayer(player);
|
brain.setOwningPlayer(player);
|
||||||
setChanged();
|
onTileEntityChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
// IInventory
|
// IInventory
|
||||||
@@ -283,16 +239,20 @@ public class TurtleBlockEntity extends AbstractComputerBlockEntity implements Ba
|
|||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ItemStack getItemSnapshot(int slot) {
|
||||||
|
return slot >= 0 && slot < inventorySnapshot.size() ? inventorySnapshot.get(slot) : ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setChanged() {
|
public void setChanged() {
|
||||||
super.setChanged();
|
super.setChanged();
|
||||||
if (!inventoryChanged) {
|
|
||||||
for (var n = 0; n < getContainerSize(); n++) {
|
for (var slot = 0; slot < getContainerSize(); slot++) {
|
||||||
if (!ItemStack.matches(getItem(n), previousInventory.get(n))) {
|
var item = getItem(slot);
|
||||||
inventoryChanged = true;
|
if (ItemStack.matches(item, inventorySnapshot.get(slot))) continue;
|
||||||
break;
|
|
||||||
}
|
inventoryChanged = true;
|
||||||
}
|
inventorySnapshot.set(slot, item.copy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +300,7 @@ public class TurtleBlockEntity extends AbstractComputerBlockEntity implements Ba
|
|||||||
public void transferStateFrom(TurtleBlockEntity copy) {
|
public void transferStateFrom(TurtleBlockEntity copy) {
|
||||||
super.transferStateFrom(copy);
|
super.transferStateFrom(copy);
|
||||||
Collections.copy(inventory, copy.inventory);
|
Collections.copy(inventory, copy.inventory);
|
||||||
Collections.copy(previousInventory, copy.previousInventory);
|
Collections.copy(inventorySnapshot, copy.inventorySnapshot);
|
||||||
inventoryChanged = copy.inventoryChanged;
|
inventoryChanged = copy.inventoryChanged;
|
||||||
brain = copy.brain;
|
brain = copy.brain;
|
||||||
brain.setOwner(this);
|
brain.setOwner(this);
|
||||||
|
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.turtle.core;
|
||||||
|
|
||||||
|
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An internal version of {@link ITurtleAccess}.
|
||||||
|
* <p>
|
||||||
|
* This exposes additional functionality we don't want in the public API, but where we don't want access to the full
|
||||||
|
* {@link TurtleBrain} interface.
|
||||||
|
*/
|
||||||
|
public interface TurtleAccessInternal extends ITurtleAccess {
|
||||||
|
/**
|
||||||
|
* Get an immutable snapshot of an item in the inventory. This is a thread-safe version of
|
||||||
|
* {@code getInventory().getItem()}.
|
||||||
|
*
|
||||||
|
* @param slot The slot
|
||||||
|
* @return The current item. This should NOT be modified.
|
||||||
|
* @see net.minecraft.world.Container#getItem(int)
|
||||||
|
*/
|
||||||
|
ItemStack getItemSnapshot(int slot);
|
||||||
|
}
|
@@ -10,7 +10,10 @@ import com.mojang.authlib.GameProfile;
|
|||||||
import dan200.computercraft.api.lua.ILuaCallback;
|
import dan200.computercraft.api.lua.ILuaCallback;
|
||||||
import dan200.computercraft.api.lua.MethodResult;
|
import dan200.computercraft.api.lua.MethodResult;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.api.turtle.*;
|
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||||
|
import dan200.computercraft.api.turtle.TurtleAnimation;
|
||||||
|
import dan200.computercraft.api.turtle.TurtleCommand;
|
||||||
|
import dan200.computercraft.api.turtle.TurtleSide;
|
||||||
import dan200.computercraft.core.computer.ComputerSide;
|
import dan200.computercraft.core.computer.ComputerSide;
|
||||||
import dan200.computercraft.core.util.Colour;
|
import dan200.computercraft.core.util.Colour;
|
||||||
import dan200.computercraft.impl.TurtleUpgrades;
|
import dan200.computercraft.impl.TurtleUpgrades;
|
||||||
@@ -21,7 +24,6 @@ import dan200.computercraft.shared.container.InventoryDelegate;
|
|||||||
import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity;
|
import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity;
|
||||||
import dan200.computercraft.shared.util.BlockEntityHelpers;
|
import dan200.computercraft.shared.util.BlockEntityHelpers;
|
||||||
import dan200.computercraft.shared.util.Holiday;
|
import dan200.computercraft.shared.util.Holiday;
|
||||||
import dan200.computercraft.shared.util.HolidayUtil;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
@@ -34,6 +36,7 @@ import net.minecraft.world.Container;
|
|||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.MoverType;
|
import net.minecraft.world.entity.MoverType;
|
||||||
import net.minecraft.world.item.DyeColor;
|
import net.minecraft.world.item.DyeColor;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.material.PushReaction;
|
import net.minecraft.world.level.material.PushReaction;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
@@ -47,7 +50,7 @@ import java.util.function.Predicate;
|
|||||||
import static dan200.computercraft.shared.common.IColouredItem.NBT_COLOUR;
|
import static dan200.computercraft.shared.common.IColouredItem.NBT_COLOUR;
|
||||||
import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED;
|
import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED;
|
||||||
|
|
||||||
public class TurtleBrain implements ITurtleAccess {
|
public class TurtleBrain implements TurtleAccessInternal {
|
||||||
public static final String NBT_RIGHT_UPGRADE = "RightUpgrade";
|
public static final String NBT_RIGHT_UPGRADE = "RightUpgrade";
|
||||||
public static final String NBT_RIGHT_UPGRADE_DATA = "RightUpgradeNbt";
|
public static final String NBT_RIGHT_UPGRADE_DATA = "RightUpgradeNbt";
|
||||||
public static final String NBT_LEFT_UPGRADE = "LeftUpgrade";
|
public static final String NBT_LEFT_UPGRADE = "LeftUpgrade";
|
||||||
@@ -456,7 +459,7 @@ public class TurtleBrain implements ITurtleAccess {
|
|||||||
return overlay;
|
return overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOverlay(ResourceLocation overlay) {
|
public void setOverlay(@Nullable ResourceLocation overlay) {
|
||||||
if (!Objects.equal(this.overlay, overlay)) {
|
if (!Objects.equal(this.overlay, overlay)) {
|
||||||
this.overlay = overlay;
|
this.overlay = overlay;
|
||||||
BlockEntityHelpers.updateBlock(owner);
|
BlockEntityHelpers.updateBlock(owner);
|
||||||
@@ -735,7 +738,7 @@ public class TurtleBrain implements ITurtleAccess {
|
|||||||
// Advance valentines day easter egg
|
// Advance valentines day easter egg
|
||||||
if (world.isClientSide && animation == TurtleAnimation.MOVE_FORWARD && animationProgress == 4) {
|
if (world.isClientSide && animation == TurtleAnimation.MOVE_FORWARD && animationProgress == 4) {
|
||||||
// Spawn love pfx if valentines day
|
// Spawn love pfx if valentines day
|
||||||
var currentHoliday = HolidayUtil.getCurrentHoliday();
|
var currentHoliday = Holiday.getCurrent();
|
||||||
if (currentHoliday == Holiday.VALENTINES) {
|
if (currentHoliday == Holiday.VALENTINES) {
|
||||||
var position = getVisualPosition(1.0f);
|
var position = getVisualPosition(1.0f);
|
||||||
if (position != null) {
|
if (position != null) {
|
||||||
@@ -768,6 +771,11 @@ public class TurtleBrain implements ITurtleAccess {
|
|||||||
return previous + (next - previous) * f;
|
return previous + (next - previous) * f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItemSnapshot(int slot) {
|
||||||
|
return owner.getItemSnapshot(slot);
|
||||||
|
}
|
||||||
|
|
||||||
private static final class CommandCallback implements ILuaCallback {
|
private static final class CommandCallback implements ILuaCallback {
|
||||||
final MethodResult pull = MethodResult.pullEvent("turtle_response", this);
|
final MethodResult pull = MethodResult.pullEvent("turtle_response", this);
|
||||||
private final int command;
|
private final int command;
|
||||||
|
@@ -58,7 +58,7 @@ public class TurtleDropCommand implements TurtleCommand {
|
|||||||
turtle.getInventory().setChanged();
|
turtle.getInventory().setChanged();
|
||||||
transferred = stack.getCount();
|
transferred = stack.getCount();
|
||||||
|
|
||||||
WorldUtil.dropItemStack(stack, world, oldPosition, direction);
|
WorldUtil.dropItemStack(world, oldPosition, direction, stack);
|
||||||
world.globalLevelEvent(LevelEvent.SOUND_DISPENSER_DISPENSE, newPosition, 0);
|
world.globalLevelEvent(LevelEvent.SOUND_DISPENSER_DISPENSE, newPosition, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,6 @@ package dan200.computercraft.shared.turtle.core;
|
|||||||
import dan200.computercraft.api.turtle.*;
|
import dan200.computercraft.api.turtle.*;
|
||||||
import dan200.computercraft.impl.TurtleUpgrades;
|
import dan200.computercraft.impl.TurtleUpgrades;
|
||||||
import dan200.computercraft.shared.turtle.TurtleUtil;
|
import dan200.computercraft.shared.turtle.TurtleUtil;
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
|
|
||||||
public class TurtleEquipCommand implements TurtleCommand {
|
public class TurtleEquipCommand implements TurtleCommand {
|
||||||
private final TurtleSide side;
|
private final TurtleSide side;
|
||||||
@@ -19,32 +18,22 @@ public class TurtleEquipCommand implements TurtleCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TurtleCommandResult execute(ITurtleAccess turtle) {
|
public TurtleCommandResult execute(ITurtleAccess turtle) {
|
||||||
|
// Determine the upgrade to replace
|
||||||
|
var oldUpgrade = turtle.getUpgrade(side);
|
||||||
|
|
||||||
// Determine the upgrade to equipLeft
|
// Determine the upgrade to equipLeft
|
||||||
ITurtleUpgrade newUpgrade;
|
ITurtleUpgrade newUpgrade;
|
||||||
ItemStack newUpgradeStack;
|
|
||||||
var selectedStack = turtle.getInventory().getItem(turtle.getSelectedSlot());
|
var selectedStack = turtle.getInventory().getItem(turtle.getSelectedSlot());
|
||||||
if (!selectedStack.isEmpty()) {
|
if (!selectedStack.isEmpty()) {
|
||||||
newUpgradeStack = selectedStack.copy();
|
newUpgrade = TurtleUpgrades.instance().get(selectedStack);
|
||||||
newUpgrade = TurtleUpgrades.instance().get(newUpgradeStack);
|
|
||||||
if (newUpgrade == null) return TurtleCommandResult.failure("Not a valid upgrade");
|
if (newUpgrade == null) return TurtleCommandResult.failure("Not a valid upgrade");
|
||||||
} else {
|
} else {
|
||||||
newUpgradeStack = null;
|
|
||||||
newUpgrade = null;
|
newUpgrade = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the upgrade to replace
|
|
||||||
ItemStack oldUpgradeStack;
|
|
||||||
var oldUpgrade = turtle.getUpgrade(side);
|
|
||||||
if (oldUpgrade != null) {
|
|
||||||
var craftingItem = oldUpgrade.getCraftingItem();
|
|
||||||
oldUpgradeStack = !craftingItem.isEmpty() ? craftingItem.copy() : null;
|
|
||||||
} else {
|
|
||||||
oldUpgradeStack = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do the swapping:
|
// Do the swapping:
|
||||||
if (newUpgradeStack != null) turtle.getInventory().removeItem(turtle.getSelectedSlot(), 1);
|
if (newUpgrade != null) turtle.getInventory().removeItem(turtle.getSelectedSlot(), 1);
|
||||||
if (oldUpgradeStack != null) TurtleUtil.storeItemOrDrop(turtle, oldUpgradeStack);
|
if (oldUpgrade != null) TurtleUtil.storeItemOrDrop(turtle, oldUpgrade.getCraftingItem().copy());
|
||||||
turtle.setUpgrade(side, newUpgrade);
|
turtle.setUpgrade(side, newUpgrade);
|
||||||
|
|
||||||
// Animate
|
// Animate
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
package dan200.computercraft.shared.turtle.core;
|
package dan200.computercraft.shared.turtle.core;
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
|
import dan200.computercraft.api.ComputerCraftTags;
|
||||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||||
import dan200.computercraft.api.turtle.TurtleAnimation;
|
import dan200.computercraft.api.turtle.TurtleAnimation;
|
||||||
import dan200.computercraft.api.turtle.TurtleCommand;
|
import dan200.computercraft.api.turtle.TurtleCommand;
|
||||||
@@ -21,9 +22,7 @@ import net.minecraft.network.chat.Component;
|
|||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.item.BlockItem;
|
import net.minecraft.world.item.*;
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.SignItem;
|
|
||||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
import net.minecraft.world.item.context.UseOnContext;
|
import net.minecraft.world.item.context.UseOnContext;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
@@ -209,7 +208,7 @@ public class TurtlePlaceCommand implements TurtleCommand {
|
|||||||
|
|
||||||
// We special case some items which we allow to place "normally". Yes, this is very ugly.
|
// We special case some items which we allow to place "normally". Yes, this is very ugly.
|
||||||
var item = stack.getItem();
|
var item = stack.getItem();
|
||||||
if (item.getUseDuration(stack) == 0) {
|
if (item instanceof BucketItem || item instanceof PlaceOnWaterBlockItem || stack.is(ComputerCraftTags.Items.TURTLE_CAN_PLACE)) {
|
||||||
return turtlePlayer.player().gameMode.useItem(turtlePlayer.player(), turtlePlayer.player().level, stack, InteractionHand.MAIN_HAND);
|
return turtlePlayer.player().gameMode.useItem(turtlePlayer.player(), turtlePlayer.player().level, stack, InteractionHand.MAIN_HAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -61,7 +61,7 @@ public final class DropConsumer {
|
|||||||
|
|
||||||
public static void clearAndDrop(Level world, BlockPos pos, @Nullable Direction direction) {
|
public static void clearAndDrop(Level world, BlockPos pos, @Nullable Direction direction) {
|
||||||
var remainingDrops = clear();
|
var remainingDrops = clear();
|
||||||
for (var remaining : remainingDrops) WorldUtil.dropItemStack(remaining, world, pos, direction);
|
for (var remaining : remainingDrops) WorldUtil.dropItemStack(world, pos, direction, remaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void handleDrops(ItemStack stack) {
|
private static void handleDrops(ItemStack stack) {
|
||||||
|
@@ -5,10 +5,30 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.util;
|
package dan200.computercraft.shared.util;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.Month;
|
||||||
|
|
||||||
public enum Holiday {
|
public enum Holiday {
|
||||||
NONE,
|
NONE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 14th February.
|
||||||
|
*/
|
||||||
VALENTINES,
|
VALENTINES,
|
||||||
APRIL_FOOLS_DAY,
|
|
||||||
HALLOWEEN,
|
/**
|
||||||
CHRISTMAS,
|
* 24th-26th December.
|
||||||
|
*
|
||||||
|
* @see net.minecraft.client.renderer.blockentity.ChestRenderer
|
||||||
|
*/
|
||||||
|
CHRISTMAS;
|
||||||
|
|
||||||
|
public static Holiday getCurrent() {
|
||||||
|
var calendar = LocalDateTime.now();
|
||||||
|
var month = calendar.getMonth();
|
||||||
|
var day = calendar.getDayOfMonth();
|
||||||
|
if (month == Month.FEBRUARY && day == 14) return VALENTINES;
|
||||||
|
if (month == Month.DECEMBER && day >= 24 && day <= 26) return CHRISTMAS;
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.util;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public final class HolidayUtil {
|
|
||||||
private HolidayUtil() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Holiday getCurrentHoliday() {
|
|
||||||
return getHoliday(Calendar.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Holiday getHoliday(Calendar calendar) {
|
|
||||||
var month = calendar.get(Calendar.MONTH);
|
|
||||||
var day = calendar.get(Calendar.DAY_OF_MONTH);
|
|
||||||
if (month == Calendar.FEBRUARY && day == 14) return Holiday.VALENTINES;
|
|
||||||
if (month == Calendar.APRIL && day == 1) return Holiday.APRIL_FOOLS_DAY;
|
|
||||||
if (month == Calendar.OCTOBER && day == 31) return Holiday.HALLOWEEN;
|
|
||||||
if (month == Calendar.DECEMBER && day >= 24 && day <= 30) return Holiday.CHRISTMAS;
|
|
||||||
return Holiday.NONE;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -51,14 +51,13 @@ public final class InventoryUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static ItemStack storeItemsImpl(Container container, ItemStack stack, int offset, int slotCount) {
|
private static ItemStack storeItemsImpl(Container container, ItemStack stack, int offset, int slotCount) {
|
||||||
var limit = container.getMaxStackSize();
|
var limit = container.getContainerSize();
|
||||||
var maxSize = Math.min(stack.getMaxStackSize(), container.getMaxStackSize());
|
var maxSize = Math.min(stack.getMaxStackSize(), container.getMaxStackSize());
|
||||||
if (maxSize <= 0) return stack;
|
if (maxSize <= 0) return stack;
|
||||||
|
|
||||||
for (var i = 0; i < slotCount; i++) {
|
for (var i = 0; i < slotCount; i++) {
|
||||||
var slot = i + offset;
|
var slot = i + offset;
|
||||||
if (slot > limit) slot -= limit;
|
if (slot >= limit) slot -= limit;
|
||||||
|
|
||||||
var currentStack = container.getItem(slot);
|
var currentStack = container.getItem(slot);
|
||||||
if (currentStack.isEmpty()) {
|
if (currentStack.isEmpty()) {
|
||||||
// If the current slot is empty and we can place them item then there's two cases:
|
// If the current slot is empty and we can place them item then there's two cases:
|
||||||
|
@@ -8,6 +8,8 @@ package dan200.computercraft.shared.util;
|
|||||||
import dan200.computercraft.shared.platform.PlatformHelper;
|
import dan200.computercraft.shared.platform.PlatformHelper;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.Position;
|
||||||
|
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.entity.item.ItemEntity;
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
@@ -118,11 +120,21 @@ public final class WorldUtil {
|
|||||||
return getRayStart(player).add(look.x * reach, look.y * reach, look.z * reach);
|
return getRayStart(player).add(look.x * reach, look.y * reach, look.z * reach);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dropItemStack(ItemStack stack, Level world, BlockPos pos) {
|
private static final double DROP_SPEED = 0.0172275 * 6;
|
||||||
dropItemStack(stack, world, pos, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void dropItemStack(ItemStack stack, Level world, BlockPos pos, @Nullable Direction direction) {
|
/**
|
||||||
|
* Drop an item stack into the world from a block.
|
||||||
|
* <p>
|
||||||
|
* This behaves similarly to {@link DefaultDispenseItemBehavior#spawnItem(Level, ItemStack, int, Direction, Position)},
|
||||||
|
* though supports a {@code null} direction (in which case the item will have no velocity) and produces a slightly
|
||||||
|
* different arc.
|
||||||
|
*
|
||||||
|
* @param level The level to drop the item in.
|
||||||
|
* @param pos The position to drop the stack from.
|
||||||
|
* @param direction The direction to drop in, or {@code null}.
|
||||||
|
* @param stack The stack to drop.
|
||||||
|
*/
|
||||||
|
public static void dropItemStack(Level level, BlockPos pos, @Nullable Direction direction, ItemStack stack) {
|
||||||
double xDir;
|
double xDir;
|
||||||
double yDir;
|
double yDir;
|
||||||
double zDir;
|
double zDir;
|
||||||
@@ -136,25 +148,20 @@ public final class WorldUtil {
|
|||||||
zDir = 0.0;
|
zDir = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var xPos = pos.getX() + 0.5 + xDir * 0.4;
|
var xPos = pos.getX() + 0.5 + xDir * 0.7;
|
||||||
var yPos = pos.getY() + 0.5 + yDir * 0.4;
|
var yPos = pos.getY() + 0.5 + yDir * 0.7;
|
||||||
var zPos = pos.getZ() + 0.5 + zDir * 0.4;
|
var zPos = pos.getZ() + 0.5 + zDir * 0.7;
|
||||||
dropItemStack(stack, world, new Vec3(xPos, yPos, zPos), xDir, yDir, zDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void dropItemStack(ItemStack stack, Level world, Vec3 pos) {
|
var item = new ItemEntity(level, xPos, yPos, zPos, stack.copy());
|
||||||
dropItemStack(stack, world, pos, 0.0, 0.0, 0.0);
|
var baseSpeed = level.random.nextDouble() * 0.1 + 0.2;
|
||||||
}
|
|
||||||
|
|
||||||
public static void dropItemStack(ItemStack stack, Level world, Vec3 pos, double xDir, double yDir, double zDir) {
|
|
||||||
var item = new ItemEntity(world, pos.x, pos.y, pos.z, stack.copy());
|
|
||||||
item.setDeltaMovement(
|
item.setDeltaMovement(
|
||||||
xDir * 0.7 + world.getRandom().nextFloat() * 0.2 - 0.1,
|
level.random.triangle(xDir * baseSpeed, DROP_SPEED),
|
||||||
yDir * 0.7 + world.getRandom().nextFloat() * 0.2 - 0.1,
|
// Vanilla ignores the yDir and does a constant 0.2, but that gives the item a higher arc than we want.
|
||||||
zDir * 0.7 + world.getRandom().nextFloat() * 0.2 - 0.1
|
level.random.triangle(yDir * baseSpeed, DROP_SPEED),
|
||||||
|
level.random.triangle(zDir * baseSpeed, DROP_SPEED)
|
||||||
);
|
);
|
||||||
item.setDefaultPickUpDelay();
|
item.setDefaultPickUpDelay();
|
||||||
world.addFreshEntity(item);
|
level.addFreshEntity(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -171,8 +178,8 @@ public final class WorldUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getBlockShape(BlockState state, BlockGetter levle, BlockPos pos) {
|
public VoxelShape getBlockShape(BlockState state, BlockGetter level, BlockPos pos) {
|
||||||
return block.get(state, levle, pos, CollisionContext.empty());
|
return block.get(state, level, pos, CollisionContext.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -139,5 +139,48 @@
|
|||||||
"upgrade.minecraft.diamond_hoe.adjective": "Contadina",
|
"upgrade.minecraft.diamond_hoe.adjective": "Contadina",
|
||||||
"upgrade.minecraft.diamond_pickaxe.adjective": "Minatrice",
|
"upgrade.minecraft.diamond_pickaxe.adjective": "Minatrice",
|
||||||
"upgrade.minecraft.diamond_shovel.adjective": "Scavatrice",
|
"upgrade.minecraft.diamond_shovel.adjective": "Scavatrice",
|
||||||
"upgrade.minecraft.diamond_sword.adjective": "Da Combattimento"
|
"upgrade.minecraft.diamond_sword.adjective": "Da Combattimento",
|
||||||
|
"gui.computercraft.config.term_sizes.computer.width.tooltip": "Intervallo: 1 ~ 255",
|
||||||
|
"gui.computercraft.config.turtle.need_fuel.tooltip": "Imposta se la Tartaruga richiede del carburante per muoversi.",
|
||||||
|
"gui.computercraft.config.command_require_creative": "Il computer Comando richiede la modalità creativa",
|
||||||
|
"tracking_field.computercraft.http_requests.name": "Richieste HTTP",
|
||||||
|
"gui.computercraft.config.command_require_creative.tooltip": "Richiede che i giocatori siano in modalità creativa e che siano operatori in ordine per interagire con\ni computer di commando. Questo è il comportamento predefinito dei blocchi di comando.",
|
||||||
|
"gui.computercraft.config.disable_lua51_features.tooltip": "Imposta a \"true\" per disattivare le funzionalità di Lua 5.1 che saranno rimosse in un\naggiornamento futuro. Utile per assicurare futura compatibilità con i tuoi programmi.",
|
||||||
|
"gui.computercraft.config.execution": "Esecuzione",
|
||||||
|
"gui.computercraft.config.execution.max_main_computer_time": "Limite di tempo nei tick del server dei computer",
|
||||||
|
"gui.computercraft.config.execution.max_main_computer_time.tooltip": "Il tempo massimo ideale che un computer può eseguire in un tick, in millisecondi.\nNota, potremmo andare ben sopra questo limite, perché non c'è modo di sapere\nquanto impiega, questa configurazione mira ad essere il limite maggiore del tempo medio.\nRange: > 1",
|
||||||
|
"gui.computercraft.config.execution.max_main_global_time": "Limite tempo globale dei tick del server",
|
||||||
|
"gui.computercraft.config.execution.tooltip": "Controlla comportamento esecuzione dei computer. Questo è largamente utilizzato\nper ritoccare la performance dei server, e generale non dovrebbe essere toccato.",
|
||||||
|
"gui.computercraft.config.floppy_space_limit.tooltip": "Limite di spazio di archiviazione per i dischi floppy, in byte.",
|
||||||
|
"gui.computercraft.config.http.bandwidth": "Banda larga",
|
||||||
|
"gui.computercraft.config.http.bandwidth.global_download": "Limite download globale",
|
||||||
|
"gui.computercraft.config.http.bandwidth.global_download.tooltip": "Numero di byte che possono essere scaricati in un secondo. Questo è condiviso tra tutti i computer. (bytes/s).\nRange: > 1",
|
||||||
|
"gui.computercraft.config.http.bandwidth.global_upload": "Limite upload globale",
|
||||||
|
"gui.computercraft.config.http.bandwidth.global_upload.tooltip": "Numero di byte che possono essere caricati in un secondo. Questo è condiviso tra tutti i computer. (bytes/s).\nRange: > 1",
|
||||||
|
"gui.computercraft.config.http.bandwidth.tooltip": "Limita la banda larga usato dai computer.",
|
||||||
|
"gui.computercraft.config.http.max_requests.tooltip": "Il numero di richieste http che un computer può fare alla volta. Ulteriori richieste\nverranno messe in coda, ed inviate quando le richieste correnti sono terminate.\nImposta a 0 per illimitato.\nRange: > 0",
|
||||||
|
"gui.computercraft.config.http.max_websockets.tooltip": "Il numero di websocket che un computer può avere aperte allo stesso momento.\nImposta a 0 per illimitato.\nRange: > 1",
|
||||||
|
"gui.computercraft.config.http.rules": "Concedi/nega regole",
|
||||||
|
"gui.computercraft.config.maximum_open_files.tooltip": "Imposta quanti file possono essere aperti allo stesso momento su un computer. Imposta a 0 per illimitato.\nRange: > 0",
|
||||||
|
"gui.computercraft.config.monitor_distance": "Distanza monitor",
|
||||||
|
"gui.computercraft.config.monitor_distance.tooltip": "Distanza massima che i monitor vengono renderizzati. Questo è predefinito al limite\nstandard dei tile entity, ma può essere esteso se desideri construire monitor più grandi.\nRange: 16 ~ 1024",
|
||||||
|
"gui.computercraft.config.monitor_renderer": "Renderizzatore monitor",
|
||||||
|
"gui.computercraft.config.peripheral.command_block_enabled.tooltip": "Attiva il supporto ai blocchi di comando come periferiche",
|
||||||
|
"gui.computercraft.config.peripheral.max_notes_per_tick.tooltip": "Quantità massima di note che un altoparlante può riprodurre allo stesso momento.\nRange: > 1",
|
||||||
|
"gui.computercraft.config.peripheral.modem_high_altitude_range.tooltip": "La distanza massima dei modem wireless all'altitudine massima durante il meteo soleggiato. in metri.\nRange: 0 ~ 100000",
|
||||||
|
"gui.computercraft.config.peripheral.modem_high_altitude_range_during_storm.tooltip": "La distanza massima dei modem wireless all'altitudine massima durante una tempesta. in metri.\nRange: 0 ~ 100000",
|
||||||
|
"gui.computercraft.config.peripheral.modem_range.tooltip": "La distanza massima dei modem wireless ad altitudini basse durante il meteo soleggiato. in metri.\nRange: 0 ~ 100000",
|
||||||
|
"gui.computercraft.config.peripheral.modem_range_during_storm.tooltip": "La distanza massima dei modem wireless ad altitudini basse durante una tempesta. in metri.\nRange: 0 ~ 100000",
|
||||||
|
"gui.computercraft.config.peripheral.monitor_bandwidth": "Banda larga monitor",
|
||||||
|
"gui.computercraft.config.computer_space_limit.tooltip": "Limite di spazio di archiviazione per i computer e le tartarughe, in byte.",
|
||||||
|
"gui.computercraft.config.default_computer_settings.tooltip": "Una lista di impostazioni predefinite per i nuovi computer, separate da virgola.\nEsempio: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\"\ndisattiverà tutti gli autocompletamenti.",
|
||||||
|
"gui.computercraft.config.execution.computer_threads.tooltip": "Imposta la quantità di thread che possono eseguire i computer. Un numero più alto significa\nche più computer possono essere eseguiti alla volta, ma può indurre a lag. Alcune mod potrebbero\nnon funzionare con numeri di thread maggiore a 1. Usare con cautela.\nRange: > 1",
|
||||||
|
"gui.computercraft.config.execution.max_main_global_time.tooltip": "Il limite massimo di tempo che può essere usato per eseguire task in un singolo tick,\nin millisecondi.\nNota, potremmo andare ben sopra questo limite, perché non c'è modo di sapere\nquanto impiega, questa configurazione mira ad essere il limite maggiore del tempo medio.\nRange: > 1",
|
||||||
|
"gui.computercraft.config.http.enabled.tooltip": "Attiva l'API \"http\" sui computer. Questo disabilita i programmi \"pastebin\" e \"wget\", \nche molti utenti dipendono. È raccomandato lasciarlo attivo ed utlizzare l'opzione \n\"rules\" per imporre controlli più adeguati.",
|
||||||
|
"gui.computercraft.config.http.rules.tooltip": "Una lista di regole che controllano il comportamento dell'API \"http\" per specifici domini\no indirizzi IP. Ogni regola è un elemento con un 'host' da confrontare, e una serie di\nproprietà. Le regole sono valutate in ordine, cioè le prime regole sovvrascrivono le successive.\nL'host può essere un dominio (\"pastebin.com\"), wildcard (\"*.pastebin.com\") oppure\nuna notazione CIDR (\"127.0.0.0/8\").\nSe non è presente nessuna regola, il dominio è bloccato.",
|
||||||
|
"gui.computercraft.config.http.tooltip": "Controlla l'API HTTP",
|
||||||
|
"gui.computercraft.config.http.websocket_enabled.tooltip": "Attiva l'uso di websocket http. Questo richiede che l'opzione \"http_enable\" sia attiva.",
|
||||||
|
"gui.computercraft.config.log_computer_errors.tooltip": "Registra le eccezioni lanciate dalle periferiche e altri oggetti di Lua. Questo rende più facile\nper gli autori di mod per il debug di problemi, ma potrebbe risultare in spam di log durante\nl'uso di metodi buggati.",
|
||||||
|
"gui.computercraft.config.monitor_renderer.tooltip": "Il renderizzatore da usare per i monitor. Generalmente si dovrebbe lasciare su \"best\", se\ni monitor hanno problemi di performance, puoi sperimentare con renderizzatori alternativi.\nValori concessi: BEST, TBO, VBO",
|
||||||
|
"gui.computercraft.config.peripheral.monitor_bandwidth.tooltip": "Il limite di quanti dati dei monitor possono essere inviati *al tick*. Nota:\n - La banda larga è misurata prima della compressione, così che il dato inviato al client è\n più piccolo."
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,128 @@
|
|||||||
|
{
|
||||||
|
"block.computercraft.disk_drive": "tomo pi lipu sona",
|
||||||
|
"block.computercraft.printer": "ilo sitelen",
|
||||||
|
"block.computercraft.monitor_normal": "ilo lukin",
|
||||||
|
"block.computercraft.monitor_advanced": "ilo lukin wawa",
|
||||||
|
"block.computercraft.speaker": "ilo kalama",
|
||||||
|
"commands.computercraft.generic.exception": "pakala awen ala (%s)",
|
||||||
|
"block.computercraft.computer_command": "ilo sona pi toki wawa",
|
||||||
|
"block.computercraft.turtle_advanced": "ilo sona pali wawa",
|
||||||
|
"block.computercraft.turtle_normal": "ilo sona pali",
|
||||||
|
"block.computercraft.computer_advanced": "ilo sona wawa",
|
||||||
|
"block.computercraft.computer_normal": "ilo sona",
|
||||||
|
"argument.computercraft.argument_expected": "mi wile e ijo",
|
||||||
|
"block.computercraft.turtle_advanced.upgraded": "ilo sona pali wawa (%s)",
|
||||||
|
"block.computercraft.turtle_normal.upgraded": "ilo sona pali (%s)",
|
||||||
|
"commands.computercraft.dump.action": "o lukin e sona mute pi ilo sona ni",
|
||||||
|
"commands.computercraft.generic.no_position": "<lon ala>",
|
||||||
|
"chat.computercraft.wired_modem.peripheral_connected": "ijo sona \"%s\" li linja tawa kulupu",
|
||||||
|
"chat.computercraft.wired_modem.peripheral_disconnected": "ijo sona \"%s\" li linja ala tawa kulupu",
|
||||||
|
"block.computercraft.wired_modem": "ilo toki linja",
|
||||||
|
"block.computercraft.wired_modem_full": "ilo toki linja",
|
||||||
|
"block.computercraft.wireless_modem_normal": "ilo toki linja ala",
|
||||||
|
"commands.computercraft.generic.additional_rows": "mute %d…",
|
||||||
|
"argument.computercraft.computer.no_matching": "mi ken ala alasa e ilo sona pi nimi '%s'",
|
||||||
|
"commands.computercraft.dump.open_path": "o lukin e lipu pi ilo sona ni",
|
||||||
|
"commands.computercraft.dump.synopsis": "mi pana e sona pi ilo sona.",
|
||||||
|
"block.computercraft.cable": "linja toki",
|
||||||
|
"block.computercraft.wireless_modem_advanced": "ilo toki pi ma End",
|
||||||
|
"commands.computercraft.generic.position": "%s, %s, %s",
|
||||||
|
"commands.computercraft.help.no_children": "toki wawa '%s' li jo ala e toki wawa insa",
|
||||||
|
"commands.computercraft.help.no_command": "toki wawa '%s' li lon ala",
|
||||||
|
"commands.computercraft.help.desc": "mi pana e toki ni",
|
||||||
|
"commands.computercraft.help.synopsis": "mi pana e sona pi toki wawa ale",
|
||||||
|
"commands.computercraft.reload.done": "mi kama open sin e ante nasin",
|
||||||
|
"commands.computercraft.shutdown.done": "mi kama pini e ilo sona %s/%s",
|
||||||
|
"commands.computercraft.shutdown.synopsis": "mi pini weka e ilo sona.",
|
||||||
|
"commands.computercraft.queue.synopsis": "mi pana e toki computer_command tawa ilo sona pi toki wawa",
|
||||||
|
"commands.computercraft.tp.desc": "o tawa ilo sona. ilo sona la, sina ken pana e nanpa pi ijo (sama 123) anu nanpa (sama #123).",
|
||||||
|
"commands.computercraft.synopsis": "mi jo e toki wawa ante tawa ni: sina lawa e ilo sona.",
|
||||||
|
"commands.computercraft.tp.action": "o tawa pi ilo sona",
|
||||||
|
"commands.computercraft.tp.not_player": "jan ala la, mi ken ala open e sitelen pi ilo sona",
|
||||||
|
"commands.computercraft.track.dump.computer": "ilo sona",
|
||||||
|
"commands.computercraft.tp.synopsis": "mi tawa pi ilo sona e sina.",
|
||||||
|
"commands.computercraft.tp.not_there": "mi ken ala alasa e ilo sona pi lon ma",
|
||||||
|
"commands.computercraft.track.desc": "ilo sona la, mi sitelen e tenpo pali e mute toki. toki wawa /forge track la, mi pana pi nasin sama e sona. mi pona tawa alasa pi tenpo ike.",
|
||||||
|
"commands.computercraft.track.dump.no_timings": "mi ken ala alasa e tenpo",
|
||||||
|
"commands.computercraft.track.stop.synopsis": "mi pini e sitelen sona ale",
|
||||||
|
"commands.computercraft.track.start.synopsis": "mi open sitelen sona e ilo sona ale",
|
||||||
|
"commands.computercraft.track.stop.action": "o luka tawa ni: mi pini sitelen sona",
|
||||||
|
"commands.computercraft.track.stop.not_enabled": "tenpo ni la, mi sitelen ala sona e ilo sona",
|
||||||
|
"commands.computercraft.track.dump.synopsis": "mi pana e sona tan sitelen sona pi sin mute",
|
||||||
|
"commands.computercraft.track.stop.desc": "ilo sona la, mi pini sitelen sona e tenpo pali e mute toki",
|
||||||
|
"commands.computercraft.track.synopsis": "mi sitelen tenpo pali e ilo sona.",
|
||||||
|
"commands.computercraft.track.dump.desc": "mi pana e sona tan sitelen sona pi sin mute.",
|
||||||
|
"commands.computercraft.view.action": "o lukin e ilo sona ni",
|
||||||
|
"commands.computercraft.view.synopsis": "o lukin e sitelen pi ilo sona.",
|
||||||
|
"commands.computercraft.turn_on.done": "mi kama open e ilo sona %s/%s",
|
||||||
|
"commands.computercraft.turn_on.synopsis": "mi open weka e ilo sona.",
|
||||||
|
"commands.computercraft.view.not_player": "jan ala la, mi ken ala open e sitelen pi ilo sona",
|
||||||
|
"gui.computercraft.config.command_require_creative": "ilo sona pi toki wawa li wile e jan sewi",
|
||||||
|
"gui.computercraft.config.execution.computer_threads": "linja pi ilo sona",
|
||||||
|
"gui.computercraft.config.http.bandwidth": "mute sona",
|
||||||
|
"gui.computercraft.config.http": "ijo HTTP",
|
||||||
|
"gui.computercraft.config.execution": "pali",
|
||||||
|
"gui.computercraft.config.monitor_renderer": "nasin sitelen pi ilo lukin",
|
||||||
|
"gui.computercraft.config.term_sizes.pocket_computer.width": "suli poka pi ilo sitelen",
|
||||||
|
"gui.computercraft.config.term_sizes": "suli pi ilo sitelen",
|
||||||
|
"gui.computercraft.config.term_sizes.computer": "ilo sona",
|
||||||
|
"gui.computercraft.config.term_sizes.monitor": "ilo lukin",
|
||||||
|
"gui.computercraft.config.term_sizes.pocket_computer": "ilo sona lili",
|
||||||
|
"gui.computercraft.config.term_sizes.pocket_computer.height": "suli sewi pi ilo sitelen",
|
||||||
|
"gui.computercraft.config.term_sizes.computer.height": "suli sewi pi ilo sitelen",
|
||||||
|
"gui.computercraft.config.term_sizes.computer.width": "suli poka pi ito sitelen",
|
||||||
|
"gui.computercraft.config.term_sizes.computer.tooltip": "suli pi ilo sitelen pi ilo sona.",
|
||||||
|
"gui.computercraft.config.peripheral.monitor_bandwidth": "mute sona pi ilo lukin",
|
||||||
|
"gui.computercraft.config.peripheral.modem_range": "suli ken ilo pi ilo toki (pona)",
|
||||||
|
"gui.computercraft.config.peripheral.modem_high_altitude_range": "suli ken ilo pi ilo toki (sewi mute)",
|
||||||
|
"item.computercraft.printed_page": "lipu pi ilo sitelen",
|
||||||
|
"item.computercraft.printed_pages": "lipu mute pi ilo sitelen",
|
||||||
|
"item.computercraft.treasure_disk": "lipu sona",
|
||||||
|
"gui.computercraft.tooltip.turn_on": "o open e ilo sona ni",
|
||||||
|
"gui.computercraft.tooltip.computer_id": "nanpa pi ilo sona: %s",
|
||||||
|
"gui.computercraft.tooltip.turn_off": "o pini e ilo sona ni",
|
||||||
|
"item.computercraft.pocket_computer_advanced": "ilo sona lili wawa",
|
||||||
|
"item.computercraft.pocket_computer_advanced.upgraded": "ilo sona lili wawa (%s)",
|
||||||
|
"item.computercraft.pocket_computer_normal": "ilo sona lili",
|
||||||
|
"item.computercraft.pocket_computer_normal.upgraded": "ilo sona lili (%s)",
|
||||||
|
"gui.computercraft.terminal": "ilo sitelen pi ilo sona",
|
||||||
|
"itemGroup.computercraft": "ComputerCraft",
|
||||||
|
"tracking_field.computercraft.computer_tasks.name": "pali",
|
||||||
|
"tracking_field.computercraft.turtle_ops.name": "pali pi ilo sona pali",
|
||||||
|
"upgrade.computercraft.speaker.adjective": "kalama",
|
||||||
|
"tracking_field.computercraft.count": "%s (mute)",
|
||||||
|
"tracking_field.computercraft.coroutines_created.name": "open linja",
|
||||||
|
"tracking_field.computercraft.coroutines_dead.name": "pini linja",
|
||||||
|
"tracking_field.computercraft.max": "%s (sewi)",
|
||||||
|
"upgrade.minecraft.crafting_table.adjective": "pali",
|
||||||
|
"upgrade.minecraft.diamond_axe.adjective": "ilo kipisi",
|
||||||
|
"upgrade.minecraft.diamond_hoe.adjective": "ilo kasi",
|
||||||
|
"upgrade.computercraft.wireless_modem_normal.adjective": "toki linja ala",
|
||||||
|
"upgrade.minecraft.diamond_pickaxe.adjective": "ilo pakala",
|
||||||
|
"upgrade.minecraft.diamond_shovel.adjective": "ilo ma",
|
||||||
|
"upgrade.minecraft.diamond_sword.adjective": "utala",
|
||||||
|
"block.computercraft.turtle_advanced.upgraded_twice": "ilo sona pali wawa (%s, %s)",
|
||||||
|
"block.computercraft.turtle_normal.upgraded_twice": "ilo sona pali (%s, %s)",
|
||||||
|
"gui.computercraft.config.turtle": "ilo sona pali",
|
||||||
|
"item.computercraft.disk": "lipu sona",
|
||||||
|
"item.computercraft.printed_book": "lipu suli pi ilo sitelen",
|
||||||
|
"upgrade.computercraft.wireless_modem_advanced.adjective": "toki pi ma End",
|
||||||
|
"gui.computercraft.tooltip.disk_id": "nanpa pi lipu sona: %s",
|
||||||
|
"gui.computercraft.config.peripheral": "ijo sona",
|
||||||
|
"gui.computercraft.config.peripheral.modem_range_during_storm": "suli ken ilo pi ilo toki (sewi ike)",
|
||||||
|
"argument.computercraft.tracking_field.no_field": "mi sona ala e nimi '%s'",
|
||||||
|
"argument.computercraft.computer.many_matching": "mi alasa e ilo sona mute pi nimi '%s' (ijo %s)",
|
||||||
|
"commands.computercraft.desc": "ilo sona la, toki wawa /computercraft li lawa li luka li pakala ala.",
|
||||||
|
"commands.computercraft.reload.desc": "mi open sin e ante nasin",
|
||||||
|
"commands.computercraft.reload.synopsis": "mi open sin e ante nasin",
|
||||||
|
"commands.computercraft.shutdown.desc": "mi pini e ilo sona pi pana sina anu ale. ilo sona la, sina ken pana e nanpa pi ijo (sama 123) anu nanpa (sama #123) anu nimi (sama \"@ilo sona mi\").",
|
||||||
|
"gui.computercraft.config.term_sizes.pocket_computer.tooltip": "suli pi ilo sitelen pi ilo sona lili.",
|
||||||
|
"gui.computercraft.config.peripheral.modem_high_altitude_range_during_storm": "suli ken ilo pi ilo toki (sewi mute, sewi ike)",
|
||||||
|
"gui.computercraft.pocket_computer_overlay": "sina open e ilo sona lili. o luka e nena ESC tawa pini.",
|
||||||
|
"commands.computercraft.dump.desc": "sona pi ilo sona la, mi pana e ale anu wan. ilo sona la, sina ken pana e nanpa pi ijo (sama 123) anu nanpa (sama #123) anu nimi (sama \"@ilo sona mi\").",
|
||||||
|
"commands.computercraft.turn_on.desc": "mi open e ilo sona pi pana sina. ilo sona la, sina ken pana e nanpa pi ijo (sama 123) anu nanpa (sama #123) anu nimi (sama \"@ilo sona mi\").",
|
||||||
|
"commands.computercraft.track.start.stop": "o toki wawa %s tawa ni: sina pini sitelen sona. sina lukin e sona ni",
|
||||||
|
"commands.computercraft.track.start.desc": "ilo sona la, mi open sitelen sona e tenpo pali e mute toki. mi weka e sitelen sona pini.",
|
||||||
|
"commands.computercraft.view.desc": "mi open e sitelen pi ilo sona tawa ni: sina lawa weka e ilo sona. taso, sina ken ala open e jo pi ilo sona pali. ilo sona la, sina ken pana e nanpa pi ijo (sama 123) anu nanpa (sama #123).",
|
||||||
|
"gui.computercraft.config.disable_lua51_features": "ijo pona pi ilo Lua 5.1 li weka"
|
||||||
|
}
|
@@ -6,6 +6,7 @@
|
|||||||
package dan200.computercraft;
|
package dan200.computercraft;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.brigadier.arguments.ArgumentType;
|
import com.mojang.brigadier.arguments.ArgumentType;
|
||||||
import dan200.computercraft.api.network.wired.WiredElement;
|
import dan200.computercraft.api.network.wired.WiredElement;
|
||||||
@@ -77,6 +78,17 @@ public class TestPlatformHelper extends AbstractComputerCraftAPI implements Plat
|
|||||||
throw new UnsupportedOperationException("Cannot query registry inside tests");
|
throw new UnsupportedOperationException("Cannot query registry inside tests");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public <T> T tryGetRegistryObject(ResourceKey<Registry<T>> registry, ResourceLocation id) {
|
||||||
|
throw new UnsupportedOperationException("Cannot query registries");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldLoadResource(JsonObject object) {
|
||||||
|
throw new UnsupportedOperationException("Cannot use loot conditions");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends BlockEntity> BlockEntityType<T> createBlockEntityType(BiFunction<BlockPos, BlockState, T> factory, Block block) {
|
public <T extends BlockEntity> BlockEntityType<T> createBlockEntityType(BiFunction<BlockPos, BlockState, T> factory, Block block) {
|
||||||
throw new UnsupportedOperationException("Cannot create BlockEntityType inside tests");
|
throw new UnsupportedOperationException("Cannot create BlockEntityType inside tests");
|
||||||
@@ -219,10 +231,4 @@ public class TestPlatformHelper extends AbstractComputerCraftAPI implements Plat
|
|||||||
public String getInstalledVersion() {
|
public String getInstalledVersion() {
|
||||||
return "1.0";
|
return "1.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public <T> T tryGetRegistryObject(ResourceKey<Registry<T>> registry, ResourceLocation id) {
|
|
||||||
throw new UnsupportedOperationException("Cannot query registries");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.util;
|
||||||
|
|
||||||
|
import dan200.computercraft.test.shared.WithMinecraft;
|
||||||
|
import net.minecraft.world.SimpleContainer;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static dan200.computercraft.test.shared.ItemStackMatcher.isStack;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
@WithMinecraft
|
||||||
|
public class InventoryUtilTest {
|
||||||
|
@Test
|
||||||
|
public void testStoreOffset() {
|
||||||
|
var container = new SimpleContainer(9);
|
||||||
|
|
||||||
|
var remainder = InventoryUtil.storeItemsFromOffset(container, new ItemStack(Items.COBBLESTONE, 32), 4);
|
||||||
|
assertThat("Remainder is empty", remainder, isStack(ItemStack.EMPTY));
|
||||||
|
assertThat("Was inserted into slot", container.getItem(4), isStack(new ItemStack(Items.COBBLESTONE, 32)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoreOffsetWraps() {
|
||||||
|
var container = new SimpleContainer(9);
|
||||||
|
container.setItem(0, new ItemStack(Items.DIRT));
|
||||||
|
for (var slot = 4; slot < 9; slot++) container.setItem(slot, new ItemStack(Items.DIRT));
|
||||||
|
|
||||||
|
var remainder = InventoryUtil.storeItemsFromOffset(container, new ItemStack(Items.COBBLESTONE, 32), 4);
|
||||||
|
assertThat("Remainder is empty", remainder, isStack(ItemStack.EMPTY));
|
||||||
|
assertThat("Was inserted into slot", container.getItem(1), isStack(new ItemStack(Items.COBBLESTONE, 32)));
|
||||||
|
}
|
||||||
|
}
|
@@ -130,6 +130,22 @@ public interface ContainerTransferContract {
|
|||||||
assertNoOverlap(source, destination);
|
assertNoOverlap(source, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
default void testMoveRotateWraps() {
|
||||||
|
var source = new SimpleContainer(1);
|
||||||
|
source.setItem(0, new ItemStack(Items.COBBLESTONE, 32));
|
||||||
|
|
||||||
|
var destination = new SimpleContainer(9);
|
||||||
|
destination.setItem(0, new ItemStack(Items.DIRT));
|
||||||
|
for (var slot = 4; slot < 9; slot++) destination.setItem(slot, new ItemStack(Items.DIRT));
|
||||||
|
|
||||||
|
var move = wrap(source).moveTo(wrap(destination).rotate(4), 64);
|
||||||
|
assertEquals(32, move);
|
||||||
|
|
||||||
|
assertThat("Source is empty", source.getItem(0), isStack(ItemStack.EMPTY));
|
||||||
|
assertThat("Was inserted into slot", destination.getItem(1), isStack(new ItemStack(Items.COBBLESTONE, 32)));
|
||||||
|
}
|
||||||
|
|
||||||
static void assertNoOverlap(Container... containers) {
|
static void assertNoOverlap(Container... containers) {
|
||||||
Set<ItemStack> stacks = Collections.newSetFromMap(new IdentityHashMap<>());
|
Set<ItemStack> stacks = Collections.newSetFromMap(new IdentityHashMap<>());
|
||||||
for (var container : containers) {
|
for (var container : containers) {
|
||||||
|
@@ -8,6 +8,7 @@ package dan200.computercraft.gametest.core;
|
|||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import dan200.computercraft.api.ComputerCraftAPI;
|
import dan200.computercraft.api.ComputerCraftAPI;
|
||||||
import dan200.computercraft.mixin.gametest.TestCommandAccessor;
|
import dan200.computercraft.mixin.gametest.TestCommandAccessor;
|
||||||
|
import dan200.computercraft.shared.ModRegistry;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.gametest.framework.GameTestRegistry;
|
import net.minecraft.gametest.framework.GameTestRegistry;
|
||||||
@@ -81,6 +82,27 @@ class CCTestCommand {
|
|||||||
player.getLevel().addFreshEntity(armorStand);
|
player.getLevel().addFreshEntity(armorStand);
|
||||||
return 0;
|
return 0;
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
.then(literal("give-computer").executes(context -> {
|
||||||
|
var player = context.getSource().getPlayerOrException();
|
||||||
|
var pos = StructureUtils.findNearestStructureBlock(player.blockPosition(), 15, player.getLevel());
|
||||||
|
if (pos == null) return error(context.getSource(), "No nearby test");
|
||||||
|
|
||||||
|
var structureBlock = (StructureBlockEntity) player.getLevel().getBlockEntity(pos);
|
||||||
|
if (structureBlock == null) return error(context.getSource(), "No nearby structure block");
|
||||||
|
var info = GameTestRegistry.getTestFunction(structureBlock.getStructurePath());
|
||||||
|
|
||||||
|
var item = ModRegistry.Items.COMPUTER_ADVANCED.get().create(1, info.getTestName());
|
||||||
|
if (!player.getInventory().add(item)) {
|
||||||
|
var itemEntity = player.drop(item, false);
|
||||||
|
if (itemEntity != null) {
|
||||||
|
itemEntity.setNoPickUpDelay();
|
||||||
|
itemEntity.setOwner(player.getUUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@ package dan200.computercraft.gametest
|
|||||||
import dan200.computercraft.core.apis.FSAPI
|
import dan200.computercraft.core.apis.FSAPI
|
||||||
import dan200.computercraft.gametest.api.*
|
import dan200.computercraft.gametest.api.*
|
||||||
import dan200.computercraft.shared.ModRegistry
|
import dan200.computercraft.shared.ModRegistry
|
||||||
|
import dan200.computercraft.shared.media.items.DiskItem
|
||||||
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveBlock
|
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveBlock
|
||||||
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveState
|
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveState
|
||||||
import dan200.computercraft.test.core.assertArrayEquals
|
import dan200.computercraft.test.core.assertArrayEquals
|
||||||
@@ -45,10 +46,14 @@ class Disk_Drive_Test {
|
|||||||
thenWaitUntil { helper.assertItemEntityPresent(Items.MUSIC_DISC_13, stackAt, 0.0) }
|
thenWaitUntil { helper.assertItemEntityPresent(Items.MUSIC_DISC_13, stackAt, 0.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mount is initially attached, and then removed when the disk is ejected.
|
||||||
|
*/
|
||||||
@GameTest
|
@GameTest
|
||||||
fun Adds_removes_mount(helper: GameTestHelper) = helper.sequence {
|
fun Adds_removes_mount(helper: GameTestHelper) = helper.sequence {
|
||||||
thenIdle(2)
|
thenOnComputer { } // Wait for the computer to start up
|
||||||
thenOnComputer {
|
thenIdle(2) // Let the disk drive tick once to create the mount
|
||||||
|
thenOnComputer { // Then actually assert things!
|
||||||
getApi<FSAPI>().getDrive("disk").assertArrayEquals("right")
|
getApi<FSAPI>().getDrive("disk").assertArrayEquals("right")
|
||||||
callPeripheral("right", "ejectDisk")
|
callPeripheral("right", "ejectDisk")
|
||||||
}
|
}
|
||||||
@@ -56,6 +61,18 @@ class Disk_Drive_Test {
|
|||||||
thenOnComputer { assertEquals(null, getApi<FSAPI>().getDrive("disk")) }
|
thenOnComputer { assertEquals(null, getApi<FSAPI>().getDrive("disk")) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When creating a new mount, the item is with a new disk ID.
|
||||||
|
*/
|
||||||
|
@GameTest
|
||||||
|
fun Creates_disk_id(helper: GameTestHelper) = helper.sequence {
|
||||||
|
val drivePos = BlockPos(2, 2, 2)
|
||||||
|
thenWaitUntil {
|
||||||
|
val drive = helper.getBlockEntity(drivePos, ModRegistry.BlockEntities.DISK_DRIVE.get())
|
||||||
|
if (DiskItem.getDiskID(drive.getItem(0)) == -1) helper.fail("Disk has no item", drivePos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check comparators can read the contents of the disk drive
|
* Check comparators can read the contents of the disk drive
|
||||||
*/
|
*/
|
||||||
|
@@ -66,4 +66,19 @@ class Inventory_Test {
|
|||||||
helper.assertContainerExactly(BlockPos(3, 2, 2), NonNullList.withSize(27, ItemStack(Items.POLISHED_ANDESITE)))
|
helper.assertContainerExactly(BlockPos(3, 2, 2), NonNullList.withSize(27, ItemStack(Items.POLISHED_ANDESITE)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures inventory methods see a complete double chest
|
||||||
|
*
|
||||||
|
* @see <https://github.com/cc-tweaked/CC-Tweaked/issues/1279>
|
||||||
|
*/
|
||||||
|
@GameTest
|
||||||
|
fun Double_chest_size(helper: GameTestHelper) = helper.sequence {
|
||||||
|
thenOnComputer {
|
||||||
|
getApi<PeripheralAPI>().call(context, ObjectArguments("left", "size")).await()
|
||||||
|
.assertArrayEquals(54, message = "Has 54 slots")
|
||||||
|
getApi<PeripheralAPI>().call(context, ObjectArguments("left", "pushItems", "right", 1)).await()
|
||||||
|
.assertArrayEquals(32, message = "Moved 32 items into a double chest")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -70,6 +70,20 @@ class Modem_Test {
|
|||||||
.assertArrayEquals("modem_message", "left", 12, 34, "Hello", 4, message = "Modem message")
|
.assertArrayEquals("modem_message", "left", 12, 34, "Hello", 4, message = "Modem message")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert that full block modems act like cables.
|
||||||
|
*
|
||||||
|
* @see [#1278](https://github.com/cc-tweaked/CC-Tweaked/issues/1278)
|
||||||
|
*/
|
||||||
|
@GameTest(setupTicks = 1)
|
||||||
|
fun Full_modems_form_networks(helper: GameTestHelper) = helper.sequence {
|
||||||
|
thenExecute {
|
||||||
|
val modem1 = helper.getBlockEntity(BlockPos(1, 2, 1), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get())
|
||||||
|
val modem2 = helper.getBlockEntity(BlockPos(3, 2, 1), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get())
|
||||||
|
assertEquals(modem1.element.node.network, modem2.element.node.network, "On the same network")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LuaTaskContext.findPeripheral(type: String): String? {
|
private fun LuaTaskContext.findPeripheral(type: String): String? {
|
||||||
|
@@ -63,7 +63,7 @@ class Monitor_Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test
|
* Test monitors render correctly
|
||||||
*/
|
*/
|
||||||
@GameTestGenerator
|
@GameTestGenerator
|
||||||
fun Render_monitor_tests(): List<TestFunction> {
|
fun Render_monitor_tests(): List<TestFunction> {
|
||||||
@@ -72,7 +72,7 @@ class Monitor_Test {
|
|||||||
fun addTest(label: String, renderer: MonitorRenderer, time: Long = Times.NOON, tag: String = TestTags.CLIENT) {
|
fun addTest(label: String, renderer: MonitorRenderer, time: Long = Times.NOON, tag: String = TestTags.CLIENT) {
|
||||||
if (!TestTags.isEnabled(tag)) return
|
if (!TestTags.isEnabled(tag)) return
|
||||||
|
|
||||||
val className = Monitor_Test::class.java.simpleName.lowercase()
|
val className = this::class.java.simpleName.lowercase()
|
||||||
val testName = "$className.render_monitor"
|
val testName = "$className.render_monitor"
|
||||||
|
|
||||||
tests.add(
|
tests.add(
|
||||||
|
@@ -0,0 +1,53 @@
|
|||||||
|
package dan200.computercraft.gametest
|
||||||
|
|
||||||
|
import dan200.computercraft.gametest.api.*
|
||||||
|
import net.minecraft.gametest.framework.GameTestGenerator
|
||||||
|
import net.minecraft.gametest.framework.GameTestHelper
|
||||||
|
import net.minecraft.gametest.framework.TestFunction
|
||||||
|
|
||||||
|
class Printout_Test {
|
||||||
|
/**
|
||||||
|
* Test printouts render correctly
|
||||||
|
*/
|
||||||
|
@GameTestGenerator
|
||||||
|
fun Render_in_frame(): List<TestFunction> {
|
||||||
|
val tests = mutableListOf<TestFunction>()
|
||||||
|
|
||||||
|
fun addTest(label: String, time: Long = Times.NOON, tag: String = TestTags.CLIENT) {
|
||||||
|
if (!TestTags.isEnabled(tag)) return
|
||||||
|
|
||||||
|
val className = this::class.java.simpleName.lowercase()
|
||||||
|
val testName = "$className.render_in_frame"
|
||||||
|
|
||||||
|
tests.add(
|
||||||
|
TestFunction(
|
||||||
|
"$testName.$label",
|
||||||
|
"$testName.$label",
|
||||||
|
testName,
|
||||||
|
Timeouts.DEFAULT,
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
) { renderPrintout(it, time) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
addTest("noon", Times.NOON)
|
||||||
|
addTest("midnight", Times.MIDNIGHT)
|
||||||
|
|
||||||
|
addTest("sodium", tag = "sodium")
|
||||||
|
|
||||||
|
addTest("iris_noon", Times.NOON, tag = "iris")
|
||||||
|
addTest("iris_midnight", Times.MIDNIGHT, tag = "iris")
|
||||||
|
|
||||||
|
return tests
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderPrintout(helper: GameTestHelper, time: Long) = helper.sequence {
|
||||||
|
thenExecute {
|
||||||
|
helper.level.dayTime = time
|
||||||
|
helper.positionAtArmorStand()
|
||||||
|
}
|
||||||
|
|
||||||
|
thenScreenshot()
|
||||||
|
}
|
||||||
|
}
|
@@ -15,6 +15,8 @@ import dan200.computercraft.mixin.gametest.GameTestHelperAccessor
|
|||||||
import dan200.computercraft.mixin.gametest.GameTestInfoAccessor
|
import dan200.computercraft.mixin.gametest.GameTestInfoAccessor
|
||||||
import dan200.computercraft.shared.ModRegistry
|
import dan200.computercraft.shared.ModRegistry
|
||||||
import dan200.computercraft.shared.media.items.PrintoutItem
|
import dan200.computercraft.shared.media.items.PrintoutItem
|
||||||
|
import dan200.computercraft.shared.peripheral.modem.wired.CableBlock
|
||||||
|
import dan200.computercraft.shared.peripheral.modem.wired.CableModemVariant
|
||||||
import dan200.computercraft.shared.peripheral.monitor.MonitorBlock
|
import dan200.computercraft.shared.peripheral.monitor.MonitorBlock
|
||||||
import dan200.computercraft.shared.peripheral.monitor.MonitorEdgeState
|
import dan200.computercraft.shared.peripheral.monitor.MonitorEdgeState
|
||||||
import dan200.computercraft.shared.turtle.apis.TurtleAPI
|
import dan200.computercraft.shared.turtle.apis.TurtleAPI
|
||||||
@@ -89,7 +91,7 @@ class Turtle_Test {
|
|||||||
.assertArrayEquals(true, message = "Placed oak fence")
|
.assertArrayEquals(true, message = "Placed oak fence")
|
||||||
}
|
}
|
||||||
thenExecute {
|
thenExecute {
|
||||||
helper.assertBlockIs(BlockPos(2, 2, 2), { it.block == Blocks.OAK_FENCE && it.getValue(FenceBlock.WATERLOGGED) })
|
helper.assertBlockIs(BlockPos(2, 2, 2)) { it.block == Blocks.OAK_FENCE && it.getValue(FenceBlock.WATERLOGGED) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +125,33 @@ class Turtle_Test {
|
|||||||
thenExecute { helper.assertBlockPresent(Blocks.FARMLAND, BlockPos(1, 2, 1)) }
|
thenExecute { helper.assertBlockPresent(Blocks.FARMLAND, BlockPos(1, 2, 1)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks turtles break cables in two parts.
|
||||||
|
*/
|
||||||
|
@GameTest
|
||||||
|
fun Break_cable(helper: GameTestHelper) = helper.sequence {
|
||||||
|
thenOnComputer { turtle.dig(Optional.empty()).await() }
|
||||||
|
thenExecute {
|
||||||
|
helper.assertBlockIs(BlockPos(2, 2, 3)) {
|
||||||
|
it.block == ModRegistry.Blocks.CABLE.get() && !it.getValue(CableBlock.CABLE) && it.getValue(CableBlock.MODEM) == CableModemVariant.DownOff
|
||||||
|
}
|
||||||
|
|
||||||
|
helper.assertContainerExactly(BlockPos(2, 2, 2), listOf(ItemStack(ModRegistry.Items.CABLE.get())))
|
||||||
|
}
|
||||||
|
thenOnComputer { turtle.dig(Optional.empty()).await().assertArrayEquals(true) }
|
||||||
|
thenExecute {
|
||||||
|
helper.assertBlockPresent(Blocks.AIR, BlockPos(2, 2, 3))
|
||||||
|
|
||||||
|
helper.assertContainerExactly(
|
||||||
|
BlockPos(2, 2, 2),
|
||||||
|
listOf(
|
||||||
|
ItemStack(ModRegistry.Items.CABLE.get()),
|
||||||
|
ItemStack(ModRegistry.Items.WIRED_MODEM.get()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks turtles can place monitors
|
* Checks turtles can place monitors
|
||||||
*
|
*
|
||||||
@@ -289,6 +318,23 @@ class Turtle_Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test calling `turtle.refuel` on non-fuels
|
||||||
|
*/
|
||||||
|
@GameTest
|
||||||
|
fun Refuel_fail(helper: GameTestHelper) = helper.sequence {
|
||||||
|
val turtlePos = BlockPos(2, 2, 2)
|
||||||
|
|
||||||
|
thenOnComputer {
|
||||||
|
assertEquals(0, turtle.fuelLevel)
|
||||||
|
turtle.refuel(Optional.empty()).await().assertArrayEquals(false, "Items not combustible")
|
||||||
|
assertEquals(0, turtle.fuelLevel)
|
||||||
|
}
|
||||||
|
thenExecute {
|
||||||
|
helper.assertContainerExactly(turtlePos, listOf(ItemStack(Items.DIRT, 32)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test calling `turtle.refuel` with a bucket of lava
|
* Test calling `turtle.refuel` with a bucket of lava
|
||||||
*/
|
*/
|
||||||
@@ -307,6 +353,26 @@ class Turtle_Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test moving a turtle forwards preserves the turtle's inventory.
|
||||||
|
*
|
||||||
|
* @see [#1276](https://github.com/cc-tweaked/CC-Tweaked/pull/1276)
|
||||||
|
*/
|
||||||
|
@GameTest
|
||||||
|
fun Move_preserves_state(helper: GameTestHelper) = helper.sequence {
|
||||||
|
thenOnComputer { turtle.forward().await().assertArrayEquals(true, message = "Turtle moved forward") }
|
||||||
|
thenExecute {
|
||||||
|
helper.assertContainerExactly(BlockPos(2, 2, 3), listOf(ItemStack(Items.DIRT, 32)))
|
||||||
|
|
||||||
|
val turtle = helper.getBlockEntity(BlockPos(2, 2, 3), ModRegistry.BlockEntities.TURTLE_NORMAL.get())
|
||||||
|
assertEquals(1, turtle.computerID)
|
||||||
|
assertEquals("turtle_test.move_preserves_state", turtle.label)
|
||||||
|
assertEquals(79, turtle.access.fuelLevel)
|
||||||
|
|
||||||
|
helper.assertEntityNotPresent(EntityType.ITEM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test turtles are not obstructed by plants and instead replace them.
|
* Test turtles are not obstructed by plants and instead replace them.
|
||||||
*/
|
*/
|
||||||
@@ -329,7 +395,7 @@ class Turtle_Test {
|
|||||||
thenOnComputer { turtle.forward().await().assertArrayEquals(true, message = "Turtle moved forward") }
|
thenOnComputer { turtle.forward().await().assertArrayEquals(true, message = "Turtle moved forward") }
|
||||||
thenExecute {
|
thenExecute {
|
||||||
// Assert we're no longer waterlogged and we've left a source block.
|
// Assert we're no longer waterlogged and we've left a source block.
|
||||||
helper.assertBlockIs(BlockPos(2, 2, 2), { it.block == Blocks.WATER && it.fluidState.isSource })
|
helper.assertBlockIs(BlockPos(2, 2, 2)) { it.block == Blocks.WATER && it.fluidState.isSource }
|
||||||
helper.assertBlockHas(BlockPos(2, 2, 3), WaterloggableHelpers.WATERLOGGED, false)
|
helper.assertBlockHas(BlockPos(2, 2, 3), WaterloggableHelpers.WATERLOGGED, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -143,7 +143,12 @@ private fun GameTestHelper.fail(message: String?, detail: String, pos: BlockPos)
|
|||||||
/**
|
/**
|
||||||
* A version of [GameTestHelper.assertBlockState] which also includes the current block state.
|
* A version of [GameTestHelper.assertBlockState] which also includes the current block state.
|
||||||
*/
|
*/
|
||||||
fun GameTestHelper.assertBlockIs(pos: BlockPos, predicate: (BlockState) -> Boolean, message: String = "") {
|
fun GameTestHelper.assertBlockIs(pos: BlockPos, predicate: (BlockState) -> Boolean) = assertBlockIs(pos, predicate, "")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A version of [GameTestHelper.assertBlockState] which also includes the current block state.
|
||||||
|
*/
|
||||||
|
fun GameTestHelper.assertBlockIs(pos: BlockPos, predicate: (BlockState) -> Boolean, message: String) {
|
||||||
val state = getBlockState(pos)
|
val state = getBlockState(pos)
|
||||||
if (!predicate(state)) fail(message, state.toString(), pos)
|
if (!predicate(state)) fail(message, state.toString(), pos)
|
||||||
}
|
}
|
||||||
|
@@ -80,6 +80,7 @@ object TestHooks {
|
|||||||
Monitor_Test::class.java,
|
Monitor_Test::class.java,
|
||||||
Pocket_Computer_Test::class.java,
|
Pocket_Computer_Test::class.java,
|
||||||
Printer_Test::class.java,
|
Printer_Test::class.java,
|
||||||
|
Printout_Test::class.java,
|
||||||
Recipe_Test::class.java,
|
Recipe_Test::class.java,
|
||||||
Turtle_Test::class.java,
|
Turtle_Test::class.java,
|
||||||
)
|
)
|
||||||
|
138
projects/common/src/testMod/resources/data/cctest/structures/disk_drive_test.creates_disk_id.snbt
generated
Normal file
138
projects/common/src/testMod/resources/data/cctest/structures/disk_drive_test.creates_disk_id.snbt
generated
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
{
|
||||||
|
DataVersion: 3218,
|
||||||
|
size: [5, 5, 5],
|
||||||
|
data: [
|
||||||
|
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 2], state: "computercraft:computer_advanced{facing:north,state:on}", nbt: {ComputerId: 1, Label: "disk_drive_test.creates_disk_id", On: 1b, id: "computercraft:computer_advanced"}},
|
||||||
|
{pos: [1, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 2], state: "computercraft:disk_drive{facing:north,state:full}", nbt: {Item: {Count: 1b, id: "computercraft:disk", tag: {Color: 1118481}}, id: "computercraft:disk_drive"}},
|
||||||
|
{pos: [2, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 4], state: "minecraft:air"}
|
||||||
|
],
|
||||||
|
entities: [],
|
||||||
|
palette: [
|
||||||
|
"minecraft:polished_andesite",
|
||||||
|
"minecraft:air",
|
||||||
|
"computercraft:computer_advanced{facing:north,state:on}",
|
||||||
|
"computercraft:disk_drive{facing:north,state:full}"
|
||||||
|
]
|
||||||
|
}
|
139
projects/common/src/testMod/resources/data/cctest/structures/inventory_test.double_chest_size.snbt
generated
Normal file
139
projects/common/src/testMod/resources/data/cctest/structures/inventory_test.double_chest_size.snbt
generated
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
{
|
||||||
|
DataVersion: 3218,
|
||||||
|
size: [5, 5, 5],
|
||||||
|
data: [
|
||||||
|
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 2], state: "minecraft:chest{facing:north,type:left,waterlogged:false}", nbt: {Items: [], id: "minecraft:chest"}},
|
||||||
|
{pos: [0, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 2], state: "minecraft:chest{facing:north,type:right,waterlogged:false}", nbt: {Items: [{Count: 64b, Slot: 0b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 1b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 2b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 3b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 4b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 5b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 6b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 7b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 8b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 9b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 10b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 11b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 12b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 13b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 14b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 15b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 16b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 17b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 18b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 19b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 20b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 21b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 22b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 23b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 24b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 25b, id: "minecraft:polished_andesite"}, {Count: 64b, Slot: 26b, id: "minecraft:polished_andesite"}], id: "minecraft:chest"}},
|
||||||
|
{pos: [1, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 2], state: "computercraft:computer_advanced{facing:north,state:on}", nbt: {ComputerId: 1, Label: "inventory_test.double_chest_size", On: 1b, id: "computercraft:computer_advanced"}},
|
||||||
|
{pos: [2, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 2], state: "minecraft:chest{facing:north,type:left,waterlogged:false}", nbt: {Items: [], id: "minecraft:chest"}},
|
||||||
|
{pos: [3, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 2], state: "minecraft:chest{facing:north,type:right,waterlogged:false}", nbt: {Items: [{Count: 32b, Slot: 0b, id: "minecraft:dirt"}], id: "minecraft:chest"}},
|
||||||
|
{pos: [4, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 4], state: "minecraft:air"}
|
||||||
|
],
|
||||||
|
entities: [],
|
||||||
|
palette: [
|
||||||
|
"minecraft:polished_andesite",
|
||||||
|
"minecraft:air",
|
||||||
|
"minecraft:chest{facing:north,type:left,waterlogged:false}",
|
||||||
|
"minecraft:chest{facing:north,type:right,waterlogged:false}",
|
||||||
|
"computercraft:computer_advanced{facing:north,state:on}"
|
||||||
|
]
|
||||||
|
}
|
137
projects/common/src/testMod/resources/data/cctest/structures/modem_test.full_modems_form_networks.snbt
generated
Normal file
137
projects/common/src/testMod/resources/data/cctest/structures/modem_test.full_modems_form_networks.snbt
generated
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
{
|
||||||
|
DataVersion: 3218,
|
||||||
|
size: [5, 5, 5],
|
||||||
|
data: [
|
||||||
|
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 1], state: "computercraft:wired_modem_full{modem:false,peripheral:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:wired_modem_full"}},
|
||||||
|
{pos: [1, 1, 2], state: "computercraft:wired_modem_full{modem:false,peripheral:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:wired_modem_full"}},
|
||||||
|
{pos: [1, 1, 3], state: "computercraft:wired_modem_full{modem:false,peripheral:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:wired_modem_full"}},
|
||||||
|
{pos: [1, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 3], state: "computercraft:wired_modem_full{modem:false,peripheral:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:wired_modem_full"}},
|
||||||
|
{pos: [2, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 1], state: "computercraft:wired_modem_full{modem:false,peripheral:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:wired_modem_full"}},
|
||||||
|
{pos: [3, 1, 2], state: "computercraft:wired_modem_full{modem:false,peripheral:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:wired_modem_full"}},
|
||||||
|
{pos: [3, 1, 3], state: "computercraft:wired_modem_full{modem:false,peripheral:false}", nbt: {PeripheralAccess: 0b, id: "computercraft:wired_modem_full"}},
|
||||||
|
{pos: [3, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 4], state: "minecraft:air"}
|
||||||
|
],
|
||||||
|
entities: [],
|
||||||
|
palette: [
|
||||||
|
"minecraft:polished_andesite",
|
||||||
|
"minecraft:air",
|
||||||
|
"computercraft:wired_modem_full{modem:false,peripheral:false}"
|
||||||
|
]
|
||||||
|
}
|
139
projects/common/src/testMod/resources/data/cctest/structures/printout_test.render_in_frame.snbt
generated
Normal file
139
projects/common/src/testMod/resources/data/cctest/structures/printout_test.render_in_frame.snbt
generated
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
{
|
||||||
|
DataVersion: 3218,
|
||||||
|
size: [5, 5, 5],
|
||||||
|
data: [
|
||||||
|
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 4], state: "minecraft:air"}
|
||||||
|
],
|
||||||
|
entities: [
|
||||||
|
{blockPos: [2, 1, 2], pos: [2.583196949396921d, 1.0d, 2.608974919959593d], nbt: {AbsorptionAmount: 0.0f, Air: 300s, ArmorItems: [{}, {}, {}, {}], Attributes: [{Base: 0.699999988079071d, Name: "minecraft:generic.movement_speed"}], Brain: {memories: {}}, CustomName: '{"text":"printouttest.in_frame_at_night"}', DeathTime: 0s, DisabledSlots: 0, FallDistance: 0.0f, FallFlying: 0b, Fire: -1s, HandItems: [{}, {}], Health: 20.0f, HurtByTimestamp: 0, HurtTime: 0s, Invisible: 1b, Invulnerable: 0b, Marker: 1b, Motion: [0.0d, 0.0d, 0.0d], NoBasePlate: 0b, OnGround: 0b, PortalCooldown: 0, Pos: [221.58319694939692d, -58.0d, 92.60897491995959d], Pose: {}, Rotation: [1.3504658f, 6.7031174f], ShowArms: 0b, Small: 0b, UUID: [I; 1854159985, -991539606, -1317309541, 1483112386], id: "minecraft:armor_stand"}},
|
||||||
|
{blockPos: [2, 2, 3], pos: [2.5d, 2.5d, 3.96875d], nbt: {Air: 300s, Facing: 2b, FallDistance: 0.0f, Fire: -1s, Fixed: 0b, Invisible: 0b, Invulnerable: 0b, Item: {Count: 1b, id: "computercraft:printed_page", tag: {Color0: "eeeeeeeeeeeeeeeeeeeeeeeee", Color1: "eeeeeeeeeeeeeeeeeeeeeeeee", Color10: "eeeeeeeeeeeeeeeeeeeeeeeee", Color11: "eeeeeeeeeeeeeeeeeeeeeeeee", Color12: "eeeeeeeeeeeeeeeeeeeeeeeee", Color13: "eeeeeeeeeeeeeeeeeeeeeeeee", Color14: "eeeeeeeeeeeeeeeeeeeeeeeee", Color15: "eeeeeeeeeeeeeeeeeeeeeeeee", Color16: "eeeeeeeeeeeeeeeeeeeeeeeee", Color17: "eeeeeeeeeeeeeeeeeeeeeeeee", Color18: "eeeeeeeeeeeeeeeeeeeeeeeee", Color19: "eeeeeeeeeeeeeeeeeeeeeeeee", Color2: "eeeeeeeeeeeeeeeeeeeeeeeee", Color20: "eeeeeeeeeeeeeeeeeeeeeeeee", Color3: "eeeeeeeeeeeeeeeeeeeeeeeee", Color4: "eeeeeeeeeeeeeeeeeeeeeeeee", Color5: "eeeeeeeeeeeeeeeeeeeeeeeee", Color6: "eeeeeeeeeeeeeeeeeeeeeeeee", Color7: "eeeeeeeeeeeeeeeeeeeeeeeee", Color8: "eeeeeeeeeeeeeeeeeeeeeeeee", Color9: "eeeeeeeeeeeeeeeeeeeeeeeee", Pages: 1, Text0: "If you're reading this, ", Text1: "the test failed. ", Text10: " ", Text11: " ", Text12: " ", Text13: " ", Text14: " ", Text15: " ", Text16: " ", Text17: " ", Text18: " ", Text19: " ", Text2: " ", Text20: " ", Text3: " ", Text4: " ", Text5: " ", Text6: " ", Text7: " ", Text8: " ", Text9: " ", Title: "a.lua"}}, ItemDropChance: 1.0f, ItemRotation: 0b, Motion: [0.0d, 0.0d, 0.0d], OnGround: 0b, PortalCooldown: 0, Pos: [221.5d, -56.5d, 93.96875d], Rotation: [-540.0f, 0.0f], TileX: 221, TileY: -57, TileZ: 93, UUID: [I; 1972443954, 193152445, -1823446000, -1684171214], id: "minecraft:item_frame"}}
|
||||||
|
],
|
||||||
|
palette: [
|
||||||
|
"minecraft:polished_andesite",
|
||||||
|
"minecraft:air"
|
||||||
|
]
|
||||||
|
}
|
@@ -1,140 +0,0 @@
|
|||||||
{
|
|
||||||
DataVersion: 2730,
|
|
||||||
size: [5, 5, 5],
|
|
||||||
data: [
|
|
||||||
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
|
||||||
{pos: [0, 1, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 1, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 1, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 1, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 1, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 1, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 1, 1], state: "minecraft:air"},
|
|
||||||
{pos: [1, 1, 2], state: "minecraft:air"},
|
|
||||||
{pos: [1, 1, 3], state: "minecraft:air"},
|
|
||||||
{pos: [1, 1, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 1, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 1, 1], state: "minecraft:air"},
|
|
||||||
{pos: [2, 1, 2], state: "minecraft:air"},
|
|
||||||
{pos: [2, 1, 3], state: "minecraft:air"},
|
|
||||||
{pos: [2, 1, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 1, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 1, 1], state: "minecraft:air"},
|
|
||||||
{pos: [3, 1, 2], state: "minecraft:air"},
|
|
||||||
{pos: [3, 1, 3], state: "minecraft:air"},
|
|
||||||
{pos: [3, 1, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 1, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 1, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 1, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 1, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 1, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 2, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 2, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 2, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 2, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 2, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 2, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 2, 1], state: "minecraft:air"},
|
|
||||||
{pos: [1, 2, 2], state: "minecraft:air"},
|
|
||||||
{pos: [1, 2, 3], state: "minecraft:air"},
|
|
||||||
{pos: [1, 2, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 2, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 2, 1], state: "minecraft:air"},
|
|
||||||
{pos: [2, 2, 2], state: "minecraft:air"},
|
|
||||||
{pos: [2, 2, 3], state: "minecraft:air"},
|
|
||||||
{pos: [2, 2, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 2, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 2, 1], state: "minecraft:air"},
|
|
||||||
{pos: [3, 2, 2], state: "minecraft:air"},
|
|
||||||
{pos: [3, 2, 3], state: "minecraft:air"},
|
|
||||||
{pos: [3, 2, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 2, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 2, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 2, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 2, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 2, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 3, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 3, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 3, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 3, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 3, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 3, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 3, 1], state: "minecraft:air"},
|
|
||||||
{pos: [1, 3, 2], state: "minecraft:air"},
|
|
||||||
{pos: [1, 3, 3], state: "minecraft:air"},
|
|
||||||
{pos: [1, 3, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 3, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 3, 1], state: "minecraft:air"},
|
|
||||||
{pos: [2, 3, 2], state: "minecraft:air"},
|
|
||||||
{pos: [2, 3, 3], state: "minecraft:air"},
|
|
||||||
{pos: [2, 3, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 3, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 3, 1], state: "minecraft:air"},
|
|
||||||
{pos: [3, 3, 2], state: "minecraft:air"},
|
|
||||||
{pos: [3, 3, 3], state: "minecraft:air"},
|
|
||||||
{pos: [3, 3, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 3, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 3, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 3, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 3, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 3, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 4, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 4, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 4, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 4, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [0, 4, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 4, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 4, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 4, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 4, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [1, 4, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 4, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 4, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 4, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 4, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [2, 4, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 4, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 4, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 4, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 4, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [3, 4, 4], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 4, 0], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 4, 1], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 4, 2], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 4, 3], state: "minecraft:white_concrete"},
|
|
||||||
{pos: [4, 4, 4], state: "minecraft:white_concrete"}
|
|
||||||
],
|
|
||||||
entities: [
|
|
||||||
{blockPos: [2, 2, 3], pos: [2.5d, 2.5d, 3.96875d], nbt: {Air: 300s, CanUpdate: 1b, Facing: 2b, FallDistance: 0.0f, Fire: -1s, Fixed: 0b, Invisible: 0b, Invulnerable: 0b, Item: {Count: 1b, id: "computercraft:printed_page", tag: {Color0: "eeeeeeeeeeeeeeeeeeeeeeeee", Color1: "eeeeeeeeeeeeeeeeeeeeeeeee", Color10: "eeeeeeeeeeeeeeeeeeeeeeeee", Color11: "eeeeeeeeeeeeeeeeeeeeeeeee", Color12: "eeeeeeeeeeeeeeeeeeeeeeeee", Color13: "eeeeeeeeeeeeeeeeeeeeeeeee", Color14: "eeeeeeeeeeeeeeeeeeeeeeeee", Color15: "eeeeeeeeeeeeeeeeeeeeeeeee", Color16: "eeeeeeeeeeeeeeeeeeeeeeeee", Color17: "eeeeeeeeeeeeeeeeeeeeeeeee", Color18: "eeeeeeeeeeeeeeeeeeeeeeeee", Color19: "eeeeeeeeeeeeeeeeeeeeeeeee", Color2: "eeeeeeeeeeeeeeeeeeeeeeeee", Color20: "eeeeeeeeeeeeeeeeeeeeeeeee", Color3: "eeeeeeeeeeeeeeeeeeeeeeeee", Color4: "eeeeeeeeeeeeeeeeeeeeeeeee", Color5: "eeeeeeeeeeeeeeeeeeeeeeeee", Color6: "eeeeeeeeeeeeeeeeeeeeeeeee", Color7: "eeeeeeeeeeeeeeeeeeeeeeeee", Color8: "eeeeeeeeeeeeeeeeeeeeeeeee", Color9: "eeeeeeeeeeeeeeeeeeeeeeeee", Pages: 1, Text0: "If you're reading this, ", Text1: "the test failed. ", Text10: " ", Text11: " ", Text12: " ", Text13: " ", Text14: " ", Text15: " ", Text16: " ", Text17: " ", Text18: " ", Text19: " ", Text2: " ", Text20: " ", Text3: " ", Text4: " ", Text5: " ", Text6: " ", Text7: " ", Text8: " ", Text9: " ", Title: "a.lua"}}, ItemDropChance: 1.0f, ItemRotation: 0b, Motion: [0.0d, 0.0d, 0.0d], OnGround: 0b, PortalCooldown: 0, Pos: [10.5d, 7.5d, 44.96875d], Rotation: [180.0f, 0.0f], TileX: 10, TileY: 7, TileZ: 44, UUID: [I; 1043973837, -2076424529, -1762893135, -165665834], id: "minecraft:item_frame"}},
|
|
||||||
{blockPos: [2, 1, 2], pos: [2.583196949396914d, 1.0d, 2.6089749199596d], nbt: {AbsorptionAmount: 0.0f, Air: 300s, ArmorItems: [{}, {}, {}, {}], Attributes: [{Base: 0.699999988079071d, Name: "minecraft:generic.movement_speed"}], Brain: {memories: {}}, CanUpdate: 1b, CustomName: '{"text":"printouttest.in_frame_at_night"}', DeathTime: 0s, DisabledSlots: 0, FallDistance: 0.0f, FallFlying: 0b, Fire: -1s, HandItems: [{}, {}], Health: 20.0f, HurtByTimestamp: 0, HurtTime: 0s, Invisible: 1b, Invulnerable: 0b, Marker: 1b, Motion: [0.0d, 0.0d, 0.0d], NoBasePlate: 0b, OnGround: 0b, PortalCooldown: 0, Pos: [10.583196949396914d, 6.0d, 43.6089749199596d], Pose: {}, Rotation: [1.3504658f, 6.7031174f], ShowArms: 0b, Small: 0b, UUID: [I; -1917933016, 1390888530, -2109873447, -2136052677], id: "minecraft:armor_stand"}}
|
|
||||||
],
|
|
||||||
palette: [
|
|
||||||
"minecraft:polished_andesite",
|
|
||||||
"minecraft:white_concrete",
|
|
||||||
"minecraft:air"
|
|
||||||
]
|
|
||||||
}
|
|
138
projects/common/src/testMod/resources/data/cctest/structures/turtle_test.break_cable.snbt
generated
Normal file
138
projects/common/src/testMod/resources/data/cctest/structures/turtle_test.break_cable.snbt
generated
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
{
|
||||||
|
DataVersion: 3218,
|
||||||
|
size: [5, 5, 5],
|
||||||
|
data: [
|
||||||
|
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 2], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 80, Items: [], Label: "turtle_test.break_cable", LeftUpgrade: "minecraft:diamond_pickaxe", On: 1b, Owner: {LowerId: -6876936588741668278L, Name: "Dev", UpperId: 4039158846114182220L}, Slot: 0, id: "computercraft:turtle_normal"}},
|
||||||
|
{pos: [2, 1, 3], state: "computercraft:cable{cable:true,down:true,east:false,modem:down_off,north:false,south:false,up:false,waterlogged:false,west:false}", nbt: {PeirpheralAccess: 0b, id: "computercraft:cable"}},
|
||||||
|
{pos: [2, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 4], state: "minecraft:air"}
|
||||||
|
],
|
||||||
|
entities: [],
|
||||||
|
palette: [
|
||||||
|
"minecraft:polished_andesite",
|
||||||
|
"minecraft:air",
|
||||||
|
"computercraft:turtle_normal{facing:south,waterlogged:false}",
|
||||||
|
"computercraft:cable{cable:true,down:true,east:false,modem:down_off,north:false,south:false,up:false,waterlogged:false,west:false}"
|
||||||
|
]
|
||||||
|
}
|
137
projects/common/src/testMod/resources/data/cctest/structures/turtle_test.move_preserves_state.snbt
generated
Normal file
137
projects/common/src/testMod/resources/data/cctest/structures/turtle_test.move_preserves_state.snbt
generated
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
{
|
||||||
|
DataVersion: 2975,
|
||||||
|
size: [5, 5, 5],
|
||||||
|
data: [
|
||||||
|
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 2], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Label: "turtle_test.move_preserves_state", Fuel: 80, Items: [{Count: 32b, Slot: 0b, id: "minecraft:dirt"}], On: 1b, Owner: {LowerId: -6876936588741668278L, Name: "Dev", UpperId: 4039158846114182220L}, Slot: 0, id: "computercraft:turtle_normal"}},
|
||||||
|
{pos: [2, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 4], state: "minecraft:air"}
|
||||||
|
],
|
||||||
|
entities: [],
|
||||||
|
palette: [
|
||||||
|
"minecraft:polished_andesite",
|
||||||
|
"minecraft:air",
|
||||||
|
"computercraft:turtle_normal{facing:south,waterlogged:false}"
|
||||||
|
]
|
||||||
|
}
|
137
projects/common/src/testMod/resources/data/cctest/structures/turtle_test.refuel_fail.snbt
generated
Normal file
137
projects/common/src/testMod/resources/data/cctest/structures/turtle_test.refuel_fail.snbt
generated
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
{
|
||||||
|
DataVersion: 2975,
|
||||||
|
size: [5, 5, 5],
|
||||||
|
data: [
|
||||||
|
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
|
||||||
|
{pos: [0, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 2], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Label: "turtle_test.refuel_fail", Fuel: 0, Items: [{Count: 32b, Slot: 0b, id: "minecraft:dirt"}], On: 1b, Owner: {LowerId: -6876936588741668278L, Name: "Dev", UpperId: 4039158846114182220L}, Slot: 0, id: "computercraft:turtle_normal"}},
|
||||||
|
{pos: [2, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 1, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 2, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 3, 4], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [0, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [1, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [2, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [3, 4, 4], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 0], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 1], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 2], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 3], state: "minecraft:air"},
|
||||||
|
{pos: [4, 4, 4], state: "minecraft:air"}
|
||||||
|
],
|
||||||
|
entities: [],
|
||||||
|
palette: [
|
||||||
|
"minecraft:polished_andesite",
|
||||||
|
"minecraft:air",
|
||||||
|
"computercraft:turtle_normal{facing:south,waterlogged:false}"
|
||||||
|
]
|
||||||
|
}
|
@@ -20,6 +20,7 @@ dependencies {
|
|||||||
implementation(libs.asm)
|
implementation(libs.asm)
|
||||||
|
|
||||||
testFixturesImplementation(libs.slf4j)
|
testFixturesImplementation(libs.slf4j)
|
||||||
|
testFixturesApi(platform(libs.kotlin.platform))
|
||||||
testFixturesApi(libs.bundles.test)
|
testFixturesApi(libs.bundles.test)
|
||||||
testFixturesApi(libs.bundles.kotlin)
|
testFixturesApi(libs.bundles.kotlin)
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ dependencies {
|
|||||||
tasks.processResources {
|
tasks.processResources {
|
||||||
inputs.property("gitHash", cct.gitHash)
|
inputs.property("gitHash", cct.gitHash)
|
||||||
|
|
||||||
filesMatching("data/computercraft/lua/rom/help/credits.txt") {
|
filesMatching("data/computercraft/lua/rom/help/credits.md") {
|
||||||
expand(mapOf("gitContributors" to cct.gitContributors.map { it.joinToString("\n") }.get()))
|
expand(mapOf("gitContributors" to cct.gitContributors.map { it.joinToString("\n") }.get()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,10 +15,12 @@ public final class Logging {
|
|||||||
public static final Marker COMPUTER_ERROR = MarkerFactory.getMarker("COMPUTER_ERROR");
|
public static final Marker COMPUTER_ERROR = MarkerFactory.getMarker("COMPUTER_ERROR");
|
||||||
public static final Marker HTTP_ERROR = MarkerFactory.getMarker("COMPUTER_ERROR.HTTP");
|
public static final Marker HTTP_ERROR = MarkerFactory.getMarker("COMPUTER_ERROR.HTTP");
|
||||||
public static final Marker JAVA_ERROR = MarkerFactory.getMarker("COMPUTER_ERROR.JAVA");
|
public static final Marker JAVA_ERROR = MarkerFactory.getMarker("COMPUTER_ERROR.JAVA");
|
||||||
|
public static final Marker VM_ERROR = MarkerFactory.getMarker("COMPUTER_ERROR.VM");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
HTTP_ERROR.add(COMPUTER_ERROR);
|
HTTP_ERROR.add(COMPUTER_ERROR);
|
||||||
JAVA_ERROR.add(JAVA_ERROR);
|
JAVA_ERROR.add(COMPUTER_ERROR);
|
||||||
|
VM_ERROR.add(COMPUTER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Logging() {
|
private Logging() {
|
||||||
|
@@ -117,7 +117,7 @@ public class RedstoneAPI implements ILuaAPI {
|
|||||||
*
|
*
|
||||||
* @param side The side to set.
|
* @param side The side to set.
|
||||||
* @param value The signal strength between 0 and 15.
|
* @param value The signal strength between 0 and 15.
|
||||||
* @throws LuaException If {@code value} is not betwene 0 and 15.
|
* @throws LuaException If {@code value} is not between 0 and 15.
|
||||||
* @cc.since 1.51
|
* @cc.since 1.51
|
||||||
*/
|
*/
|
||||||
@LuaFunction({ "setAnalogOutput", "setAnalogueOutput" })
|
@LuaFunction({ "setAnalogOutput", "setAnalogueOutput" })
|
||||||
|
@@ -42,8 +42,8 @@ public class BinaryWritableHandle extends HandleGeneric {
|
|||||||
*
|
*
|
||||||
* @param arguments The value to write.
|
* @param arguments The value to write.
|
||||||
* @throws LuaException If the file has been closed.
|
* @throws LuaException If the file has been closed.
|
||||||
* @cc.tparam [1] number The byte to write.
|
* @cc.tparam [1] number charcode The byte to write.
|
||||||
* @cc.tparam [2] string The string to write.
|
* @cc.tparam [2] string contents The string to write.
|
||||||
* @cc.changed 1.80pr1 Now accepts a string to write multiple bytes.
|
* @cc.changed 1.80pr1 Now accepts a string to write multiple bytes.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
|
@@ -51,7 +51,7 @@ public class EncodedWritableHandle extends HandleGeneric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a string of characters to the file, follwing them with a new line character.
|
* Write a string of characters to the file, following them with a new line character.
|
||||||
*
|
*
|
||||||
* @param args The value to write.
|
* @param args The value to write.
|
||||||
* @throws LuaException If the file has been closed.
|
* @throws LuaException If the file has been closed.
|
||||||
|
@@ -17,8 +17,8 @@ import java.net.URI;
|
|||||||
* A version of {@link WebSocketClientHandshaker13} which doesn't add the {@link HttpHeaderNames#ORIGIN} header to the
|
* A version of {@link WebSocketClientHandshaker13} which doesn't add the {@link HttpHeaderNames#ORIGIN} header to the
|
||||||
* original HTTP request.
|
* original HTTP request.
|
||||||
*/
|
*/
|
||||||
public class NoOriginWebSocketHanshakder extends WebSocketClientHandshaker13 {
|
public class NoOriginWebSocketHandshaker extends WebSocketClientHandshaker13 {
|
||||||
public NoOriginWebSocketHanshakder(URI webSocketURL, WebSocketVersion version, String subprotocol, boolean allowExtensions, HttpHeaders customHeaders, int maxFramePayloadLength) {
|
public NoOriginWebSocketHandshaker(URI webSocketURL, WebSocketVersion version, String subprotocol, boolean allowExtensions, HttpHeaders customHeaders, int maxFramePayloadLength) {
|
||||||
super(webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength);
|
super(webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength);
|
||||||
}
|
}
|
||||||
|
|
@@ -133,7 +133,7 @@ public class Websocket extends Resource<Websocket> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var subprotocol = headers.get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL);
|
var subprotocol = headers.get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL);
|
||||||
WebSocketClientHandshaker handshaker = new NoOriginWebSocketHanshakder(
|
WebSocketClientHandshaker handshaker = new NoOriginWebSocketHandshaker(
|
||||||
uri, WebSocketVersion.V13, subprotocol, true, headers,
|
uri, WebSocketVersion.V13, subprotocol, true, headers,
|
||||||
options.websocketMessage <= 0 ? MAX_MESSAGE_SIZE : options.websocketMessage
|
options.websocketMessage <= 0 ? MAX_MESSAGE_SIZE : options.websocketMessage
|
||||||
);
|
);
|
||||||
|
@@ -83,6 +83,11 @@ public class CobaltLuaMachine implements ILuaMachine {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
.errorReporter((e, msg) -> {
|
||||||
|
if (LOG.isErrorEnabled(Logging.VM_ERROR)) {
|
||||||
|
LOG.error(Logging.VM_ERROR, "Error occurred in the Lua runtime. Computer will continue to execute:\n{}", msg.get(), e);
|
||||||
|
}
|
||||||
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
globals = new LuaTable();
|
globals = new LuaTable();
|
||||||
|
@@ -7,7 +7,7 @@ local expect
|
|||||||
|
|
||||||
do
|
do
|
||||||
local h = fs.open("rom/modules/main/cc/expect.lua", "r")
|
local h = fs.open("rom/modules/main/cc/expect.lua", "r")
|
||||||
local f, err = loadstring(h.readAll(), "@expect.lua")
|
local f, err = loadstring(h.readAll(), "@/rom/modules/main/cc/expect.lua")
|
||||||
h.close()
|
h.close()
|
||||||
|
|
||||||
if not f then error(err) end
|
if not f then error(err) end
|
||||||
@@ -467,7 +467,7 @@ function loadfile(filename, mode, env)
|
|||||||
local file = fs.open(filename, "r")
|
local file = fs.open(filename, "r")
|
||||||
if not file then return nil, "File not found" end
|
if not file then return nil, "File not found" end
|
||||||
|
|
||||||
local func, err = load(file.readAll(), "@" .. fs.getName(filename), mode, env)
|
local func, err = load(file.readAll(), "@/" .. fs.combine(filename), mode, env)
|
||||||
file.close()
|
file.close()
|
||||||
return func, err
|
return func, err
|
||||||
end
|
end
|
||||||
@@ -700,7 +700,7 @@ settings.define("motd.path", {
|
|||||||
|
|
||||||
settings.define("lua.warn_against_use_of_local", {
|
settings.define("lua.warn_against_use_of_local", {
|
||||||
default = true,
|
default = true,
|
||||||
description = [[Print a message when input in the Lua REPL starts with the word 'local'. Local variables defined in the Lua REPL are be inaccessable on the next input.]],
|
description = [[Print a message when input in the Lua REPL starts with the word 'local'. Local variables defined in the Lua REPL are be inaccessible on the next input.]],
|
||||||
type = "boolean",
|
type = "boolean",
|
||||||
})
|
})
|
||||||
settings.define("lua.function_args", {
|
settings.define("lua.function_args", {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user