1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-11-10 20:09:58 +00:00
Commit Graph

260 Commits

Author SHA1 Message Date
Jonathan Coates
5c457950d8
Merge branch 'mc-1.20.x' into mc-1.20.y 2024-04-24 20:30:59 +01:00
Jonathan Coates
03bb279206
Move computer right click code to the block
Rather than handling right clicks within the block entity code, we now
handle it within the block. Turtles now handle the nametagging
behaviour themselves, rather than overriding canNameWithTag.
2024-04-17 15:01:50 +01:00
Weblate
fabd77132d Translations for Czech
Co-authored-by: Patriik <apatriik0@gmail.com>
2024-04-09 08:54:05 +00:00
Jonathan Coates
75f3ecce18
Render printout pages further forward in the UI
Rather than rendering the background further back. This was causing some
of the pages to not be rendered. I'm not quite sure why this is -- there
shouldn't be any z-fighting -- but this does work as a fix!

Fixes #1777
2024-04-08 12:07:53 +01:00
Jonathan Coates
688fdc40a6
Don't render background in the off-hand pocket UI
Fixes #1778
2024-04-08 12:02:25 +01:00
Jonathan Coates
22bd5309ba
Merge branch 'mc-1.20.x' into mc-1.20.y 2024-04-07 22:06:49 +01:00
Jonathan Coates
825d45eb26
Fix NPE when rendering turtle's label
Minecraft.hitResult may /technically/ be null when rendering a turtle.
In vanilla, this doesn't appear to happen, but other mods (e.g.
Immersive Portals) may still take advantage of this.

This hitResult is then propagated to BlockEntityRenderDispatcher, where
the field was /not/ marked as nullable. This meant we didn't even notice
the potential of an NPE!

Closes #1775
2024-04-06 08:46:19 +01:00
Jonathan Coates
8b2516abb5
Update to latest NullAway
This fixes several issues with @Nullable fields not being checked. This
is great in principle, but a little annoying in practice as MC's
@Nullable annotations are sometimes a little overly strict -- we now
need to wrap a couple of things in assertNonNull checks.
2024-04-06 08:38:44 +01:00
Jonathan Coates
6d14ce625f
Use the correct modem in create:brittle
I tested this in-game, I swear! Just, typically, only with ender and
wired modems.
2024-04-03 09:29:31 +01:00
Jonathan Coates
c8eadf4011
Register CC's modems as brittle
This tells Create that modems will pop-off if their neighbour is moved,
and so changes the order that the block is moved in.

We possibly should use BlockMovementChecks.AttachedCheck instead, to
properly handle the direction modems are facing in. However, this
doesn't appear to be part of the public API, so probably best avoided.

Fixes #948
2024-04-03 08:44:30 +01:00
Jonathan Coates
0f623c2cca
Move can-place modem logic to one place
This should make future changes easier. Closes #1769.
2024-04-01 13:55:44 +01:00
Jonathan Coates
c764981a40
Merge pull request #1761 from cc-tweaked/feature/no-play-record
Prevent playing music discs with speaker.playSound
2024-03-29 07:55:31 +00:00
Jonathan Coates
6363164f2b
Fix creating a zero-sized pocket terminal
When the terminal data is not present, width/height are set to 0, rather
than the terminal's width/height. This meant we'd create an empty
terminal, which then crashes when we try to render it.

We now make the terminal nullable and initialise it the first time we
receive the terminal data. To prevent future mistakes, we hide
width/height, and use TerminalState.create everywhere.

Fixes #1765
2024-03-26 21:59:41 +00:00
Jonathan Coates
0e5248e5e6
Prevent playing music discs with speaker.playSound
I have mixed feelings about speaker.playSound. On one hand, it's pretty
useful to be able to play any sound. On the other, it sometimes feels
... maybe a little too magic?

One particular thing I don't like is that it allows you to play
arbitrary records, which sidesteps both a vanilla mechanic (finding
record discs) and existing CC functionality (disk.playAudio). We now
prevent playing record tracks from the speaker.
2024-03-24 12:53:57 +00:00
Jonathan Coates
e154b0db2a
Fix speaker.playSound overwriting current sound
playSound should return false if we've already played a sound this tick,
rather than overwriting it.
2024-03-24 12:20:53 +00:00
Jonathan Coates
c50d56d9fa
Remove canClickRunClientCommand
This was added in 4675583e1c to handle
Forge on longer supporting RUN_COMMAND for client-side commands.
However, the mixins are still present on NF/1.20.4, so we don't need
this!
2024-03-23 15:38:18 +00:00
Jonathan Coates
286f969f94
Remove computers from both lookups when they timeout
In 5d8c46c7e6, we switched to using UUIDs
for looking up computers (rather than an integer ID). However, for
compatibility in some of the command code, we need to maintain the old
integer lookup map.

