1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-02 22:53:15 +00:00

Load turtle overlays during model loading

Back in f10e401aea, we changed turtle
overlays to be loaded as a dynamic registry. This solved some of the
problems we had with upgrades (elf-compatibility), and seemed like a
good idea at the time.

However, because overlays are part of datapacks (not resource packs), we
also needed support for loading overlay models, which we did via an
"extra_models.json" file.

With the ItemModel changes, we can go for a different approach:
 - Turtle overlays are now stored on the item/BE as a simple
   ResourceLocation again.

 - The TurtleOverlay class is moved to the client, and loaded from
   resource packs, during model loading. They're now split into a baked
   form (holding a StandaloneModel) and an unbaked one (holding the
   ResourceLocation).

 - extra_model.json is no longer supported.
This commit is contained in:
Jonathan Coates
2025-05-10 22:14:58 +01:00
parent e13e8ff92e
commit 598fd98a8b
31 changed files with 365 additions and 408 deletions

View File

@@ -6,12 +6,9 @@ package dan200.computercraft.client;
import com.google.common.reflect.TypeToken;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.client.StandaloneModel;
import dan200.computercraft.api.client.turtle.RegisterTurtleModelEvent;
import dan200.computercraft.api.client.turtle.TurtleUpgradeModel;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.client.model.ExtraModels;
import dan200.computercraft.client.platform.ForgeModelKey;
import dan200.computercraft.client.platform.ModelKey;
import dan200.computercraft.client.render.ExtendedItemFrameRenderState;
import dan200.computercraft.client.turtle.TurtleUpgradeModels;
import net.minecraft.client.Minecraft;
@@ -29,6 +26,11 @@ import net.neoforged.neoforge.client.event.*;
import net.neoforged.neoforge.client.model.standalone.UnbakedStandaloneModel;
import net.neoforged.neoforge.client.renderstate.RegisterRenderStateModifiersEvent;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
/**
* Registers textures and models for items.
@@ -44,12 +46,18 @@ public final class ForgeClientRegistry {
public static void registerModels(ModelEvent.RegisterStandalone event) {
TurtleUpgradeModels.fetch(() -> ModLoader.postEvent(new RegisterTurtleModelEvent(TurtleUpgradeModels::register)));
var extraModels = ExtraModels.loadAll(Minecraft.getInstance().getResourceManager());
ClientRegistry.registerExtraModels(
(key, model) -> event.register(ForgeModelKey.key(key), StandaloneModel::of),
(key, model) -> event.register(ForgeModelKey.erased(key), new TurtleModelWrapper<>(model)),
extraModels
);
// Load resources
Queue<Runnable> tasks = new ArrayDeque<>();
var state = ClientRegistry.gatherExtraModels(Minecraft.getInstance().getResourceManager(), tasks::add);
Runnable task;
while ((task = tasks.poll()) != null) task.run();
ClientRegistry.registerExtraModels(new ClientRegistry.RegisterExtraModels() {
@Override
public <U, T> void register(ModelKey<T> key, U unbaked, BiConsumer<U, ResolvableModel.Resolver> resolve, BiFunction<U, ModelBaker, T> bake) {
event.register(ForgeModelKey.key(key), new ModelWrapper<>(unbaked, resolve, bake));
}
}, state.resultNow());
}
@SubscribeEvent
@@ -102,17 +110,17 @@ public final class ForgeClientRegistry {
ClientRegistry.register();
}
private record TurtleModelWrapper<T extends ITurtleUpgrade>(
TurtleUpgradeModel.Unbaked<T> model
) implements UnbakedStandaloneModel<TurtleUpgradeModel<T>> {
private record ModelWrapper<U, T>(
U model, BiConsumer<U, ResolvableModel.Resolver> resolve, BiFunction<U, ModelBaker, T> bake
) implements UnbakedStandaloneModel<T> {
@Override
public TurtleUpgradeModel<T> bake(ModelBaker baker) {
return model().bake(baker);
public T bake(ModelBaker baker) {
return bake().apply(model(), baker);
}
@Override
public void resolveDependencies(ResolvableModel.Resolver resolver) {
model().resolveDependencies(resolver);
resolve().accept(model(), resolver);
}
}
}

View File

@@ -24,11 +24,6 @@ public final class ForgeModelKey<T> implements ModelKey<T> {
return ((ForgeModelKey<T>) key).key;
}
@SuppressWarnings("unchecked")
public static <T> StandaloneModelKey<T> erased(ModelKey<?> key) {
return ((ForgeModelKey<T>) key).key;
}
@Override
public @Nullable T get(ModelManager manager) {
return manager.getStandaloneModel(key);

View File

@@ -30,7 +30,6 @@ import dan200.computercraft.shared.peripheral.generic.methods.FluidMethods;
import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods;
import dan200.computercraft.shared.platform.ForgeConfigFile;
import dan200.computercraft.shared.recipe.function.RecipeFunction;
import dan200.computercraft.shared.turtle.TurtleOverlay;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
@@ -104,7 +103,6 @@ public final class ComputerCraft {
public static void registerDynamicRegistries(DataPackRegistryEvent.NewRegistry event) {
event.dataPackRegistry(ITurtleUpgrade.REGISTRY, TurtleUpgrades.instance().upgradeCodec(), TurtleUpgrades.instance().upgradeCodec());
event.dataPackRegistry(IPocketUpgrade.REGISTRY, PocketUpgrades.instance().upgradeCodec(), PocketUpgrades.instance().upgradeCodec());
event.dataPackRegistry(TurtleOverlay.REGISTRY, TurtleOverlay.DIRECT_CODEC, TurtleOverlay.DIRECT_CODEC);
}
@SubscribeEvent