switch to mojmap

This commit is contained in:
techno-sam
2026-04-05 03:00:12 +02:00
parent e0c571a1fd
commit 2c6c100b62
44 changed files with 760 additions and 786 deletions
+14 -1
View File
@@ -36,6 +36,18 @@ repositories {
includeGroup "com.terraformersmc"
}
}
exclusiveContent {
forRepository {
//noinspection ForeignDelegate
maven {
name 'ParchmentMC'
url "https://maven.parchmentmc.org"
}
}
filter {
includeGroup "org.parchmentmc.data"
}
}
flatDir {
dir("libs")
}
@@ -44,7 +56,8 @@ repositories {
dependencies {
minecraft libs.mc
mappings loom.layered {
it.mappings variantOf(libs.yarn) { classifier "v2" }
it.officialMojangMappings()
it.parchment variantOf(libs.parchment) { artifactType "zip" }
it.mappings file("custom_mappings.tiny")
}
+2 -57
View File
@@ -1,61 +1,6 @@
tiny 2 0 official intermediary named
c ua net/minecraft/class_2483 net/minecraft/nbt/AbstractNbtList
m (I)Luy; k method_10534 get
m (I)Luy; c method_10536 remove
c uh net/minecraft/class_2499 net/minecraft/nbt/NbtList
m (I)Luy; method_10534 method_10534 get
m (I)Luy; method_10536 method_10536 remove
c eov net/minecraft/class_3558 net/minecraft/world/chunk/light/ChunkLightProvider
f I a field_44729 MAX_LEVEL
f I b field_44730 MIN_OPACITY
f J c field_44731 PULL_LIGHT_IN_ENTRY
f I g field_44732 MIN_QUEUE_SIZE
f Lit/unimi/dsi/fastutil/longs/LongArrayFIFOQueue; i field_44734 decreaseQueue
f Lit/unimi/dsi/fastutil/longs/LongArrayFIFOQueue; j field_44735 increaseQueue
f I l field_31709 CACHE_SIZE
m (J)V a method_51529 checkNode
m (JJ)V a method_51530 propagateDecrease
m (JJI)V a method_51531 propagateIncrease
m (JJ)V b method_51565 enqueueDecrease
m (JJ)V c method_51566 enqueueIncrease
m ()I d method_51567 propagateIncreases
m ()I e method_51570 propagateDecreases
c eov$a net/minecraft/class_3558$class_8531 net/minecraft/world/chunk/light/ChunkLightProvider$QueueEntry
m (IZ)J a method_51573 increaseLightFromEmission
m (IZLji;)J a method_51574 packWithOneDirectionCleared
p 0 lightLevel
p 1 trivial
p 2 direction
m (ZZZZZ)J a method_51578 increaseSkySourceInDirections
m (IZLji;)J b method_51579 increaseOnlyOneDirection
m (J)Z c method_51582 isIncreaseFromEmission
c eox net/minecraft/class_3572 net/minecraft/world/chunk/light/ChunkSkyLightProvider
f J g field_44743 REMOVE_TOP_SKY_SOURCE_ENTRY
f J h field_44744 REMOVE_SKY_SOURCE_ENTRY
f J i field_44745 ADD_SKY_SOURCE_ENTRY
f Ljd$a; j field_44746 scratchPos
f Leoo; k field_44747 defaultSkyLight
m (I)Z a method_51584 isMaxLightLevel
p 0 lightLevel
m (III)I a method_51585 getSkyLightOrDefault
p 1 x
p 2 z
p 3 defaultValue
m (JLji;IZI)V a method_51587 propagateFromEmptySections
p 1 blockPos
p 3 direction
p 4 lightLevel
p 5 shouldIncrease
p 6 emptySections
m (II)Leoo; b method_51589 getSkyLight
p 1 chunkX
p 2 chunkZ
c eox net/minecraft/class_3572 net/minecraft/world/level/lighting/SkyLightEngine
m (III)V b method_51590 updateSourcesInColumn
p 1 x
p 2 z
p 3 lowestSourceY
v 4 15 -1 _ _ minY
m (IIII)V a method_51586 removeSourcesBelow
p 1 x
@@ -101,7 +46,7 @@ c eox net/minecraft/class_3572 net/minecraft/world/chunk/light/ChunkSkyLightProv
v 15 98 -1 _ _ baseLevelToPropagate
v 16 128 -1 _ _ targetState
v 17 139 -1 _ _ trueLevelToPropagate
m (Ldcd;)V b method_51471 propagateLight
m (Ldcd;)V b method_51471 propagateLightSources
v 2 12 -1 _ _ packedZeroPos
v 4 48 -1 _ _ sourcesO
v 5 74 -1 _ _ sourcesZN
+2
View File
@@ -6,6 +6,8 @@ org.gradle.configureondemand=true
org.gradle.configuration-cache=false
# Loom
fabric.loom.multiProjectOptimisation=true
# otherwise layering tiny mappings on mojmap explodes
fabric.loom.dropNonIntermediateRootMethods=true
# Mod Metadata
group=io.github.slimeistdev
user=techno-sam
+2 -2
View File
@@ -4,7 +4,7 @@ minotaur = "2.+"
mc = "1.21.1"
fl = "0.18.6"
yarn = "1.21.1+build.3"
parchment = "2024.11.17"
fapi = "0.116.10+1.21.1"
mixinextras = "0.5.0"
mm = "11.0.4"
@@ -22,7 +22,7 @@ minotaur = { id = "com.modrinth.minotaur", version.ref = "minotaur" }
[libraries]
mc = { group = "mojang", name = "minecraft", version.ref = "mc" }
fl = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fl" }
yarn = { group = "net.fabricmc", name = "yarn", version.ref = "yarn" }
parchment = { group = "org.parchmentmc.data", name = "parchment-1.21.1", version.ref = "parchment" }
fapi = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fapi" }
mixinextras = { group = "io.github.llamalad7", name = "mixinextras-fabric", version.ref = "mixinextras" }
mm = { group = "com.terraformersmc", name = "modmenu", version.ref = "mm" }
@@ -1,9 +1,9 @@
package io.github.slimeistdev.crystalline_sky;
import net.fabricmc.api.ModInitializer;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -16,11 +16,11 @@ public class CrystallineSky implements ModInitializer {
ModSetup.init();
}
public static Identifier id(String path) {
return Identifier.of(ID, path);
public static ResourceLocation id(String path) {
return ResourceLocation.fromNamespaceAndPath(ID, path);
}
public static <T> RegistryKey<T> key(RegistryKey<? extends Registry<T>> registryKey, String path) {
return RegistryKey.of(registryKey, id(path));
public static <T> ResourceKey<T> key(ResourceKey<? extends Registry<T>> registryKey, String path) {
return ResourceKey.create(registryKey, id(path));
}
}
@@ -8,16 +8,16 @@ import net.fabricmc.api.ClientModInitializer;
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.block.LightBlock;
import net.minecraft.client.item.ModelPredicateProviderRegistry;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.BlockStateComponent;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.world.level.block.LightBlock;
import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.client.KeyMapping;
import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.item.component.BlockItemStateProperties;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.ChatFormatting;
import net.minecraft.resources.ResourceLocation;
import org.lwjgl.glfw.GLFW;
public class CrystallineSkyClient implements ClientModInitializer {
@@ -26,35 +26,35 @@ public class CrystallineSkyClient implements ClientModInitializer {
BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.SKY, CrystallineRenderLayers.SKY);
BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.WEEPING_SKY, CrystallineRenderLayers.SKY);
var weepingSkyKeybind = KeyBindingHelper.registerKeyBinding(new KeyBinding(
var weepingSkyKeybind = KeyBindingHelper.registerKeyBinding(new KeyMapping(
"crystalline_sky.key.toggle_weeping_sky_debug",
InputUtil.Type.KEYSYM,
InputConstants.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN,
"crystalline_sky.category.crystalline_sky"
));
ClientTickEvents.END_CLIENT_TICK.register(client -> {
while (weepingSkyKeybind.wasPressed()) {
while (weepingSkyKeybind.consumeClick()) {
int mode = ((DebugRenderer_Duck) client.debugRenderer).crystalline_sky$toggleWeepingSky();
Text message = getDebugMessage(Formatting.YELLOW,
Text.translatable("message.crystalline_sky.weeping_sky_debug." + mode)
Component message = getDebugMessage(ChatFormatting.YELLOW,
Component.translatable("message.crystalline_sky.weeping_sky_debug." + mode)
);
client.inGameHud.getChatHud().addMessage(message);
client.gui.getChat().addMessage(message);
}
});
ModelPredicateProviderRegistry.register(CrystallineItems.SKY_LIGHT, Identifier.ofVanilla("level"),
ItemProperties.register(CrystallineItems.SKY_LIGHT, ResourceLocation.withDefaultNamespace("level"),
(stack, world, entity, seed) -> {
BlockStateComponent blockStateComponent = stack.getOrDefault(DataComponentTypes.BLOCK_STATE, BlockStateComponent.DEFAULT);
Integer integer = blockStateComponent.getValue(LightBlock.LEVEL_15);
BlockItemStateProperties blockStateComponent = stack.getOrDefault(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY);
Integer integer = blockStateComponent.get(LightBlock.LEVEL);
return integer != null ? integer / 16.0F : 1.0F;
});
}
@SuppressWarnings("SameParameterValue")
private static Text getDebugMessage(Formatting formatting, Text message) {
return Text.empty().append(Text.translatable("debug.prefix").formatted(formatting, Formatting.BOLD)).append(ScreenTexts.SPACE).append(message);
private static Component getDebugMessage(ChatFormatting formatting, Component message) {
return Component.empty().append(Component.translatable("debug.prefix").withStyle(formatting, ChatFormatting.BOLD)).append(CommonComponents.SPACE).append(message);
}
}
@@ -12,8 +12,8 @@ import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderOptions;
import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderTextureSlot;
import net.caffeinemc.mods.sodium.client.render.chunk.shader.ShaderBindingContext;
import net.caffeinemc.mods.sodium.client.util.TextureUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.math.MathHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Mth;
import org.joml.Matrix4fc;
import org.lwjgl.opengl.GL32C;
@@ -50,16 +50,16 @@ public class SkyShaderInterface implements ChunkShaderInterface {
public void setupState() {
this.bindTexture(ChunkShaderTextureSlot.BLOCK, TextureUtil.getBlockTextureId());
MinecraftClient client = MinecraftClient.getInstance();
if (client.world != null
Minecraft client = Minecraft.getInstance();
if (client.level != null
&& client.player != null
&& (client.player.getMainHandStack().isOf(CrystallineItems.SKY)
|| client.player.getOffHandStack().isOf(CrystallineItems.SKY)
|| client.player.getMainHandStack().isOf(CrystallineItems.WEEPING_SKY)
|| client.player.getOffHandStack().isOf(CrystallineItems.WEEPING_SKY))) {
&& (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))) {
float f = client.world.getTime() + client.getRenderTickCounter().getTickDelta(true);
float alpha = (MathHelper.sin(f / 10.0f) + 1.0f) / 2.0f;
float f = client.level.getGameTime() + client.getTimer().getGameTimeDeltaPartialTick(true);
float alpha = (Mth.sin(f / 10.0f) + 1.0f) / 2.0f;
// remap alpha from [0, 1] to [0, 0.75]
float maxAlpha = 1.0f - 0.25f;
alpha = alpha * maxAlpha;
@@ -1,21 +1,22 @@
package io.github.slimeistdev.crystalline_sky.content.blocks;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.minecraft.block.BlockState;
import net.minecraft.block.LightBlock;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
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;
public class SkyLightBlock extends LightBlock {
public SkyLightBlock(Settings settings) {
public SkyLightBlock(Properties settings) {
super(settings);
}
@Override
protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return context.isHolding(CrystallineItems.SKY_LIGHT) ? VoxelShapes.fullCube() : VoxelShapes.empty();
protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
return context.isHoldingItem(CrystallineItems.SKY_LIGHT) ? Shapes.block() : Shapes.empty();
}
}
@@ -1,74 +1,75 @@
package io.github.slimeistdev.crystalline_sky.content.blocks;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.Waterloggable;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.WorldAccess;
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;
public class WeepingSkyLightBlock extends Block implements Waterloggable {
public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED;
public class WeepingSkyLightBlock extends Block implements SimpleWaterloggedBlock {
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public WeepingSkyLightBlock(Settings settings) {
public WeepingSkyLightBlock(Properties settings) {
super(settings);
setDefaultState(getStateManager().getDefaultState().with(WATERLOGGED, false));
registerDefaultState(getStateDefinition().any().setValue(WATERLOGGED, false));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(WATERLOGGED);
}
@Override
protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return context.isHolding(CrystallineItems.WEEPING_SKY_LIGHT) ? VoxelShapes.fullCube() : VoxelShapes.empty();
protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
return context.isHoldingItem(CrystallineItems.WEEPING_SKY_LIGHT) ? Shapes.block() : Shapes.empty();
}
@Override
protected boolean isTransparent(BlockState state, BlockView world, BlockPos pos) {
protected boolean propagatesSkylightDown(BlockState state, BlockGetter world, BlockPos pos) {
return state.getFluidState().isEmpty();
}
@Override
protected BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.INVISIBLE;
protected RenderShape getRenderShape(BlockState state) {
return RenderShape.INVISIBLE;
}
@Override
protected float getAmbientOcclusionLightLevel(BlockState state, BlockView world, BlockPos pos) {
protected float getShadeBrightness(BlockState state, BlockGetter world, BlockPos pos) {
return 1.0f;
}
@Override
protected BlockState getStateForNeighborUpdate(
protected BlockState updateShape(
BlockState state,
Direction direction,
BlockState neighborState,
WorldAccess world,
LevelAccessor world,
BlockPos pos,
BlockPos neighborPos
) {
if (state.get(WATERLOGGED)) {
world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
if (state.getValue(WATERLOGGED)) {
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
}
return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos);
return super.updateShape(state, direction, neighborState, world, pos, neighborPos);
}
@Override
protected FluidState getFluidState(BlockState state) {
return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state);
}
}
@@ -1,45 +1,46 @@
package io.github.slimeistdev.crystalline_sky.content.items;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineDataComponentTypes;
import net.minecraft.block.Block;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ColumnPos;
import net.minecraft.world.World;
import net.minecraft.world.item.Item.Properties;
import net.minecraft.world.level.block.Block;
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;
public class WeepingSkyBlockItem extends BlockItem {
public WeepingSkyBlockItem(Block block, Settings settings) {
public WeepingSkyBlockItem(Block block, Properties settings) {
super(block, settings);
}
@Override
public ActionResult useOnBlock(ItemUsageContext context) {
ItemStack stack = context.getStack();
public InteractionResult useOn(UseOnContext context) {
ItemStack stack = context.getItemInHand();
if (stack.get(CrystallineDataComponentTypes.WEEPING_SKY_DEBUG_COLUMN_TOOL) != null) {
if (context.getWorld().isClient) {
BlockPos pos = context.getBlockPos();
if (context.getLevel().isClientSide) {
BlockPos pos = context.getClickedPos();
WeepingSkyBlockItemClient.setSelectedColumn(new ColumnPos(pos.getX(), pos.getZ()));
}
return ActionResult.SUCCESS;
return InteractionResult.SUCCESS;
}
return super.useOnBlock(context);
return super.useOn(context);
}
@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
ItemStack stack = user.getStackInHand(hand);
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
ItemStack stack = user.getItemInHand(hand);
if (stack.get(CrystallineDataComponentTypes.WEEPING_SKY_DEBUG_COLUMN_TOOL) != null) {
if (world.isClient) {
if (world.isClientSide) {
WeepingSkyBlockItemClient.setSelectedColumn(null);
}
return TypedActionResult.success(stack);
return InteractionResultHolder.success(stack);
}
return super.use(world, user, hand);
@@ -4,22 +4,22 @@ import io.github.slimeistdev.crystalline_sky.infrastructure.client.WeepingSkyDeb
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.DebugRenderer_Duck;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.minecraft.util.math.ColumnPos;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ColumnPos;
import org.jetbrains.annotations.Nullable;
public class WeepingSkyBlockItemClient {
// todone check if this is server-safe
@Environment(EnvType.CLIENT)
public static void setSelectedColumn(@Nullable ColumnPos column) {
MinecraftClient mc = MinecraftClient.getInstance();
Minecraft mc = Minecraft.getInstance();
WeepingSkyDebugRenderer weepingSkyDebugRenderer = ((DebugRenderer_Duck) mc.debugRenderer).crystalline_sky$getWeepingSkyDebugRenderer();
weepingSkyDebugRenderer.setColumn(column);
Text text = column == null
? Text.translatable("message.crystalline_sky.weeping_sky_debug.column.cleared")
: Text.translatable("message.crystalline_sky.weeping_sky_debug.column.set", column.x(), column.z());
mc.inGameHud.setOverlayMessage(text, false);
Component text = column == null
? Component.translatable("message.crystalline_sky.weeping_sky_debug.column.cleared")
: Component.translatable("message.crystalline_sky.weeping_sky_debug.column.set", column.x(), column.z());
mc.gui.setOverlayMessage(text, false);
}
}
@@ -4,27 +4,27 @@ import io.github.slimeistdev.crystalline_sky.CrystallineSky;
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.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.core.registries.Registries;
import net.minecraft.core.HolderLookup;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.TagKey;
import java.util.concurrent.CompletableFuture;
public class CrystallineSkyBlockTagProvider extends FabricTagProvider.BlockTagProvider {
public CrystallineSkyBlockTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
public CrystallineSkyBlockTagProvider(FabricDataOutput output, CompletableFuture<HolderLookup.Provider> registriesFuture) {
super(output, registriesFuture);
}
@Override
protected void configure(RegistryWrapper.WrapperLookup wrapperLookup) {
getOrCreateTagBuilder(TagKey.of(RegistryKeys.BLOCK, CrystallineSky.id("sky_light_emitters")))
protected void addTags(HolderLookup.Provider wrapperLookup) {
tag(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)
tag(BlockTags.CRYSTAL_SOUND_BLOCKS)
.add(CrystallineBlocks.SKY)
.add(CrystallineBlocks.WEEPING_SKY);
}
@@ -3,18 +3,18 @@ package io.github.slimeistdev.crystalline_sky.datagen.providers;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.core.HolderLookup;
import java.util.concurrent.CompletableFuture;
public class CrystallineSkyLootProvider extends FabricBlockLootTableProvider {
public CrystallineSkyLootProvider(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) {
public CrystallineSkyLootProvider(FabricDataOutput dataOutput, CompletableFuture<HolderLookup.Provider> registryLookup) {
super(dataOutput, registryLookup);
}
@Override
public void generate() {
addDropWithSilkTouch(CrystallineBlocks.SKY);
addDropWithSilkTouch(CrystallineBlocks.WEEPING_SKY);
dropWhenSilkTouch(CrystallineBlocks.SKY);
dropWhenSilkTouch(CrystallineBlocks.WEEPING_SKY);
}
}
@@ -6,19 +6,19 @@ import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateModelGenerator;
import net.minecraft.data.client.BlockStateVariant;
import net.minecraft.data.client.BlockStateVariantMap;
import net.minecraft.data.client.ItemModelGenerator;
import net.minecraft.data.client.ModelIds;
import net.minecraft.data.client.Models;
import net.minecraft.data.client.TextureMap;
import net.minecraft.data.client.VariantSettings;
import net.minecraft.data.client.VariantsBlockStateSupplier;
import net.minecraft.item.Item;
import net.minecraft.state.property.Properties;
import net.minecraft.util.Identifier;
import net.minecraft.world.level.block.Block;
import net.minecraft.data.models.BlockModelGenerators;
import net.minecraft.data.models.blockstates.Variant;
import net.minecraft.data.models.blockstates.PropertyDispatch;
import net.minecraft.data.models.ItemModelGenerators;
import net.minecraft.data.models.model.ModelLocationUtils;
import net.minecraft.data.models.model.ModelTemplates;
import net.minecraft.data.models.model.TextureMapping;
import net.minecraft.data.models.blockstates.VariantProperties;
import net.minecraft.data.models.blockstates.MultiVariantGenerator;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.resources.ResourceLocation;
import java.util.Locale;
@@ -29,45 +29,45 @@ public class CrystallineSkyModelProvider extends FabricModelProvider {
}
@Override
public void generateBlockStateModels(BlockStateModelGenerator gen) {
public void generateBlockStateModels(BlockModelGenerators gen) {
registerSkyBlock(gen, CrystallineBlocks.SKY);
registerSkyBlock(gen, CrystallineBlocks.WEEPING_SKY);
registerSkyLightBlock(gen, CrystallineBlocks.SKY_LIGHT, CrystallineItems.SKY_LIGHT);
gen.registerBuiltinWithParticle(CrystallineBlocks.WEEPING_SKY_LIGHT, CrystallineItems.WEEPING_SKY_LIGHT);
gen.registerItemModel(CrystallineItems.WEEPING_SKY_LIGHT);
gen.createAirLikeBlock(CrystallineBlocks.WEEPING_SKY_LIGHT, CrystallineItems.WEEPING_SKY_LIGHT);
gen.createSimpleFlatItemModel(CrystallineItems.WEEPING_SKY_LIGHT);
}
private void registerSkyBlock(BlockStateModelGenerator gen, Block block) {
gen.registerSimpleCubeAll(block);
gen.registerItemModel(block);
private void registerSkyBlock(BlockModelGenerators gen, Block block) {
gen.createTrivialCube(block);
gen.createSimpleFlatItemModel(block);
}
private void registerSkyLightBlock(BlockStateModelGenerator gen, Block block, Item item) {
gen.excludeFromSimpleItemModelGeneration(block);
BlockStateVariantMap.SingleProperty<Integer> singleProperty = BlockStateVariantMap.create(Properties.LEVEL_15);
private void registerSkyLightBlock(BlockModelGenerators gen, Block block, Item item) {
gen.skipAutoItemBlock(block);
PropertyDispatch.C1<Integer> singleProperty = PropertyDispatch.property(BlockStateProperties.LEVEL);
for (int level = 0; level <= 15; level++) {
String suffix = String.format(Locale.ROOT, "_%02d", level);
Identifier texture = TextureMap.getSubId(item, suffix);
ResourceLocation texture = TextureMapping.getItemTexture(item, suffix);
singleProperty.register(level, BlockStateVariant.create().put(
VariantSettings.MODEL,
Models.PARTICLE.upload(block, suffix, TextureMap.particle(texture), gen.modelCollector))
singleProperty.select(level, Variant.variant().with(
VariantProperties.MODEL,
ModelTemplates.PARTICLE_ONLY.createWithSuffix(block, suffix, TextureMapping.particle(texture), gen.modelOutput))
);
Models.GENERATED.upload(
ModelIds.getItemSubModelId(item, suffix),
TextureMap.layer0(texture),
gen.modelCollector
ModelTemplates.FLAT_ITEM.create(
ModelLocationUtils.getModelLocation(item, suffix),
TextureMapping.layer0(texture),
gen.modelOutput
);
}
Models.GENERATED.upload(
ModelIds.getItemModelId(item),
TextureMap.layer0(item),
gen.modelCollector,
ModelTemplates.FLAT_ITEM.create(
ModelLocationUtils.getModelLocation(item),
TextureMapping.layer0(item),
gen.modelOutput,
(id, textures) -> {
JsonObject base = Models.GENERATED.createJson(id, textures);
JsonObject base = ModelTemplates.FLAT_ITEM.createBaseTemplate(id, textures);
var overrides = new JsonArray();
for (int level = 0; level <= 15; level++) {
JsonObject override = new JsonObject();
@@ -77,7 +77,7 @@ public class CrystallineSkyModelProvider extends FabricModelProvider {
override.add("predicate", predicate);
String suffix = String.format(Locale.ROOT, "_%02d", level);
Identifier model = TextureMap.getSubId(item, suffix);
ResourceLocation model = TextureMapping.getItemTexture(item, suffix);
override.addProperty("model", model.toString());
overrides.add(override);
@@ -85,9 +85,9 @@ public class CrystallineSkyModelProvider extends FabricModelProvider {
base.add("overrides", overrides);
return base;
});
gen.blockStateCollector.accept(VariantsBlockStateSupplier.create(block).coordinate(singleProperty));
gen.blockStateOutput.accept(MultiVariantGenerator.multiVariant(block).with(singleProperty));
}
@Override
public void generateItemModels(ItemModelGenerator gen) {}
public void generateItemModels(ItemModelGenerators gen) {}
}
@@ -1,28 +1,28 @@
package io.github.slimeistdev.crystalline_sky.infrastructure;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.chunk.light.ChunkLightProvider;
import net.minecraft.world.level.block.state.BlockState;
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.lighting.LightEngine;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
private @Nullable BlockView blockView;
private @Nullable BlockGetter blockView;
private final int minY;
private final BlockPos.Mutable reusablePos1 = new BlockPos.Mutable();
private final BlockPos.Mutable reusablePos2 = new BlockPos.Mutable();
private final BlockPos.MutableBlockPos reusablePos1 = new BlockPos.MutableBlockPos();
private final BlockPos.MutableBlockPos reusablePos2 = new BlockPos.MutableBlockPos();
public MutableWeepingScanner(int minY) {
this.minY = minY;
}
public void setBlockView(@Nullable BlockView blockView) {
public void setBlockView(@Nullable BlockGetter blockView) {
this.blockView = blockView;
}
@@ -34,7 +34,7 @@ public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
return y == Integer.MIN_VALUE ? -1 : y - minY;
}
private @NotNull BlockView checkBlockView() {
private @NotNull BlockGetter checkBlockView() {
if (blockView == null) {
throw new IllegalStateException("blockView is not set");
} else {
@@ -44,12 +44,12 @@ public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
@Override
public int scan(int localX, int yMax, int localZ) {
BlockView blockView = checkBlockView();
BlockGetter blockView = checkBlockView();
int actualYMax = transformInputY(yMax);
BlockPos.Mutable topPos = reusablePos1.set(localX, actualYMax, localZ);
BlockPos.Mutable bottomPos = reusablePos2.set(localX, actualYMax - 1, localZ);
BlockPos.MutableBlockPos topPos = reusablePos1.set(localX, actualYMax, localZ);
BlockPos.MutableBlockPos bottomPos = reusablePos2.set(localX, actualYMax - 1, localZ);
BlockState topState = blockView.getBlockState(topPos);
while (bottomPos.getY() >= minY) {
@@ -68,12 +68,12 @@ public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
@Override
public int scanForWeepingSky(int localX, int yMax, int localZ) {
BlockView blockView = checkBlockView();
BlockGetter blockView = checkBlockView();
int actualYMax = transformInputY(yMax);
BlockPos.Mutable topPos = reusablePos1.set(localX, actualYMax, localZ);
BlockPos.Mutable bottomPos = reusablePos2.set(localX, actualYMax - 1, localZ);
BlockPos.MutableBlockPos topPos = reusablePos1.set(localX, actualYMax, localZ);
BlockPos.MutableBlockPos bottomPos = reusablePos2.set(localX, actualYMax - 1, localZ);
BlockState topState = blockView.getBlockState(topPos);
if (CrystallineBlocks.isWeepingSky(topState))
@@ -99,7 +99,7 @@ public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
@Override
public boolean faceBlocksLight(int localX, int upperY, int localZ) {
BlockView blockView = checkBlockView();
BlockGetter blockView = checkBlockView();
int actualY = transformInputY(upperY);
reusablePos1.set(localX, actualY, localZ);
@@ -110,13 +110,13 @@ public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
return faceBlocksLight(blockView, upper, lower, reusablePos1, reusablePos2);
}
private static boolean faceBlocksLight(BlockView world, BlockState upper, BlockState lower, BlockPos upperPos, BlockPos lowerPos) {
if (lower.getOpacity(world, lowerPos) != 0) {
private static boolean faceBlocksLight(BlockGetter world, BlockState upper, BlockState lower, BlockPos upperPos, BlockPos lowerPos) {
if (lower.getLightBlock(world, lowerPos) != 0) {
return true;
} else {
VoxelShape voxelShape = ChunkLightProvider.getOpaqueShape(world, upperPos, upper, Direction.DOWN);
VoxelShape voxelShape2 = ChunkLightProvider.getOpaqueShape(world, lowerPos, lower, Direction.UP);
return VoxelShapes.unionCoversFullCube(voxelShape, voxelShape2);
VoxelShape voxelShape = LightEngine.getOcclusionShape(world, upperPos, upper, Direction.DOWN);
VoxelShape voxelShape2 = LightEngine.getOcclusionShape(world, lowerPos, lower, Direction.UP);
return Shapes.faceShapeOccludes(voxelShape, voxelShape2);
}
}
}
@@ -4,22 +4,22 @@ import io.github.slimeistdev.crystalline_sky.infrastructure.WeepingStorage;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.ChunkSkyLight_Duck;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.debug.DebugRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.ColumnPos;
import net.minecraft.world.chunk.light.ChunkSkyLight;
import net.minecraft.world.chunk.light.LightSourceView;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.debug.DebugRenderer;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.server.level.ColumnPos;
import net.minecraft.world.level.lighting.ChunkSkyLightSources;
import net.minecraft.world.level.chunk.LightChunk;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
@Environment(EnvType.CLIENT)
public class WeepingSkyDebugRenderer implements DebugRenderer.Renderer {
private final MinecraftClient client;
public class WeepingSkyDebugRenderer implements DebugRenderer.SimpleDebugRenderer {
private final Minecraft client;
private @Nullable ColumnPos column = null;
private boolean litMode = true;
@@ -36,7 +36,7 @@ public class WeepingSkyDebugRenderer implements DebugRenderer.Renderer {
0xFFFF007F,
};
public WeepingSkyDebugRenderer(MinecraftClient client) {
public WeepingSkyDebugRenderer(Minecraft client) {
this.client = client;
}
@@ -49,19 +49,19 @@ public class WeepingSkyDebugRenderer implements DebugRenderer.Renderer {
}
@Override
public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, double cameraX, double cameraY, double cameraZ) {
public void render(PoseStack matrices, MultiBufferSource vertexConsumers, double cameraX, double cameraY, double cameraZ) {
if (column == null)
return;
if (client.world == null)
if (client.level == null)
return;
ChunkPos chunkPos = column.toChunkPos();
LightSourceView chunk = client.world.getChunkManager().getChunk(chunkPos.x, chunkPos.z);
LightChunk chunk = client.level.getChunkSource().getChunkForLighting(chunkPos.x, chunkPos.z);
if (chunk == null)
return;
ChunkSkyLight chunkSkyLight = chunk.getChunkSkyLight();
ChunkSkyLightSources chunkSkyLight = chunk.getSkyLightSources();
WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage();
if (weepingStorage == null)
return;
@@ -69,9 +69,9 @@ public class WeepingSkyDebugRenderer implements DebugRenderer.Renderer {
int localX = column.x() & 15;
int localZ = column.z() & 15;
int lowestSourceY = chunkSkyLight.get(localX, localZ);
int lowestSourceY = chunkSkyLight.getLowestSourceY(localX, localZ);
Matrix4f matrix4f = matrices.peek().getPositionMatrix();
Matrix4f matrix4f = matrices.last().pose();
float x1 = (float) (column.x() - cameraX);
float x2 = x1 + 1;
@@ -104,8 +104,8 @@ public class WeepingSkyDebugRenderer implements DebugRenderer.Renderer {
}
}
private static void renderOutlinedBox(VertexConsumerProvider vertexConsumers, Matrix4f matrix, float x1, float x2, float y1, float y2, float z1, float z2, int color) {
VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getDebugLineStrip(2.0));
private static void renderOutlinedBox(MultiBufferSource vertexConsumers, Matrix4f matrix, float x1, float x2, float y1, float y2, float z1, float z2, int color) {
VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderType.debugLineStrip(2.0));
// render top face
renderHorizontalSquare(matrix, x1, x2, y1, z1, z2, color, vertexConsumer);
@@ -116,24 +116,24 @@ public class WeepingSkyDebugRenderer implements DebugRenderer.Renderer {
// the (x1, z1) vertical edge has been drawn, draw the other 3
// (x2, z1)
vertexConsumer.vertex(matrix, x2, y2, z1).color(color);
vertexConsumer.vertex(matrix, x2, y1, z1).color(color);
vertexConsumer.addVertex(matrix, x2, y2, z1).setColor(color);
vertexConsumer.addVertex(matrix, x2, y1, z1).setColor(color);
// (x2, z2)
vertexConsumer.vertex(matrix, x2, y1, z2).color(color);
vertexConsumer.vertex(matrix, x2, y2, z2).color(color);
vertexConsumer.addVertex(matrix, x2, y1, z2).setColor(color);
vertexConsumer.addVertex(matrix, x2, y2, z2).setColor(color);
// (x1, z2)
vertexConsumer.vertex(matrix, x1, y2, z2).color(color);
vertexConsumer.vertex(matrix, x1, y1, z2).color(color);
vertexConsumer.addVertex(matrix, x1, y2, z2).setColor(color);
vertexConsumer.addVertex(matrix, x1, y1, z2).setColor(color);
}
private static void renderHorizontalSquare(Matrix4f matrix, float x1, float x2, float y, float z1, float z2, int color, VertexConsumer vertexConsumer) {
vertexConsumer.vertex(matrix, x1, y, z1).color(color);
vertexConsumer.vertex(matrix, x2, y, z1).color(color);
vertexConsumer.vertex(matrix, x2, y, z2).color(color);
vertexConsumer.vertex(matrix, x1, y, z2).color(color);
vertexConsumer.vertex(matrix, x1, y, z1).color(color);
vertexConsumer.addVertex(matrix, x1, y, z1).setColor(color);
vertexConsumer.addVertex(matrix, x2, y, z1).setColor(color);
vertexConsumer.addVertex(matrix, x2, y, z2).setColor(color);
vertexConsumer.addVertex(matrix, x1, y, z2).setColor(color);
vertexConsumer.addVertex(matrix, x1, y, z1).setColor(color);
}
@Override
@@ -8,40 +8,40 @@ import io.github.slimeistdev.crystalline_sky.mixin_ducks.ChunkSkyLight_Duck;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import it.unimi.dsi.fastutil.shorts.ShortArrayList;
import it.unimi.dsi.fastutil.shorts.ShortList;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkSectionPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
import net.minecraft.world.HeightLimitView;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.chunk.light.ChunkSkyLight;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.lighting.ChunkSkyLightSources;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ChunkSkyLight.class)
public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
@Mixin(ChunkSkyLightSources.class)
public abstract class ChunkSkyLightSourcesMixin implements ChunkSkyLight_Duck {
@Shadow
@Final
private int minY;
@Shadow
@Final
private BlockPos.Mutable reusableBlockPos1;
private BlockPos.MutableBlockPos mutablePos1;
@Shadow
private static boolean faceBlocksLight(BlockView blockView, BlockPos upperPos, BlockState upperState, BlockPos lowerPos, BlockState lowerState) {
private static boolean isEdgeOccluded(BlockGetter blockView, BlockPos upperPos, BlockState upperState, BlockPos lowerPos, BlockState lowerState) {
throw new RuntimeException("Mixin failed to apply");
}
@Shadow
@Final
private BlockPos.Mutable reusableBlockPos2;
private BlockPos.MutableBlockPos mutablePos2;
@Unique
@Final
@@ -54,7 +54,7 @@ public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
private MutableWeepingScanner crystalline_sky$weepingScanner;
@Inject(method = "<init>", at = @At("RETURN"))
private void init(HeightLimitView heightLimitView, CallbackInfo ci) {
private void init(LevelHeightAccessor heightLimitView, CallbackInfo ci) {
crystalline_sky$weepingStorage = new IntWeepingStorage(minY + 1);
crystalline_sky$weepingScanner = new MutableWeepingScanner(minY + 1);
}
@@ -64,13 +64,13 @@ public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
return crystalline_sky$weepingStorage;
}
@Inject(method = "refreshSurfaceY", at = @At("HEAD"))
private void refreshWeepingSurfaceY(Chunk chunk, CallbackInfo ci) {
int highestNonEmptySectionIndex = chunk.getHighestNonEmptySection();
@Inject(method = "fillFrom", at = @At("HEAD"))
private void refreshWeepingSurfaceY(ChunkAccess chunk, CallbackInfo ci) {
int highestNonEmptySectionIndex = chunk.getHighestFilledSectionIndex();
if (highestNonEmptySectionIndex == -1) {
crystalline_sky$weepingStorage.clear();
} else {
int topY = ChunkSectionPos.getBlockCoord(chunk.sectionIndexToCoord(highestNonEmptySectionIndex) + 1);
int topY = SectionPos.sectionToBlockCoord(chunk.getSectionYFromSectionIndex(highestNonEmptySectionIndex) + 1);
int weepingMinY = minY + 1;
ShortList data = new ShortArrayList();
@@ -79,18 +79,18 @@ public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
for (int x = 0; x < 16; x++) {
data.clear();
BlockPos.Mutable topPos = reusableBlockPos1.set(x, topY, z);
BlockPos.Mutable bottomPos = reusableBlockPos2.set(x, topY - 1, z);
BlockState topState = Blocks.AIR.getDefaultState();
BlockPos.MutableBlockPos topPos = mutablePos1.set(x, topY, z);
BlockPos.MutableBlockPos bottomPos = mutablePos2.set(x, topY - 1, z);
BlockState topState = Blocks.AIR.defaultBlockState();
short foundSky = -1;
for (int sectionIndex = highestNonEmptySectionIndex; sectionIndex >= 0; sectionIndex--) {
ChunkSection section = chunk.getSection(sectionIndex);
LevelChunkSection section = chunk.getSection(sectionIndex);
if (section.isEmpty()) {
topState = Blocks.AIR.getDefaultState();
topPos.setY(ChunkSectionPos.getBlockCoord(chunk.sectionIndexToCoord(sectionIndex)));
if (section.hasOnlyAir()) {
topState = Blocks.AIR.defaultBlockState();
topPos.setY(SectionPos.sectionToBlockCoord(chunk.getSectionYFromSectionIndex(sectionIndex)));
bottomPos.setY(topPos.getY() - 1);
} else {
for (int y = 15; y >= 0; y--) {
@@ -100,7 +100,7 @@ public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
if (foundSky == -1) {
foundSky = (short) (bottomPos.getY() - weepingMinY);
}
} else if (faceBlocksLight(chunk, topPos, topState, bottomPos, bottomState)) {
} else if (isEdgeOccluded(chunk, topPos, topState, bottomPos, bottomState)) {
if (foundSky != -1) {
short lastLitY = (short) (bottomPos.getY() - weepingMinY + 1);
data.add(foundSky);
@@ -127,9 +127,9 @@ public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
}
}
@Inject(method = "isSkyLightAccessible(Lnet/minecraft/world/BlockView;III)Z", at = @At("HEAD"))
private void updateWeepingSkyState(BlockView blockView, int localX, int y, int localZ, CallbackInfoReturnable<Boolean> cir) {
BlockPos pos = reusableBlockPos1.set(localX, y, localZ);
@Inject(method = "update(Lnet/minecraft/world/level/BlockGetter;III)Z", at = @At("HEAD"))
private void updateWeepingSkyState(BlockGetter blockView, int localX, int y, int localZ, CallbackInfoReturnable<Boolean> cir) {
BlockPos pos = mutablePos1.set(localX, y, localZ);
BlockState state = blockView.getBlockState(pos);
crystalline_sky$weepingScanner.setBlockView(blockView);
@@ -140,7 +140,7 @@ public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
crystalline_sky$weepingStorage.insertAir(localX, y - weepingMinY, localZ, crystalline_sky$weepingScanner);
} else if (CrystallineBlocks.isWeepingSky(state)) {
crystalline_sky$weepingStorage.insertSky(localX, y - weepingMinY, localZ, crystalline_sky$weepingScanner);
} else if (state.isOpaque()) {
} else if (state.canOcclude()) {
crystalline_sky$weepingStorage.insertSolid(localX, y - weepingMinY, localZ, crystalline_sky$weepingScanner);
}
@@ -0,0 +1,25 @@
package io.github.slimeistdev.crystalline_sky.mixin;
import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.lighting.LayerLightSectionStorage;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(LayerLightSectionStorage.class)
public interface LayerLightSectionStorageAccessor {
@Invoker("lightOnInSection")
boolean crystalline_sky$callLightOnInSection(long sectionPos);
@Invoker("storingLightForSection")
boolean crystalline_sky$hasSection(long sectionPos);
@Invoker("getStoredLevel")
int crystalline_sky$get(long blockPos);
@Invoker("setStoredLevel")
void crystalline_sky$set(long blockPos, int lightLevel);
@Invoker("getDataLayerToWrite")
@Nullable DataLayer crystalline_sky$method_51547(long sectionPos);
}
@@ -3,16 +3,16 @@ package io.github.slimeistdev.crystalline_sky.mixin;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.chunk.light.ChunkLightProvider;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.lighting.LightEngine;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(ChunkLightProvider.class)
public class ChunkLightProviderMixin {
@WrapMethod(method = "needsLightUpdate")
private static boolean updateSky(BlockView blockView, BlockPos pos, BlockState oldState, BlockState newState, Operation<Boolean> original) {
@Mixin(LightEngine.class)
public class LightEngineMixin {
@WrapMethod(method = "hasDifferentLightProperties")
private static boolean updateSky(BlockGetter blockView, BlockPos pos, BlockState oldState, BlockState newState, Operation<Boolean> original) {
return original.call(blockView, pos, oldState, newState)
|| (CrystallineBlocks.getSkyLightLevel(oldState) != CrystallineBlocks.getSkyLightLevel(newState))
|| (CrystallineBlocks.isWeepingSky(oldState) != CrystallineBlocks.isWeepingSky(newState));
@@ -1,25 +0,0 @@
package io.github.slimeistdev.crystalline_sky.mixin;
import net.minecraft.world.chunk.ChunkNibbleArray;
import net.minecraft.world.chunk.light.LightStorage;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(LightStorage.class)
public interface LightStorageAccessor {
@Invoker("isSectionInEnabledColumn")
boolean crystalline_sky$callIsSectionInEnabledColumn(long sectionPos);
@Invoker("hasSection")
boolean crystalline_sky$hasSection(long sectionPos);
@Invoker("get")
int crystalline_sky$get(long blockPos);
@Invoker("set")
void crystalline_sky$set(long blockPos, int lightLevel);
@Invoker("method_51547")
@Nullable ChunkNibbleArray crystalline_sky$method_51547(long sectionPos);
}
@@ -8,20 +8,20 @@ import com.llamalad7.mixinextras.sugar.Local;
import io.github.slimeistdev.crystalline_sky.infrastructure.WeepingStorage;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.ChunkSkyLight_Duck;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.ChunkSectionPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkNibbleArray;
import net.minecraft.world.chunk.ChunkProvider;
import net.minecraft.world.chunk.ChunkToNibbleArrayMap;
import net.minecraft.world.chunk.light.ChunkLightProvider;
import net.minecraft.world.chunk.light.ChunkSkyLight;
import net.minecraft.world.chunk.light.ChunkSkyLightProvider;
import net.minecraft.world.chunk.light.LightSourceView;
import net.minecraft.world.chunk.light.LightStorage;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.core.SectionPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.LightChunkGetter;
import net.minecraft.world.level.lighting.DataLayerStorageMap;
import net.minecraft.world.level.lighting.LightEngine;
import net.minecraft.world.level.lighting.ChunkSkyLightSources;
import net.minecraft.world.level.lighting.SkyLightEngine;
import net.minecraft.world.level.chunk.LightChunk;
import net.minecraft.world.level.lighting.LayerLightSectionStorage;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -30,14 +30,14 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
// todone add ordinal to all name = "..." locals
@Mixin(ChunkSkyLightProvider.class)
public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap<M>, S extends LightStorage<M>> extends ChunkLightProvider<M, S> {
@Mixin(SkyLightEngine.class)
public abstract class SkyLightEngineMixin<M extends DataLayerStorageMap<M>, S extends LayerLightSectionStorage<M>> extends LightEngine<M, S> {
@Shadow
@Final
private BlockPos.Mutable scratchPos;
private BlockPos.MutableBlockPos mutablePos;
@Shadow
private static boolean isMaxLightLevel(int lightLevel) {
private static boolean isSourceLevel(int lightLevel) {
throw new RuntimeException("Mixin failed to apply");
}
@@ -53,18 +53,18 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
@Final
private static long ADD_SKY_SOURCE_ENTRY;
protected ChunkSkyLightProviderMixin(ChunkProvider chunkProvider, S lightStorage) {
protected SkyLightEngineMixin(LightChunkGetter chunkProvider, S lightStorage) {
super(chunkProvider, lightStorage);
}
@Inject(method = "checkNode", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/SkyLightStorage;get(J)I"))
@Inject(method = "checkNode", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/lighting/SkyLightSectionStorage;getStoredLevel(J)I"))
private void emitFromCrystallineSky(long blockPos, CallbackInfo ci) {
BlockState state = getStateForLighting(scratchPos.set(blockPos));
BlockState state = getState(mutablePos.set(blockPos));
int level = CrystallineBlocks.isWeepingSky(state)
? 15
: CrystallineBlocks.getSkyLightLevel(state);
if (level > 0 && ((LightStorageAccessor) lightStorage).crystalline_sky$callIsSectionInEnabledColumn(ChunkSectionPos.fromBlockPos(blockPos))) {
enqueueIncrease(blockPos, QueueEntry.increaseLightFromEmission(level, isTrivialForLighting(state)));
if (level > 0 && ((LayerLightSectionStorageAccessor) storage).crystalline_sky$callLightOnInSection(SectionPos.blockToSection(blockPos))) {
enqueueIncrease(blockPos, QueueEntry.increaseLightFromEmission(level, isEmptyShape(state)));
}
}
@@ -78,14 +78,14 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
return true;
}
LightSourceView chunk = chunkProvider.getChunk(ChunkSectionPos.getSectionCoord(x), ChunkSectionPos.getSectionCoord(z));
LightChunk chunk = chunkSource.getChunkForLighting(SectionPos.blockToSectionCoord(x), SectionPos.blockToSectionCoord(z));
if (chunk == null) return false;
ChunkSkyLight chunkSkyLight = chunk.getChunkSkyLight();
ChunkSkyLightSources chunkSkyLight = chunk.getSkyLightSources();
if (chunkSkyLight == null) return false;
int localX = ChunkSectionPos.getLocalCoord(x);
int localZ = ChunkSectionPos.getLocalCoord(z);
int localX = SectionPos.sectionRelative(x);
int localZ = SectionPos.sectionRelative(z);
WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage();
if (weepingStorage.isColumnEmpty(localX, localZ)) return false;
@@ -93,11 +93,11 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
return weepingStorage.isLit(localX, y, localZ);
}
@WrapOperation(method = "propagateDecrease", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/ChunkSkyLightProvider;enqueueDecrease(JJ)V"))
private void decreaseTakesLightIntoAccount1(ChunkSkyLightProvider instance, long blockPos, long flags,
@WrapOperation(method = "propagateDecrease", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/lighting/SkyLightEngine;enqueueDecrease(JJ)V"))
private void decreaseTakesLightIntoAccount1(SkyLightEngine instance, long blockPos, long flags,
Operation<Void> original, @Local(name = "k", ordinal = 2) int k) {
// k is the old light level at blockPos
BlockState state = getStateForLighting(scratchPos.set(blockPos));
BlockState state = getState(mutablePos.set(blockPos));
int luminance = CrystallineBlocks.getSkyLightLevel(state);
if (luminance < k) {
@@ -105,16 +105,16 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
}
if (luminance > 0) {
enqueueIncrease(blockPos, QueueEntry.increaseLightFromEmission(luminance, isTrivialForLighting(state)));
enqueueIncrease(blockPos, QueueEntry.increaseLightFromEmission(luminance, isEmptyShape(state)));
}
}
@WrapOperation(method = "propagateDecrease", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/ChunkSkyLightProvider;propagateFromEmptySections(JLnet/minecraft/util/math/Direction;IZI)V"))
private void decreaseTakesLightIntoAccount2(ChunkSkyLightProvider instance, long blockPos, Direction direction,
@WrapOperation(method = "propagateDecrease", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/lighting/SkyLightEngine;propagateFromEmptySections(JLnet/minecraft/core/Direction;IZI)V"))
private void decreaseTakesLightIntoAccount2(SkyLightEngine instance, long blockPos, Direction direction,
int lightLevel, boolean shouldIncrease, int emptySections,
Operation<Void> original, @Local(name = "k", ordinal = 2) int k) {
// k is the old light level at blockPos
BlockState state = getStateForLighting(scratchPos.set(blockPos));
BlockState state = getState(mutablePos.set(blockPos));
int luminance = CrystallineBlocks.getSkyLightLevel(state);
if (luminance < k) {
@@ -126,26 +126,28 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
}
}
@Inject(method = "propagateLight", at = @At("RETURN"))
@Inject(method = "propagateLightSources", at = @At("RETURN"))
private void propagateCrystallineSkyLight(ChunkPos chunkPos, CallbackInfo ci) {
LightSourceView lightSourceView = this.chunkProvider.getChunk(chunkPos.x, chunkPos.z);
if (!(lightSourceView instanceof Chunk chunk)) return;
LightChunk lightSourceView = this.chunkSource.getChunkForLighting(chunkPos.x, chunkPos.z);
if (!(lightSourceView instanceof ChunkAccess chunk)) return;
chunk.forEachBlockMatchingPredicate(CrystallineBlocks::isCrystallineSky, (pos, state) -> {
enqueueIncrease(pos.asLong(), QueueEntry.increaseLightFromEmission(CrystallineBlocks.getSkyLightLevel(state), isTrivialForLighting(state)));
chunk.findBlocks(CrystallineBlocks::isCrystallineSky, (pos, state) -> {
enqueueIncrease(pos.asLong(), QueueEntry.increaseLightFromEmission(CrystallineBlocks.getSkyLightLevel(state), isEmptyShape(state)));
});
}
// NOTE: lowestSourceY becomes minY, and minY becomes bottomSectionY under parchment.
// We're keeping the old names since it makes things more legible
@Inject(method = "removeSourcesBelow", at = @At("HEAD"), cancellable = true)
private void removeWeepingSourcesBelow(int x, int z, int lowestSourceY, int minY, CallbackInfo ci) {
LightSourceView chunk = chunkProvider.getChunk(ChunkSectionPos.getSectionCoord(x), ChunkSectionPos.getSectionCoord(z));
LightChunk chunk = chunkSource.getChunkForLighting(SectionPos.blockToSectionCoord(x), SectionPos.blockToSectionCoord(z));
if (chunk == null) return;
ChunkSkyLight chunkSkyLight = chunk.getChunkSkyLight();
ChunkSkyLightSources chunkSkyLight = chunk.getSkyLightSources();
if (chunkSkyLight == null) return;
int localX = ChunkSectionPos.getLocalCoord(x);
int localZ = ChunkSectionPos.getLocalCoord(z);
int localX = SectionPos.sectionRelative(x);
int localZ = SectionPos.sectionRelative(z);
WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage();
if (weepingStorage.isColumnEmpty(localX, localZ) && weepingStorage.hasNoUnlitSplits(localX, localZ)) return;
@@ -153,20 +155,20 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
// there's little chance of accidental mixin compatibility anyway, so just cancel
ci.cancel();
int sectionX = ChunkSectionPos.getSectionCoord(x);
int sectionZ = ChunkSectionPos.getSectionCoord(z);
int sectionX = SectionPos.blockToSectionCoord(x);
int sectionZ = SectionPos.blockToSectionCoord(z);
int effectiveLowestSourceY = lowestSourceY <= minY ? Integer.MIN_VALUE : lowestSourceY;
SkyLightStorageAccessor lightStorageAccessor = (SkyLightStorageAccessor) this.lightStorage;
SkyLightSectionStorageAccessor lightStorageAccessor = (SkyLightSectionStorageAccessor) this.storage;
RunIter: for (WeepingStorage.Run run : weepingStorage.iterateUnlitRuns(localX, localZ, effectiveLowestSourceY)) {
// check lighting state of run
int topUnlit = run.topY();
int bottomUnlit = run.bottomY();
for (int sectionY = ChunkSectionPos.getSectionCoord(topUnlit); lightStorageAccessor.crystalline_sky$isAboveMinHeight(sectionY); sectionY--) {
if (lightStorageAccessor.crystalline_sky$hasSection(ChunkSectionPos.asLong(sectionX, sectionY, sectionZ))) {
int minYInSection = ChunkSectionPos.getBlockCoord(sectionY);
for (int sectionY = SectionPos.blockToSectionCoord(topUnlit); lightStorageAccessor.crystalline_sky$isAboveMinHeight(sectionY); sectionY--) {
if (lightStorageAccessor.crystalline_sky$hasSection(SectionPos.asLong(sectionX, sectionY, sectionZ))) {
int minYInSection = SectionPos.sectionToBlockCoord(sectionY);
int maxYInSection = minYInSection + 15;
if (maxYInSection < bottomUnlit) { // todone break outer early if we're below bottomUnlit
@@ -176,11 +178,11 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
for (int it_y = Math.min(maxYInSection, topUnlit); it_y >= Math.max(minYInSection, bottomUnlit); it_y--) {
long it_pos = BlockPos.asLong(x, it_y, z);
if (CrystallineBlocks.isCrystallineSky(chunk.getBlockState(scratchPos.set(it_pos)))) {
if (CrystallineBlocks.isCrystallineSky(chunk.getBlockState(mutablePos.set(it_pos)))) {
continue;
}
if (!isMaxLightLevel(lightStorageAccessor.crystalline_sky$get(it_pos))) {
if (!isSourceLevel(lightStorageAccessor.crystalline_sky$get(it_pos))) {
continue RunIter;
}
@@ -194,17 +196,19 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
}
}
// NOTE: lowestSourceY becomes maxY, and minY becomes bottomSectionY under parchment.
// We're keeping the old names since it makes things more legible
@Inject(method = "addSourcesAbove", at = @At("RETURN"))
private void addAdditionalWeepingSourcesAbove(int x, int z, int lowestSourceY, int minY, CallbackInfo ci,
@Local(name = "maxAdjacentLowestSourceY", ordinal = 6) int maxAdjacentLowestSourceY) {
LightSourceView chunk = chunkProvider.getChunk(ChunkSectionPos.getSectionCoord(x), ChunkSectionPos.getSectionCoord(z));
LightChunk chunk = chunkSource.getChunkForLighting(SectionPos.blockToSectionCoord(x), SectionPos.blockToSectionCoord(z));
if (chunk == null) return;
ChunkSkyLight chunkSkyLight = chunk.getChunkSkyLight();
ChunkSkyLightSources chunkSkyLight = chunk.getSkyLightSources();
if (chunkSkyLight == null) return;
int localX = ChunkSectionPos.getLocalCoord(x);
int localZ = ChunkSectionPos.getLocalCoord(z);
int localX = SectionPos.sectionRelative(x);
int localZ = SectionPos.sectionRelative(z);
WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage();
if (weepingStorage.isColumnEmpty(localX, localZ)) {
@@ -212,8 +216,8 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
return;
}
int sectionX = ChunkSectionPos.getSectionCoord(x);
int sectionZ = ChunkSectionPos.getSectionCoord(z);
int sectionX = SectionPos.blockToSectionCoord(x);
int sectionZ = SectionPos.blockToSectionCoord(z);
int effectiveLowestSourceY = lowestSourceY <= minY ? Integer.MIN_VALUE : lowestSourceY;
if (effectiveLowestSourceY == Integer.MIN_VALUE) {
@@ -221,7 +225,7 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
return;
}
SkyLightStorageAccessor lightStorageAccessor = (SkyLightStorageAccessor) this.lightStorage;
SkyLightSectionStorageAccessor lightStorageAccessor = (SkyLightSectionStorageAccessor) this.storage;
RunIter: for (WeepingStorage.Run run : weepingStorage.iterateLitRuns(localX, localZ, effectiveLowestSourceY)) {
if (run.topY() == Integer.MAX_VALUE) {
@@ -233,12 +237,12 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
}
int lowestRelevantY = Math.max(run.bottomY(), minY);
for (long it_packedSection = ChunkSectionPos.asLong(sectionX, ChunkSectionPos.getSectionCoord(lowestRelevantY), sectionZ);
for (long it_packedSection = SectionPos.asLong(sectionX, SectionPos.blockToSectionCoord(lowestRelevantY), sectionZ);
!lightStorageAccessor.crystalline_sky$isAtOrAboveTopmostSection(it_packedSection);
it_packedSection = ChunkSectionPos.offset(it_packedSection, Direction.UP)
it_packedSection = SectionPos.offset(it_packedSection, Direction.UP)
) {
if (lightStorageAccessor.crystalline_sky$hasSection(it_packedSection)) {
int minYInSection = ChunkSectionPos.getBlockCoord(ChunkSectionPos.unpackY(it_packedSection));
int minYInSection = SectionPos.sectionToBlockCoord(SectionPos.y(it_packedSection));
int maxYInSection = minYInSection + 15;
if (minYInSection > run.topY()) { // todone break outer early if we're above run.topY()
@@ -248,11 +252,11 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
for (int it_y = Math.max(minYInSection, lowestRelevantY); it_y <= Math.min(maxYInSection, run.topY()); it_y++) {
long it_pos = BlockPos.asLong(x, it_y, z);
if (CrystallineBlocks.isCrystallineSky(chunk.getBlockState(scratchPos.set(it_pos)))) {
if (CrystallineBlocks.isCrystallineSky(chunk.getBlockState(mutablePos.set(it_pos)))) {
continue;
}
if (isMaxLightLevel(lightStorageAccessor.crystalline_sky$get(it_pos))) {
if (isSourceLevel(lightStorageAccessor.crystalline_sky$get(it_pos))) {
continue RunIter;
}
@@ -268,13 +272,13 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
weepingStorage.clearTempRunSplits(localX, localZ);
}
@Inject(method = "propagateLight", at = @At("RETURN"))
@Inject(method = "propagateLightSources", at = @At("RETURN"))
private void propagateWeepingLight(ChunkPos chunkPos, CallbackInfo ci,
@Local(name = "sourcesO", ordinal = 0) ChunkSkyLight sourcesO,
@Local(name = "sourcesZN", ordinal = 1) ChunkSkyLight sourcesZN,
@Local(name = "sourcesZP", ordinal = 2) ChunkSkyLight sourcesZP,
@Local(name = "sourcesXN", ordinal = 3) ChunkSkyLight sourcesXN,
@Local(name = "sourcesXP", ordinal = 4) ChunkSkyLight sourcesXP
@Local(name = "sourcesO", ordinal = 0) ChunkSkyLightSources sourcesO,
@Local(name = "sourcesZN", ordinal = 1) ChunkSkyLightSources sourcesZN,
@Local(name = "sourcesZP", ordinal = 2) ChunkSkyLightSources sourcesZP,
@Local(name = "sourcesXN", ordinal = 3) ChunkSkyLightSources sourcesXN,
@Local(name = "sourcesXP", ordinal = 4) ChunkSkyLightSources sourcesXP
) {
WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) sourcesO).crystalline_sky$getWeepingStorage();
if (weepingStorage == null) return;
@@ -291,19 +295,19 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
if (!hasAny)
return;
long packedZeroPos = ChunkSectionPos.withZeroY(chunkPos.x, chunkPos.z);
SkyLightStorageAccessor lightStorageAccessor = (SkyLightStorageAccessor) this.lightStorage;
long packedZeroPos = SectionPos.getZeroNode(chunkPos.x, chunkPos.z);
SkyLightSectionStorageAccessor lightStorageAccessor = (SkyLightSectionStorageAccessor) this.storage;
int topSectionY = lightStorageAccessor.crystalline_sky$getTopSectionForColumn(packedZeroPos);
int bottomSectionY = lightStorageAccessor.crystalline_sky$getMinSectionY();
int baseX = ChunkSectionPos.getBlockCoord(chunkPos.x);
int baseZ = ChunkSectionPos.getBlockCoord(chunkPos.z);
int baseX = SectionPos.sectionToBlockCoord(chunkPos.x);
int baseZ = SectionPos.sectionToBlockCoord(chunkPos.z);
int minY = ChunkSectionPos.getBlockCoord(bottomSectionY);
int minY = SectionPos.sectionToBlockCoord(bottomSectionY);
ChunkNibbleArray[] lightArrays = new ChunkNibbleArray[topSectionY - bottomSectionY];
DataLayer[] lightArrays = new DataLayer[topSectionY - bottomSectionY];
for (int sectionY = topSectionY - 1; sectionY >= bottomSectionY; sectionY--) {
long packedSectionPos = ChunkSectionPos.asLong(chunkPos.x, sectionY, chunkPos.z);
long packedSectionPos = SectionPos.asLong(chunkPos.x, sectionY, chunkPos.z);
lightArrays[sectionY - bottomSectionY] = lightStorageAccessor.crystalline_sky$method_51547(packedSectionPos);
}
@@ -311,14 +315,14 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
for (int localX = 0; localX < 16; localX++) {
if (weepingStorage.isColumnEmpty(localX, localZ)) continue;
int lowestSourceY = sourcesO.get(localX, localZ);
int lowestSourceY = sourcesO.getLowestSourceY(localX, localZ);
int effectiveLowestSourceY = lowestSourceY <= minY ? Integer.MIN_VALUE : lowestSourceY;
if (effectiveLowestSourceY == Integer.MIN_VALUE) continue;
int minSourceY_ZN = localZ == 0 ? sourcesZN.get(localX, 15) : sourcesO.get(localX, localZ - 1);
int minSourceY_ZP = localZ == 15 ? sourcesZP.get(localX, 0) : sourcesO.get(localX, localZ + 1);
int minSourceY_XN = localX == 0 ? sourcesXN.get(15, localZ) : sourcesO.get(localX - 1, localZ);
int minSourceY_XP = localX == 15 ? sourcesXP.get(0, localZ) : sourcesO.get(localX + 1, localZ);
int minSourceY_ZN = localZ == 0 ? sourcesZN.getLowestSourceY(localX, 15) : sourcesO.getLowestSourceY(localX, localZ - 1);
int minSourceY_ZP = localZ == 15 ? sourcesZP.getLowestSourceY(localX, 0) : sourcesO.getLowestSourceY(localX, localZ + 1);
int minSourceY_XN = localX == 0 ? sourcesXN.getLowestSourceY(15, localZ) : sourcesO.getLowestSourceY(localX - 1, localZ);
int minSourceY_XP = localX == 15 ? sourcesXP.getLowestSourceY(0, localZ) : sourcesO.getLowestSourceY(localX + 1, localZ);
int minSourceY_max = Math.max(Math.max(minSourceY_ZN, minSourceY_ZP), Math.max(minSourceY_XN, minSourceY_XP));
for (WeepingStorage.Run run : weepingStorage.iterateLitRuns(localX, localZ, effectiveLowestSourceY)) {
@@ -331,11 +335,11 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
}
int lowestRelevantY = Math.max(run.bottomY(), minY);
for (int sectionY = ChunkSectionPos.getSectionCoord(lowestRelevantY); sectionY <= topSectionY - 1; sectionY++) {
ChunkNibbleArray lightArray = lightArrays[sectionY - bottomSectionY];
for (int sectionY = SectionPos.blockToSectionCoord(lowestRelevantY); sectionY <= topSectionY - 1; sectionY++) {
DataLayer lightArray = lightArrays[sectionY - bottomSectionY];
if (lightArray == null) continue;
int minYInSection = ChunkSectionPos.getBlockCoord(sectionY);
int minYInSection = SectionPos.sectionToBlockCoord(sectionY);
int maxYInSection = minYInSection + 15;
if (minYInSection > run.topY()) { // todone break outer early if we're above run.topY()
@@ -343,7 +347,7 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
}
for (int it_y = Math.max(minYInSection, lowestRelevantY); it_y <= Math.min(maxYInSection, run.topY()); it_y++) {
lightArray.set(localX, ChunkSectionPos.getLocalCoord(it_y), localZ, 15);
lightArray.set(localX, SectionPos.sectionRelative(it_y), localZ, 15);
if (it_y == lowestRelevantY || it_y < minSourceY_max) {
long it_pos = BlockPos.asLong(baseX + localX, it_y, baseZ + localZ);
@@ -1,20 +1,20 @@
package io.github.slimeistdev.crystalline_sky.mixin;
import net.minecraft.world.chunk.light.SkyLightStorage;
import net.minecraft.world.level.lighting.SkyLightSectionStorage;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(SkyLightStorage.class)
public interface SkyLightStorageAccessor extends LightStorageAccessor {
@Invoker("isAboveMinHeight")
@Mixin(SkyLightSectionStorage.class)
public interface SkyLightSectionStorageAccessor extends LayerLightSectionStorageAccessor {
@Invoker("hasLightDataAtOrBelow")
boolean crystalline_sky$isAboveMinHeight(int sectionY);
@Invoker("isAtOrAboveTopmostSection")
@Invoker("isAboveData")
boolean crystalline_sky$isAtOrAboveTopmostSection(long sectionPos);
@Invoker("getTopSectionForColumn")
@Invoker("getTopSectionY")
int crystalline_sky$getTopSectionForColumn(long columnPos);
@Invoker("getMinSectionY")
@Invoker("getBottomSectionY")
int crystalline_sky$getMinSectionY();
}
@@ -1,8 +1,8 @@
package io.github.slimeistdev.crystalline_sky.mixin.client;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.item.Item;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.item.Item;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
@@ -14,19 +14,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.HashSet;
import java.util.Set;
@Mixin(ClientWorld.class)
public class ClientWorldMixin {
@Mixin(ClientLevel.class)
public class ClientLevelMixin {
@Shadow
@Final
@Mutable
private static Set<Item> BLOCK_MARKER_ITEMS;
private static Set<Item> MARKER_PARTICLE_ITEMS;
@Inject(method = "<clinit>", at = @At("RETURN"))
private static void modifyBlockMarkerItems(CallbackInfo ci) {
BLOCK_MARKER_ITEMS = new HashSet<>(BLOCK_MARKER_ITEMS);
BLOCK_MARKER_ITEMS.add(CrystallineItems.SKY_LIGHT);
BLOCK_MARKER_ITEMS.add(CrystallineItems.WEEPING_SKY_LIGHT);
BLOCK_MARKER_ITEMS.add(CrystallineItems.SKY);
BLOCK_MARKER_ITEMS.add(CrystallineItems.WEEPING_SKY);
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);
}
}
@@ -2,10 +2,10 @@ package io.github.slimeistdev.crystalline_sky.mixin.client;
import io.github.slimeistdev.crystalline_sky.infrastructure.client.WeepingSkyDebugRenderer;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.DebugRenderer_Duck;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.debug.DebugRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.debug.DebugRenderer;
import com.mojang.blaze3d.vertex.PoseStack;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
@@ -36,19 +36,19 @@ public class DebugRendererMixin implements DebugRenderer_Duck {
}
@Inject(method = "<init>", at = @At("RETURN"))
private void init(MinecraftClient client, CallbackInfo ci) {
private void init(Minecraft client, CallbackInfo ci) {
this.crystalline_sky$weepingSkyDebugRenderer = new WeepingSkyDebugRenderer(client);
}
@Inject(method = "render", at = @At("RETURN"))
private void render(MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) {
private void render(PoseStack matrices, MultiBufferSource.BufferSource vertexConsumers, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) {
if (crystalline_sky$weepingSkyMode != 0) {
crystalline_sky$weepingSkyDebugRenderer.setLitMode(crystalline_sky$weepingSkyMode == 1);
crystalline_sky$weepingSkyDebugRenderer.render(matrices, vertexConsumers, cameraX, cameraY, cameraZ);
}
}
@Inject(method = "reset", at = @At("RETURN"))
@Inject(method = "clear", at = @At("RETURN"))
private void reset(CallbackInfo ci) {
crystalline_sky$weepingSkyDebugRenderer.clear();
}
@@ -4,10 +4,10 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.mojang.datafixers.util.Pair;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineShaderPrograms;
import net.minecraft.client.gl.ShaderProgram;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.resource.ResourceFactory;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.client.renderer.GameRenderer;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import net.minecraft.server.packs.resources.ResourceProvider;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -17,18 +17,18 @@ import java.util.function.Consumer;
@Mixin(GameRenderer.class)
public class GameRendererMixin {
@WrapOperation(method = "loadPrograms", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 0))
private <E extends Pair<ShaderProgram, Consumer<ShaderProgram>>> boolean loadSkyProgram(
@WrapOperation(method = "reloadShaders", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 0))
private <E extends Pair<ShaderInstance, Consumer<ShaderInstance>>> boolean loadSkyProgram(
List<E> instance,
Object e,
Operation<Boolean> original,
ResourceFactory factory
ResourceProvider factory
) throws IOException {
original.call(instance, Pair.of(new ShaderProgram(
original.call(instance, Pair.of(new ShaderInstance(
factory,
"crystalline_sky_rendertype_sky",
VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL
), (Consumer<ShaderProgram>) program -> CrystallineShaderPrograms.renderTypeSkyProgram = program));
DefaultVertexFormat.BLOCK
), (Consumer<ShaderInstance>) program -> CrystallineShaderPrograms.renderTypeSkyProgram = program));
return original.call(instance, e);
}
}
@@ -0,0 +1,138 @@
package io.github.slimeistdev.crystalline_sky.mixin.client;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.Framebuffer_Duck;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.WorldRenderer_Duck;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderLayers;
import net.minecraft.client.Minecraft;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.pipeline.TextureTarget;
import net.minecraft.client.CloudStatus;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.renderer.LevelRenderer;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(value = LevelRenderer.class, remap = false)
public abstract class LevelRendererMixin implements WorldRenderer_Duck {
@Shadow
@Final
private Minecraft minecraft;
@Shadow
protected abstract boolean doesMobEffectBlockSky(Camera camera);
@Shadow
protected abstract void renderSectionLayer(RenderType renderLayer, double x, double y, double z, Matrix4f matrix4f, Matrix4f positionMatrix);
@Shadow
private @Nullable RenderTarget cloudsTarget;
@Shadow
public abstract void renderClouds(PoseStack matrices, Matrix4f matrix4f, Matrix4f matrix4f2, float tickDelta, double cameraX, double cameraY, double cameraZ);
@Unique
@Nullable
private RenderTarget crystalline_sky$skyBuffer;
@Override
public RenderTarget crystalline_sky$getSkyFramebuffer() {
if (crystalline_sky$skyBuffer == null) {
var fb = minecraft.getMainRenderTarget();
crystalline_sky$skyBuffer = new TextureTarget(fb.width, fb.height, true, Minecraft.ON_OSX);
}
return crystalline_sky$skyBuffer;
}
@Inject(
method = "renderLevel",
at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V",
args = "ldc=clear",
shift = At.Shift.AFTER
)
)
private void setupSkyBuffer(DeltaTracker tickCounter, boolean renderBlockOutline, Camera camera,
GameRenderer gameRenderer, LightTexture lightmapTextureManager,
Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci) {
crystalline_sky$getSkyFramebuffer();
}
@Inject(method = "resize", at = @At("RETURN"))
private void resizeSkyBuffer(int width, int height, CallbackInfo ci) {
if (crystalline_sky$skyBuffer != null) {
crystalline_sky$skyBuffer.resize(width, height, Minecraft.ON_OSX);
}
}
@Inject(method = "close", at = @At("RETURN"))
private void closeSkyBuffer(CallbackInfo ci) {
if (crystalline_sky$skyBuffer != null) {
crystalline_sky$skyBuffer.destroyBuffers();
crystalline_sky$skyBuffer = null;
}
}
@Inject(
method = "renderLevel",
at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V",
args = "ldc=terrain_setup"
)
)
private void copyAfterSky(DeltaTracker tickCounter, boolean renderBlockOutline, Camera camera,
GameRenderer gameRenderer, LightTexture lightmapTextureManager,
Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci) {
var skyBuffer = crystalline_sky$getSkyFramebuffer();
skyBuffer.clear(Minecraft.ON_OSX);
((Framebuffer_Duck) skyBuffer).crystalline_sky$copyColorFrom(minecraft.getMainRenderTarget());
// render clouds
CloudStatus cloudRenderMode = this.minecraft.options.getCloudsType();
if (cloudRenderMode != CloudStatus.OFF && !this.doesMobEffectBlockSky(camera)) {
float f = tickCounter.getGameTimeDeltaPartialTick(false);
Vec3 vec3d = camera.getPosition();
double cx = vec3d.x();
double cy = vec3d.y();
double cz = vec3d.z();
var cloudsFramebuffer0 = this.cloudsTarget;
this.cloudsTarget = skyBuffer;
cloudsTarget.bindWrite(false);
this.renderClouds(new PoseStack(), matrix4f, matrix4f2, f, cx, cy, cz);
minecraft.getMainRenderTarget().bindWrite(false);
this.cloudsTarget = cloudsFramebuffer0;
}
}
// after solid, cutoutMipped, and cutout
@WrapOperation(
method = "renderLevel",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/LevelRenderer;renderSectionLayer(Lnet/minecraft/client/renderer/RenderType;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V",
ordinal = 2
)
)
private void renderCrystallineSky(LevelRenderer instance, RenderType renderLayer, double x, double y, double z,
Matrix4f matrix4f, Matrix4f positionMatrix, Operation<Void> original) {
original.call(instance, renderLayer, x, y, z, matrix4f, positionMatrix);
renderSectionLayer(CrystallineRenderLayers.SKY, x, y, z, matrix4f, positionMatrix);
}
}
@@ -0,0 +1,58 @@
package io.github.slimeistdev.crystalline_sky.mixin.client;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.mojang.blaze3d.systems.RenderSystem;
import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin;
import io.github.slimeistdev.crystalline_sky.compat.Mods;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderLayers;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.LevelRenderer;
import com.mojang.blaze3d.platform.Window;
import net.minecraft.util.Mth;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ConditionalMixin(mods = Mods.SODIUM, applyIfPresent = false)
@Mixin(LevelRenderer.class)
public class LevelRenderer_NoSodium_Mixin {
@Shadow
@Final
private Minecraft minecraft;
@Shadow
private int ticks;
@WrapOperation(method = "renderSectionLayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ShaderInstance;setDefaultUniforms(Lcom/mojang/blaze3d/vertex/VertexFormat$Mode;Lorg/joml/Matrix4f;Lorg/joml/Matrix4f;Lcom/mojang/blaze3d/platform/Window;)V"))
private void tintSkyBlocks(ShaderInstance instance, VertexFormat.Mode drawMode, Matrix4f viewMatrix,
Matrix4f projectionMatrix, Window window, Operation<Void> original,
RenderType renderLayer) {
original.call(instance, drawMode, viewMatrix, projectionMatrix, window);
if (renderLayer == CrystallineRenderLayers.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))) {
float f = ticks + minecraft.getTimer().getGameTimeDeltaPartialTick(true);
float alpha = (Mth.sin(f / 10.0f) + 1.0f) / 2.0f;
// remap alpha from [0, 1] to [0, 0.75]
float maxAlpha = 1.0f - 0.25f;
alpha = alpha * maxAlpha;
float[] colorModulator = RenderSystem.getShaderColor().clone();
colorModulator[3] *= alpha;
instance.COLOR_MODULATOR.set(colorModulator);
}
}
}
@@ -4,40 +4,40 @@ import com.mojang.blaze3d.platform.GlConst;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.Framebuffer_Duck;
import net.minecraft.client.gl.Framebuffer;
import com.mojang.blaze3d.pipeline.RenderTarget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(Framebuffer.class)
public class FramebufferMixin implements Framebuffer_Duck {
@Mixin(RenderTarget.class)
public class RenderTargetMixin implements Framebuffer_Duck {
@Shadow
protected int colorAttachment;
protected int colorTextureId;
@Shadow
public int textureWidth;
public int width;
@Shadow
public int textureHeight;
public int height;
@Shadow
public int fbo;
public int frameBufferId;
@Override
public void crystalline_sky$copyColorFrom(Framebuffer framebuffer) {
public void crystalline_sky$copyColorFrom(RenderTarget framebuffer) {
RenderSystem.assertOnRenderThreadOrInit();
if (this.colorAttachment == -1) {
if (this.colorTextureId == -1) {
throw new IllegalStateException("Trying to copy color texture to a RenderTarget without a color texture");
} else if (framebuffer.getColorAttachment() == -1) {
} else if (framebuffer.getColorTextureId() == -1) {
throw new IllegalStateException("Trying to copy color texture from a RenderTarget without a color texture");
} else {
GlStateManager._glBindFramebuffer(GlConst.GL_READ_FRAMEBUFFER, framebuffer.fbo);
GlStateManager._glBindFramebuffer(GlConst.GL_DRAW_FRAMEBUFFER, this.fbo);
GlStateManager._glBindFramebuffer(GlConst.GL_READ_FRAMEBUFFER, framebuffer.frameBufferId);
GlStateManager._glBindFramebuffer(GlConst.GL_DRAW_FRAMEBUFFER, this.frameBufferId);
GlStateManager._glBlitFrameBuffer(
0, 0, framebuffer.textureWidth, framebuffer.textureHeight,
0, 0, this.textureWidth, this.textureHeight,
0, 0, framebuffer.width, framebuffer.height,
0, 0, this.width, this.height,
GlConst.GL_COLOR_BUFFER_BIT, GlConst.GL_NEAREST
);
GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, framebuffer.fbo);
GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, framebuffer.frameBufferId);
}
}
}
@@ -2,24 +2,24 @@ package io.github.slimeistdev.crystalline_sky.mixin.client;
import com.google.common.collect.ImmutableList;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.RenderLayer_Duck;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.renderer.RenderType;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(RenderLayer.class)
public class RenderLayerMixin implements RenderLayer_Duck {
@Mixin(RenderType.class)
public class RenderTypeMixin implements RenderLayer_Duck {
@Shadow
@Final
@Mutable
private static ImmutableList<RenderLayer> BLOCK_LAYERS;
private static ImmutableList<RenderType> CHUNK_BUFFER_LAYERS;
@Override
public void crystalline_sky$markAsBlockLayer() {
BLOCK_LAYERS = ImmutableList.<RenderLayer>builder()
.addAll(BLOCK_LAYERS)
.add((RenderLayer) (Object) this)
CHUNK_BUFFER_LAYERS = ImmutableList.<RenderType>builder()
.addAll(CHUNK_BUFFER_LAYERS)
.add((RenderType) (Object) this)
.build();
}
}
@@ -1,138 +0,0 @@
package io.github.slimeistdev.crystalline_sky.mixin.client;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.Framebuffer_Duck;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.WorldRenderer_Duck;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderLayers;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.Framebuffer;
import net.minecraft.client.gl.SimpleFramebuffer;
import net.minecraft.client.option.CloudRenderMode;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.LightmapTextureManager;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Vec3d;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(value = WorldRenderer.class, remap = false)
public abstract class WorldRendererMixin implements WorldRenderer_Duck {
@Shadow
@Final
private MinecraftClient client;
@Shadow
protected abstract boolean hasBlindnessOrDarkness(Camera camera);
@Shadow
protected abstract void renderLayer(RenderLayer renderLayer, double x, double y, double z, Matrix4f matrix4f, Matrix4f positionMatrix);
@Shadow
private @Nullable Framebuffer cloudsFramebuffer;
@Shadow
public abstract void renderClouds(MatrixStack matrices, Matrix4f matrix4f, Matrix4f matrix4f2, float tickDelta, double cameraX, double cameraY, double cameraZ);
@Unique
@Nullable
private Framebuffer crystalline_sky$skyBuffer;
@Override
public Framebuffer crystalline_sky$getSkyFramebuffer() {
if (crystalline_sky$skyBuffer == null) {
var fb = client.getFramebuffer();
crystalline_sky$skyBuffer = new SimpleFramebuffer(fb.textureWidth, fb.textureHeight, true, MinecraftClient.IS_SYSTEM_MAC);
}
return crystalline_sky$skyBuffer;
}
@Inject(
method = "render",
at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V",
args = "ldc=clear",
shift = At.Shift.AFTER
)
)
private void setupSkyBuffer(RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera,
GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager,
Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci) {
crystalline_sky$getSkyFramebuffer();
}
@Inject(method = "onResized", at = @At("RETURN"))
private void resizeSkyBuffer(int width, int height, CallbackInfo ci) {
if (crystalline_sky$skyBuffer != null) {
crystalline_sky$skyBuffer.resize(width, height, MinecraftClient.IS_SYSTEM_MAC);
}
}
@Inject(method = "close", at = @At("RETURN"))
private void closeSkyBuffer(CallbackInfo ci) {
if (crystalline_sky$skyBuffer != null) {
crystalline_sky$skyBuffer.delete();
crystalline_sky$skyBuffer = null;
}
}
@Inject(
method = "render",
at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V",
args = "ldc=terrain_setup"
)
)
private void copyAfterSky(RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera,
GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager,
Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci) {
var skyBuffer = crystalline_sky$getSkyFramebuffer();
skyBuffer.clear(MinecraftClient.IS_SYSTEM_MAC);
((Framebuffer_Duck) skyBuffer).crystalline_sky$copyColorFrom(client.getFramebuffer());
// render clouds
CloudRenderMode cloudRenderMode = this.client.options.getCloudRenderModeValue();
if (cloudRenderMode != CloudRenderMode.OFF && !this.hasBlindnessOrDarkness(camera)) {
float f = tickCounter.getTickDelta(false);
Vec3d vec3d = camera.getPos();
double cx = vec3d.getX();
double cy = vec3d.getY();
double cz = vec3d.getZ();
var cloudsFramebuffer0 = this.cloudsFramebuffer;
this.cloudsFramebuffer = skyBuffer;
cloudsFramebuffer.beginWrite(false);
this.renderClouds(new MatrixStack(), matrix4f, matrix4f2, f, cx, cy, cz);
client.getFramebuffer().beginWrite(false);
this.cloudsFramebuffer = cloudsFramebuffer0;
}
}
// after solid, cutoutMipped, and cutout
@WrapOperation(
method = "render",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/render/WorldRenderer;renderLayer(Lnet/minecraft/client/render/RenderLayer;DDDLorg/joml/Matrix4f;Lorg/joml/Matrix4f;)V",
ordinal = 2
)
)
private void renderCrystallineSky(WorldRenderer instance, RenderLayer renderLayer, double x, double y, double z,
Matrix4f matrix4f, Matrix4f positionMatrix, Operation<Void> original) {
original.call(instance, renderLayer, x, y, z, matrix4f, positionMatrix);
renderLayer(CrystallineRenderLayers.SKY, x, y, z, matrix4f, positionMatrix);
}
}
@@ -1,58 +0,0 @@
package io.github.slimeistdev.crystalline_sky.mixin.client;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.mojang.blaze3d.systems.RenderSystem;
import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin;
import io.github.slimeistdev.crystalline_sky.compat.Mods;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderLayers;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.ShaderProgram;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.Window;
import net.minecraft.util.math.MathHelper;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ConditionalMixin(mods = Mods.SODIUM, applyIfPresent = false)
@Mixin(WorldRenderer.class)
public class WorldRenderer_NoSodium_Mixin {
@Shadow
@Final
private MinecraftClient client;
@Shadow
private int ticks;
@WrapOperation(method = "renderLayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gl/ShaderProgram;initializeUniforms(Lnet/minecraft/client/render/VertexFormat$DrawMode;Lorg/joml/Matrix4f;Lorg/joml/Matrix4f;Lnet/minecraft/client/util/Window;)V"))
private void tintSkyBlocks(ShaderProgram instance, VertexFormat.DrawMode drawMode, Matrix4f viewMatrix,
Matrix4f projectionMatrix, Window window, Operation<Void> original,
RenderLayer renderLayer) {
original.call(instance, drawMode, viewMatrix, projectionMatrix, window);
if (renderLayer == CrystallineRenderLayers.SKY
&& instance.colorModulator != null
&& client.player != null
&& (client.player.getMainHandStack().isOf(CrystallineItems.SKY)
|| client.player.getOffHandStack().isOf(CrystallineItems.SKY)
|| client.player.getMainHandStack().isOf(CrystallineItems.WEEPING_SKY)
|| client.player.getOffHandStack().isOf(CrystallineItems.WEEPING_SKY))) {
float f = ticks + client.getRenderTickCounter().getTickDelta(true);
float alpha = (MathHelper.sin(f / 10.0f) + 1.0f) / 2.0f;
// remap alpha from [0, 1] to [0, 0.75]
float maxAlpha = 1.0f - 0.25f;
alpha = alpha * maxAlpha;
float[] colorModulator = RenderSystem.getShaderColor().clone();
colorModulator[3] *= alpha;
instance.colorModulator.set(colorModulator);
}
}
}
@@ -4,7 +4,7 @@ import com.moulberry.axiom.render.ChunkRenderOverrider;
import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin;
import io.github.slimeistdev.crystalline_sky.compat.Mods;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderLayers;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.renderer.RenderType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ChunkRenderOverrider.AxiomChunkOverrideLayer.class)
public class ChunkRenderOverrider_AxiomChunkOverrideLayerMixin {
@Inject(method = "fromVanilla", at = @At("HEAD"), cancellable = true)
private static void unexplodeSky(RenderLayer layer, CallbackInfoReturnable<ChunkRenderOverrider.AxiomChunkOverrideLayer> cir) {
private static void unexplodeSky(RenderType layer, CallbackInfoReturnable<ChunkRenderOverrider.AxiomChunkOverrideLayer> cir) {
if (layer == CrystallineRenderLayers.SKY) {
cir.setReturnValue(ChunkRenderOverrider.AxiomChunkOverrideLayer.CUTOUT_MIPPED);
}
@@ -7,7 +7,7 @@ import net.caffeinemc.mods.sodium.client.render.chunk.terrain.DefaultTerrainRend
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.DefaultMaterials;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.Material;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.parameters.AlphaCutoffParameter;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.renderer.RenderType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@@ -31,7 +31,7 @@ public class DefaultMaterialsMixin {
);
@Inject(method = "forRenderLayer", at = @At(value = "NEW", target = "(Ljava/lang/String;)Ljava/lang/IllegalArgumentException;"), cancellable = true)
private static void addCrystallineSkyMaterial(RenderLayer layer, CallbackInfoReturnable<Material> cir) {
private static void addCrystallineSkyMaterial(RenderType layer, CallbackInfoReturnable<Material> cir) {
if (layer == CrystallineRenderLayers.SKY) {
cir.setReturnValue(crystalline_sky$SKY);
}
@@ -12,7 +12,7 @@ import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderInterfac
import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderOptions;
import net.caffeinemc.mods.sodium.client.render.chunk.shader.ShaderBindingContext;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.DefaultMaterials;
import net.minecraft.util.Identifier;
import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -30,8 +30,8 @@ public class ShaderChunkRendererMixin {
return original.call(instance, path, options);
}
@WrapOperation(method = "createShader", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Identifier;of(Ljava/lang/String;Ljava/lang/String;)Lnet/minecraft/util/Identifier;"))
private Identifier redirectShaderNamespace(String namespace, String path, Operation<Identifier> original, String pathArg) {
@WrapOperation(method = "createShader", at = @At(value = "INVOKE", target = "Lnet/minecraft/resources/ResourceLocation;fromNamespaceAndPath(Ljava/lang/String;Ljava/lang/String;)Lnet/minecraft/resources/ResourceLocation;"))
private ResourceLocation redirectShaderNamespace(String namespace, String path, Operation<ResourceLocation> original, String pathArg) {
if (pathArg.equals("sodium_compat/block_layer_sky")) {
namespace = "crystalline_sky";
}
@@ -7,7 +7,7 @@ import net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer;
import net.caffeinemc.mods.sodium.client.render.chunk.ChunkRenderMatrices;
import net.caffeinemc.mods.sodium.client.render.chunk.RenderSectionManager;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.DefaultMaterials;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.renderer.RenderType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@@ -21,7 +21,7 @@ public class SodiumWorldRendererMixin {
private RenderSectionManager renderSectionManager;
@Inject(method = "drawChunkLayer", at = @At("RETURN"))
private void drawCrystallineLayer(RenderLayer renderLayer, ChunkRenderMatrices matrices, double x, double y, double z, CallbackInfo ci) {
private void drawCrystallineLayer(RenderType renderLayer, ChunkRenderMatrices matrices, double x, double y, double z, CallbackInfo ci) {
if (renderLayer != CrystallineRenderLayers.SKY) return;
renderSectionManager.renderLayer(matrices, DefaultMaterials.forRenderLayer(CrystallineRenderLayers.SKY).pass, x, y, z);
@@ -3,7 +3,7 @@ package io.github.slimeistdev.crystalline_sky.mixin.client.compat.sodium;
import io.github.slimeistdev.crystalline_sky.annotation.mixin.ConditionalMixin;
import io.github.slimeistdev.crystalline_sky.compat.Mods;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.TerrainRenderPass;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.renderer.RenderType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@@ -11,5 +11,5 @@ import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(TerrainRenderPass.class)
public interface TerrainRenderPassAccessor {
@Accessor("renderType")
RenderLayer crystalline_sky$getRenderLayer();
RenderType crystalline_sky$getRenderLayer();
}
@@ -1,7 +1,7 @@
package io.github.slimeistdev.crystalline_sky.mixin_ducks.client;
import net.minecraft.client.gl.Framebuffer;
import com.mojang.blaze3d.pipeline.RenderTarget;
public interface Framebuffer_Duck {
void crystalline_sky$copyColorFrom(Framebuffer framebuffer);
void crystalline_sky$copyColorFrom(RenderTarget framebuffer);
}
@@ -1,7 +1,7 @@
package io.github.slimeistdev.crystalline_sky.mixin_ducks.client;
import net.minecraft.client.gl.Framebuffer;
import com.mojang.blaze3d.pipeline.RenderTarget;
public interface WorldRenderer_Duck {
Framebuffer crystalline_sky$getSkyFramebuffer();
RenderTarget crystalline_sky$getSkyFramebuffer();
}
@@ -4,57 +4,64 @@ import io.github.slimeistdev.crystalline_sky.CrystallineSky;
import io.github.slimeistdev.crystalline_sky.content.blocks.SkyLightBlock;
import io.github.slimeistdev.crystalline_sky.content.blocks.WeepingSkyLightBlock;
import net.minecraft.block.*;
import net.minecraft.block.AbstractBlock.Settings;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.state.property.Properties;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
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, Settings.create()
public static final Block SKY = register("sky", TransparentBlock::new, Properties.of()
.strength(0.3f)
.sounds(BlockSoundGroup.AMETHYST_BLOCK)
.nonOpaque()
.allowsSpawning(Blocks::never)
.solidBlock(Blocks::never)
.suffocates(Blocks::never)
.blockVision(Blocks::never)
.emissiveLighting(Blocks::always));
.sound(SoundType.AMETHYST)
.noOcclusion()
.isValidSpawn(Blocks::never)
.isRedstoneConductor(Blocks::never)
.isSuffocating(Blocks::never)
.isViewBlocking(Blocks::never)
.emissiveRendering(Blocks::always));
public static final Block WEEPING_SKY = register("weeping_sky", TransparentBlock::new, Settings.copy(SKY));
public static final Block WEEPING_SKY = register("weeping_sky", TransparentBlock::new, Properties.ofFullCopy(SKY));
public static final Block SKY_LIGHT = register(
"sky_light",
SkyLightBlock::new,
AbstractBlock.Settings.create()
BlockBehaviour.Properties.of()
.replaceable()
.strength(-1.0F, 3600000.8F)
.mapColor(state -> state.get(Properties.WATERLOGGED) ? MapColor.WATER_BLUE : MapColor.CLEAR)
.dropsNothing()
.nonOpaque()
.mapColor(state -> state.getValue(BlockStateProperties.WATERLOGGED) ? MapColor.WATER : MapColor.NONE)
.noLootTable()
.noOcclusion()
);
public static final Block WEEPING_SKY_LIGHT = register(
"weeping_sky_light",
WeepingSkyLightBlock::new,
AbstractBlock.Settings.create()
BlockBehaviour.Properties.of()
.replaceable()
.strength(-1.0F, 3600000.8F)
.mapColor(state -> state.get(Properties.WATERLOGGED) ? MapColor.WATER_BLUE : MapColor.CLEAR)
.dropsNothing()
.nonOpaque()
.mapColor(state -> state.getValue(BlockStateProperties.WATERLOGGED) ? MapColor.WATER : MapColor.NONE)
.noLootTable()
.noOcclusion()
);
public static void init() {}
private static <T extends Block> T register(String id, Function<Settings, T> factory, Settings settings) {
RegistryKey<Block> key = CrystallineSky.key(RegistryKeys.BLOCK, id);
return Registry.register(Registries.BLOCK, key, factory.apply(settings));
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) {
@@ -62,9 +69,9 @@ public class CrystallineBlocks {
}
public static int getSkyLightLevel(BlockState state) {
if (state.isOf(SKY_LIGHT)) {
return state.get(LightBlock.LEVEL_15);
} else if (state.isOf(SKY)) { // weeping sky explicitly excluded, that's handled differently
if (state.is(SKY_LIGHT)) {
return state.getValue(LightBlock.LEVEL);
} else if (state.is(SKY)) { // weeping sky explicitly excluded, that's handled differently
return 15;
}
@@ -72,6 +79,6 @@ public class CrystallineBlocks {
}
public static boolean isWeepingSky(BlockState state) {
return state.isOf(WEEPING_SKY) || state.isOf(WEEPING_SKY_LIGHT);
return state.is(WEEPING_SKY) || state.is(WEEPING_SKY_LIGHT);
}
}
@@ -1,25 +1,25 @@
package io.github.slimeistdev.crystalline_sky.registry;
import io.github.slimeistdev.crystalline_sky.CrystallineSky;
import net.minecraft.component.ComponentType;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.core.component.DataComponentType;
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 ComponentType<Unit> WEEPING_SKY_DEBUG_COLUMN_TOOL = register(
public static final DataComponentType<Unit> WEEPING_SKY_DEBUG_COLUMN_TOOL = register(
"weeping_sky_debug_column_tool",
b -> b
.packetCodec(PacketCodec.unit(Unit.INSTANCE))
.codec(Unit.CODEC)
.networkSynchronized(StreamCodec.unit(Unit.INSTANCE))
.persistent(Unit.CODEC)
);
@SuppressWarnings("SameParameterValue")
private static <T> ComponentType<T> register(String id, UnaryOperator<ComponentType.Builder<T>> builderOperator) {
return Registry.register(Registries.DATA_COMPONENT_TYPE, CrystallineSky.id(id), builderOperator.apply(ComponentType.builder()).build());
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() {}
@@ -3,23 +3,23 @@ package io.github.slimeistdev.crystalline_sky.registry;
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.block.Block;
import net.minecraft.block.LightBlock;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.BlockStateComponent;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroups;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.Rarity;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.LightBlock;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.item.component.BlockItemStateProperties;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.CreativeModeTabs;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.Rarity;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
public class CrystallineItems {
public static final Item SKY = Items.register(
public static final Item SKY = Items.registerBlock(
CrystallineBlocks.SKY,
settings -> settings.rarity(Rarity.EPIC)
);
@@ -29,24 +29,24 @@ public class CrystallineItems {
(block, settings) -> new WeepingSkyBlockItem(block, settings.rarity(Rarity.EPIC))
);
public static final Item SKY_LIGHT = Items.register(
public static final Item SKY_LIGHT = Items.registerBlock(
CrystallineBlocks.SKY_LIGHT,
settings -> settings.rarity(Rarity.EPIC)
.component(DataComponentTypes.BLOCK_STATE, BlockStateComponent.DEFAULT.with(LightBlock.LEVEL_15, 15))
.component(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY.with(LightBlock.LEVEL, 15))
);
public static final Item WEEPING_SKY_LIGHT = Items.register(
public static final Item WEEPING_SKY_LIGHT = Items.registerBlock(
CrystallineBlocks.WEEPING_SKY_LIGHT,
settings -> settings.rarity(Rarity.EPIC)
);
@SuppressWarnings("SameParameterValue")
private static Item register(Block block, BiFunction<Block, Item.Settings, BlockItem> factory) {
return Items.register(factory.apply(block, new Item.Settings()));
private static Item register(Block block, BiFunction<Block, Item.Properties, BlockItem> factory) {
return Items.registerBlock(factory.apply(block, new Item.Properties()));
}
public static void init() {
ItemGroupEvents.modifyEntriesEvent(ItemGroups.OPERATOR).register(entries -> {
ItemGroupEvents.modifyEntriesEvent(CreativeModeTabs.OP_BLOCKS).register(entries -> {
if (!entries.getContext().hasPermissions()) return;
List<ItemStack> stacks = new ArrayList<>();
@@ -55,7 +55,7 @@ public class CrystallineItems {
stacks.add(new ItemStack(WEEPING_SKY));
for (int i = 15; i >= 0; i--) {
stacks.add(SkyLightBlock.addNbtForLevel(new ItemStack(SKY_LIGHT), i));
stacks.add(SkyLightBlock.setLightOnStack(new ItemStack(SKY_LIGHT), i));
}
stacks.add(new ItemStack(WEEPING_SKY_LIGHT));
@@ -5,32 +5,32 @@ import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.RenderLayer_Duck
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.WorldRenderer_Duck;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderPhase;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
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.render.RenderLayer.of;
import static net.minecraft.client.render.RenderPhase.ENABLE_LIGHTMAP;
import static net.minecraft.client.renderer.RenderType.create;
import static net.minecraft.client.renderer.RenderStateShard.LIGHTMAP;
@Environment(EnvType.CLIENT)
public class CrystallineRenderLayers {
private static final RenderPhase.TextureBase SKY_TEXTURE = new SkyBufferTexture();
private static final RenderPhase.ShaderProgram SKY_PROGRAM = new RenderPhase.ShaderProgram(CrystallineShaderPrograms::getRenderTypeSkyProgram);
private static final RenderStateShard.EmptyTextureStateShard SKY_TEXTURE = new SkyBufferTexture();
private static final RenderStateShard.ShaderStateShard SKY_PROGRAM = new RenderStateShard.ShaderStateShard(CrystallineShaderPrograms::getRenderTypeSkyProgram);
public static final RenderLayer SKY = of(
public static final RenderType SKY = create(
"crystalline_sky_sky",
VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL,
VertexFormat.DrawMode.QUADS,
DefaultVertexFormat.BLOCK,
VertexFormat.Mode.QUADS,
4194304,
true,
false,
RenderLayer.MultiPhaseParameters.builder()
.lightmap(ENABLE_LIGHTMAP)
.program(SKY_PROGRAM)
.texture(SKY_TEXTURE)
.build(true)
RenderType.CompositeState.builder()
.setLightmapState(LIGHTMAP)
.setShaderState(SKY_PROGRAM)
.setTextureState(SKY_TEXTURE)
.createCompositeState(true)
);
static {
@@ -38,12 +38,12 @@ public class CrystallineRenderLayers {
((RenderLayer_Duck) SKY).crystalline_sky$markAsBlockLayer();
}
private static class SkyBufferTexture extends RenderPhase.TextureBase {
private static class SkyBufferTexture extends RenderStateShard.EmptyTextureStateShard {
public SkyBufferTexture() {
super(() -> {
MinecraftClient mc = MinecraftClient.getInstance();
var fb = ((WorldRenderer_Duck) mc.worldRenderer).crystalline_sky$getSkyFramebuffer();
RenderSystem.setShaderTexture(0, fb.getColorAttachment());
Minecraft mc = Minecraft.getInstance();
var fb = ((WorldRenderer_Duck) mc.levelRenderer).crystalline_sky$getSkyFramebuffer();
RenderSystem.setShaderTexture(0, fb.getColorTextureId());
}, () -> {});
}
}
@@ -1,14 +1,14 @@
package io.github.slimeistdev.crystalline_sky.registry.client;
import net.minecraft.client.gl.ShaderProgram;
import net.minecraft.client.renderer.ShaderInstance;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
public class CrystallineShaderPrograms {
@ApiStatus.Internal
public static @Nullable ShaderProgram renderTypeSkyProgram;
public static @Nullable ShaderInstance renderTypeSkyProgram;
public static @Nullable ShaderProgram getRenderTypeSkyProgram() {
public static @Nullable ShaderInstance getRenderTypeSkyProgram() {
return renderTypeSkyProgram;
}
}
+10 -10
View File
@@ -8,20 +8,20 @@
"plugin": "io.github.slimeistdev.crystalline_sky.mixin.CrystallineSkyMixinPlugin",
"compatibilityLevel": "JAVA_21",
"mixins": [
"ChunkLightProviderMixin",
"ChunkSkyLightMixin",
"ChunkSkyLightProviderMixin",
"LightStorageAccessor",
"SkyLightStorageAccessor"
"LightEngineMixin",
"ChunkSkyLightSourcesMixin",
"SkyLightEngineMixin",
"LayerLightSectionStorageAccessor",
"SkyLightSectionStorageAccessor"
],
"client": [
"client.ClientWorldMixin",
"client.ClientLevelMixin",
"client.DebugRendererMixin",
"client.FramebufferMixin",
"client.RenderTargetMixin",
"client.GameRendererMixin",
"client.RenderLayerMixin",
"client.WorldRenderer_NoSodium_Mixin",
"client.WorldRendererMixin",
"client.RenderTypeMixin",
"client.LevelRenderer_NoSodium_Mixin",
"client.LevelRendererMixin",
"client.compat.axiom.ChunkRenderOverrider_AxiomChunkOverrideLayerMixin",
"client.compat.sodium.DefaultMaterialsMixin",
"client.compat.sodium.DefaultTerrainRenderPassesMixin",