Most of the code was updated to handle this, *except* the code to remove
a computer from the registry. This meant that we'd fail to remove a
computer from the UUID lookup map, so computers ended up in a phantom
state where they were destroyed, but still accessible.

This is not an issue on 1.20.4, because the legacy int lookup map was
removed.

Fixes #1760
2024-03-23 10:59:47 +00:00
Jonathan Coates
7b9a156abc
Register our block entities with DFU
This ensures that data fixers will be applied to items in these
inventories.
2024-03-22 21:47:11 +00:00
Jonathan Coates
0a9e5c78f3
Remove some deprecated code
Some of this is technically an API break, but 1.20.4 is pretty unstable.

 - Remove WiredNetwork from the public API
 - Remove legacy computer selectors
2024-03-22 21:36:52 +00:00
Jonathan Coates
da5885ef35
Merge branch 'mc-1.20.x' into mc-1.20.y 2024-03-22 21:23:49 +00:00
Jonathan Coates
57c72711bb
Use a platform method to register item properties
The two mod loaders expose different methods for this (Forge's method
takes a ItemPropertyFunction, Fabric's a ClampedItemPropertyFunction).
This is fine in a Gradle build, as the methods are compatible. However,
when running from IntelliJ, we get crashes as the common code tries to
reference the wrong method.

We now pass in the method reference instead, ensuring we use the right
method on each loader.
2024-03-22 20:19:32 +00:00
Jonathan Coates
cbafbca86b
Invalidate wired element when cable is added/removed
Otherwise we end up caching the old value of getWiredElement, which
might be absent if there is no cable!

Fixes #1759
2024-03-22 20:13:02 +00:00
Jonathan Coates
4675583e1c
STOP DOING MIXINS (on Forge)
BYTECODE WAS NOT SUPPOSED TO BE REWRITTEN

YEARS OF DEBUGGING REMAPPING FAILURES yet NO ACTUAL SOLUTION FOUND.

Wanted to use Mixins for anyway for a laugh? We had a tool for that: it
was called "FABRIC LOOM".

"Yes, please produce completely broken jars for no discernable reason"
Statements dreamed up by the utterly Deranged.

 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

This removes our two mixins used on Forge:

 - Breaking progress for cabled/wired modems.
 - Running client commands from chat click events. We now suggest the
   command on Forge instead.

Occasionally we get issues where the mixin annotation processor doesn't
write its tsrg file in time for the reobfJar/reobfJarJar task. I thought
we'd fixed that cb8e06af2a, but sometimes
we still produce missing jars - I have a feeling this might be to do
with incremental compilation.

We can maybe re-evaluate this on 1.20.4, where we don't need to worry
about remapping any more.
2024-03-21 21:45:17 +00:00
Jonathan Coates
afe16cc593
Clean up turtle inventory reading 2024-03-21 21:21:31 +00:00
Jonathan Coates
04900dc82f
Skip main-thread tasks if peripheral is detached
Due to the asynchronous nature of main-thread tasks, it's possible for
them to be executed on peripherals which have been detached. This has
been known for a long time (#893 was opened back in 2021), but finding a
good solution here is tricky.

Most of the time the method will silently succeed, but if we try to
interact with an IComputerAccess (such as in inventory methods, as seen
in #1750), we throw a NotAttachedException exception and spam the logs!

This is an initial step towards fixing this - when calling a peripheral
method via peripheral.call/modem.callRemote, we now wrap any enqueued
main-thread tasks and silently skip them if the peripheral has been
detached since.

This means that peripheral methods may start to return nil when they
didn't before. I think this is *fine* (though not ideal for sure!) - we
return nil if the peripheral has been detached, so it's largely
equivalent to that.
2024-03-21 19:54:22 +00:00
Jonathan Coates
ad97b2922b
Invalidate peripherals on updateShape
This fixes chests not being reattached when their size changes.
2024-03-20 10:07:29 +00:00
Jonathan Coates
52986f8d73
Drop modems as an item in updateShape
We were still handling this logic in neighborChanged, like this was
1.12. The horror!
2024-03-17 22:09:21 +00:00
Jonathan Coates
ab00580389
Simplify the previous patch a little
We can use BlockEntityType.getKey, rather than having to extend our
registry wrappers.
2024-03-17 16:21:56 +00:00
Jonathan Coates
128ac2f109
Better handling when a BE type isn't registered
This should never happen, but apparently it does!? We now log an error
(rather than crashing), and include the original BE (and associated
block), as the BE type isn't very useful.

See #1750. Technically this fixes it, but want to do some more poking
there first.
2024-03-17 16:13:33 +00:00
Jonathan Coates
5d8c46c7e6
Replace integer instance IDs with UUIDs
Here's a fun bug you can try at home:
 - Create a new world
 - Spawn in a pocket computer, turn it on, and place it in a chest.
 - Reload the world - the pocket computer in the chest should now be
   off.
 - Spawn in a new pocket computer, and turn it on. The computer in chest
   will also appear to be on!

This bug has been present since pocket computers were added (27th March,
2024).

When a pocket computer is added to a player's inventory, it is assigned
a unique *per-session* "instance id" , which is used to find the
associated computer. Note the "per-session" there - these ids will be
reused if you reload the world (or restart the server).

In the above bug, we see the following:

 - The first pocket computer is assigned an instance id of 0.
 - After reloading, the second pocket computer is assigned an instance
   id of 0.
 - If the first pocket computer was in our inventory, it'd be ticked and
   assigned a new instance id. However, because it's in an inventory, it
   keeps its old one.
 - Both computers look up their client-side computer state and get the
   same value, meaning the first pocket computer mirrors the second!

To fix this, we now ensure instance ids are entirely unique (not just
per-session). Rather than sequentially assigning an int, we now use a
random UUID (we probably could get away with a random long, but this
feels more idiomatic).

This has a couple of user-visible changes:

 - /computercraft no longer lists instance ids outside of dumping an
   individual computer.
 - The @c[instance=...] selector uses UUIDs. We still use int instance
   ids for the legacy selector, but that'll be removed in a later MC
   version.
 - Pocket computers now store a UUID rather than an int.

Related to this change (I made this change first, but then they got
kinda mixed up together), we now only create PocketComputerData when
receiving server data. This makes the code a little uglier in some
places (the data may now be null), but means we don't populate the
client-side pocket computer map with computers the server doesn't know
about.
2024-03-17 14:56:12 +00:00
Jonathan Coates
1a5dc92bd4
Some more cleanup to wired modems
- Remove "initial connections" flag, and just refresh connections +
   peripherals on the first tick.

 - Remove "peripheral attached" from NBT, and just read/write it from
   the block state. This might cause issues with #1010, but that's
   sufficiently old I hope it won't!
2024-03-17 00:18:27 +00:00
Jonathan Coates
98b2d3f310
Simplify WiredModemPeripheral interface a little 2024-03-16 23:24:55 +00:00
Jonathan Coates
e92c2d02f8
Fix turtle.suck reporting incorrect error
Our GatedPredicate hack was clever, but also fundamentally didn't work.
The predicate is called before extraction, so if extraction fails (for
instance, canTakeItemThroughFace returns false), then we still think an
item has been removed.

To fix that, we inline StorageUtil.move, specialising it for what we
need.
2024-03-16 21:27:21 +00:00
Jonathan Coates
f8ef40d378
Add a method for checking peripheral equality
This feels a little overkill, but nice to standardise how this code
looks.

There's a bit of me which wonders if we should remove
IPeripheral.equals, and just use Object.equals, but I do also kinda like
the explicitness of the current interface? IDK.
2024-03-16 14:01:22 +00:00
Jonathan Coates
61f9b1d0c6
Send entire DFPWM encoder state to the client
This ensures the client decoder is in sync with the server. Well, mostly
- we don't handle the anti-jerk, but that should correct itself within a
few samples.

Fixes #1748
2024-03-15 18:25:57 +00:00
Jonathan Coates
b7df91349a
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.

Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.

This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
Jonathan Coates
a9191a4d4e
Don't cache the client monitor
When rendering non-origin monitors, we would fetch the origin monitor,
read its client state, and then cache that on the current monitor to
avoid repeated lookups.

However, if the origin monitor is unloaded/removed on the client, and
then loaded agin, this cache will be not be invalidated, causing us to
render both the old and new monitor!

I think the correct thing to do here is cache the origin monitor. This
allows us to check when the origin monitor has been removed, and
invalidate the cache if needed.

However, I'm wary of any other edge cases here, so for now we do
something much simpler, and remove the cache entirely. This does mean
that monitors now need to perform extra block entity lookups, but the
performance cost doesn't appear to be too bad.

Fixes #1741
2024-03-10 10:57:56 +00:00
Jonathan Coates
451a2593ce
Move WiredNode default methods to the impl 2024-03-10 10:00:52 +00:00
Jonathan Coates
d38b1da974
Don't propagate redstone when blink/label changes
Historically, computers tracked whether any world-visible state
(on/off/blinking, label and redstone outputs) had changed with a single
"has changed" flag. While this is simple to use, this has the curious
side effect of that term.setCursorBlink() or os.setComputerLabel() would
cause a block update!

This isn't really a problem in practice - it just means slightly more
block updates. However, the redstone propagation sometimes causes the
computer to invalidate/recheck peripherals, which masks several other
(yet unfixed) bugs.
2024-03-06 18:59:38 +00:00
Jonathan Coates
4daa2a2b6a
Reschedule block entities when chunks are loaded
Minecraft sometimes keeps chunks in-memory, but not actively loaded. If
we schedule a block entity to be ticked and that chunk is is then
transitioned to this partially-loaded state, then the block entity is
never actually ticked.

This is most visible with monitors. When a monitor's contents changes,
if the monitor is not already marked as changed, we set it as changed
and schedule a tick (see ServerMonitor). However, if the tick is
dropped, we don't clear the changed flag, meaning subsequent changes
don't requeue the monitor to be ticked, and so the monitor is never
updated.

We fix this by maintaining a list of block entities whose tick was
dropped. If these block entities (or rather their owning chunk) is ever
re-loaded, then we reschedule them to be ticked.

An alternative approach here would be to add the scheduled tick directly
to the LevelChunk. However, getting hold of the LevelChunk for unloaded
blocks is quiet nasty, so I think best avoided.

Fixes #1146. Fixes #1560 - I believe the second one is a duplicate, and
I noticed too late :D.
2024-02-26 19:25:38 +00:00
Jonathan Coates
84b6edab82
More efficient removal of wired nodes from networks
When we remove a wired node from a network, we need to find connected
components in the rest of the graph. Typically, this requires a
traversal of the whole graph, taking O(|V| + |E|) time.

If we remove a lot of nodes at once (such as when unloading chunks),
this ends up being quadratic in the number of nodes. In some test
networks, this can take anywhere from a few seconds, to hanging the game
indefinitely.

This attempts to reduce the cases where this can happen, with a couple
of optimisations:

 - Instead of constructing a new hash set of reachable nodes (requiring
   multiple allocations and hash lookups), we store reachability as a
   temporary field on the WiredNode.

 - We abort our traversal of the graph if we can prove the graph remains
   connected after removing the node.

There's definitely future work to be done here in optimising large wired
networks, but this is a good first step.
2024-02-24 15:02:34 +00:00
Jonathan Coates
31aaf46d09
Deprecate WiredNetwork
We don't actually need this to be in the public API.
2024-02-24 14:55:22 +00:00
Jonathan Coates
2d11b51c62
Clean up the wired network tests
- Replace usages of WiredNetwork.connect/disconnect/remove with the
   WiredNode equivalents.

 - Convert "testLarge" into a proper JMH benchmark.

 - Don't put a peripheral on every node in the benchmarks. This isn't
   entirely representative, and means the peripheral juggling code ends
   up dominating the benchmark time.
2024-02-24 14:52:44 +00:00
Jonathan Coates
9c202bd1c2
Fix incorrect cast for JEI 2024-02-05 18:52:20 +00:00
Jonathan Coates
fc834cd97f
Update to 1.20.4 2024-01-31 20:55:14 +00:00
Jonathan Coates
27c72a4571
Use client-side commands for opening computer folders
Forge doesn't run client-side commands from sendUnsignedCommand, so we
still require a mixin there.

We do need to change the command name, as Fabric doesn't properly merge
the two command trees.
2024-01-30 22:00:36 +00:00
Jonathan Coates
f284328656
Regenerate Gradle wrapper 2024-01-29 22:14:48 +00:00
Jonathan Coates
6b83c63991
Switch to our own Gradle plugin for vanilla Minecraft
I didn't make a new years resolution to stop writing build tooling, but
maybe I should have.

This replaces our use of VanillaGradle with a new project,
VanillaExtract. This offers a couple of useful features for multi-loader
dev, including Parchment and Unpick support, both of which we now use in
CC:T.
2024-01-29 20:59:16 +00:00
Jonathan Coates
9ccee75a99
Fix the docs for ReadHandle.read's "count"
This was copied over from the old binary handle, and so states we
always return a single number if no count is given. This is only the
case when the file is opened in binary mode.
2024-01-23 22:39:49 +00:00
Jonathan Coates
359c8d6652
Reformat JSON by wrapping CachedOutput
Rather than mixing-in to CachedOutput, we just wrap our DataProviders to
use a custom CachedOutput which reformats the JSON before writing. This
allows us to drop mixins for common+non-client code.
2024-01-21 17:50:59 +00:00