Multiloader V

fabric is working
This commit is contained in:
techno-sam
2026-04-16 10:49:24 +02:00
parent b4355e8fd8
commit d4b8894a3b
53 changed files with 983 additions and 169 deletions
+2 -1
View File
@@ -14,7 +14,8 @@ 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)
compileOnly(libs.jsr305)
modCompileOnly(libs.sodium.fabric) modCompileOnly(libs.sodium.fabric)
@@ -1,14 +1,17 @@
package io.github.slimeistdev.crystalline_sky; package io.github.slimeistdev.crystalline_sky;
import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.ApiStatus;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class CrystallineSky { public class CrystallineSky {
public static final String ID = "crystalline_sky"; public static final String ID = "crystalline_sky";
public static final Logger LOG = LoggerFactory.getLogger(ID); public static final Logger LOG = LoggerFactory.getLogger(ID);
private static final CatnipRegistry REGISTRY = new CatnipRegistry(ID);
public static void init() { public static void init() {
ModSetup.init(); ModSetup.init();
@@ -21,4 +24,9 @@ public class CrystallineSky {
public static <T> ResourceKey<T> key(ResourceKey<? extends Registry<T>> registryKey, String path) { public static <T> ResourceKey<T> key(ResourceKey<? extends Registry<T>> registryKey, String path) {
return ResourceKey.create(registryKey, id(path)); return ResourceKey.create(registryKey, id(path));
} }
@ApiStatus.Internal
public static CatnipRegistry registry() {
return REGISTRY;
}
} }
@@ -31,7 +31,7 @@ public class CrystallineSkyClient {
public static void init() { public static void init() {
ClientPlatformHelper.registerItemProperty( ClientPlatformHelper.registerItemProperty(
CrystallineItems.SKY_LIGHT, CrystallineItems.SKY_LIGHT.value(),
ResourceLocation.withDefaultNamespace("level"), ResourceLocation.withDefaultNamespace("level"),
(stack, world, entity, seed) -> { (stack, world, entity, seed) -> {
BlockItemStateProperties state = stack.getOrDefault(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY); BlockItemStateProperties state = stack.getOrDefault(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY);
@@ -1,6 +1,6 @@
package io.github.slimeistdev.crystalline_sky.compat; 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.Optional;
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -14,7 +14,12 @@ public enum Mods {
Mods(String id) { Mods(String id) {
this.id = id; this.id = id;
this.isLoaded = FabricLoader.getInstance().isModLoaded(id); this.isLoaded = isModLoaded(id);
}
@ExpectPlatform
public static boolean isModLoaded(String id) {
throw new AssertionError();
} }
/** /**
@@ -53,10 +53,8 @@ public class SkyShaderInterface implements ChunkShaderInterface {
Minecraft client = Minecraft.getInstance(); Minecraft client = Minecraft.getInstance();
if (client.level != null if (client.level != null
&& client.player != null && client.player != null
&& (client.player.getMainHandItem().is(CrystallineItems.SKY) && (CrystallineItems.isSky(client.player.getMainHandItem())
|| client.player.getOffhandItem().is(CrystallineItems.SKY) || CrystallineItems.isSky(client.player.getOffhandItem()))) {
|| client.player.getMainHandItem().is(CrystallineItems.WEEPING_SKY)
|| client.player.getOffhandItem().is(CrystallineItems.WEEPING_SKY))) {
float f = client.level.getGameTime() + client.getTimer().getGameTimeDeltaPartialTick(true); float f = client.level.getGameTime() + client.getTimer().getGameTimeDeltaPartialTick(true);
float alpha = (Mth.sin(f / 10.0f) + 1.0f) / 2.0f; float alpha = (Mth.sin(f / 10.0f) + 1.0f) / 2.0f;
@@ -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);
}
}
@@ -1,14 +1,13 @@
package io.github.slimeistdev.crystalline_sky.content.blocks; package io.github.slimeistdev.crystalline_sky.content.blocks;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems; 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.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.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 class SkyLightBlock extends LightBlock {
public SkyLightBlock(Properties settings) { public SkyLightBlock(Properties settings) {
@@ -17,6 +16,6 @@ public class SkyLightBlock extends LightBlock {
@Override @Override
protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { 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();
} }
} }
@@ -1,23 +1,22 @@
package io.github.slimeistdev.crystalline_sky.content.blocks; package io.github.slimeistdev.crystalline_sky.content.blocks;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems; 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.BlockPos;
import net.minecraft.core.Direction; 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.BlockGetter;
import net.minecraft.world.level.LevelAccessor; 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 class WeepingSkyLightBlock extends Block implements SimpleWaterloggedBlock {
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
@@ -34,7 +33,7 @@ public class WeepingSkyLightBlock extends Block implements SimpleWaterloggedBloc
@Override @Override
protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { 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 @Override
@@ -0,0 +1,3 @@
@javax.annotation.ParametersAreNonnullByDefault
@net.minecraft.MethodsReturnNonnullByDefault
package io.github.slimeistdev.crystalline_sky.content.blocks;
@@ -1,18 +1,18 @@
package io.github.slimeistdev.crystalline_sky.content.items; package io.github.slimeistdev.crystalline_sky.content.items;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineDataComponentTypes; import io.github.slimeistdev.crystalline_sky.registry.CrystallineDataComponentTypes;
import net.minecraft.world.item.Item.Properties; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Block; 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.entity.player.Player;
import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext; 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.Level;
import net.minecraft.world.level.block.Block;
import org.jetbrains.annotations.NotNull;
public class WeepingSkyBlockItem extends BlockItem { public class WeepingSkyBlockItem extends BlockItem {
public WeepingSkyBlockItem(Block block, Properties settings) { public WeepingSkyBlockItem(Block block, Properties settings) {
@@ -20,9 +20,9 @@ public class WeepingSkyBlockItem extends BlockItem {
} }
@Override @Override
public InteractionResult useOn(UseOnContext context) { public @NotNull InteractionResult useOn(UseOnContext context) {
ItemStack stack = context.getItemInHand(); 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) { if (context.getLevel().isClientSide) {
BlockPos pos = context.getClickedPos(); BlockPos pos = context.getClickedPos();
WeepingSkyBlockItemClient.setSelectedColumn(new ColumnPos(pos.getX(), pos.getZ())); WeepingSkyBlockItemClient.setSelectedColumn(new ColumnPos(pos.getX(), pos.getZ()));
@@ -34,9 +34,9 @@ public class WeepingSkyBlockItem extends BlockItem {
} }
@Override @Override
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) { public @NotNull InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
ItemStack stack = user.getItemInHand(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) { if (world.isClientSide) {
WeepingSkyBlockItemClient.setSelectedColumn(null); WeepingSkyBlockItemClient.setSelectedColumn(null);
} }
@@ -0,0 +1,3 @@
@javax.annotation.ParametersAreNonnullByDefault
@net.minecraft.MethodsReturnNonnullByDefault
package io.github.slimeistdev.crystalline_sky.content.items;
@@ -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<Registry<?>, Registration<?, ?, ?>> REGISTRATIONS = HashMultimap.create();
public static final Multimap<Registry<?>, Registration<?, ?, ?>> REGISTRATIONS_VIEW = Multimaps.unmodifiableMultimap(REGISTRATIONS);
public CatnipRegistry(String modId) {
this.modId = modId;
}
@ApiStatus.Internal
public static <R, T extends R, H extends BaseHolder<T>> void addToRegistrationMap(Registry<R> registry, Registration<R, T, H> registration) {
REGISTRATIONS.put(registry, registration);
}
public <T> DataComponentTypeBuilder<T> dataComponentType(String id) {
return new DataComponentTypeBuilder<>(this, id);
}
public BlockBuilder<Block> block(String id) {
return block(id, Block::new);
}
public <R extends Block> BlockBuilder<R> block(String id, Function<BlockBehaviour.Properties, R> factory) {
return new BlockBuilder<>(this, id, factory);
}
public ItemBuilder<Item> item(String id) {
return item(id, Item::new);
}
public <R extends Item> ItemBuilder<R> item(String id, Function<Item.Properties, R> factory) {
return new ItemBuilder<>(this, id, factory);
}
public <B extends Block> ItemBuilder<BlockItem> item(BlockHolder<B> block) {
return item(block, BlockItem::new);
}
public <R extends BlockItem, B extends Block> ItemBuilder<R> item(BlockHolder<B> block, BiFunction<? super B, Item.Properties, R> factory) {
return new ItemBuilder<>(this, block.getRegisteredNamePath(), properties -> factory.apply(block.value(), properties));
}
}
@@ -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<R, T extends R, H extends BaseHolder<T>>(
ResourceLocation id,
Registry<R> registry,
Supplier<T> value,
H holder,
Consumer<H> afterRegisterCallback
) {
@SuppressWarnings("unchecked")
public void register() {
T registered = Registry.register(registry, id, value.get());
((Holder$ReferenceAccessor<T>) holder).crystalline_sky$bindValue(registered);
afterRegisterCallback.accept(holder);
}
}
@@ -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<T> {
private @Nullable T obj;
private @Nullable Consumer<T> cons;
public void registered(T obj) {
this.obj = obj;
if (cons != null) {
cons.accept(obj);
cons = null;
}
}
public void addListener(Consumer<? super T> consumer) {
if (obj != null) {
consumer.accept(obj);
} else if (cons == null) {
cons = consumer::accept;
} else {
cons = cons.andThen(consumer);
}
}
}
@@ -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<R, T extends R, H extends BaseHolder<T>> {
protected final CatnipRegistry owner;
protected final ResourceLocation id;
protected final Registry<R> registry;
protected @Nullable H holder;
private Consumer<H> afterRegisterCallback = h -> h.getInternalRegistrationListener().accept(h.value());
public AbstractBuilder(CatnipRegistry owner, String name, Registry<R> registry) {
this.owner = owner;
this.id = ResourceLocation.fromNamespaceAndPath(owner.modId, name);
this.registry = registry;
}
public void chainAfterRegisterCallback(Consumer<H> callback) {
afterRegisterCallback = afterRegisterCallback.andThen(callback);
}
abstract T build();
abstract H getHolder(HolderOwner<R> owner, ResourceKey<R> key);
public H register() {
ResourceKey<R> key = ResourceKey.create(registry.key(), id);
holder = getHolder(registry.holderOwner(), key);
Registration<R, T, H> registration = new Registration<>(id, registry, this::build, holder, afterRegisterCallback);
if (Loader.FABRIC.isCurrent()) {
registration.register();
} else {
CatnipRegistry.addToRegistrationMap(registry, registration);
}
return holder;
}
}
@@ -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<T extends Block> extends AbstractBuilder<Block, T, BlockHolder<T>> {
private final Function<Properties, T> factory;
private Supplier<Properties> initialProperties = Properties::of;
private Function<Properties, Properties> properties = Function.identity();
public BlockBuilder(CatnipRegistry owner, String name, Function<Properties, T> factory) {
super(owner, name, BuiltInRegistries.BLOCK);
this.factory = factory;
}
public BlockBuilder<T> initialProperties(Supplier<? extends BlockBehaviour> block) {
initialProperties = () -> Properties.ofFullCopy(block.get());
return this;
}
public BlockBuilder<T> properties(Function<Properties, Properties> 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<T> getHolder(HolderOwner<Block> owner, ResourceKey<Block> key) {
//noinspection unchecked
return (BlockHolder<T>) new BlockHolder<>(owner, key);
}
}
@@ -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<T> extends AbstractBuilder<DataComponentType<?>, DataComponentType<T>, DataComponentTypeHolder<T>> {
private final DataComponentType.Builder<T> builder;
public DataComponentTypeBuilder(CatnipRegistry owner, String name) {
super(owner, name, BuiltInRegistries.DATA_COMPONENT_TYPE);
this.builder = DataComponentType.builder();
}
public DataComponentTypeBuilder<T> persistent(Codec<T> codec) {
this.builder.persistent(codec);
return this;
}
public DataComponentTypeBuilder<T> networkSynchronized(StreamCodec<? super RegistryFriendlyByteBuf, T> streamCodec) {
this.builder.networkSynchronized(streamCodec);
return this;
}
public DataComponentTypeBuilder<T> cacheEncoding() {
this.builder.cacheEncoding();
return this;
}
@Override
DataComponentType<T> build() {
return builder.build();
}
@Override
DataComponentTypeHolder<T> getHolder(HolderOwner<DataComponentType<?>> owner, ResourceKey<DataComponentType<?>> key) {
//noinspection rawtypes,unchecked
return new DataComponentTypeHolder<T>((HolderOwner) owner, (ResourceKey) key);
}
}
@@ -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<T extends Item> extends AbstractBuilder<Item, T, ItemHolder<T>> {
private final Function<Properties, T> factory;
private Function<Properties, Properties> properties = Function.identity();
public ItemBuilder(CatnipRegistry owner, String name, Function<Properties, T> factory) {
super(owner, name, BuiltInRegistries.ITEM);
this.factory = factory;
}
public ItemBuilder<T> properties(Function<Properties, Properties> 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<T> getHolder(HolderOwner<Item> owner, ResourceKey<Item> key) {
//noinspection unchecked
return (ItemHolder<T>) new ItemHolder<>(owner, key);
}
}
@@ -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/
@@ -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<T> extends Holder.Reference<T> {
private final RegistrationListeners<T> registrationListeners = new RegistrationListeners<>();
protected BaseHolder(HolderOwner<T> owner, ResourceKey<T> key) {
super(Type.STAND_ALONE, owner, key, null);
}
public <V> boolean is(V value) {
return value() == value;
}
@ApiStatus.Internal
public Consumer<T> getInternalRegistrationListener() {
return registrationListeners::registered;
}
public void onRegistered(Consumer<? super T> consumer) {
registrationListeners.addListener(consumer);
}
public static <T> Holder<T> downcast(Holder<? extends T> holder) {
//noinspection unchecked
return (Holder<T>) holder;
}
public String getRegisteredNamePath() {
return this.unwrapKey().map((resourceKey) -> resourceKey.location().getPath()).orElse("[unregistered]");
}
}
@@ -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<T extends Block> extends ItemLikeHolder.NonItem<T> {
public BlockHolder(HolderOwner<T> owner, ResourceKey<T> key) {
super(owner, key);
}
public BlockState defaultBlockState() {
return value().defaultBlockState();
}
public boolean is(BlockState state) {
return is(state.getBlock());
}
}
@@ -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<T> extends BaseHolder<DataComponentType<T>> {
public DataComponentTypeHolder(HolderOwner<DataComponentType<T>> owner, ResourceKey<DataComponentType<T>> key) {
super(owner, key);
}
}
@@ -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<T extends Item> extends ItemLikeHolder<T> {
public ItemHolder(HolderOwner<T> owner, ResourceKey<T> key) {
super(owner, key);
}
@Override
public boolean is(Item item) {
return asItem() == item;
}
}
@@ -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<T extends ItemLike> extends BaseHolder<T> implements ItemLike {
protected ItemLikeHolder(HolderOwner<T> owner, ResourceKey<T> 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<T extends ItemLike> extends ItemLikeHolder<T> {
protected NonItem(HolderOwner<T> owner, ResourceKey<T> key) {
super(owner, key);
}
@Override
public boolean is(Item item) {
return asItem() == item;
}
}
}
@@ -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/
@@ -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/
@@ -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<T> {
@Accessor("owner")
HolderOwner<T> crystalline_sky$getOwner();
@Invoker("bindValue")
void crystalline_sky$bindValue(T value);
}
@@ -24,9 +24,9 @@ public class ClientLevelMixin {
@Inject(method = "<clinit>", at = @At("RETURN")) @Inject(method = "<clinit>", at = @At("RETURN"))
private static void modifyBlockMarkerItems(CallbackInfo ci) { private static void modifyBlockMarkerItems(CallbackInfo ci) {
MARKER_PARTICLE_ITEMS = new HashSet<>(MARKER_PARTICLE_ITEMS); MARKER_PARTICLE_ITEMS = new HashSet<>(MARKER_PARTICLE_ITEMS);
MARKER_PARTICLE_ITEMS.add(CrystallineItems.SKY_LIGHT); MARKER_PARTICLE_ITEMS.add(CrystallineItems.SKY_LIGHT.value());
MARKER_PARTICLE_ITEMS.add(CrystallineItems.WEEPING_SKY_LIGHT); MARKER_PARTICLE_ITEMS.add(CrystallineItems.WEEPING_SKY_LIGHT.value());
MARKER_PARTICLE_ITEMS.add(CrystallineItems.SKY); MARKER_PARTICLE_ITEMS.add(CrystallineItems.SKY.value());
MARKER_PARTICLE_ITEMS.add(CrystallineItems.WEEPING_SKY); MARKER_PARTICLE_ITEMS.add(CrystallineItems.WEEPING_SKY.value());
} }
} }
@@ -39,10 +39,8 @@ public class LevelRenderer_NoSodium_Mixin {
if (renderLayer == CrystallineRenderTypes.SKY if (renderLayer == CrystallineRenderTypes.SKY
&& instance.COLOR_MODULATOR != null && instance.COLOR_MODULATOR != null
&& minecraft.player != null && minecraft.player != null
&& (minecraft.player.getMainHandItem().is(CrystallineItems.SKY) && (CrystallineItems.isSky(minecraft.player.getMainHandItem())
|| minecraft.player.getOffhandItem().is(CrystallineItems.SKY) || CrystallineItems.isSky(minecraft.player.getOffhandItem()))) {
|| minecraft.player.getMainHandItem().is(CrystallineItems.WEEPING_SKY)
|| minecraft.player.getOffhandItem().is(CrystallineItems.WEEPING_SKY))) {
float f = ticks + minecraft.getTimer().getGameTimeDeltaPartialTick(true); float f = ticks + minecraft.getTimer().getGameTimeDeltaPartialTick(true);
float alpha = (Mth.sin(f / 10.0f) + 1.0f) / 2.0f; float alpha = (Mth.sin(f / 10.0f) + 1.0f) / 2.0f;
@@ -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<CreativeModeTab> getTab();
boolean hasPermissions();
void addAfter(ItemLike reference, List<ItemStack> stacks);
}
@@ -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 <https://www.gnu.org/licenses/>.
*/
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<Runnable> 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();
}
}
@@ -1,76 +1,63 @@
package io.github.slimeistdev.crystalline_sky.registry; package io.github.slimeistdev.crystalline_sky.registry;
import io.github.slimeistdev.crystalline_sky.CrystallineSky; 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.SkyLightBlock;
import io.github.slimeistdev.crystalline_sky.content.blocks.WeepingSkyLightBlock; import io.github.slimeistdev.crystalline_sky.content.blocks.WeepingSkyLightBlock;
import net.minecraft.world.level.block.Block; import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry;
import net.minecraft.world.level.block.Blocks; 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.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.SoundType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.material.MapColor; import net.minecraft.world.level.material.MapColor;
import java.util.function.Function;
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
public class CrystallineBlocks { public class CrystallineBlocks {
public static final Block SKY = register("sky", TransparentBlock::new, Properties.of() private static final CatnipRegistry REGISTRY = CrystallineSky.registry();
public static final BlockHolder<SkyBlock> SKY = REGISTRY.block("sky", SkyBlock::new)
.properties(p -> p
.strength(0.3f) .strength(0.3f)
.sound(SoundType.AMETHYST) .sound(SoundType.AMETHYST)
.noOcclusion() .noOcclusion()
.isValidSpawn(Blocks::never) .isValidSpawn(CrystallineBlocks::never)
.isRedstoneConductor(Blocks::never) .isRedstoneConductor(CrystallineBlocks::never)
.isSuffocating(Blocks::never) .isSuffocating(CrystallineBlocks::never)
.isViewBlocking(Blocks::never) .isViewBlocking(CrystallineBlocks::never)
.emissiveRendering(Blocks::always)); .emissiveRendering(CrystallineBlocks::always))
.register();
public static final Block WEEPING_SKY = register("weeping_sky", TransparentBlock::new, Properties.ofFullCopy(SKY)); public static final BlockHolder<SkyBlock> WEEPING_SKY = REGISTRY.block("weeping_sky", SkyBlock::new)
.initialProperties(SKY::value)
.register();
public static final Block SKY_LIGHT = register( public static final BlockHolder<SkyLightBlock> SKY_LIGHT = REGISTRY.block("sky_light", SkyLightBlock::new)
"sky_light", .properties(p -> p
SkyLightBlock::new,
BlockBehaviour.Properties.of()
.replaceable() .replaceable()
.strength(-1.0F, 3600000.8F) .strength(-1.0F, 3600000.8F)
.mapColor(state -> state.getValue(BlockStateProperties.WATERLOGGED) ? MapColor.WATER : MapColor.NONE) .mapColor(CrystallineBlocks::waterloggedColor)
.noLootTable() .noLootTable()
.noOcclusion() .noOcclusion())
); .register();
public static final Block WEEPING_SKY_LIGHT = register( public static final BlockHolder<WeepingSkyLightBlock> WEEPING_SKY_LIGHT = REGISTRY.block("weeping_sky_light", WeepingSkyLightBlock::new)
"weeping_sky_light", .initialProperties(SKY_LIGHT::value)
WeepingSkyLightBlock::new, .register();
BlockBehaviour.Properties.of()
.replaceable()
.strength(-1.0F, 3600000.8F)
.mapColor(state -> state.getValue(BlockStateProperties.WATERLOGGED) ? MapColor.WATER : MapColor.NONE)
.noLootTable()
.noOcclusion()
);
public static void init() {} public static void init() {}
private static <T extends Block> T register(String id, Function<Properties, T> factory, Properties settings) {
ResourceKey<Block> key = CrystallineSky.key(Registries.BLOCK, id);
return Registry.register(BuiltInRegistries.BLOCK, key, factory.apply(settings));
}
public static boolean isCrystallineSky(BlockState state) { public static boolean isCrystallineSky(BlockState state) {
return getSkyLightLevel(state) > 0; return getSkyLightLevel(state) > 0;
} }
public static int getSkyLightLevel(BlockState state) { public static int getSkyLightLevel(BlockState state) {
if (state.is(SKY_LIGHT)) { if (SKY_LIGHT.is(state)) {
return state.getValue(LightBlock.LEVEL); 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; return 15;
} }
@@ -78,6 +65,26 @@ public class CrystallineBlocks {
} }
public static boolean isWeepingSky(BlockState state) { 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;
} }
} }
@@ -1,26 +1,19 @@
package io.github.slimeistdev.crystalline_sky.registry; package io.github.slimeistdev.crystalline_sky.registry;
import io.github.slimeistdev.crystalline_sky.CrystallineSky; 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.network.codec.StreamCodec;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.Registry;
import net.minecraft.util.Unit; import net.minecraft.util.Unit;
import java.util.function.UnaryOperator;
public class CrystallineDataComponentTypes { public class CrystallineDataComponentTypes {
public static final DataComponentType<Unit> WEEPING_SKY_DEBUG_COLUMN_TOOL = register( private static final CatnipRegistry REGISTRY = CrystallineSky.registry();
"weeping_sky_debug_column_tool",
b -> b public static final DataComponentTypeHolder<Unit> WEEPING_SKY_DEBUG_COLUMN_TOOL =
REGISTRY.<Unit>dataComponentType("weeping_sky_debug_column_tool")
.networkSynchronized(StreamCodec.unit(Unit.INSTANCE)) .networkSynchronized(StreamCodec.unit(Unit.INSTANCE))
.persistent(Unit.CODEC) .persistent(Unit.CODEC)
); .register();
@SuppressWarnings("SameParameterValue")
private static <T> DataComponentType<T> register(String id, UnaryOperator<DataComponentType.Builder<T>> builderOperator) {
return Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, CrystallineSky.id(id), builderOperator.apply(DataComponentType.builder()).build());
}
public static void init() {} public static void init() {}
} }
@@ -1,54 +1,54 @@
package io.github.slimeistdev.crystalline_sky.registry; 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.blocks.SkyLightBlock;
import io.github.slimeistdev.crystalline_sky.content.items.WeepingSkyBlockItem; import io.github.slimeistdev.crystalline_sky.content.items.WeepingSkyBlockItem;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; import io.github.slimeistdev.crystalline_sky.foundation.registration.CatnipRegistry;
import net.minecraft.world.level.block.Block; import io.github.slimeistdev.crystalline_sky.foundation.registration.holder.ItemHolder;
import net.minecraft.world.level.block.LightBlock; import io.github.slimeistdev.crystalline_sky.multiloader.ItemGroupRegistrationEvent;
import net.minecraft.core.component.DataComponents; 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.BlockItem;
import net.minecraft.world.item.Item; import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.CreativeModeTabs;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.Rarity; 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.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.BiFunction;
public class CrystallineItems { public class CrystallineItems {
public static final Item SKY = Items.registerBlock( private static final CatnipRegistry REGISTRY = CrystallineSky.registry();
CrystallineBlocks.SKY,
settings -> settings.rarity(Rarity.EPIC)
);
public static final Item WEEPING_SKY = register( public static final ItemHolder<BlockItem> SKY = REGISTRY.item(CrystallineBlocks.SKY)
CrystallineBlocks.WEEPING_SKY, .properties(p -> p.rarity(Rarity.EPIC))
(block, settings) -> new WeepingSkyBlockItem(block, settings.rarity(Rarity.EPIC)) .register();
);
public static final Item SKY_LIGHT = Items.registerBlock( public static final ItemHolder<WeepingSkyBlockItem> WEEPING_SKY = REGISTRY.item(CrystallineBlocks.WEEPING_SKY, WeepingSkyBlockItem::new)
CrystallineBlocks.SKY_LIGHT, .properties(p -> p.rarity(Rarity.EPIC))
settings -> settings.rarity(Rarity.EPIC) .register();
.component(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY.with(LightBlock.LEVEL, 15))
);
public static final Item WEEPING_SKY_LIGHT = Items.registerBlock( public static final ItemHolder<BlockItem> SKY_LIGHT = REGISTRY.item(CrystallineBlocks.SKY_LIGHT)
CrystallineBlocks.WEEPING_SKY_LIGHT, .properties(p -> p
settings -> settings.rarity(Rarity.EPIC) .rarity(Rarity.EPIC)
); .component(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY.with(LightBlock.LEVEL, 15)))
.register();
public static final ItemHolder<BlockItem> WEEPING_SKY_LIGHT = REGISTRY.item(CrystallineBlocks.WEEPING_SKY_LIGHT)
.properties(p -> p.rarity(Rarity.EPIC))
.register();
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
private static Item register(Block block, BiFunction<Block, Item.Properties, BlockItem> factory) { private static ResourceKey<CreativeModeTab> tabKey(String name) {
return Items.registerBlock(factory.apply(block, new Item.Properties())); return ResourceKey.create(Registries.CREATIVE_MODE_TAB, ResourceLocation.withDefaultNamespace(name));
} }
public static void init() { public static void onItemGroupRegistration(ItemGroupRegistrationEvent event) {
ItemGroupEvents.modifyEntriesEvent(CreativeModeTabs.OP_BLOCKS).register(entries -> { if (event.getTab().equals(tabKey("op_blocks")) && event.hasPermissions()) {
if (!entries.getContext().hasPermissions()) return;
List<ItemStack> stacks = new ArrayList<>(); List<ItemStack> stacks = new ArrayList<>();
stacks.add(new ItemStack(SKY)); stacks.add(new ItemStack(SKY));
@@ -60,7 +60,13 @@ public class CrystallineItems {
stacks.add(new ItemStack(WEEPING_SKY_LIGHT)); 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);
} }
} }
@@ -1,21 +1,18 @@
package io.github.slimeistdev.crystalline_sky.registry.client; package io.github.slimeistdev.crystalline_sky.registry.client;
import com.mojang.blaze3d.systems.RenderSystem; 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.LevelRenderer_Duck;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.RenderType_Duck;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderStateShard;
import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import static net.minecraft.client.renderer.RenderType.create;
import static net.minecraft.client.renderer.RenderStateShard.LIGHTMAP;
@Environment(EnvType.CLIENT) @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.EmptyTextureStateShard SKY_TEXTURE = new SkyBufferTexture();
private static final RenderStateShard.ShaderStateShard SKY_PROGRAM = new RenderStateShard.ShaderStateShard(CrystallineShaderInstances::getRenderTypeSkyProgram); 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(); ((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 { private static class SkyBufferTexture extends RenderStateShard.EmptyTextureStateShard {
public SkyBufferTexture() { public SkyBufferTexture() {
super(() -> { super(() -> {
@@ -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 <https://www.gnu.org/licenses/>.
*/
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, "_"));
}
}
@@ -8,20 +8,20 @@
"plugin": "io.github.slimeistdev.crystalline_sky.mixin.CrystallineSkyMixinPlugin", "plugin": "io.github.slimeistdev.crystalline_sky.mixin.CrystallineSkyMixinPlugin",
"compatibilityLevel": "JAVA_21", "compatibilityLevel": "JAVA_21",
"mixins": [ "mixins": [
"LightEngineMixin",
"ChunkSkyLightSourcesMixin", "ChunkSkyLightSourcesMixin",
"SkyLightEngineMixin", "Holder$ReferenceAccessor",
"LayerLightSectionStorageAccessor", "LayerLightSectionStorageAccessor",
"LightEngineMixin",
"SkyLightEngineMixin",
"SkyLightSectionStorageAccessor" "SkyLightSectionStorageAccessor"
], ],
"client": [ "client": [
"client.ClientLevelMixin", "client.ClientLevelMixin",
"client.DebugRendererMixin", "client.DebugRendererMixin",
"client.RenderTargetMixin",
"client.GameRendererMixin", "client.GameRendererMixin",
"client.LevelRenderer_NoSodium_Mixin", "client.LevelRenderer_NoSodium_Mixin",
"client.LevelRendererMixin", "client.LevelRendererMixin",
"client.compat.axiom.ChunkRenderOverrider_AxiomChunkOverrideLayerMixin", "client.RenderTargetMixin",
"client.compat.sodium.DefaultMaterialsMixin", "client.compat.sodium.DefaultMaterialsMixin",
"client.compat.sodium.DefaultTerrainRenderPassesMixin", "client.compat.sodium.DefaultTerrainRenderPassesMixin",
"client.compat.sodium.ShaderChunkRendererMixin", "client.compat.sodium.ShaderChunkRendererMixin",
+2 -2
View File
@@ -10,9 +10,9 @@ loom {
client() client()
name = "Minecraft Data" 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.output-dir=${common.file("src/generated/resources")}")
vmArg("-Dfabric-api.datagen.modid=${"slug"()}") vmArg("-Dfabric-api.datagen.modid=${"modId"()}")
environmentVariable("DATAGEN", "TRUE") environmentVariable("DATAGEN", "TRUE")
} }
@@ -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);
}
}
@@ -1,6 +1,7 @@
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.multiloader.fabric.ItemGroupRegistrationEventImpl;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderTypes; import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderTypes;
import net.fabricmc.api.ClientModInitializer; 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.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.world.level.block.Block;
import java.util.function.Consumer;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class CrystallineSkyClientImpl implements ClientModInitializer { public class CrystallineSkyClientImpl implements ClientModInitializer {
@@ -16,9 +20,11 @@ public class CrystallineSkyClientImpl implements ClientModInitializer {
public void onInitializeClient() { public void onInitializeClient() {
CrystallineSkyClient.init(); CrystallineSkyClient.init();
CrystallineSkyClient.registerKeybindings(KeyBindingHelper::registerKeyBinding); CrystallineSkyClient.registerKeybindings(KeyBindingHelper::registerKeyBinding);
ItemGroupRegistrationEventImpl.register();
BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.SKY, CrystallineRenderTypes.SKY); Consumer<Block> makeSky = b -> BlockRenderLayerMap.INSTANCE.putBlock(b, CrystallineRenderTypes.SKY);
BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.WEEPING_SKY, CrystallineRenderTypes.SKY); CrystallineBlocks.SKY.onRegistered(makeSky);
CrystallineBlocks.WEEPING_SKY.onRegistered(makeSky);
ClientTickEvents.END_CLIENT_TICK.register(CrystallineSkyClient::onEndTick); ClientTickEvents.END_CLIENT_TICK.register(CrystallineSkyClient::onEndTick);
} }
@@ -1,13 +1,16 @@
package io.github.slimeistdev.crystalline_sky.fabric.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.foundation.registration.holder.BaseHolder;
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;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; 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.HolderLookup;
import net.minecraft.core.registries.Registries;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.level.block.Block;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -18,14 +21,25 @@ public class CrystallineSkyBlockTagProvider extends FabricTagProvider.BlockTagPr
@Override @Override
protected void addTags(HolderLookup.Provider wrapperLookup) { 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)
.add(CrystallineBlocks.SKY_LIGHT) .add(CrystallineBlocks.SKY_LIGHT)
.add(CrystallineBlocks.WEEPING_SKY) .add(CrystallineBlocks.WEEPING_SKY)
.add(CrystallineBlocks.WEEPING_SKY_LIGHT); .add(CrystallineBlocks.WEEPING_SKY_LIGHT);
getOrCreateTagBuilder(BlockTags.CRYSTAL_SOUND_BLOCKS) builder(BlockTags.CRYSTAL_SOUND_BLOCKS)
.add(CrystallineBlocks.SKY) .add(CrystallineBlocks.SKY)
.add(CrystallineBlocks.WEEPING_SKY); .add(CrystallineBlocks.WEEPING_SKY);
} }
private TagBuilder<Block> builder(TagKey<Block> tag) {
return new TagBuilder<>(getOrCreateTagBuilder(tag));
}
private record TagBuilder<T>(FabricTagProvider<T>.FabricTagBuilder wrapped) {
public <R extends T> TagBuilder<T> add(Holder<R> object) {
BaseHolder.<T>downcast(object).unwrap().map(wrapped::add, wrapped::add);
return this;
}
}
} }
@@ -14,7 +14,7 @@ public class CrystallineSkyLootProvider extends FabricBlockLootTableProvider {
@Override @Override
public void generate() { public void generate() {
dropWhenSilkTouch(CrystallineBlocks.SKY); dropWhenSilkTouch(CrystallineBlocks.SKY.value());
dropWhenSilkTouch(CrystallineBlocks.WEEPING_SKY); dropWhenSilkTouch(CrystallineBlocks.WEEPING_SKY.value());
} }
} }
@@ -32,12 +32,12 @@ public class CrystallineSkyModelProvider extends FabricModelProvider {
@Override @Override
public void generateBlockStateModels(BlockModelGenerators gen) { public void generateBlockStateModels(BlockModelGenerators gen) {
registerSkyBlock(gen, CrystallineBlocks.SKY); registerSkyBlock(gen, CrystallineBlocks.SKY.value());
registerSkyBlock(gen, CrystallineBlocks.WEEPING_SKY); registerSkyBlock(gen, CrystallineBlocks.WEEPING_SKY.value());
registerSkyLightBlock(gen, CrystallineBlocks.SKY_LIGHT, CrystallineItems.SKY_LIGHT); registerSkyLightBlock(gen, CrystallineBlocks.SKY_LIGHT.value(), CrystallineItems.SKY_LIGHT.value());
gen.createAirLikeBlock(CrystallineBlocks.WEEPING_SKY_LIGHT, CrystallineItems.WEEPING_SKY_LIGHT); gen.createAirLikeBlock(CrystallineBlocks.WEEPING_SKY_LIGHT.value(), CrystallineItems.WEEPING_SKY_LIGHT.value());
gen.createSimpleFlatItemModel(CrystallineItems.WEEPING_SKY_LIGHT); gen.createSimpleFlatItemModel(CrystallineItems.WEEPING_SKY_LIGHT.value());
} }
private void registerSkyBlock(BlockModelGenerators gen, Block block) { private void registerSkyBlock(BlockModelGenerators gen, Block block) {
@@ -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 com.moulberry.axiom.render.ChunkRenderOverrider;
import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin; import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin;
@@ -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<CreativeModeTab> tab;
private final FabricItemGroupEntries entries;
public ItemGroupRegistrationEventImpl(ResourceKey<CreativeModeTab> tab, FabricItemGroupEntries entries) {
this.tab = tab;
this.entries = entries;
}
@Override
public ResourceKey<CreativeModeTab> getTab() {
return tab;
}
@Override
public boolean hasPermissions() {
return entries.getContext().hasPermissions();
}
@Override
public void addAfter(ItemLike reference, List<ItemStack> 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
));
});
}
}
@@ -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;
}
}
@@ -10,7 +10,8 @@
"mixins": [ "mixins": [
], ],
"client": [ "client": [
"client.RenderTypeMixin" "client.RenderTypeMixin",
"client.compat.axiom.ChunkRenderOverrider_AxiomChunkOverrideLayerMixin"
], ],
"server": [ "server": [
], ],
+3
View File
@@ -9,6 +9,7 @@ parchment = "2024.11.17"
fl = "0.18.6" fl = "0.18.6"
fapi = "0.116.10+1.21.1" fapi = "0.116.10+1.21.1"
nf = "21.1.215" nf = "21.1.215"
jsr305 = "3.0.2"
mixinextras = "0.5.0" mixinextras = "0.5.0"
mm = "11.0.4" mm = "11.0.4"
sodium-fabric = "mc1.21.1-0.6.13-fabric" 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" } 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-common = { group = "io.github.llamalad7", name = "mixinextras-common", version.ref = "mixinextras" }
mixinextras-fabric = { group = "io.github.llamalad7", name = "mixinextras-fabric", 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" } mixinextras-neoforge = { group = "io.github.llamalad7", name = "mixinextras-neoforge", version.ref = "mixinextras" }
@@ -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<ModInfo> mods = LoadingModList.get().getMods();
for (ModInfo mod : mods) {
if (mod.getModId().equals(id)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,6 @@
package io.github.slimeistdev.crystalline_sky.multiloader.neoforge;
public class ItemGroupRegistrationEventImpl {
public static void create() {
}
}
@@ -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;
}
}
@@ -5,12 +5,15 @@ import io.github.slimeistdev.crystalline_sky.CrystallineSkyClient;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderTypes; import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderTypes;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType; 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.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent;
import net.neoforged.neoforge.client.event.RegisterNamedRenderTypesEvent; import net.neoforged.neoforge.client.event.RegisterNamedRenderTypesEvent;
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent;
@EventBusSubscriber(value = Dist.CLIENT, modid = CrystallineSky.ID) @EventBusSubscriber(value = Dist.CLIENT, modid = CrystallineSky.ID)
public class CrystallineSkyClientImpl { public class CrystallineSkyClientImpl {
@@ -33,4 +36,9 @@ public class CrystallineSkyClientImpl {
public static void onEndTick(ClientTickEvent.Post event) { public static void onEndTick(ClientTickEvent.Post event) {
CrystallineSkyClient.onEndTick(Minecraft.getInstance()); CrystallineSkyClient.onEndTick(Minecraft.getInstance());
} }
@SubscribeEvent
public static void buildCreativeModeTabContents(BuildCreativeModeTabContentsEvent event) {
event.insertAfter();
}
} }
@@ -2,11 +2,16 @@ package io.github.slimeistdev.crystalline_sky.neoforge;
import io.github.slimeistdev.crystalline_sky.CrystallineSky; import io.github.slimeistdev.crystalline_sky.CrystallineSky;
import io.github.slimeistdev.crystalline_sky.multiloader.Env; import io.github.slimeistdev.crystalline_sky.multiloader.Env;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.common.Mod; import net.neoforged.fml.common.Mod;
@Mod(CrystallineSky.ID) @Mod(CrystallineSky.ID)
public class CrystallineSkyImpl { public class CrystallineSkyImpl {
public CrystallineSkyImpl() { static IEventBus bus;
public CrystallineSkyImpl(IEventBus bus) {
CrystallineSkyImpl.bus = bus;
CrystallineSky.init(); CrystallineSky.init();
//noinspection Convert2MethodRef //noinspection Convert2MethodRef
Env.CLIENT.runIfCurrent(() -> () -> CrystallineSkyClientImpl.init()); Env.CLIENT.runIfCurrent(() -> () -> CrystallineSkyClientImpl.init());