From d4b8894a3b59b3cfaefe978a20bcfba6ada51128 Mon Sep 17 00:00:00 2001 From: techno-sam <77073745+techno-sam@users.noreply.github.com> Date: Thu, 16 Apr 2026 10:49:24 +0200 Subject: [PATCH] Multiloader V fabric is working --- common/build.gradle.kts | 3 +- .../crystalline_sky/CrystallineSky.java | 8 ++ .../crystalline_sky/CrystallineSkyClient.java | 2 +- .../crystalline_sky/compat/Mods.java | 9 +- .../compat/sodium/SkyShaderInterface.java | 6 +- .../content/blocks/SkyBlock.java | 9 ++ .../content/blocks/SkyLightBlock.java | 13 +-- .../content/blocks/WeepingSkyLightBlock.java | 27 +++-- .../content/blocks/package-info.java | 3 + .../content/items/WeepingSkyBlockItem.java | 22 ++-- .../content/items/package-info.java | 3 + .../registration/CatnipRegistry.java | 63 +++++++++++ .../foundation/registration/Registration.java | 24 ++++ .../registration/RegistrationListeners.java | 28 +++++ .../registration/builder/AbstractBuilder.java | 49 ++++++++ .../registration/builder/BlockBuilder.java | 47 ++++++++ .../builder/DataComponentTypeBuilder.java | 46 ++++++++ .../registration/builder/ItemBuilder.java | 39 +++++++ .../registration/builder/package-info.java | 5 + .../registration/holder/BaseHolder.java | 39 +++++++ .../registration/holder/BlockHolder.java | 20 ++++ .../holder/DataComponentTypeHolder.java | 11 ++ .../registration/holder/ItemHolder.java | 16 +++ .../registration/holder/ItemLikeHolder.java | 43 +++++++ .../registration/holder/package-info.java | 5 + .../foundation/registration/package-info.java | 5 + .../mixin/Holder$ReferenceAccessor.java | 16 +++ .../mixin/client/ClientLevelMixin.java | 8 +- .../client/LevelRenderer_NoSodium_Mixin.java | 6 +- .../ItemGroupRegistrationEvent.java | 14 +++ .../crystalline_sky/multiloader/Loader.java | 60 ++++++++++ .../registry/CrystallineBlocks.java | 99 ++++++++-------- .../CrystallineDataComponentTypes.java | 21 ++-- .../registry/CrystallineItems.java | 70 ++++++------ .../client/CrystallineRenderTypes.java | 17 +-- .../crystalline_sky/util/TextUtils.java | 107 ++++++++++++++++++ .../crystalline_sky-common.mixins.json | 8 +- fabric/build.gradle.kts | 4 +- .../compat/fabric/ModsImpl.java | 11 ++ .../fabric/CrystallineSkyClientImpl.java | 10 +- .../CrystallineSkyBlockTagProvider.java | 20 +++- .../providers/CrystallineSkyLootProvider.java | 4 +- .../CrystallineSkyModelProvider.java | 10 +- ...verrider_AxiomChunkOverrideLayerMixin.java | 2 +- .../ItemGroupRegistrationEventImpl.java | 47 ++++++++ .../multiloader/fabric/LoaderImpl.java | 13 +++ .../resources/crystalline_sky.mixins.json | 3 +- libs.versions.toml | 3 + .../compat/neoforge/ModsImpl.java | 20 ++++ .../ItemGroupRegistrationEventImpl.java | 6 + .../multiloader/neoforge/LoaderImpl.java | 13 +++ .../neoforge/CrystallineSkyClientImpl.java | 8 ++ .../neoforge/CrystallineSkyImpl.java | 7 +- 53 files changed, 983 insertions(+), 169 deletions(-) create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/SkyBlock.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/package-info.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/content/items/package-info.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/CatnipRegistry.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/Registration.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/RegistrationListeners.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/AbstractBuilder.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/BlockBuilder.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/DataComponentTypeBuilder.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/ItemBuilder.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/package-info.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/BaseHolder.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/BlockHolder.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/DataComponentTypeHolder.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/ItemHolder.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/ItemLikeHolder.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/package-info.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/package-info.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/Holder$ReferenceAccessor.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/ItemGroupRegistrationEvent.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/Loader.java create mode 100644 common/src/main/java/io/github/slimeistdev/crystalline_sky/util/TextUtils.java create mode 100644 fabric/src/main/java/io/github/slimeistdev/crystalline_sky/compat/fabric/ModsImpl.java rename {common/src/main/java/io/github/slimeistdev/crystalline_sky => fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric}/mixin/client/compat/axiom/ChunkRenderOverrider_AxiomChunkOverrideLayerMixin.java (92%) create mode 100644 fabric/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/fabric/ItemGroupRegistrationEventImpl.java create mode 100644 fabric/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/fabric/LoaderImpl.java create mode 100644 neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/compat/neoforge/ModsImpl.java create mode 100644 neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/neoforge/ItemGroupRegistrationEventImpl.java create mode 100644 neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/neoforge/LoaderImpl.java diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 833f498..c97718e 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -14,7 +14,8 @@ dependencies { modImplementation(libs.fl) // required for proper remapping and compiling - //modCompileOnly(libs.fapi) // TODO: try removing this and seeing if that breaks stuff + modCompileOnly(libs.fapi) + compileOnly(libs.jsr305) modCompileOnly(libs.sodium.fabric) diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/CrystallineSky.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/CrystallineSky.java index 41e326c..b5914c8 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/CrystallineSky.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/CrystallineSky.java @@ -1,14 +1,17 @@ package io.github.slimeistdev.crystalline_sky; +import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.ApiStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class CrystallineSky { public static final String ID = "crystalline_sky"; public static final Logger LOG = LoggerFactory.getLogger(ID); + private static final CatnipRegistry REGISTRY = new CatnipRegistry(ID); public static void init() { ModSetup.init(); @@ -21,4 +24,9 @@ public class CrystallineSky { public static ResourceKey key(ResourceKey> registryKey, String path) { return ResourceKey.create(registryKey, id(path)); } + + @ApiStatus.Internal + public static CatnipRegistry registry() { + return REGISTRY; + } } diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/CrystallineSkyClient.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/CrystallineSkyClient.java index 29fac28..d7dc717 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/CrystallineSkyClient.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/CrystallineSkyClient.java @@ -31,7 +31,7 @@ public class CrystallineSkyClient { public static void init() { ClientPlatformHelper.registerItemProperty( - CrystallineItems.SKY_LIGHT, + CrystallineItems.SKY_LIGHT.value(), ResourceLocation.withDefaultNamespace("level"), (stack, world, entity, seed) -> { BlockItemStateProperties state = stack.getOrDefault(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY); diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/compat/Mods.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/compat/Mods.java index b9df232..3243aa1 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/compat/Mods.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/compat/Mods.java @@ -1,6 +1,6 @@ package io.github.slimeistdev.crystalline_sky.compat; -import net.fabricmc.loader.api.FabricLoader; +import dev.architectury.injectables.annotations.ExpectPlatform; import java.util.Optional; import java.util.function.Supplier; @@ -14,7 +14,12 @@ public enum Mods { Mods(String id) { this.id = id; - this.isLoaded = FabricLoader.getInstance().isModLoaded(id); + this.isLoaded = isModLoaded(id); + } + + @ExpectPlatform + public static boolean isModLoaded(String id) { + throw new AssertionError(); } /** diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/compat/sodium/SkyShaderInterface.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/compat/sodium/SkyShaderInterface.java index 82e593f..1ccd63f 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/compat/sodium/SkyShaderInterface.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/compat/sodium/SkyShaderInterface.java @@ -53,10 +53,8 @@ public class SkyShaderInterface implements ChunkShaderInterface { Minecraft client = Minecraft.getInstance(); if (client.level != null && client.player != null - && (client.player.getMainHandItem().is(CrystallineItems.SKY) - || client.player.getOffhandItem().is(CrystallineItems.SKY) - || client.player.getMainHandItem().is(CrystallineItems.WEEPING_SKY) - || client.player.getOffhandItem().is(CrystallineItems.WEEPING_SKY))) { + && (CrystallineItems.isSky(client.player.getMainHandItem()) + || CrystallineItems.isSky(client.player.getOffhandItem()))) { float f = client.level.getGameTime() + client.getTimer().getGameTimeDeltaPartialTick(true); float alpha = (Mth.sin(f / 10.0f) + 1.0f) / 2.0f; diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/SkyBlock.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/SkyBlock.java new file mode 100644 index 0000000..b498246 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/SkyBlock.java @@ -0,0 +1,9 @@ +package io.github.slimeistdev.crystalline_sky.content.blocks; + +import net.minecraft.world.level.block.TransparentBlock; + +public class SkyBlock extends TransparentBlock { + public SkyBlock(Properties properties) { + super(properties); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/SkyLightBlock.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/SkyLightBlock.java index 0d71b9d..d297e72 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/SkyLightBlock.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/SkyLightBlock.java @@ -1,14 +1,13 @@ package io.github.slimeistdev.crystalline_sky.content.blocks; import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems; -import net.minecraft.world.level.block.state.BlockBehaviour.Properties; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.LightBlock; -import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.core.BlockPos; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.LightBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; public class SkyLightBlock extends LightBlock { public SkyLightBlock(Properties settings) { @@ -17,6 +16,6 @@ public class SkyLightBlock extends LightBlock { @Override protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { - return context.isHoldingItem(CrystallineItems.SKY_LIGHT) ? Shapes.block() : Shapes.empty(); + return context.isHoldingItem(CrystallineItems.SKY_LIGHT.value()) ? Shapes.block() : Shapes.empty(); } } diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/WeepingSkyLightBlock.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/WeepingSkyLightBlock.java index b22b70d..0e420c7 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/WeepingSkyLightBlock.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/WeepingSkyLightBlock.java @@ -1,23 +1,22 @@ package io.github.slimeistdev.crystalline_sky.content.blocks; import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.RenderShape; -import net.minecraft.world.level.block.state.BlockBehaviour.Properties; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.level.block.SimpleWaterloggedBlock; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; public class WeepingSkyLightBlock extends Block implements SimpleWaterloggedBlock { public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; @@ -34,7 +33,7 @@ public class WeepingSkyLightBlock extends Block implements SimpleWaterloggedBloc @Override protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { - return context.isHoldingItem(CrystallineItems.WEEPING_SKY_LIGHT) ? Shapes.block() : Shapes.empty(); + return context.isHoldingItem(CrystallineItems.WEEPING_SKY_LIGHT.value()) ? Shapes.block() : Shapes.empty(); } @Override diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/package-info.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/package-info.java new file mode 100644 index 0000000..4035c12 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/blocks/package-info.java @@ -0,0 +1,3 @@ +@javax.annotation.ParametersAreNonnullByDefault +@net.minecraft.MethodsReturnNonnullByDefault +package io.github.slimeistdev.crystalline_sky.content.blocks; diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/items/WeepingSkyBlockItem.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/items/WeepingSkyBlockItem.java index 3828f8c..26739bb 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/items/WeepingSkyBlockItem.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/items/WeepingSkyBlockItem.java @@ -1,18 +1,18 @@ package io.github.slimeistdev.crystalline_sky.content.items; import io.github.slimeistdev.crystalline_sky.registry.CrystallineDataComponentTypes; -import net.minecraft.world.item.Item.Properties; -import net.minecraft.world.level.block.Block; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ColumnPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResultHolder; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ColumnPos; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import org.jetbrains.annotations.NotNull; public class WeepingSkyBlockItem extends BlockItem { public WeepingSkyBlockItem(Block block, Properties settings) { @@ -20,9 +20,9 @@ public class WeepingSkyBlockItem extends BlockItem { } @Override - public InteractionResult useOn(UseOnContext context) { + public @NotNull InteractionResult useOn(UseOnContext context) { ItemStack stack = context.getItemInHand(); - if (stack.get(CrystallineDataComponentTypes.WEEPING_SKY_DEBUG_COLUMN_TOOL) != null) { + if (stack.get(CrystallineDataComponentTypes.WEEPING_SKY_DEBUG_COLUMN_TOOL.value()) != null) { if (context.getLevel().isClientSide) { BlockPos pos = context.getClickedPos(); WeepingSkyBlockItemClient.setSelectedColumn(new ColumnPos(pos.getX(), pos.getZ())); @@ -34,9 +34,9 @@ public class WeepingSkyBlockItem extends BlockItem { } @Override - public InteractionResultHolder use(Level world, Player user, InteractionHand hand) { + public @NotNull InteractionResultHolder use(Level world, Player user, InteractionHand hand) { ItemStack stack = user.getItemInHand(hand); - if (stack.get(CrystallineDataComponentTypes.WEEPING_SKY_DEBUG_COLUMN_TOOL) != null) { + if (stack.get(CrystallineDataComponentTypes.WEEPING_SKY_DEBUG_COLUMN_TOOL.value()) != null) { if (world.isClientSide) { WeepingSkyBlockItemClient.setSelectedColumn(null); } diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/items/package-info.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/items/package-info.java new file mode 100644 index 0000000..2206113 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/content/items/package-info.java @@ -0,0 +1,3 @@ +@javax.annotation.ParametersAreNonnullByDefault +@net.minecraft.MethodsReturnNonnullByDefault +package io.github.slimeistdev.crystalline_sky.content.items; diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/CatnipRegistry.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/CatnipRegistry.java new file mode 100644 index 0000000..8aa47df --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/CatnipRegistry.java @@ -0,0 +1,63 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import io.github.slimeistdev.crystalline_sky.foundation.registration.builder.BlockBuilder; +import io.github.slimeistdev.crystalline_sky.foundation.registration.builder.DataComponentTypeBuilder; +import io.github.slimeistdev.crystalline_sky.foundation.registration.builder.ItemBuilder; +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.BaseHolder; +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.BlockHolder; +import net.minecraft.core.Registry; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import org.jetbrains.annotations.ApiStatus; + +import java.util.function.BiFunction; +import java.util.function.Function; + +public class CatnipRegistry { + public final String modId; + + private static final Multimap, Registration> REGISTRATIONS = HashMultimap.create(); + public static final Multimap, Registration> REGISTRATIONS_VIEW = Multimaps.unmodifiableMultimap(REGISTRATIONS); + + public CatnipRegistry(String modId) { + this.modId = modId; + } + + @ApiStatus.Internal + public static > void addToRegistrationMap(Registry registry, Registration registration) { + REGISTRATIONS.put(registry, registration); + } + + public DataComponentTypeBuilder dataComponentType(String id) { + return new DataComponentTypeBuilder<>(this, id); + } + + public BlockBuilder block(String id) { + return block(id, Block::new); + } + + public BlockBuilder block(String id, Function factory) { + return new BlockBuilder<>(this, id, factory); + } + + public ItemBuilder item(String id) { + return item(id, Item::new); + } + + public ItemBuilder item(String id, Function factory) { + return new ItemBuilder<>(this, id, factory); + } + + public ItemBuilder item(BlockHolder block) { + return item(block, BlockItem::new); + } + + public ItemBuilder item(BlockHolder block, BiFunction factory) { + return new ItemBuilder<>(this, block.getRegisteredNamePath(), properties -> factory.apply(block.value(), properties)); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/Registration.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/Registration.java new file mode 100644 index 0000000..dbec23e --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/Registration.java @@ -0,0 +1,24 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration; + +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.BaseHolder; +import io.github.slimeistdev.crystalline_sky.mixin.Holder$ReferenceAccessor; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public record Registration>( + ResourceLocation id, + Registry registry, + Supplier value, + H holder, + Consumer afterRegisterCallback +) { + @SuppressWarnings("unchecked") + public void register() { + T registered = Registry.register(registry, id, value.get()); + ((Holder$ReferenceAccessor) holder).crystalline_sky$bindValue(registered); + afterRegisterCallback.accept(holder); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/RegistrationListeners.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/RegistrationListeners.java new file mode 100644 index 0000000..ffd72b0 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/RegistrationListeners.java @@ -0,0 +1,28 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration; + +import org.jetbrains.annotations.Nullable; + +import java.util.function.Consumer; + +public class RegistrationListeners { + private @Nullable T obj; + private @Nullable Consumer cons; + + public void registered(T obj) { + this.obj = obj; + if (cons != null) { + cons.accept(obj); + cons = null; + } + } + + public void addListener(Consumer consumer) { + if (obj != null) { + consumer.accept(obj); + } else if (cons == null) { + cons = consumer::accept; + } else { + cons = cons.andThen(consumer); + } + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/AbstractBuilder.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/AbstractBuilder.java new file mode 100644 index 0000000..ef96a02 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/AbstractBuilder.java @@ -0,0 +1,49 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration.builder; + +import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry; +import io.github.slimeistdev.crystalline_sky.foundation.registration.Registration; +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.BaseHolder; +import io.github.slimeistdev.crystalline_sky.multiloader.Loader; +import net.minecraft.core.HolderOwner; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Consumer; + +public abstract class AbstractBuilder> { + protected final CatnipRegistry owner; + protected final ResourceLocation id; + protected final Registry registry; + protected @Nullable H holder; + private Consumer afterRegisterCallback = h -> h.getInternalRegistrationListener().accept(h.value()); + + public AbstractBuilder(CatnipRegistry owner, String name, Registry registry) { + this.owner = owner; + this.id = ResourceLocation.fromNamespaceAndPath(owner.modId, name); + this.registry = registry; + } + + public void chainAfterRegisterCallback(Consumer callback) { + afterRegisterCallback = afterRegisterCallback.andThen(callback); + } + + abstract T build(); + + abstract H getHolder(HolderOwner owner, ResourceKey key); + + public H register() { + ResourceKey key = ResourceKey.create(registry.key(), id); + holder = getHolder(registry.holderOwner(), key); + Registration registration = new Registration<>(id, registry, this::build, holder, afterRegisterCallback); + + if (Loader.FABRIC.isCurrent()) { + registration.register(); + } else { + CatnipRegistry.addToRegistrationMap(registry, registration); + } + + return holder; + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/BlockBuilder.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/BlockBuilder.java new file mode 100644 index 0000000..efc258b --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/BlockBuilder.java @@ -0,0 +1,47 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration.builder; + +import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry; +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.BlockHolder; +import net.minecraft.core.HolderOwner; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockBehaviour.Properties; + +import java.util.function.Function; +import java.util.function.Supplier; + +public class BlockBuilder extends AbstractBuilder> { + private final Function factory; + private Supplier initialProperties = Properties::of; + private Function properties = Function.identity(); + + public BlockBuilder(CatnipRegistry owner, String name, Function factory) { + super(owner, name, BuiltInRegistries.BLOCK); + this.factory = factory; + } + + public BlockBuilder initialProperties(Supplier block) { + initialProperties = () -> Properties.ofFullCopy(block.get()); + return this; + } + + public BlockBuilder properties(Function properties) { + this.properties = this.properties.andThen(properties); + return this; + } + + @Override + T build() { + Properties properties = initialProperties.get(); + properties = this.properties.apply(properties); + return factory.apply(properties); + } + + @Override + BlockHolder getHolder(HolderOwner owner, ResourceKey key) { + //noinspection unchecked + return (BlockHolder) new BlockHolder<>(owner, key); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/DataComponentTypeBuilder.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/DataComponentTypeBuilder.java new file mode 100644 index 0000000..2e31d81 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/DataComponentTypeBuilder.java @@ -0,0 +1,46 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration.builder; + +import com.mojang.serialization.Codec; +import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry; +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.DataComponentTypeHolder; +import net.minecraft.core.HolderOwner; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceKey; + +public class DataComponentTypeBuilder extends AbstractBuilder, DataComponentType, DataComponentTypeHolder> { + private final DataComponentType.Builder builder; + + public DataComponentTypeBuilder(CatnipRegistry owner, String name) { + super(owner, name, BuiltInRegistries.DATA_COMPONENT_TYPE); + this.builder = DataComponentType.builder(); + } + + public DataComponentTypeBuilder persistent(Codec codec) { + this.builder.persistent(codec); + return this; + } + + public DataComponentTypeBuilder networkSynchronized(StreamCodec streamCodec) { + this.builder.networkSynchronized(streamCodec); + return this; + } + + public DataComponentTypeBuilder cacheEncoding() { + this.builder.cacheEncoding(); + return this; + } + + @Override + DataComponentType build() { + return builder.build(); + } + + @Override + DataComponentTypeHolder getHolder(HolderOwner> owner, ResourceKey> key) { + //noinspection rawtypes,unchecked + return new DataComponentTypeHolder((HolderOwner) owner, (ResourceKey) key); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/ItemBuilder.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/ItemBuilder.java new file mode 100644 index 0000000..071f109 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/ItemBuilder.java @@ -0,0 +1,39 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration.builder; + +import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry; +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.ItemHolder; +import net.minecraft.core.HolderOwner; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Item.Properties; + +import java.util.function.Function; + +public class ItemBuilder extends AbstractBuilder> { + private final Function factory; + private Function properties = Function.identity(); + + public ItemBuilder(CatnipRegistry owner, String name, Function factory) { + super(owner, name, BuiltInRegistries.ITEM); + this.factory = factory; + } + + public ItemBuilder properties(Function properties) { + this.properties = this.properties.andThen(properties); + return this; + } + + @Override + T build() { + Properties properties = new Properties(); + properties = this.properties.apply(properties); + return factory.apply(properties); + } + + @Override + ItemHolder getHolder(HolderOwner owner, ResourceKey key) { + //noinspection unchecked + return (ItemHolder) new ItemHolder<>(owner, key); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/package-info.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/package-info.java new file mode 100644 index 0000000..2e451f0 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/builder/package-info.java @@ -0,0 +1,5 @@ +@net.minecraft.FieldsAreNonnullByDefault +@javax.annotation.ParametersAreNonnullByDefault +@net.minecraft.MethodsReturnNonnullByDefault +package io.github.slimeistdev.crystalline_sky.foundation.registration.builder; +// Copied from IThundxr's 1.21.1/registration branch of https://github.com/Creators-of-Create/Ponder/ diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/BaseHolder.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/BaseHolder.java new file mode 100644 index 0000000..2526260 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/BaseHolder.java @@ -0,0 +1,39 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration.holder; + +import io.github.slimeistdev.crystalline_sky.foundation.registration.RegistrationListeners; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderOwner; +import net.minecraft.resources.ResourceKey; +import org.jetbrains.annotations.ApiStatus; + +import java.util.function.Consumer; + +public class BaseHolder extends Holder.Reference { + private final RegistrationListeners registrationListeners = new RegistrationListeners<>(); + + protected BaseHolder(HolderOwner owner, ResourceKey key) { + super(Type.STAND_ALONE, owner, key, null); + } + + public boolean is(V value) { + return value() == value; + } + + @ApiStatus.Internal + public Consumer getInternalRegistrationListener() { + return registrationListeners::registered; + } + + public void onRegistered(Consumer consumer) { + registrationListeners.addListener(consumer); + } + + public static Holder downcast(Holder holder) { + //noinspection unchecked + return (Holder) holder; + } + + public String getRegisteredNamePath() { + return this.unwrapKey().map((resourceKey) -> resourceKey.location().getPath()).orElse("[unregistered]"); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/BlockHolder.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/BlockHolder.java new file mode 100644 index 0000000..d7c1b17 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/BlockHolder.java @@ -0,0 +1,20 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration.holder; + +import net.minecraft.core.HolderOwner; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +public class BlockHolder extends ItemLikeHolder.NonItem { + public BlockHolder(HolderOwner owner, ResourceKey key) { + super(owner, key); + } + + public BlockState defaultBlockState() { + return value().defaultBlockState(); + } + + public boolean is(BlockState state) { + return is(state.getBlock()); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/DataComponentTypeHolder.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/DataComponentTypeHolder.java new file mode 100644 index 0000000..066539b --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/DataComponentTypeHolder.java @@ -0,0 +1,11 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration.holder; + +import net.minecraft.core.HolderOwner; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.resources.ResourceKey; + +public class DataComponentTypeHolder extends BaseHolder> { + public DataComponentTypeHolder(HolderOwner> owner, ResourceKey> key) { + super(owner, key); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/ItemHolder.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/ItemHolder.java new file mode 100644 index 0000000..ecc9552 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/ItemHolder.java @@ -0,0 +1,16 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration.holder; + +import net.minecraft.core.HolderOwner; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.item.Item; + +public class ItemHolder extends ItemLikeHolder { + public ItemHolder(HolderOwner owner, ResourceKey key) { + super(owner, key); + } + + @Override + public boolean is(Item item) { + return asItem() == item; + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/ItemLikeHolder.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/ItemLikeHolder.java new file mode 100644 index 0000000..208fc23 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/ItemLikeHolder.java @@ -0,0 +1,43 @@ +package io.github.slimeistdev.crystalline_sky.foundation.registration.holder; + +import net.minecraft.core.HolderOwner; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ItemLike; + +abstract class ItemLikeHolder extends BaseHolder implements ItemLike { + protected ItemLikeHolder(HolderOwner owner, ResourceKey key) { + super(owner, key); + } + + public ItemStack asStack() { + return new ItemStack(this); + } + + public ItemStack asStack(int count) { + return new ItemStack(this, count); + } + + public boolean is(ItemStack stack) { + return is(stack.getItem()); + } + + public abstract boolean is(Item item); + + @Override + public Item asItem() { + return value().asItem(); + } + + static class NonItem extends ItemLikeHolder { + protected NonItem(HolderOwner owner, ResourceKey key) { + super(owner, key); + } + + @Override + public boolean is(Item item) { + return asItem() == item; + } + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/package-info.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/package-info.java new file mode 100644 index 0000000..aad2ec5 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/holder/package-info.java @@ -0,0 +1,5 @@ +@net.minecraft.FieldsAreNonnullByDefault +@javax.annotation.ParametersAreNonnullByDefault +@net.minecraft.MethodsReturnNonnullByDefault +package io.github.slimeistdev.crystalline_sky.foundation.registration.holder; +// Copied from IThundxr's 1.21.1/registration branch of https://github.com/Creators-of-Create/Ponder/ diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/package-info.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/package-info.java new file mode 100644 index 0000000..f254810 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/foundation/registration/package-info.java @@ -0,0 +1,5 @@ +@net.minecraft.FieldsAreNonnullByDefault +@javax.annotation.ParametersAreNonnullByDefault +@net.minecraft.MethodsReturnNonnullByDefault +package io.github.slimeistdev.crystalline_sky.foundation.registration; +// Copied from IThundxr's 1.21.1/registration branch of https://github.com/Creators-of-Create/Ponder/ diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/Holder$ReferenceAccessor.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/Holder$ReferenceAccessor.java new file mode 100644 index 0000000..3545d94 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/Holder$ReferenceAccessor.java @@ -0,0 +1,16 @@ +package io.github.slimeistdev.crystalline_sky.mixin; + +import net.minecraft.core.Holder; +import net.minecraft.core.HolderOwner; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(Holder.Reference.class) +public interface Holder$ReferenceAccessor { + @Accessor("owner") + HolderOwner crystalline_sky$getOwner(); + + @Invoker("bindValue") + void crystalline_sky$bindValue(T value); +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/ClientLevelMixin.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/ClientLevelMixin.java index bfea28f..cfaa1e2 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/ClientLevelMixin.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/ClientLevelMixin.java @@ -24,9 +24,9 @@ public class ClientLevelMixin { @Inject(method = "", at = @At("RETURN")) private static void modifyBlockMarkerItems(CallbackInfo ci) { MARKER_PARTICLE_ITEMS = new HashSet<>(MARKER_PARTICLE_ITEMS); - MARKER_PARTICLE_ITEMS.add(CrystallineItems.SKY_LIGHT); - MARKER_PARTICLE_ITEMS.add(CrystallineItems.WEEPING_SKY_LIGHT); - MARKER_PARTICLE_ITEMS.add(CrystallineItems.SKY); - MARKER_PARTICLE_ITEMS.add(CrystallineItems.WEEPING_SKY); + MARKER_PARTICLE_ITEMS.add(CrystallineItems.SKY_LIGHT.value()); + MARKER_PARTICLE_ITEMS.add(CrystallineItems.WEEPING_SKY_LIGHT.value()); + MARKER_PARTICLE_ITEMS.add(CrystallineItems.SKY.value()); + MARKER_PARTICLE_ITEMS.add(CrystallineItems.WEEPING_SKY.value()); } } diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/LevelRenderer_NoSodium_Mixin.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/LevelRenderer_NoSodium_Mixin.java index faf01c8..930e9c5 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/LevelRenderer_NoSodium_Mixin.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/LevelRenderer_NoSodium_Mixin.java @@ -39,10 +39,8 @@ public class LevelRenderer_NoSodium_Mixin { if (renderLayer == CrystallineRenderTypes.SKY && instance.COLOR_MODULATOR != null && minecraft.player != null - && (minecraft.player.getMainHandItem().is(CrystallineItems.SKY) - || minecraft.player.getOffhandItem().is(CrystallineItems.SKY) - || minecraft.player.getMainHandItem().is(CrystallineItems.WEEPING_SKY) - || minecraft.player.getOffhandItem().is(CrystallineItems.WEEPING_SKY))) { + && (CrystallineItems.isSky(minecraft.player.getMainHandItem()) + || CrystallineItems.isSky(minecraft.player.getOffhandItem()))) { float f = ticks + minecraft.getTimer().getGameTimeDeltaPartialTick(true); float alpha = (Mth.sin(f / 10.0f) + 1.0f) / 2.0f; diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/ItemGroupRegistrationEvent.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/ItemGroupRegistrationEvent.java new file mode 100644 index 0000000..8667120 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/ItemGroupRegistrationEvent.java @@ -0,0 +1,14 @@ +package io.github.slimeistdev.crystalline_sky.multiloader; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ItemLike; + +import java.util.List; + +public interface ItemGroupRegistrationEvent { + ResourceKey getTab(); + boolean hasPermissions(); + void addAfter(ItemLike reference, List stacks); +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/Loader.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/Loader.java new file mode 100644 index 0000000..d6eae71 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/Loader.java @@ -0,0 +1,60 @@ +/* + * Steam 'n' Rails + * Copyright (c) 2022-2024 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 . + */ + +package io.github.slimeistdev.crystalline_sky.multiloader; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import io.github.slimeistdev.crystalline_sky.compat.Mods; +import io.github.slimeistdev.crystalline_sky.util.TextUtils; +import org.jetbrains.annotations.ApiStatus.Internal; + +import java.util.Locale; +import java.util.function.Supplier; + +public enum Loader { + NEOFORGE, FABRIC, QUILT; + + public static final Loader CURRENT = getCurrent(); + + public boolean isCurrent() { + return this == CURRENT; + } + + public void runIfCurrent(Supplier run) { + if (isCurrent()) + run.get().run(); + } + + public static String getFormatted() { + return TextUtils.titleCaseConversion(getActual().name().toLowerCase(Locale.ROOT)); + } + + // Returns the actual loader, ex: quilt on quilt instead of fabric for quilt + public static Loader getActual() { + //noinspection ConstantValue + if (FABRIC.isCurrent() && Mods.isModLoaded("quilt_loader")) + return QUILT; + return CURRENT; + } + + @Internal + @ExpectPlatform + private static Loader getCurrent() { + throw new AssertionError(); + } +} diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineBlocks.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineBlocks.java index 0f5ce12..6b6e6e3 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineBlocks.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineBlocks.java @@ -1,76 +1,63 @@ package io.github.slimeistdev.crystalline_sky.registry; import io.github.slimeistdev.crystalline_sky.CrystallineSky; +import io.github.slimeistdev.crystalline_sky.content.blocks.SkyBlock; import io.github.slimeistdev.crystalline_sky.content.blocks.SkyLightBlock; import io.github.slimeistdev.crystalline_sky.content.blocks.WeepingSkyLightBlock; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; +import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry; +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.BlockHolder; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.LightBlock; -import net.minecraft.world.level.block.TransparentBlock; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockBehaviour.Properties; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; -import net.minecraft.core.registries.Registries; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.material.MapColor; -import java.util.function.Function; - @SuppressWarnings("SameParameterValue") public class CrystallineBlocks { - public static final Block SKY = register("sky", TransparentBlock::new, Properties.of() - .strength(0.3f) - .sound(SoundType.AMETHYST) - .noOcclusion() - .isValidSpawn(Blocks::never) - .isRedstoneConductor(Blocks::never) - .isSuffocating(Blocks::never) - .isViewBlocking(Blocks::never) - .emissiveRendering(Blocks::always)); + private static final CatnipRegistry REGISTRY = CrystallineSky.registry(); - public static final Block WEEPING_SKY = register("weeping_sky", TransparentBlock::new, Properties.ofFullCopy(SKY)); + public static final BlockHolder SKY = REGISTRY.block("sky", SkyBlock::new) + .properties(p -> p + .strength(0.3f) + .sound(SoundType.AMETHYST) + .noOcclusion() + .isValidSpawn(CrystallineBlocks::never) + .isRedstoneConductor(CrystallineBlocks::never) + .isSuffocating(CrystallineBlocks::never) + .isViewBlocking(CrystallineBlocks::never) + .emissiveRendering(CrystallineBlocks::always)) + .register(); - public static final Block SKY_LIGHT = register( - "sky_light", - SkyLightBlock::new, - BlockBehaviour.Properties.of() + public static final BlockHolder WEEPING_SKY = REGISTRY.block("weeping_sky", SkyBlock::new) + .initialProperties(SKY::value) + .register(); + + public static final BlockHolder SKY_LIGHT = REGISTRY.block("sky_light", SkyLightBlock::new) + .properties(p -> p .replaceable() .strength(-1.0F, 3600000.8F) - .mapColor(state -> state.getValue(BlockStateProperties.WATERLOGGED) ? MapColor.WATER : MapColor.NONE) + .mapColor(CrystallineBlocks::waterloggedColor) .noLootTable() - .noOcclusion() - ); + .noOcclusion()) + .register(); - public static final Block WEEPING_SKY_LIGHT = register( - "weeping_sky_light", - WeepingSkyLightBlock::new, - BlockBehaviour.Properties.of() - .replaceable() - .strength(-1.0F, 3600000.8F) - .mapColor(state -> state.getValue(BlockStateProperties.WATERLOGGED) ? MapColor.WATER : MapColor.NONE) - .noLootTable() - .noOcclusion() - ); + public static final BlockHolder WEEPING_SKY_LIGHT = REGISTRY.block("weeping_sky_light", WeepingSkyLightBlock::new) + .initialProperties(SKY_LIGHT::value) + .register(); public static void init() {} - private static T register(String id, Function factory, Properties settings) { - ResourceKey key = CrystallineSky.key(Registries.BLOCK, id); - return Registry.register(BuiltInRegistries.BLOCK, key, factory.apply(settings)); - } - public static boolean isCrystallineSky(BlockState state) { return getSkyLightLevel(state) > 0; } public static int getSkyLightLevel(BlockState state) { - if (state.is(SKY_LIGHT)) { + if (SKY_LIGHT.is(state)) { return state.getValue(LightBlock.LEVEL); - } else if (state.is(SKY)) { // weeping sky explicitly excluded, that's handled differently + } else if (SKY.is(state)) { // weeping sky explicitly excluded, that's handled differently return 15; } @@ -78,6 +65,26 @@ public class CrystallineBlocks { } public static boolean isWeepingSky(BlockState state) { - return state.is(WEEPING_SKY) || state.is(WEEPING_SKY_LIGHT); + return WEEPING_SKY.is(state) || WEEPING_SKY_LIGHT.is(state); + } + + private static Boolean never(BlockState state, BlockGetter blockGetter, BlockPos pos, EntityType entity) { + return false; + } + + private static Boolean always(BlockState state, BlockGetter blockGetter, BlockPos pos, EntityType entity) { + return true; + } + + private static boolean always(BlockState state, BlockGetter blockGetter, BlockPos pos) { + return true; + } + + private static boolean never(BlockState state, BlockGetter blockGetter, BlockPos pos) { + return false; + } + + private static MapColor waterloggedColor(BlockState state) { + return state.getValue(BlockStateProperties.WATERLOGGED) ? MapColor.WATER : MapColor.NONE; } } diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineDataComponentTypes.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineDataComponentTypes.java index 955fb32..80b0ac9 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineDataComponentTypes.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineDataComponentTypes.java @@ -1,26 +1,19 @@ package io.github.slimeistdev.crystalline_sky.registry; import io.github.slimeistdev.crystalline_sky.CrystallineSky; -import net.minecraft.core.component.DataComponentType; +import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry; +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.DataComponentTypeHolder; import net.minecraft.network.codec.StreamCodec; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.Registry; import net.minecraft.util.Unit; -import java.util.function.UnaryOperator; - public class CrystallineDataComponentTypes { - public static final DataComponentType WEEPING_SKY_DEBUG_COLUMN_TOOL = register( - "weeping_sky_debug_column_tool", - b -> b + private static final CatnipRegistry REGISTRY = CrystallineSky.registry(); + + public static final DataComponentTypeHolder WEEPING_SKY_DEBUG_COLUMN_TOOL = + REGISTRY.dataComponentType("weeping_sky_debug_column_tool") .networkSynchronized(StreamCodec.unit(Unit.INSTANCE)) .persistent(Unit.CODEC) - ); - - @SuppressWarnings("SameParameterValue") - private static DataComponentType register(String id, UnaryOperator> builderOperator) { - return Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, CrystallineSky.id(id), builderOperator.apply(DataComponentType.builder()).build()); - } + .register(); public static void init() {} } diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineItems.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineItems.java index b6e0cf1..a7306fa 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineItems.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/CrystallineItems.java @@ -1,54 +1,54 @@ package io.github.slimeistdev.crystalline_sky.registry; +import io.github.slimeistdev.crystalline_sky.CrystallineSky; import io.github.slimeistdev.crystalline_sky.content.blocks.SkyLightBlock; import io.github.slimeistdev.crystalline_sky.content.items.WeepingSkyBlockItem; -import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LightBlock; +import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry; +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.ItemHolder; +import io.github.slimeistdev.crystalline_sky.multiloader.ItemGroupRegistrationEvent; import net.minecraft.core.component.DataComponents; -import net.minecraft.world.item.component.BlockItemStateProperties; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.CreativeModeTabs; +import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.Rarity; +import net.minecraft.world.item.component.BlockItemStateProperties; +import net.minecraft.world.level.block.LightBlock; import java.util.ArrayList; import java.util.List; -import java.util.function.BiFunction; public class CrystallineItems { - public static final Item SKY = Items.registerBlock( - CrystallineBlocks.SKY, - settings -> settings.rarity(Rarity.EPIC) - ); + private static final CatnipRegistry REGISTRY = CrystallineSky.registry(); - public static final Item WEEPING_SKY = register( - CrystallineBlocks.WEEPING_SKY, - (block, settings) -> new WeepingSkyBlockItem(block, settings.rarity(Rarity.EPIC)) - ); + public static final ItemHolder SKY = REGISTRY.item(CrystallineBlocks.SKY) + .properties(p -> p.rarity(Rarity.EPIC)) + .register(); - public static final Item SKY_LIGHT = Items.registerBlock( - CrystallineBlocks.SKY_LIGHT, - settings -> settings.rarity(Rarity.EPIC) - .component(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY.with(LightBlock.LEVEL, 15)) - ); + public static final ItemHolder WEEPING_SKY = REGISTRY.item(CrystallineBlocks.WEEPING_SKY, WeepingSkyBlockItem::new) + .properties(p -> p.rarity(Rarity.EPIC)) + .register(); - public static final Item WEEPING_SKY_LIGHT = Items.registerBlock( - CrystallineBlocks.WEEPING_SKY_LIGHT, - settings -> settings.rarity(Rarity.EPIC) - ); + public static final ItemHolder SKY_LIGHT = REGISTRY.item(CrystallineBlocks.SKY_LIGHT) + .properties(p -> p + .rarity(Rarity.EPIC) + .component(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY.with(LightBlock.LEVEL, 15))) + .register(); + + public static final ItemHolder WEEPING_SKY_LIGHT = REGISTRY.item(CrystallineBlocks.WEEPING_SKY_LIGHT) + .properties(p -> p.rarity(Rarity.EPIC)) + .register(); @SuppressWarnings("SameParameterValue") - private static Item register(Block block, BiFunction factory) { - return Items.registerBlock(factory.apply(block, new Item.Properties())); + private static ResourceKey tabKey(String name) { + return ResourceKey.create(Registries.CREATIVE_MODE_TAB, ResourceLocation.withDefaultNamespace(name)); } - public static void init() { - ItemGroupEvents.modifyEntriesEvent(CreativeModeTabs.OP_BLOCKS).register(entries -> { - if (!entries.getContext().hasPermissions()) return; - + public static void onItemGroupRegistration(ItemGroupRegistrationEvent event) { + if (event.getTab().equals(tabKey("op_blocks")) && event.hasPermissions()) { List stacks = new ArrayList<>(); stacks.add(new ItemStack(SKY)); @@ -60,7 +60,13 @@ public class CrystallineItems { stacks.add(new ItemStack(WEEPING_SKY_LIGHT)); - entries.addAfter(Items.LIGHT, stacks); - }); + event.addAfter(Items.LIGHT, stacks); + } + } + + public static void init() {} + + public static boolean isSky(ItemStack stack) { + return SKY.is(stack) || WEEPING_SKY.is(stack); } } diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/client/CrystallineRenderTypes.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/client/CrystallineRenderTypes.java index fd04d3e..2521635 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/client/CrystallineRenderTypes.java +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/registry/client/CrystallineRenderTypes.java @@ -1,21 +1,18 @@ package io.github.slimeistdev.crystalline_sky.registry.client; import com.mojang.blaze3d.systems.RenderSystem; -import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.RenderType_Duck; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.VertexFormat; import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.LevelRenderer_Duck; +import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.RenderType_Duck; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderStateShard; -import com.mojang.blaze3d.vertex.VertexFormat; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; - -import static net.minecraft.client.renderer.RenderType.create; -import static net.minecraft.client.renderer.RenderStateShard.LIGHTMAP; +import net.minecraft.client.renderer.RenderType; @Environment(EnvType.CLIENT) -public class CrystallineRenderTypes { +public abstract class CrystallineRenderTypes extends RenderType { private static final RenderStateShard.EmptyTextureStateShard SKY_TEXTURE = new SkyBufferTexture(); private static final RenderStateShard.ShaderStateShard SKY_PROGRAM = new RenderStateShard.ShaderStateShard(CrystallineShaderInstances::getRenderTypeSkyProgram); @@ -38,6 +35,10 @@ public class CrystallineRenderTypes { ((RenderType_Duck) SKY).crystalline_sky$markAsBlockLayer(); } + private CrystallineRenderTypes(String name, VertexFormat format, VertexFormat.Mode mode, int bufferSize, boolean affectsCrumbling, boolean sortOnUpload, Runnable setupState, Runnable clearState) { + super(name, format, mode, bufferSize, affectsCrumbling, sortOnUpload, setupState, clearState); + } + private static class SkyBufferTexture extends RenderStateShard.EmptyTextureStateShard { public SkyBufferTexture() { super(() -> { diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/util/TextUtils.java b/common/src/main/java/io/github/slimeistdev/crystalline_sky/util/TextUtils.java new file mode 100644 index 0000000..87b7f03 --- /dev/null +++ b/common/src/main/java/io/github/slimeistdev/crystalline_sky/util/TextUtils.java @@ -0,0 +1,107 @@ +/* + * Steam 'n' Rails + * Copyright (c) 2022-2026 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 . + */ + +package io.github.slimeistdev.crystalline_sky.util; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.Style; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Locale; +import java.util.Optional; +import java.util.stream.Stream; + +public class TextUtils { + public static String snakeCaseToTitleCase(String inputString) { + return titleCaseConversion(inputString.replace("_", " ")); + } + + public static String titleCaseConversion(String inputString) { + if (StringUtils.isBlank(inputString)) { + return ""; + } + + if (StringUtils.length(inputString) == 1) { + return inputString.toUpperCase(Locale.ROOT); + } + + StringBuffer resultPlaceHolder = new StringBuffer(inputString.length()); + + Stream.of(inputString.split(" ")).forEach(stringPart -> { + if (stringPart.length() > 1) + resultPlaceHolder.append(stringPart.substring(0, 1) + .toUpperCase(Locale.ROOT)) + .append(stringPart.substring(1) + .toLowerCase(Locale.ROOT)); + else + resultPlaceHolder.append(stringPart.toUpperCase(Locale.ROOT)); + + resultPlaceHolder.append(" "); + }); + return StringUtils.trim(resultPlaceHolder.toString()); + } + + public static Component translateWithFormatting(String key, Object... args) { + MutableComponent base = Component.translatable(key, args); + StringBuilder partsStringBuilder = new StringBuilder(); + base.visit((style, part) -> { + partsStringBuilder.append(part); + return Optional.empty(); + }, Style.EMPTY); + return Component.literal(partsStringBuilder.toString()); + } + + public static String joinSpace(@Nullable String... strings) { + return join(" ", strings); + } + + public static String joinUnderscore(@Nullable String... strings) { + return join("_", strings); + } + + public static String join(final String separator, final @Nullable String... strings) { + String[] filtered = Stream.of(strings).filter(s -> s != null && !s.isEmpty()).toArray(String[]::new); + StringBuilder out = new StringBuilder(); + for (int i = 0; i < filtered.length; i++) { + out.append(filtered[i]); + if (i < filtered.length - 1) out.append(separator); + } + return out.toString(); + } + + public static String stripPrefix(String string, String prefix) { + if (string.startsWith(prefix)) { + return string.substring(prefix.length()); + } + return string; + } + + public static String ensureEndsWith(String string, String suffix) { + if (!string.endsWith(suffix)) { + return string + suffix; + } + return string; + } + + public static String prefixToFolder(String name, @NotNull String prefix) { + return prefix + "/" + stripPrefix(name, ensureEndsWith(prefix, "_")); + } +} diff --git a/common/src/main/resources/crystalline_sky-common.mixins.json b/common/src/main/resources/crystalline_sky-common.mixins.json index 8421ea7..892cd81 100644 --- a/common/src/main/resources/crystalline_sky-common.mixins.json +++ b/common/src/main/resources/crystalline_sky-common.mixins.json @@ -8,20 +8,20 @@ "plugin": "io.github.slimeistdev.crystalline_sky.mixin.CrystallineSkyMixinPlugin", "compatibilityLevel": "JAVA_21", "mixins": [ - "LightEngineMixin", "ChunkSkyLightSourcesMixin", - "SkyLightEngineMixin", + "Holder$ReferenceAccessor", "LayerLightSectionStorageAccessor", + "LightEngineMixin", + "SkyLightEngineMixin", "SkyLightSectionStorageAccessor" ], "client": [ "client.ClientLevelMixin", "client.DebugRendererMixin", - "client.RenderTargetMixin", "client.GameRendererMixin", "client.LevelRenderer_NoSodium_Mixin", "client.LevelRendererMixin", - "client.compat.axiom.ChunkRenderOverrider_AxiomChunkOverrideLayerMixin", + "client.RenderTargetMixin", "client.compat.sodium.DefaultMaterialsMixin", "client.compat.sodium.DefaultTerrainRenderPassesMixin", "client.compat.sodium.ShaderChunkRendererMixin", diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index b6153d3..83c750a 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -10,9 +10,9 @@ loom { client() name = "Minecraft Data" - vmArg("-Dfabric-api.data") + vmArg("-Dfabric-api.datagen") vmArg("-Dfabric-api.datagen.output-dir=${common.file("src/generated/resources")}") - vmArg("-Dfabric-api.datagen.modid=${"slug"()}") + vmArg("-Dfabric-api.datagen.modid=${"modId"()}") environmentVariable("DATAGEN", "TRUE") } diff --git a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/compat/fabric/ModsImpl.java b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/compat/fabric/ModsImpl.java new file mode 100644 index 0000000..35783d4 --- /dev/null +++ b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/compat/fabric/ModsImpl.java @@ -0,0 +1,11 @@ +package io.github.slimeistdev.crystalline_sky.compat.fabric; + +import io.github.slimeistdev.crystalline_sky.annotation.multiloader.ImplClass; +import net.fabricmc.loader.api.FabricLoader; + +@ImplClass +public class ModsImpl { + public static boolean isModLoaded(String id) { + return FabricLoader.getInstance().isModLoaded(id); + } +} diff --git a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/CrystallineSkyClientImpl.java b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/CrystallineSkyClientImpl.java index 9bfc345..14a5263 100644 --- a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/CrystallineSkyClientImpl.java +++ b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/CrystallineSkyClientImpl.java @@ -1,6 +1,7 @@ package io.github.slimeistdev.crystalline_sky.fabric; import io.github.slimeistdev.crystalline_sky.CrystallineSkyClient; +import io.github.slimeistdev.crystalline_sky.multiloader.fabric.ItemGroupRegistrationEventImpl; import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderTypes; import net.fabricmc.api.ClientModInitializer; @@ -9,6 +10,9 @@ 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.world.level.block.Block; + +import java.util.function.Consumer; @Environment(EnvType.CLIENT) public class CrystallineSkyClientImpl implements ClientModInitializer { @@ -16,9 +20,11 @@ public class CrystallineSkyClientImpl implements ClientModInitializer { public void onInitializeClient() { CrystallineSkyClient.init(); CrystallineSkyClient.registerKeybindings(KeyBindingHelper::registerKeyBinding); + ItemGroupRegistrationEventImpl.register(); - BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.SKY, CrystallineRenderTypes.SKY); - BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.WEEPING_SKY, CrystallineRenderTypes.SKY); + Consumer makeSky = b -> BlockRenderLayerMap.INSTANCE.putBlock(b, CrystallineRenderTypes.SKY); + CrystallineBlocks.SKY.onRegistered(makeSky); + CrystallineBlocks.WEEPING_SKY.onRegistered(makeSky); ClientTickEvents.END_CLIENT_TICK.register(CrystallineSkyClient::onEndTick); } diff --git a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyBlockTagProvider.java b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyBlockTagProvider.java index 6a5f5f4..6560a10 100644 --- a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyBlockTagProvider.java +++ b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyBlockTagProvider.java @@ -1,13 +1,16 @@ package io.github.slimeistdev.crystalline_sky.fabric.datagen.providers; import io.github.slimeistdev.crystalline_sky.CrystallineSky; +import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.BaseHolder; import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; -import net.minecraft.core.registries.Registries; +import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; import net.minecraft.tags.BlockTags; import net.minecraft.tags.TagKey; +import net.minecraft.world.level.block.Block; import java.util.concurrent.CompletableFuture; @@ -18,14 +21,25 @@ public class CrystallineSkyBlockTagProvider extends FabricTagProvider.BlockTagPr @Override protected void addTags(HolderLookup.Provider wrapperLookup) { - getOrCreateTagBuilder(TagKey.create(Registries.BLOCK, CrystallineSky.id("sky_light_emitters"))) + builder(TagKey.create(Registries.BLOCK, CrystallineSky.id("sky_light_emitters"))) .add(CrystallineBlocks.SKY) .add(CrystallineBlocks.SKY_LIGHT) .add(CrystallineBlocks.WEEPING_SKY) .add(CrystallineBlocks.WEEPING_SKY_LIGHT); - getOrCreateTagBuilder(BlockTags.CRYSTAL_SOUND_BLOCKS) + builder(BlockTags.CRYSTAL_SOUND_BLOCKS) .add(CrystallineBlocks.SKY) .add(CrystallineBlocks.WEEPING_SKY); } + + private TagBuilder builder(TagKey tag) { + return new TagBuilder<>(getOrCreateTagBuilder(tag)); + } + + private record TagBuilder(FabricTagProvider.FabricTagBuilder wrapped) { + public TagBuilder add(Holder object) { + BaseHolder.downcast(object).unwrap().map(wrapped::add, wrapped::add); + return this; + } + } } diff --git a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyLootProvider.java b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyLootProvider.java index fd677a4..ae099b1 100644 --- a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyLootProvider.java +++ b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyLootProvider.java @@ -14,7 +14,7 @@ public class CrystallineSkyLootProvider extends FabricBlockLootTableProvider { @Override public void generate() { - dropWhenSilkTouch(CrystallineBlocks.SKY); - dropWhenSilkTouch(CrystallineBlocks.WEEPING_SKY); + dropWhenSilkTouch(CrystallineBlocks.SKY.value()); + dropWhenSilkTouch(CrystallineBlocks.WEEPING_SKY.value()); } } diff --git a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyModelProvider.java b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyModelProvider.java index 21c1784..08a1e28 100644 --- a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyModelProvider.java +++ b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/datagen/providers/CrystallineSkyModelProvider.java @@ -32,12 +32,12 @@ public class CrystallineSkyModelProvider extends FabricModelProvider { @Override public void generateBlockStateModels(BlockModelGenerators gen) { - registerSkyBlock(gen, CrystallineBlocks.SKY); - registerSkyBlock(gen, CrystallineBlocks.WEEPING_SKY); - registerSkyLightBlock(gen, CrystallineBlocks.SKY_LIGHT, CrystallineItems.SKY_LIGHT); + registerSkyBlock(gen, CrystallineBlocks.SKY.value()); + registerSkyBlock(gen, CrystallineBlocks.WEEPING_SKY.value()); + registerSkyLightBlock(gen, CrystallineBlocks.SKY_LIGHT.value(), CrystallineItems.SKY_LIGHT.value()); - gen.createAirLikeBlock(CrystallineBlocks.WEEPING_SKY_LIGHT, CrystallineItems.WEEPING_SKY_LIGHT); - gen.createSimpleFlatItemModel(CrystallineItems.WEEPING_SKY_LIGHT); + gen.createAirLikeBlock(CrystallineBlocks.WEEPING_SKY_LIGHT.value(), CrystallineItems.WEEPING_SKY_LIGHT.value()); + gen.createSimpleFlatItemModel(CrystallineItems.WEEPING_SKY_LIGHT.value()); } private void registerSkyBlock(BlockModelGenerators gen, Block block) { diff --git a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/axiom/ChunkRenderOverrider_AxiomChunkOverrideLayerMixin.java b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/mixin/client/compat/axiom/ChunkRenderOverrider_AxiomChunkOverrideLayerMixin.java similarity index 92% rename from common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/axiom/ChunkRenderOverrider_AxiomChunkOverrideLayerMixin.java rename to fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/mixin/client/compat/axiom/ChunkRenderOverrider_AxiomChunkOverrideLayerMixin.java index 78064da..a301106 100644 --- a/common/src/main/java/io/github/slimeistdev/crystalline_sky/mixin/client/compat/axiom/ChunkRenderOverrider_AxiomChunkOverrideLayerMixin.java +++ b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/fabric/mixin/client/compat/axiom/ChunkRenderOverrider_AxiomChunkOverrideLayerMixin.java @@ -1,4 +1,4 @@ -package io.github.slimeistdev.crystalline_sky.mixin.client.compat.axiom; +package io.github.slimeistdev.crystalline_sky.fabric.mixin.client.compat.axiom; import com.moulberry.axiom.render.ChunkRenderOverrider; import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin; diff --git a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/fabric/ItemGroupRegistrationEventImpl.java b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/fabric/ItemGroupRegistrationEventImpl.java new file mode 100644 index 0000000..2d76f0b --- /dev/null +++ b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/fabric/ItemGroupRegistrationEventImpl.java @@ -0,0 +1,47 @@ +package io.github.slimeistdev.crystalline_sky.multiloader.fabric; + +import io.github.slimeistdev.crystalline_sky.multiloader.ItemGroupRegistrationEvent; +import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems; +import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroupEntries; +import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ItemLike; + +import java.util.List; + +public class ItemGroupRegistrationEventImpl implements ItemGroupRegistrationEvent { + private final ResourceKey tab; + private final FabricItemGroupEntries entries; + + public ItemGroupRegistrationEventImpl(ResourceKey tab, FabricItemGroupEntries entries) { + this.tab = tab; + this.entries = entries; + } + + @Override + public ResourceKey getTab() { + return tab; + } + + @Override + public boolean hasPermissions() { + return entries.getContext().hasPermissions(); + } + + @Override + public void addAfter(ItemLike reference, List stacks) { + entries.addAfter(reference, stacks); + } + + public static void register() { + ItemGroupEvents.MODIFY_ENTRIES_ALL.register((tab, entries) -> { + CrystallineItems.onItemGroupRegistration(new ItemGroupRegistrationEventImpl( + BuiltInRegistries.CREATIVE_MODE_TAB.getResourceKey(tab).orElseThrow(), + entries + )); + }); + } +} diff --git a/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/fabric/LoaderImpl.java b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/fabric/LoaderImpl.java new file mode 100644 index 0000000..864581c --- /dev/null +++ b/fabric/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/fabric/LoaderImpl.java @@ -0,0 +1,13 @@ +package io.github.slimeistdev.crystalline_sky.multiloader.fabric; + +import io.github.slimeistdev.crystalline_sky.annotation.multiloader.ImplClass; +import io.github.slimeistdev.crystalline_sky.multiloader.Loader; +import org.jetbrains.annotations.ApiStatus.Internal; + +@ImplClass +public class LoaderImpl { + @Internal + public static Loader getCurrent() { + return Loader.FABRIC; + } +} diff --git a/fabric/src/main/resources/crystalline_sky.mixins.json b/fabric/src/main/resources/crystalline_sky.mixins.json index 91d844e..cbb1742 100644 --- a/fabric/src/main/resources/crystalline_sky.mixins.json +++ b/fabric/src/main/resources/crystalline_sky.mixins.json @@ -10,7 +10,8 @@ "mixins": [ ], "client": [ - "client.RenderTypeMixin" + "client.RenderTypeMixin", + "client.compat.axiom.ChunkRenderOverrider_AxiomChunkOverrideLayerMixin" ], "server": [ ], diff --git a/libs.versions.toml b/libs.versions.toml index 88f07ea..d3c3317 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -9,6 +9,7 @@ parchment = "2024.11.17" fl = "0.18.6" fapi = "0.116.10+1.21.1" nf = "21.1.215" +jsr305 = "3.0.2" mixinextras = "0.5.0" mm = "11.0.4" sodium-fabric = "mc1.21.1-0.6.13-fabric" @@ -34,6 +35,8 @@ fapi = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = " nf = { group = "net.neoforged", name = "neoforge", version.ref = "nf" } +jsr305 = { group = "com.google.code.findbugs", name = "jsr305", version.ref = "jsr305" } + mixinextras-common = { group = "io.github.llamalad7", name = "mixinextras-common", version.ref = "mixinextras" } mixinextras-fabric = { group = "io.github.llamalad7", name = "mixinextras-fabric", version.ref = "mixinextras" } mixinextras-neoforge = { group = "io.github.llamalad7", name = "mixinextras-neoforge", version.ref = "mixinextras" } diff --git a/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/compat/neoforge/ModsImpl.java b/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/compat/neoforge/ModsImpl.java new file mode 100644 index 0000000..da86fb4 --- /dev/null +++ b/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/compat/neoforge/ModsImpl.java @@ -0,0 +1,20 @@ +package io.github.slimeistdev.crystalline_sky.compat.neoforge; + +import io.github.slimeistdev.crystalline_sky.annotation.multiloader.ImplClass; +import net.neoforged.fml.loading.LoadingModList; +import net.neoforged.fml.loading.moddiscovery.ModInfo; + +import java.util.List; + +@ImplClass +public class ModsImpl { + public static boolean isModLoaded(String id) { + List mods = LoadingModList.get().getMods(); + for (ModInfo mod : mods) { + if (mod.getModId().equals(id)) { + return true; + } + } + return false; + } +} diff --git a/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/neoforge/ItemGroupRegistrationEventImpl.java b/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/neoforge/ItemGroupRegistrationEventImpl.java new file mode 100644 index 0000000..f2d0dcd --- /dev/null +++ b/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/neoforge/ItemGroupRegistrationEventImpl.java @@ -0,0 +1,6 @@ +package io.github.slimeistdev.crystalline_sky.multiloader.neoforge; + +public class ItemGroupRegistrationEventImpl { + public static void create() { + } +} diff --git a/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/neoforge/LoaderImpl.java b/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/neoforge/LoaderImpl.java new file mode 100644 index 0000000..95a9b5b --- /dev/null +++ b/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/multiloader/neoforge/LoaderImpl.java @@ -0,0 +1,13 @@ +package io.github.slimeistdev.crystalline_sky.multiloader.neoforge; + +import io.github.slimeistdev.crystalline_sky.annotation.multiloader.ImplClass; +import io.github.slimeistdev.crystalline_sky.multiloader.Loader; +import org.jetbrains.annotations.ApiStatus.Internal; + +@ImplClass +public class LoaderImpl { + @Internal + public static Loader getCurrent() { + return Loader.NEOFORGE; + } +} diff --git a/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/neoforge/CrystallineSkyClientImpl.java b/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/neoforge/CrystallineSkyClientImpl.java index e6e9dfb..e2d5801 100644 --- a/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/neoforge/CrystallineSkyClientImpl.java +++ b/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/neoforge/CrystallineSkyClientImpl.java @@ -5,12 +5,15 @@ 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.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.CreativeModeTabs; 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; +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; @EventBusSubscriber(value = Dist.CLIENT, modid = CrystallineSky.ID) public class CrystallineSkyClientImpl { @@ -33,4 +36,9 @@ public class CrystallineSkyClientImpl { public static void onEndTick(ClientTickEvent.Post event) { CrystallineSkyClient.onEndTick(Minecraft.getInstance()); } + + @SubscribeEvent + public static void buildCreativeModeTabContents(BuildCreativeModeTabContentsEvent event) { + event.insertAfter(); + } } diff --git a/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/neoforge/CrystallineSkyImpl.java b/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/neoforge/CrystallineSkyImpl.java index 41c68fb..fd37487 100644 --- a/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/neoforge/CrystallineSkyImpl.java +++ b/neoforge/src/main/java/io/github/slimeistdev/crystalline_sky/neoforge/CrystallineSkyImpl.java @@ -2,11 +2,16 @@ package io.github.slimeistdev.crystalline_sky.neoforge; import io.github.slimeistdev.crystalline_sky.CrystallineSky; import io.github.slimeistdev.crystalline_sky.multiloader.Env; +import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; @Mod(CrystallineSky.ID) public class CrystallineSkyImpl { - public CrystallineSkyImpl() { + static IEventBus bus; + + public CrystallineSkyImpl(IEventBus bus) { + CrystallineSkyImpl.bus = bus; + CrystallineSky.init(); //noinspection Convert2MethodRef Env.CLIENT.runIfCurrent(() -> () -> CrystallineSkyClientImpl.init());