Multiloader IV

client setup ported
This commit is contained in:
techno-sam
2026-04-05 22:20:27 +02:00
parent 7c20d34844
commit b4355e8fd8
18 changed files with 212 additions and 52 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ dependencies {
modImplementation(libs.fl) modImplementation(libs.fl)
// required for proper remapping and compiling // required for proper remapping and compiling
modCompileOnly(libs.fapi) // TODO: try removing this and seeing if that breaks stuff //modCompileOnly(libs.fapi) // TODO: try removing this and seeing if that breaks stuff
modCompileOnly(libs.sodium.fabric) modCompileOnly(libs.sodium.fabric)
@@ -1,18 +1,15 @@
package io.github.slimeistdev.crystalline_sky; package io.github.slimeistdev.crystalline_sky;
import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants;
import io.github.slimeistdev.crystalline_sky.annotation.multiloader.MultiLoaderEvent;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.DebugRenderer_Duck; import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.DebugRenderer_Duck;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import io.github.slimeistdev.crystalline_sky.multiloader.ClientPlatformHelper;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems; import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderTypes;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.client.KeyMapping; import net.minecraft.client.KeyMapping;
import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.client.Minecraft;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@@ -21,37 +18,44 @@ import net.minecraft.world.item.component.BlockItemStateProperties;
import net.minecraft.world.level.block.LightBlock; import net.minecraft.world.level.block.LightBlock;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.function.Consumer;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class CrystallineSkyClient { public class CrystallineSkyClient {
public static void init() { private static final KeyMapping KEY_TOGGLE_DEBUG = new KeyMapping(
BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.SKY, CrystallineRenderTypes.SKY);
BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.WEEPING_SKY, CrystallineRenderTypes.SKY);
var weepingSkyKeybind = KeyBindingHelper.registerKeyBinding(new KeyMapping(
"crystalline_sky.key.toggle_weeping_sky_debug", "crystalline_sky.key.toggle_weeping_sky_debug",
InputConstants.Type.KEYSYM, InputConstants.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN, GLFW.GLFW_KEY_UNKNOWN,
"crystalline_sky.category.crystalline_sky" "crystalline_sky.category.crystalline_sky"
)); );
ClientTickEvents.END_CLIENT_TICK.register(client -> { public static void init() {
while (weepingSkyKeybind.consumeClick()) { ClientPlatformHelper.registerItemProperty(
int mode = ((DebugRenderer_Duck) client.debugRenderer).crystalline_sky$toggleWeepingSky(); CrystallineItems.SKY_LIGHT,
ResourceLocation.withDefaultNamespace("level"),
(stack, world, entity, seed) -> {
BlockItemStateProperties state = stack.getOrDefault(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY);
Integer level = state.get(LightBlock.LEVEL);
return level != null ? level / 16.0F : 1.0F;
}
);
}
public static void registerKeybindings(Consumer<KeyMapping> registrar) {
registrar.accept(KEY_TOGGLE_DEBUG);
}
@MultiLoaderEvent
public static void onEndTick(Minecraft mc) {
while (KEY_TOGGLE_DEBUG.consumeClick()) {
int mode = ((DebugRenderer_Duck) mc.debugRenderer).crystalline_sky$toggleWeepingSky();
Component message = getDebugMessage(ChatFormatting.YELLOW, Component message = getDebugMessage(ChatFormatting.YELLOW,
Component.translatable("message.crystalline_sky.weeping_sky_debug." + mode) Component.translatable("message.crystalline_sky.weeping_sky_debug." + mode)
); );
client.gui.getChat().addMessage(message); mc.gui.getChat().addMessage(message);
} }
});
ItemProperties.register(CrystallineItems.SKY_LIGHT, ResourceLocation.withDefaultNamespace("level"),
(stack, world, entity, seed) -> {
BlockItemStateProperties blockStateComponent = stack.getOrDefault(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY);
Integer integer = blockStateComponent.get(LightBlock.LEVEL);
return integer != null ? integer / 16.0F : 1.0F;
});
} }
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
@@ -0,0 +1,33 @@
/*
* Steam 'n' Rails
* Copyright (c) 2022-2025 The Railways Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package io.github.slimeistdev.crystalline_sky.annotation.multiloader;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to mark methods that are called via abstracted loader-specific events.
* <p>
* Meant purely for documentation and does not exist at compile-time or runtime.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface MultiLoaderEvent { }
@@ -0,0 +1,16 @@
package io.github.slimeistdev.crystalline_sky.multiloader;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.renderer.item.ClampedItemPropertyFunction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
@Environment(EnvType.CLIENT)
public class ClientPlatformHelper {
@ExpectPlatform
public static void registerItemProperty(Item item, ResourceLocation name, ClampedItemPropertyFunction property) {
throw new AssertionError();
}
}
@@ -19,7 +19,6 @@
"client.DebugRendererMixin", "client.DebugRendererMixin",
"client.RenderTargetMixin", "client.RenderTargetMixin",
"client.GameRendererMixin", "client.GameRendererMixin",
"client.RenderTypeMixin",
"client.LevelRenderer_NoSodium_Mixin", "client.LevelRenderer_NoSodium_Mixin",
"client.LevelRendererMixin", "client.LevelRendererMixin",
"client.compat.axiom.ChunkRenderOverrider_AxiomChunkOverrideLayerMixin", "client.compat.axiom.ChunkRenderOverrider_AxiomChunkOverrideLayerMixin",
@@ -1,14 +1,25 @@
package io.github.slimeistdev.crystalline_sky.fabric; package io.github.slimeistdev.crystalline_sky.fabric;
import io.github.slimeistdev.crystalline_sky.CrystallineSkyClient; import io.github.slimeistdev.crystalline_sky.CrystallineSkyClient;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderTypes;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class CrystallineSkyClientImpl implements ClientModInitializer { public class CrystallineSkyClientImpl implements ClientModInitializer {
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
CrystallineSkyClient.init(); CrystallineSkyClient.init();
CrystallineSkyClient.registerKeybindings(KeyBindingHelper::registerKeyBinding);
BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.SKY, CrystallineRenderTypes.SKY);
BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.WEEPING_SKY, CrystallineRenderTypes.SKY);
ClientTickEvents.END_CLIENT_TICK.register(CrystallineSkyClient::onEndTick);
} }
} }
@@ -1,8 +1,8 @@
package io.github.slimeistdev.crystalline_sky.datagen; package io.github.slimeistdev.crystalline_sky.fabric.datagen;
import io.github.slimeistdev.crystalline_sky.datagen.providers.CrystallineSkyBlockTagProvider; import io.github.slimeistdev.crystalline_sky.fabric.datagen.providers.CrystallineSkyBlockTagProvider;
import io.github.slimeistdev.crystalline_sky.datagen.providers.CrystallineSkyLootProvider; import io.github.slimeistdev.crystalline_sky.fabric.datagen.providers.CrystallineSkyLootProvider;
import io.github.slimeistdev.crystalline_sky.datagen.providers.CrystallineSkyModelProvider; import io.github.slimeistdev.crystalline_sky.fabric.datagen.providers.CrystallineSkyModelProvider;
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
@@ -1,4 +1,4 @@
package io.github.slimeistdev.crystalline_sky.datagen.providers; package io.github.slimeistdev.crystalline_sky.fabric.datagen.providers;
import io.github.slimeistdev.crystalline_sky.CrystallineSky; import io.github.slimeistdev.crystalline_sky.CrystallineSky;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
@@ -1,4 +1,4 @@
package io.github.slimeistdev.crystalline_sky.datagen.providers; package io.github.slimeistdev.crystalline_sky.fabric.datagen.providers;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
@@ -1,24 +1,26 @@
package io.github.slimeistdev.crystalline_sky.datagen.providers; package io.github.slimeistdev.crystalline_sky.fabric.datagen.providers;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import io.github.slimeistdev.crystalline_sky.CrystallineSky;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems; import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
import net.minecraft.world.level.block.Block;
import net.minecraft.data.models.BlockModelGenerators; import net.minecraft.data.models.BlockModelGenerators;
import net.minecraft.data.models.blockstates.Variant;
import net.minecraft.data.models.blockstates.PropertyDispatch;
import net.minecraft.data.models.ItemModelGenerators; import net.minecraft.data.models.ItemModelGenerators;
import net.minecraft.data.models.blockstates.MultiVariantGenerator;
import net.minecraft.data.models.blockstates.PropertyDispatch;
import net.minecraft.data.models.blockstates.Variant;
import net.minecraft.data.models.blockstates.VariantProperties;
import net.minecraft.data.models.model.ModelLocationUtils; import net.minecraft.data.models.model.ModelLocationUtils;
import net.minecraft.data.models.model.ModelTemplates; import net.minecraft.data.models.model.ModelTemplates;
import net.minecraft.data.models.model.TextureMapping; import net.minecraft.data.models.model.TextureMapping;
import net.minecraft.data.models.blockstates.VariantProperties; import net.minecraft.data.models.model.TexturedModel;
import net.minecraft.data.models.blockstates.MultiVariantGenerator;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import java.util.Locale; import java.util.Locale;
@@ -39,7 +41,16 @@ public class CrystallineSkyModelProvider extends FabricModelProvider {
} }
private void registerSkyBlock(BlockModelGenerators gen, Block block) { private void registerSkyBlock(BlockModelGenerators gen, Block block) {
gen.createTrivialCube(block); gen.blockStateOutput.accept(BlockModelGenerators.createSimpleBlock(block, TexturedModel.CUBE.create(
block,
(id, json) -> {
gen.modelOutput.accept(id, () -> {
JsonObject root = json.get().getAsJsonObject();
root.addProperty("render_type", CrystallineSky.id("sky").toString());
return root;
});
}
)));
gen.createSimpleFlatItemModel(block); gen.createSimpleFlatItemModel(block);
} }
@@ -1,4 +1,4 @@
package io.github.slimeistdev.crystalline_sky.mixin.client; package io.github.slimeistdev.crystalline_sky.fabric.mixin.client;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.RenderType_Duck; import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.RenderType_Duck;
@@ -0,0 +1,14 @@
package io.github.slimeistdev.crystalline_sky.multiloader.fabric;
import io.github.slimeistdev.crystalline_sky.annotation.multiloader.ImplClass;
import net.minecraft.client.renderer.item.ClampedItemPropertyFunction;
import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
@ImplClass
public class ClientPlatformHelperImpl {
public static void registerItemProperty(Item item, ResourceLocation name, ClampedItemPropertyFunction property) {
ItemProperties.register(item, name, property);
}
}
@@ -10,6 +10,7 @@
"mixins": [ "mixins": [
], ],
"client": [ "client": [
"client.RenderTypeMixin"
], ],
"server": [ "server": [
], ],
+1 -1
View File
@@ -36,7 +36,7 @@
"io.github.slimeistdev.crystalline_sky.fabric.CrystallineSkyClientImpl" "io.github.slimeistdev.crystalline_sky.fabric.CrystallineSkyClientImpl"
], ],
"fabric-datagen": [ "fabric-datagen": [
"io.github.slimeistdev.crystalline_sky.datagen.CrystallineSkyDataGenerator" "io.github.slimeistdev.crystalline_sky.fabric.datagen.CrystallineSkyDataGenerator"
] ]
} }
} }
@@ -0,0 +1,14 @@
package io.github.slimeistdev.crystalline_sky.multiloader.neoforge;
import io.github.slimeistdev.crystalline_sky.annotation.multiloader.ImplClass;
import net.minecraft.client.renderer.item.ClampedItemPropertyFunction;
import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
@ImplClass
public class ClientPlatformHelperImpl {
public static void registerItemProperty(Item item, ResourceLocation name, ClampedItemPropertyFunction property) {
ItemProperties.register(item, name, property);
}
}
@@ -1,9 +1,36 @@
package io.github.slimeistdev.crystalline_sky.neoforge; package io.github.slimeistdev.crystalline_sky.neoforge;
import io.github.slimeistdev.crystalline_sky.CrystallineSky;
import io.github.slimeistdev.crystalline_sky.CrystallineSkyClient; import io.github.slimeistdev.crystalline_sky.CrystallineSkyClient;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderTypes;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent;
import net.neoforged.neoforge.client.event.RegisterNamedRenderTypesEvent;
@EventBusSubscriber(value = Dist.CLIENT, modid = CrystallineSky.ID)
public class CrystallineSkyClientImpl { public class CrystallineSkyClientImpl {
public static void init() { public static void init() {
CrystallineSkyClient.init(); CrystallineSkyClient.init();
} }
@SubscribeEvent
public static void registerNamedRenderTypes(RegisterNamedRenderTypesEvent event) {
// NOTE: entity render type is just a placeholder, sky rendering isn't supported for entities
event.register(CrystallineSky.id("sky"), CrystallineRenderTypes.SKY, RenderType.entitySolid(CrystallineSky.id("sky")));
}
@SubscribeEvent
public static void registerBindings(RegisterKeyMappingsEvent event) {
CrystallineSkyClient.registerKeybindings(event::register);
}
@SubscribeEvent
public static void onEndTick(ClientTickEvent.Post event) {
CrystallineSkyClient.onEndTick(Minecraft.getInstance());
}
} }
@@ -0,0 +1,29 @@
package io.github.slimeistdev.crystalline_sky.neoforge.mixin.client;
import com.google.common.collect.ImmutableList;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.RenderType_Duck;
import net.minecraft.client.renderer.RenderType;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(RenderType.class)
public class RenderTypeMixin implements RenderType_Duck {
@Shadow
@Final
@Mutable
public static ImmutableList<RenderType> CHUNK_BUFFER_LAYERS;
@Shadow
public int chunkLayerId;
@Override
public void crystalline_sky$markAsBlockLayer() {
CHUNK_BUFFER_LAYERS = ImmutableList.<RenderType>builder()
.addAll(CHUNK_BUFFER_LAYERS)
.add((RenderType) (Object) this)
.build();
chunkLayerId = CHUNK_BUFFER_LAYERS.size() - 1;
}
}
@@ -10,6 +10,7 @@
"mixins": [ "mixins": [
], ],
"client": [ "client": [
"client.RenderTypeMixin"
], ],
"server": [ "server": [
], ],