Oh, this is so broken, and really has been since the 1.13 update, if not
earlier.
- Fix call to isUnobstructed using the bounding box of the
*destination* block rather than the turtle. This is almost always
air, so the box is empty.
- Because the above check has been wrong for so many years, we now
significantly relax the "can push" checks for entities. We now allow
pushing entities in any direction.
We also remove the "isUnobstructed" check for the destination entity
pos. This causes problems (if two entities are standing on a turtle,
they'll obstruct each other), and given pistons don't perform such a
check, I don't think we need it.
- Also do a bit of cleanup around air/liquid checks. We often ended up
reading the block state multiple times, which is a little ugly.
- Remove ContainerData.open.
- Change PlatformHelper.openMenu to take a separate display name and
MenuConstructor, rather than a MenuProvider. This makes the interface
slightly easier to use in the common case, where we want to use
lambdas instead.
As part of this, we also rewrite some of the turtle placing code, and
how it uses the turtle_can_use tag:
Minecraft 1.21 cleaned up the item/block clicking code a little bit,
splitting Block.use into Block.useItemOn and Block.useWithoutItem. The
first of these is pretty much exactly what we wanted in the first place,
so the tag was kinda redundant and we commented it out in the 1.21
update.
This was never meant to be a long-term fix, but time has gone by anyway.
We now check that tag, and call useWithoutItem() if present —
effectively restoring the previous behaviour.
Fixes#2011
- Disable Gradle module metadata for all Minecraft projects
- Run dependency exclusion code for all projects
We need the former for MDG on 1.21, so might as well do some other
cleanup while we're here.
useOn is now only responsible for firing the actual mod loader events,
and just returns the result of firing that event. The actual calling of
Block.use/Item.useOn now live in TurtlePlaceCommand.
This isn't especially useful for 1.20.1, but is more relevant on 1.21.1
when we look at #2011, as the shared code is much larger.
Okay, listen. I started writing a few more gametests (see #1682), and
then thought I'd do a cheeky Gradle update. However, that broke
vanilla-extract[^1], and also triggered a load of deprecation warnings,
and at that point it was too late to separate the too.
[^1]: 8975ed5a7b
I've no motivation for modding right now, but always got time for build
system busywork!
CC:T (and CC before that) has always published its API docs. However,
they're not always the most helpful — they're useful if you know what
you're looking for, but aren't a good getting-started guide.
Part of the issue here is there's no examples, and everything is
described pretty abstractly. I have occasionally tried to improve this
(e.g. the peripheral docs in bdffabc08e2eb9895f966c949acc8334a2bf4475),
but it's a long road.
This commit adds a new example mod, which registers peripherals, an API
and a turtle upgrade. While the mod itself isn't exported as part of the
docs, we reference blocks of it using Java's new {@snippet} tag.
- Switch the Forge project to use NeoForge's new Legacy MDG plugin. We
don't *need* to do this, but it means the build logic for Forge and
NeoForge is more closely aligned.
- Add a new SnippetTaglet, which is a partial backport of Java 18+'s
{@snippet}.
- Add an example mod. This is a working multi-loader mod, complete with
datagen (albeit with no good multi-loader abstractions).
- Move our existing <pre>{@code ...}</pre> blocks into the example mod,
replacing them with {@snippet}s.
- Add a new overview page to the docs, providing some getting-started
information. We had this already in the dan200.computercraft.api
package docs, but it's not especially visible there.
MC 1.21.4 means we have to move more data generation code into the
client source set. Given all this code movement, it probably makes sense
to put data generation in a separate source set instead.
1.21.4 also has split data generators for client and server, but neither
mod loader recommends this. This means we can/should merge DataProviders
and ClientDataProviders into a single class.
Data generators are no longer bundled with the jar, which does reduce
file size, but by a tiny amount (~70KiB).
I've tried so many rewrites of the config system over the last few
months, in an attempt to get started on #1727. All of them stink, so
this is an attempt to apply some of the cleanup.
- Move some of the common logic into ConfigFile. This means we now
store more information ourselves for Forge, rather than reading it
out of the ForgeConfigSpec.
- Don't include the Range/Allowed keys in the translation key. This was
mostly there because of how we read comments from Forge, but it never
made much sense.
- Remove our separate Trie structure, and just encode the tree as part
of the children of a Group.
Some mods run their own datafixer chain, rather than piggybacking on top
of vanilla's. This is A BAD IDEA, but what can you do. If such a mod
tries to use ItemStackComponentizationFix in their own schema, then
CC:T's mixins will try to look up the turtle block entitie, and fail (as
they're not registered under the modded schema).
We now inject the block entity fix as a separate fixer, rather than
abusing ItemStackComponentizationFix.
See #2012
- Don't construct a fake player when crafting: vanilla now has its own
automated crafting, so no longer requires the presence of a player.
- Fix remainder stack not being set in some situations. Closes#2007.
- Move redstone methods out of the IAPIEnvironment, and into a new
RedstoneAccess. We similarly move the implementation from Environment
into a new RedstoneState class.
The interface is possibly a little redundant (interfaces with a
single implementation are always a little suspect), but it's nice to
keep the consumer/producer interfaces separate.
- Abstract most redstone API methods into a separate shared class, that
can be used by both the rs API and the new redstone relay.
- Add the new redstone relay block.
The docs are probably a little lacking here, but I really struggled to
write anything which wasn't just "look, it's the same as the redstone
API".
As part of the multi-loader work, we unified some of our event listening
code (0908acbe9bbb63d9c1be513d098e9a14d5bb68e3). This incorrectly caused
client pocket computer state to be reset when the player changes
dimension, rather than when the player (dis)connects.
The server code isn't aware of this behaviour, and so does not resend
pocket computer state when the player moves level. We could change this,
but just fixing when we clear the pocket computer state is a much nicer
fix!
Fixes#2004
Iris now has built-in support for NeoForge, so we can use the same
integration on both.
We also re-enable Forge's client tests, and test Iris there too.
Fixes#1967
Previously we used an RGBA byte array. However, this comes with some
overhead (extra memory reads, bounds checks).
Minecraft 1.21+ uses ARGB32 colours for rendering (well, in the public
code — internaly it converts to ABGR), so it makes sense to match that
here.
We also add some helper functions for dealing with ARGB32 colours. These
can be removed in 1.21, as Minecraft will have these builtin.
- Add a new custom lectern block, that is used to hold the printed
pages. We have to roll quite a lot of custom logic, so this is much
cleaner than trying to mixin to the existing lectern code.
- Add a new (entity) model for printed pages and books placed on a
lectern. I did originally think about just rendering the item (or the
in-hand/map version), but I think this is a bit more consistent with
vanilla.
However, we do still need to sync the item to the client (mostly to
get the current page count!). There is a risk of chunkbanning here,
but I think it's much harder than vanilla, due to the significantly
reduced page limit.
There's been a couple of bug reports in the past where the game would
crash if a turtle is destroyed while breaking a block (typically due to
the block exploding). This commit adds a test, to ensure that this is
handled gracefully.
I'm not entirely sure this is testing the right thing. Looking at the
issues in question, it doesn't look like I ever managed to reproduce the
bug. However, it's hopefully at least a quick sanity test to check we
never break this case.
- Update to latest NeoForge, fixing issues with config API changes.
Closes#1903.
- Update to latest Fabric, switching to the ender pearl conventional
tag, and new loot API.
In c8eadf401190db2b9c3145f768063097b9c345bd we marked our various modems
as "brittle", which ensures they do not pop-off computers when the whole
structure moves.
However, this still requires the modem to be glued — if the modem is
outside the superglue range, it will still pop off. We can fix it by
registering a special "attached check" for the various modem blocks,
which says that the modem should be moved when the adjacent block does.
Fixes#1913
- Add a new computercraft:turtle_overlay dynamic registry, which stores
turtle overlays. Turtle overlays are just a model id and an
(optional) boolean flag, which specifies whether this overlay is
compatible with the elf/christmas model.
- Change the computercraft:overlay component to accept a
Holder<TurtleOverlay> (instead of just a model ID). This accepts both
an overlay ID or an inline overlay object (e.g. you can do
cc:turtle_normal[computercraft:overlay={model:"foo"}].
- Update turtle model and BE rendering code to render both the overlay
and elf (if compatible). Fixes#1663.
- Ideally we'd automatically load all models listed in the overlay
registry. However, resource loading happens separately to datapacks,
so we can't link the two.
Instead, we add a new assets/computercraft/extra_models.json file
that lists any additional models that should be loaded and baked.
This file includes all built-in overlay models, but external resource
packs and/or mods can easily extend it.
API Changes:
- Minecraft had updated ModelResourceLocation to no longer inherit from
ResourceLocation.
To allow referencing both already baked models
(ModelResourceLocation) and loading new models (via ResourceLocation)
in turtle model loadders, we add a new "ModelLocation" class, that
acts as a union between the two.
I'm not entirely convinced by the design here, so might end up
changing again before a stable release.o
- Merge IMedia.getAudioTitle and IMedia.getAudio into a single
IMedia.getAudio method, which now returns a JukeboxSong rather than a
SoundEvent.
Other update notes:
- Minecraft had rewritten how buffers are managed again. This is a
fairly minor change for us (vertex -> addVertex, normal -> setNormal,
etc...), with the exception that you can no longer use
MultiBufferSource.immediate with the tesselator.
I've replaced this with GuiGraphics.bufferSource, which appears to be
fine, but worth keeping an eye on in case there's any odd render
state issues.
- Crafting now uses a CraftingInput (a list of items) rather than a
CraftingContainer, which allows us to simplify turtle crafting code.
Rather than having one single hard-coded recipe, we now have separate
recipes for printed pages and printed books. These recipes are defined
in terms of
- A list of ingredients (like shapeless recipes).
- A result item.
- An ingredient defining the acceptable page items (so printed page(s),
but not books). This cannot overlap with any of the main ingredients.
- The minimum number of printouts required.
We then override the shapeless recipe crafting logic to allow for
multiple printouts to appear.
It feels like it'd be nice to generalise this to a way of defining
shapeless recipes with variable-count ingredients (for instance, the
disk recipe could also be defined this way), but I don't think it's
worth it right now.
This solves some of the issues in #1755. Disk recipes have not been
changed yet.
- Update EMI and REI integration, and fix some issues with the upgrade
crafting hooks.
- Just use smooth stone for recipes, not #c:stone. We're mirroring
redstone's crafting recipes here.
- Some cleanup to printouts.
- Remote upgrade data generators - these can be replaced with the
standard registry data generators.
- Remove the API's PlatformHelper - we no longer have any
platform-specific code in the API.
- Use TinyRemapper to remap mixins on Fabric. Mixins in the common
project weren't being remapped correctly.
- Update to latest NeoForge
- Switch to the new tick events.
- Call refreshDimensions() in the fake player constructor.
Ever since 1.17, turtle and pocket upgrades have been loaded from
datpacks, rather than being hard-coded in Java. However, upgrades have
always been stored in our own registry-like structure, rather than using
vanilla's registries.
This has become a bit of a problem with the introduction of components.
The upgrade components now hold the upgrade object (rather than just its
id), which means we need the upgrades to be available much earlier (e.g.
when reading recipes).
The easiest fix here is to store upgrades in proper registries instead.
This means that upgrades can no longer be reloaded (it requires a world
restart), but otherwise is much nicer:
- UpgradeData now stores a Holder<T> rather than a T.
- UpgradeSerialiser has been renamed to UpgradeType. This now just
provides a Codec<T>, rather than JSON and network reading/writing
functions.
- Upgrade classes no longer implement getUpgradeID(), but instead have
a getType() function, which returns the associated UpgradeType.
- Upgrades are now stored in turtle_upgrade (or pocket_upgrade) rather
than turtle_upgrades (or pocket_upgrades). This will break existing
datapacks, sorry!
This adds a new "recipe function" system, that allows transforming the
result of a recipe according to some datapack-defined function.
Currently, we only provide one function: computercraft:copy_components,
which copies components from one of the ingredients to the result. This
allows us to replace several of our existing recipes:
- Turtle overlay recipes are now defined as a normal shapeless recipe
that copies all (non-overlay) components from the input turtle.
- Computer conversion recipes (e.g. computer -> turtle, normal ->
advanced) copy all components from the input computer to the result.
This is more complex (and thus more code), but also a little more
flexible, which hopefully is useful for someone :).
In 1.20.1, Forge and Fabric have different "common" tag conventions (for
instance, Forge uses forge:dusts/redstone, while Fabric uses
c:redstone_dusts). This means the generated recipes (and advancements)
will be different for the two loader projects. As such, we run data
generators for each loader, and store the results separately.
However, aside from some recipes and advancements, most resources /are/
the same between the two. This means we end up with a lot of duplicate
files, which make the diff even harder to read. This gets worse in
1.20.5, when NeoForge and Fabric have (largely) unified their tag names.
This commit now merges the generated resources of the two loaders,
moving shared files to the common project.
- Add a new MergeTrees command, to handle the de-duplication of files.
- Change the existing runData tasks to write to
build/generatedResources.
- Add a new :common:runData task, that reads from the
build/generatedResources folder and writes to the per-project
src/generated/resources.
NF now loads mods from neoforge.mods.toml rather than mods.toml, so CC
wasn't actually being loaded. Tests all passed, because they didn't get
run in the first place!
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.