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" includeGroup "com.terraformersmc"
} }
} }
exclusiveContent {
forRepository {
//noinspection ForeignDelegate
maven {
name 'ParchmentMC'
url "https://maven.parchmentmc.org"
}
}
filter {
includeGroup "org.parchmentmc.data"
}
}
flatDir { flatDir {
dir("libs") dir("libs")
} }
@@ -44,7 +56,8 @@ repositories {
dependencies { dependencies {
minecraft libs.mc minecraft libs.mc
mappings loom.layered { 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") it.mappings file("custom_mappings.tiny")
} }
+2 -57
View File
@@ -1,61 +1,6 @@
tiny 2 0 official intermediary named tiny 2 0 official intermediary named
c ua net/minecraft/class_2483 net/minecraft/nbt/AbstractNbtList c eox net/minecraft/class_3572 net/minecraft/world/level/lighting/SkyLightEngine
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
m (III)V b method_51590 updateSourcesInColumn m (III)V b method_51590 updateSourcesInColumn
p 1 x
p 2 z
p 3 lowestSourceY
v 4 15 -1 _ _ minY v 4 15 -1 _ _ minY
m (IIII)V a method_51586 removeSourcesBelow m (IIII)V a method_51586 removeSourcesBelow
p 1 x 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 15 98 -1 _ _ baseLevelToPropagate
v 16 128 -1 _ _ targetState v 16 128 -1 _ _ targetState
v 17 139 -1 _ _ trueLevelToPropagate 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 2 12 -1 _ _ packedZeroPos
v 4 48 -1 _ _ sourcesO v 4 48 -1 _ _ sourcesO
v 5 74 -1 _ _ sourcesZN v 5 74 -1 _ _ sourcesZN
+2
View File
@@ -6,6 +6,8 @@ org.gradle.configureondemand=true
org.gradle.configuration-cache=false org.gradle.configuration-cache=false
# Loom # Loom
fabric.loom.multiProjectOptimisation=true fabric.loom.multiProjectOptimisation=true
# otherwise layering tiny mappings on mojmap explodes
fabric.loom.dropNonIntermediateRootMethods=true
# Mod Metadata # Mod Metadata
group=io.github.slimeistdev group=io.github.slimeistdev
user=techno-sam user=techno-sam
+2 -2
View File
@@ -4,7 +4,7 @@ minotaur = "2.+"
mc = "1.21.1" mc = "1.21.1"
fl = "0.18.6" fl = "0.18.6"
yarn = "1.21.1+build.3" parchment = "2024.11.17"
fapi = "0.116.10+1.21.1" fapi = "0.116.10+1.21.1"
mixinextras = "0.5.0" mixinextras = "0.5.0"
mm = "11.0.4" mm = "11.0.4"
@@ -22,7 +22,7 @@ minotaur = { id = "com.modrinth.minotaur", version.ref = "minotaur" }
[libraries] [libraries]
mc = { group = "mojang", name = "minecraft", version.ref = "mc" } mc = { group = "mojang", name = "minecraft", version.ref = "mc" }
fl = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fl" } 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" } fapi = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fapi" }
mixinextras = { group = "io.github.llamalad7", name = "mixinextras-fabric", version.ref = "mixinextras" } mixinextras = { group = "io.github.llamalad7", name = "mixinextras-fabric", version.ref = "mixinextras" }
mm = { group = "com.terraformersmc", name = "modmenu", version.ref = "mm" } mm = { group = "com.terraformersmc", name = "modmenu", version.ref = "mm" }
@@ -1,9 +1,9 @@
package io.github.slimeistdev.crystalline_sky; package io.github.slimeistdev.crystalline_sky;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.minecraft.registry.Registry; import net.minecraft.core.Registry;
import net.minecraft.registry.RegistryKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.util.Identifier; import net.minecraft.resources.ResourceLocation;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -16,11 +16,11 @@ public class CrystallineSky implements ModInitializer {
ModSetup.init(); ModSetup.init();
} }
public static Identifier id(String path) { public static ResourceLocation id(String path) {
return Identifier.of(ID, path); return ResourceLocation.fromNamespaceAndPath(ID, path);
} }
public static <T> RegistryKey<T> key(RegistryKey<? extends Registry<T>> registryKey, String path) { public static <T> ResourceKey<T> key(ResourceKey<? extends Registry<T>> registryKey, String path) {
return RegistryKey.of(registryKey, id(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.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.block.LightBlock; import net.minecraft.world.level.block.LightBlock;
import net.minecraft.client.item.ModelPredicateProviderRegistry; import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.client.option.KeyBinding; import net.minecraft.client.KeyMapping;
import net.minecraft.client.util.InputUtil; import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.component.DataComponentTypes; import net.minecraft.core.component.DataComponents;
import net.minecraft.component.type.BlockStateComponent; import net.minecraft.world.item.component.BlockItemStateProperties;
import net.minecraft.screen.ScreenTexts; import net.minecraft.network.chat.CommonComponents;
import net.minecraft.text.Text; import net.minecraft.network.chat.Component;
import net.minecraft.util.Formatting; import net.minecraft.ChatFormatting;
import net.minecraft.util.Identifier; import net.minecraft.resources.ResourceLocation;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
public class CrystallineSkyClient implements ClientModInitializer { 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.SKY, CrystallineRenderLayers.SKY);
BlockRenderLayerMap.INSTANCE.putBlock(CrystallineBlocks.WEEPING_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", "crystalline_sky.key.toggle_weeping_sky_debug",
InputUtil.Type.KEYSYM, InputConstants.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN, GLFW.GLFW_KEY_UNKNOWN,
"crystalline_sky.category.crystalline_sky" "crystalline_sky.category.crystalline_sky"
)); ));
ClientTickEvents.END_CLIENT_TICK.register(client -> { ClientTickEvents.END_CLIENT_TICK.register(client -> {
while (weepingSkyKeybind.wasPressed()) { while (weepingSkyKeybind.consumeClick()) {
int mode = ((DebugRenderer_Duck) client.debugRenderer).crystalline_sky$toggleWeepingSky(); int mode = ((DebugRenderer_Duck) client.debugRenderer).crystalline_sky$toggleWeepingSky();
Text message = getDebugMessage(Formatting.YELLOW, Component message = getDebugMessage(ChatFormatting.YELLOW,
Text.translatable("message.crystalline_sky.weeping_sky_debug." + mode) 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) -> { (stack, world, entity, seed) -> {
BlockStateComponent blockStateComponent = stack.getOrDefault(DataComponentTypes.BLOCK_STATE, BlockStateComponent.DEFAULT); BlockItemStateProperties blockStateComponent = stack.getOrDefault(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY);
Integer integer = blockStateComponent.getValue(LightBlock.LEVEL_15); Integer integer = blockStateComponent.get(LightBlock.LEVEL);
return integer != null ? integer / 16.0F : 1.0F; return integer != null ? integer / 16.0F : 1.0F;
}); });
} }
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
private static Text getDebugMessage(Formatting formatting, Text message) { private static Component getDebugMessage(ChatFormatting formatting, Component message) {
return Text.empty().append(Text.translatable("debug.prefix").formatted(formatting, Formatting.BOLD)).append(ScreenTexts.SPACE).append(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.ChunkShaderTextureSlot;
import net.caffeinemc.mods.sodium.client.render.chunk.shader.ShaderBindingContext; import net.caffeinemc.mods.sodium.client.render.chunk.shader.ShaderBindingContext;
import net.caffeinemc.mods.sodium.client.util.TextureUtil; import net.caffeinemc.mods.sodium.client.util.TextureUtil;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.Minecraft;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.Mth;
import org.joml.Matrix4fc; import org.joml.Matrix4fc;
import org.lwjgl.opengl.GL32C; import org.lwjgl.opengl.GL32C;
@@ -50,16 +50,16 @@ public class SkyShaderInterface implements ChunkShaderInterface {
public void setupState() { public void setupState() {
this.bindTexture(ChunkShaderTextureSlot.BLOCK, TextureUtil.getBlockTextureId()); this.bindTexture(ChunkShaderTextureSlot.BLOCK, TextureUtil.getBlockTextureId());
MinecraftClient client = MinecraftClient.getInstance(); Minecraft client = Minecraft.getInstance();
if (client.world != null if (client.level != null
&& client.player != null && client.player != null
&& (client.player.getMainHandStack().isOf(CrystallineItems.SKY) && (client.player.getMainHandItem().is(CrystallineItems.SKY)
|| client.player.getOffHandStack().isOf(CrystallineItems.SKY) || client.player.getOffhandItem().is(CrystallineItems.SKY)
|| client.player.getMainHandStack().isOf(CrystallineItems.WEEPING_SKY) || client.player.getMainHandItem().is(CrystallineItems.WEEPING_SKY)
|| client.player.getOffHandStack().isOf(CrystallineItems.WEEPING_SKY))) { || client.player.getOffhandItem().is(CrystallineItems.WEEPING_SKY))) {
float f = client.world.getTime() + client.getRenderTickCounter().getTickDelta(true); float f = client.level.getGameTime() + client.getTimer().getGameTimeDeltaPartialTick(true);
float alpha = (MathHelper.sin(f / 10.0f) + 1.0f) / 2.0f; float alpha = (Mth.sin(f / 10.0f) + 1.0f) / 2.0f;
// remap alpha from [0, 1] to [0, 0.75] // remap alpha from [0, 1] to [0, 0.75]
float maxAlpha = 1.0f - 0.25f; float maxAlpha = 1.0f - 0.25f;
alpha = alpha * maxAlpha; alpha = alpha * maxAlpha;
@@ -1,21 +1,22 @@
package io.github.slimeistdev.crystalline_sky.content.blocks; package io.github.slimeistdev.crystalline_sky.content.blocks;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems; import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.minecraft.block.BlockState; import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
import net.minecraft.block.LightBlock; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.block.ShapeContext; import net.minecraft.world.level.block.LightBlock;
import net.minecraft.util.math.BlockPos; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.core.BlockPos;
import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.BlockView; import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.level.BlockGetter;
public class SkyLightBlock extends LightBlock { public class SkyLightBlock extends LightBlock {
public SkyLightBlock(Settings settings) { public SkyLightBlock(Properties settings) {
super(settings); super(settings);
} }
@Override @Override
protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
return context.isHolding(CrystallineItems.SKY_LIGHT) ? VoxelShapes.fullCube() : VoxelShapes.empty(); return context.isHoldingItem(CrystallineItems.SKY_LIGHT) ? Shapes.block() : Shapes.empty();
} }
} }
@@ -1,74 +1,75 @@
package io.github.slimeistdev.crystalline_sky.content.blocks; package io.github.slimeistdev.crystalline_sky.content.blocks;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems; import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.minecraft.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.block.BlockRenderType; import net.minecraft.world.level.block.RenderShape;
import net.minecraft.block.BlockState; import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
import net.minecraft.block.ShapeContext; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.block.Waterloggable; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.fluid.FluidState; import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.fluid.Fluids; import net.minecraft.world.level.material.FluidState;
import net.minecraft.state.StateManager; import net.minecraft.world.level.material.Fluids;
import net.minecraft.state.property.BooleanProperty; import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.state.property.Properties; import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.util.math.BlockPos; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.util.math.Direction; import net.minecraft.core.BlockPos;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.core.Direction;
import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.BlockView; import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.WorldAccess; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelAccessor;
public class WeepingSkyLightBlock extends Block implements Waterloggable { public class WeepingSkyLightBlock extends Block implements SimpleWaterloggedBlock {
public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public WeepingSkyLightBlock(Settings settings) { public WeepingSkyLightBlock(Properties settings) {
super(settings); super(settings);
setDefaultState(getStateManager().getDefaultState().with(WATERLOGGED, false)); registerDefaultState(getStateDefinition().any().setValue(WATERLOGGED, false));
} }
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(WATERLOGGED); builder.add(WATERLOGGED);
} }
@Override @Override
protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
return context.isHolding(CrystallineItems.WEEPING_SKY_LIGHT) ? VoxelShapes.fullCube() : VoxelShapes.empty(); return context.isHoldingItem(CrystallineItems.WEEPING_SKY_LIGHT) ? Shapes.block() : Shapes.empty();
} }
@Override @Override
protected boolean isTransparent(BlockState state, BlockView world, BlockPos pos) { protected boolean propagatesSkylightDown(BlockState state, BlockGetter world, BlockPos pos) {
return state.getFluidState().isEmpty(); return state.getFluidState().isEmpty();
} }
@Override @Override
protected BlockRenderType getRenderType(BlockState state) { protected RenderShape getRenderShape(BlockState state) {
return BlockRenderType.INVISIBLE; return RenderShape.INVISIBLE;
} }
@Override @Override
protected float getAmbientOcclusionLightLevel(BlockState state, BlockView world, BlockPos pos) { protected float getShadeBrightness(BlockState state, BlockGetter world, BlockPos pos) {
return 1.0f; return 1.0f;
} }
@Override @Override
protected BlockState getStateForNeighborUpdate( protected BlockState updateShape(
BlockState state, BlockState state,
Direction direction, Direction direction,
BlockState neighborState, BlockState neighborState,
WorldAccess world, LevelAccessor world,
BlockPos pos, BlockPos pos,
BlockPos neighborPos BlockPos neighborPos
) { ) {
if (state.get(WATERLOGGED)) { if (state.getValue(WATERLOGGED)) {
world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); 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 @Override
protected FluidState getFluidState(BlockState state) { 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; package io.github.slimeistdev.crystalline_sky.content.items;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineDataComponentTypes; import io.github.slimeistdev.crystalline_sky.registry.CrystallineDataComponentTypes;
import net.minecraft.block.Block; import net.minecraft.world.item.Item.Properties;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.world.level.block.Block;
import net.minecraft.item.BlockItem; import net.minecraft.world.entity.player.Player;
import net.minecraft.item.ItemStack; import net.minecraft.world.item.BlockItem;
import net.minecraft.item.ItemUsageContext; import net.minecraft.world.item.ItemStack;
import net.minecraft.util.ActionResult; import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.util.Hand; import net.minecraft.world.InteractionResult;
import net.minecraft.util.TypedActionResult; import net.minecraft.world.InteractionHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.world.InteractionResultHolder;
import net.minecraft.util.math.ColumnPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.World; import net.minecraft.server.level.ColumnPos;
import net.minecraft.world.level.Level;
public class WeepingSkyBlockItem extends BlockItem { public class WeepingSkyBlockItem extends BlockItem {
public WeepingSkyBlockItem(Block block, Settings settings) { public WeepingSkyBlockItem(Block block, Properties settings) {
super(block, settings); super(block, settings);
} }
@Override @Override
public ActionResult useOnBlock(ItemUsageContext context) { public InteractionResult useOn(UseOnContext context) {
ItemStack stack = context.getStack(); ItemStack stack = context.getItemInHand();
if (stack.get(CrystallineDataComponentTypes.WEEPING_SKY_DEBUG_COLUMN_TOOL) != null) { if (stack.get(CrystallineDataComponentTypes.WEEPING_SKY_DEBUG_COLUMN_TOOL) != null) {
if (context.getWorld().isClient) { if (context.getLevel().isClientSide) {
BlockPos pos = context.getBlockPos(); BlockPos pos = context.getClickedPos();
WeepingSkyBlockItemClient.setSelectedColumn(new ColumnPos(pos.getX(), pos.getZ())); WeepingSkyBlockItemClient.setSelectedColumn(new ColumnPos(pos.getX(), pos.getZ()));
} }
return ActionResult.SUCCESS; return InteractionResult.SUCCESS;
} }
return super.useOnBlock(context); return super.useOn(context);
} }
@Override @Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) { public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
ItemStack stack = user.getStackInHand(hand); ItemStack stack = user.getItemInHand(hand);
if (stack.get(CrystallineDataComponentTypes.WEEPING_SKY_DEBUG_COLUMN_TOOL) != null) { if (stack.get(CrystallineDataComponentTypes.WEEPING_SKY_DEBUG_COLUMN_TOOL) != null) {
if (world.isClient) { if (world.isClientSide) {
WeepingSkyBlockItemClient.setSelectedColumn(null); WeepingSkyBlockItemClient.setSelectedColumn(null);
} }
return TypedActionResult.success(stack); return InteractionResultHolder.success(stack);
} }
return super.use(world, user, hand); 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 io.github.slimeistdev.crystalline_sky.mixin_ducks.client.DebugRenderer_Duck;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.Minecraft;
import net.minecraft.text.Text; import net.minecraft.network.chat.Component;
import net.minecraft.util.math.ColumnPos; import net.minecraft.server.level.ColumnPos;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class WeepingSkyBlockItemClient { public class WeepingSkyBlockItemClient {
// todone check if this is server-safe // todone check if this is server-safe
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public static void setSelectedColumn(@Nullable ColumnPos column) { 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 weepingSkyDebugRenderer = ((DebugRenderer_Duck) mc.debugRenderer).crystalline_sky$getWeepingSkyDebugRenderer();
weepingSkyDebugRenderer.setColumn(column); weepingSkyDebugRenderer.setColumn(column);
Text text = column == null Component text = column == null
? Text.translatable("message.crystalline_sky.weeping_sky_debug.column.cleared") ? Component.translatable("message.crystalline_sky.weeping_sky_debug.column.cleared")
: Text.translatable("message.crystalline_sky.weeping_sky_debug.column.set", column.x(), column.z()); : Component.translatable("message.crystalline_sky.weeping_sky_debug.column.set", column.x(), column.z());
mc.inGameHud.setOverlayMessage(text, false); 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 io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
import net.minecraft.registry.RegistryKeys; import net.minecraft.core.registries.Registries;
import net.minecraft.registry.RegistryWrapper; import net.minecraft.core.HolderLookup;
import net.minecraft.registry.tag.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.registry.tag.TagKey; import net.minecraft.tags.TagKey;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class CrystallineSkyBlockTagProvider extends FabricTagProvider.BlockTagProvider { 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); super(output, registriesFuture);
} }
@Override @Override
protected void configure(RegistryWrapper.WrapperLookup wrapperLookup) { protected void addTags(HolderLookup.Provider wrapperLookup) {
getOrCreateTagBuilder(TagKey.of(RegistryKeys.BLOCK, CrystallineSky.id("sky_light_emitters"))) tag(TagKey.create(Registries.BLOCK, CrystallineSky.id("sky_light_emitters")))
.add(CrystallineBlocks.SKY) .add(CrystallineBlocks.SKY)
.add(CrystallineBlocks.SKY_LIGHT) .add(CrystallineBlocks.SKY_LIGHT)
.add(CrystallineBlocks.WEEPING_SKY) .add(CrystallineBlocks.WEEPING_SKY)
.add(CrystallineBlocks.WEEPING_SKY_LIGHT); .add(CrystallineBlocks.WEEPING_SKY_LIGHT);
getOrCreateTagBuilder(BlockTags.CRYSTAL_SOUND_BLOCKS) tag(BlockTags.CRYSTAL_SOUND_BLOCKS)
.add(CrystallineBlocks.SKY) .add(CrystallineBlocks.SKY)
.add(CrystallineBlocks.WEEPING_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 io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider;
import net.minecraft.registry.RegistryWrapper; import net.minecraft.core.HolderLookup;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class CrystallineSkyLootProvider extends FabricBlockLootTableProvider { public class CrystallineSkyLootProvider extends FabricBlockLootTableProvider {
public CrystallineSkyLootProvider(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) { public CrystallineSkyLootProvider(FabricDataOutput dataOutput, CompletableFuture<HolderLookup.Provider> registryLookup) {
super(dataOutput, registryLookup); super(dataOutput, registryLookup);
} }
@Override @Override
public void generate() { public void generate() {
addDropWithSilkTouch(CrystallineBlocks.SKY); dropWhenSilkTouch(CrystallineBlocks.SKY);
addDropWithSilkTouch(CrystallineBlocks.WEEPING_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 io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
import net.minecraft.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.data.client.BlockStateModelGenerator; import net.minecraft.data.models.BlockModelGenerators;
import net.minecraft.data.client.BlockStateVariant; import net.minecraft.data.models.blockstates.Variant;
import net.minecraft.data.client.BlockStateVariantMap; import net.minecraft.data.models.blockstates.PropertyDispatch;
import net.minecraft.data.client.ItemModelGenerator; import net.minecraft.data.models.ItemModelGenerators;
import net.minecraft.data.client.ModelIds; import net.minecraft.data.models.model.ModelLocationUtils;
import net.minecraft.data.client.Models; import net.minecraft.data.models.model.ModelTemplates;
import net.minecraft.data.client.TextureMap; import net.minecraft.data.models.model.TextureMapping;
import net.minecraft.data.client.VariantSettings; import net.minecraft.data.models.blockstates.VariantProperties;
import net.minecraft.data.client.VariantsBlockStateSupplier; import net.minecraft.data.models.blockstates.MultiVariantGenerator;
import net.minecraft.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.state.property.Properties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.util.Identifier; import net.minecraft.resources.ResourceLocation;
import java.util.Locale; import java.util.Locale;
@@ -29,45 +29,45 @@ public class CrystallineSkyModelProvider extends FabricModelProvider {
} }
@Override @Override
public void generateBlockStateModels(BlockStateModelGenerator gen) { public void generateBlockStateModels(BlockModelGenerators gen) {
registerSkyBlock(gen, CrystallineBlocks.SKY); registerSkyBlock(gen, CrystallineBlocks.SKY);
registerSkyBlock(gen, CrystallineBlocks.WEEPING_SKY); registerSkyBlock(gen, CrystallineBlocks.WEEPING_SKY);
registerSkyLightBlock(gen, CrystallineBlocks.SKY_LIGHT, CrystallineItems.SKY_LIGHT); registerSkyLightBlock(gen, CrystallineBlocks.SKY_LIGHT, CrystallineItems.SKY_LIGHT);
gen.registerBuiltinWithParticle(CrystallineBlocks.WEEPING_SKY_LIGHT, CrystallineItems.WEEPING_SKY_LIGHT); gen.createAirLikeBlock(CrystallineBlocks.WEEPING_SKY_LIGHT, CrystallineItems.WEEPING_SKY_LIGHT);
gen.registerItemModel(CrystallineItems.WEEPING_SKY_LIGHT); gen.createSimpleFlatItemModel(CrystallineItems.WEEPING_SKY_LIGHT);
} }
private void registerSkyBlock(BlockStateModelGenerator gen, Block block) { private void registerSkyBlock(BlockModelGenerators gen, Block block) {
gen.registerSimpleCubeAll(block); gen.createTrivialCube(block);
gen.registerItemModel(block); gen.createSimpleFlatItemModel(block);
} }
private void registerSkyLightBlock(BlockStateModelGenerator gen, Block block, Item item) { private void registerSkyLightBlock(BlockModelGenerators gen, Block block, Item item) {
gen.excludeFromSimpleItemModelGeneration(block); gen.skipAutoItemBlock(block);
BlockStateVariantMap.SingleProperty<Integer> singleProperty = BlockStateVariantMap.create(Properties.LEVEL_15); PropertyDispatch.C1<Integer> singleProperty = PropertyDispatch.property(BlockStateProperties.LEVEL);
for (int level = 0; level <= 15; level++) { for (int level = 0; level <= 15; level++) {
String suffix = String.format(Locale.ROOT, "_%02d", 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( singleProperty.select(level, Variant.variant().with(
VariantSettings.MODEL, VariantProperties.MODEL,
Models.PARTICLE.upload(block, suffix, TextureMap.particle(texture), gen.modelCollector)) ModelTemplates.PARTICLE_ONLY.createWithSuffix(block, suffix, TextureMapping.particle(texture), gen.modelOutput))
); );
Models.GENERATED.upload( ModelTemplates.FLAT_ITEM.create(
ModelIds.getItemSubModelId(item, suffix), ModelLocationUtils.getModelLocation(item, suffix),
TextureMap.layer0(texture), TextureMapping.layer0(texture),
gen.modelCollector gen.modelOutput
); );
} }
Models.GENERATED.upload( ModelTemplates.FLAT_ITEM.create(
ModelIds.getItemModelId(item), ModelLocationUtils.getModelLocation(item),
TextureMap.layer0(item), TextureMapping.layer0(item),
gen.modelCollector, gen.modelOutput,
(id, textures) -> { (id, textures) -> {
JsonObject base = Models.GENERATED.createJson(id, textures); JsonObject base = ModelTemplates.FLAT_ITEM.createBaseTemplate(id, textures);
var overrides = new JsonArray(); var overrides = new JsonArray();
for (int level = 0; level <= 15; level++) { for (int level = 0; level <= 15; level++) {
JsonObject override = new JsonObject(); JsonObject override = new JsonObject();
@@ -77,7 +77,7 @@ public class CrystallineSkyModelProvider extends FabricModelProvider {
override.add("predicate", predicate); override.add("predicate", predicate);
String suffix = String.format(Locale.ROOT, "_%02d", level); 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()); override.addProperty("model", model.toString());
overrides.add(override); overrides.add(override);
@@ -85,9 +85,9 @@ public class CrystallineSkyModelProvider extends FabricModelProvider {
base.add("overrides", overrides); base.add("overrides", overrides);
return base; return base;
}); });
gen.blockStateCollector.accept(VariantsBlockStateSupplier.create(block).coordinate(singleProperty)); gen.blockStateOutput.accept(MultiVariantGenerator.multiVariant(block).with(singleProperty));
} }
@Override @Override
public void generateItemModels(ItemModelGenerator gen) {} public void generateItemModels(ItemModelGenerators gen) {}
} }
@@ -1,28 +1,28 @@
package io.github.slimeistdev.crystalline_sky.infrastructure; package io.github.slimeistdev.crystalline_sky.infrastructure;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.minecraft.block.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.util.math.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.core.Direction;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.BlockView; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.chunk.light.ChunkLightProvider; import net.minecraft.world.level.lighting.LightEngine;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class MutableWeepingScanner implements WeepingStorage.WeepingScanner { public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
private @Nullable BlockView blockView; private @Nullable BlockGetter blockView;
private final int minY; private final int minY;
private final BlockPos.Mutable reusablePos1 = new BlockPos.Mutable(); private final BlockPos.MutableBlockPos reusablePos1 = new BlockPos.MutableBlockPos();
private final BlockPos.Mutable reusablePos2 = new BlockPos.Mutable(); private final BlockPos.MutableBlockPos reusablePos2 = new BlockPos.MutableBlockPos();
public MutableWeepingScanner(int minY) { public MutableWeepingScanner(int minY) {
this.minY = minY; this.minY = minY;
} }
public void setBlockView(@Nullable BlockView blockView) { public void setBlockView(@Nullable BlockGetter blockView) {
this.blockView = blockView; this.blockView = blockView;
} }
@@ -34,7 +34,7 @@ public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
return y == Integer.MIN_VALUE ? -1 : y - minY; return y == Integer.MIN_VALUE ? -1 : y - minY;
} }
private @NotNull BlockView checkBlockView() { private @NotNull BlockGetter checkBlockView() {
if (blockView == null) { if (blockView == null) {
throw new IllegalStateException("blockView is not set"); throw new IllegalStateException("blockView is not set");
} else { } else {
@@ -44,12 +44,12 @@ public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
@Override @Override
public int scan(int localX, int yMax, int localZ) { public int scan(int localX, int yMax, int localZ) {
BlockView blockView = checkBlockView(); BlockGetter blockView = checkBlockView();
int actualYMax = transformInputY(yMax); int actualYMax = transformInputY(yMax);
BlockPos.Mutable topPos = reusablePos1.set(localX, actualYMax, localZ); BlockPos.MutableBlockPos topPos = reusablePos1.set(localX, actualYMax, localZ);
BlockPos.Mutable bottomPos = reusablePos2.set(localX, actualYMax - 1, localZ); BlockPos.MutableBlockPos bottomPos = reusablePos2.set(localX, actualYMax - 1, localZ);
BlockState topState = blockView.getBlockState(topPos); BlockState topState = blockView.getBlockState(topPos);
while (bottomPos.getY() >= minY) { while (bottomPos.getY() >= minY) {
@@ -68,12 +68,12 @@ public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
@Override @Override
public int scanForWeepingSky(int localX, int yMax, int localZ) { public int scanForWeepingSky(int localX, int yMax, int localZ) {
BlockView blockView = checkBlockView(); BlockGetter blockView = checkBlockView();
int actualYMax = transformInputY(yMax); int actualYMax = transformInputY(yMax);
BlockPos.Mutable topPos = reusablePos1.set(localX, actualYMax, localZ); BlockPos.MutableBlockPos topPos = reusablePos1.set(localX, actualYMax, localZ);
BlockPos.Mutable bottomPos = reusablePos2.set(localX, actualYMax - 1, localZ); BlockPos.MutableBlockPos bottomPos = reusablePos2.set(localX, actualYMax - 1, localZ);
BlockState topState = blockView.getBlockState(topPos); BlockState topState = blockView.getBlockState(topPos);
if (CrystallineBlocks.isWeepingSky(topState)) if (CrystallineBlocks.isWeepingSky(topState))
@@ -99,7 +99,7 @@ public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
@Override @Override
public boolean faceBlocksLight(int localX, int upperY, int localZ) { public boolean faceBlocksLight(int localX, int upperY, int localZ) {
BlockView blockView = checkBlockView(); BlockGetter blockView = checkBlockView();
int actualY = transformInputY(upperY); int actualY = transformInputY(upperY);
reusablePos1.set(localX, actualY, localZ); reusablePos1.set(localX, actualY, localZ);
@@ -110,13 +110,13 @@ public class MutableWeepingScanner implements WeepingStorage.WeepingScanner {
return faceBlocksLight(blockView, upper, lower, reusablePos1, reusablePos2); return faceBlocksLight(blockView, upper, lower, reusablePos1, reusablePos2);
} }
private static boolean faceBlocksLight(BlockView world, BlockState upper, BlockState lower, BlockPos upperPos, BlockPos lowerPos) { private static boolean faceBlocksLight(BlockGetter world, BlockState upper, BlockState lower, BlockPos upperPos, BlockPos lowerPos) {
if (lower.getOpacity(world, lowerPos) != 0) { if (lower.getLightBlock(world, lowerPos) != 0) {
return true; return true;
} else { } else {
VoxelShape voxelShape = ChunkLightProvider.getOpaqueShape(world, upperPos, upper, Direction.DOWN); VoxelShape voxelShape = LightEngine.getOcclusionShape(world, upperPos, upper, Direction.DOWN);
VoxelShape voxelShape2 = ChunkLightProvider.getOpaqueShape(world, lowerPos, lower, Direction.UP); VoxelShape voxelShape2 = LightEngine.getOcclusionShape(world, lowerPos, lower, Direction.UP);
return VoxelShapes.unionCoversFullCube(voxelShape, voxelShape2); 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 io.github.slimeistdev.crystalline_sky.mixin_ducks.ChunkSkyLight_Duck;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.Minecraft;
import net.minecraft.client.render.RenderLayer; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.render.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.render.debug.DebugRenderer; import net.minecraft.client.renderer.debug.DebugRenderer;
import net.minecraft.client.util.math.MatrixStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.util.math.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.util.math.ColumnPos; import net.minecraft.server.level.ColumnPos;
import net.minecraft.world.chunk.light.ChunkSkyLight; import net.minecraft.world.level.lighting.ChunkSkyLightSources;
import net.minecraft.world.chunk.light.LightSourceView; import net.minecraft.world.level.chunk.LightChunk;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f; import org.joml.Matrix4f;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class WeepingSkyDebugRenderer implements DebugRenderer.Renderer { public class WeepingSkyDebugRenderer implements DebugRenderer.SimpleDebugRenderer {
private final MinecraftClient client; private final Minecraft client;
private @Nullable ColumnPos column = null; private @Nullable ColumnPos column = null;
private boolean litMode = true; private boolean litMode = true;
@@ -36,7 +36,7 @@ public class WeepingSkyDebugRenderer implements DebugRenderer.Renderer {
0xFFFF007F, 0xFFFF007F,
}; };
public WeepingSkyDebugRenderer(MinecraftClient client) { public WeepingSkyDebugRenderer(Minecraft client) {
this.client = client; this.client = client;
} }
@@ -49,19 +49,19 @@ public class WeepingSkyDebugRenderer implements DebugRenderer.Renderer {
} }
@Override @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) if (column == null)
return; return;
if (client.world == null) if (client.level == null)
return; return;
ChunkPos chunkPos = column.toChunkPos(); 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) if (chunk == null)
return; return;
ChunkSkyLight chunkSkyLight = chunk.getChunkSkyLight(); ChunkSkyLightSources chunkSkyLight = chunk.getSkyLightSources();
WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage(); WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage();
if (weepingStorage == null) if (weepingStorage == null)
return; return;
@@ -69,9 +69,9 @@ public class WeepingSkyDebugRenderer implements DebugRenderer.Renderer {
int localX = column.x() & 15; int localX = column.x() & 15;
int localZ = column.z() & 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 x1 = (float) (column.x() - cameraX);
float x2 = x1 + 1; 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) { 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(RenderLayer.getDebugLineStrip(2.0)); VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderType.debugLineStrip(2.0));
// render top face // render top face
renderHorizontalSquare(matrix, x1, x2, y1, z1, z2, color, vertexConsumer); 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 // the (x1, z1) vertical edge has been drawn, draw the other 3
// (x2, z1) // (x2, z1)
vertexConsumer.vertex(matrix, x2, y2, z1).color(color); vertexConsumer.addVertex(matrix, x2, y2, z1).setColor(color);
vertexConsumer.vertex(matrix, x2, y1, z1).color(color); vertexConsumer.addVertex(matrix, x2, y1, z1).setColor(color);
// (x2, z2) // (x2, z2)
vertexConsumer.vertex(matrix, x2, y1, z2).color(color); vertexConsumer.addVertex(matrix, x2, y1, z2).setColor(color);
vertexConsumer.vertex(matrix, x2, y2, z2).color(color); vertexConsumer.addVertex(matrix, x2, y2, z2).setColor(color);
// (x1, z2) // (x1, z2)
vertexConsumer.vertex(matrix, x1, y2, z2).color(color); vertexConsumer.addVertex(matrix, x1, y2, z2).setColor(color);
vertexConsumer.vertex(matrix, x1, y1, z2).color(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) { 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.addVertex(matrix, x1, y, z1).setColor(color);
vertexConsumer.vertex(matrix, x2, y, z1).color(color); vertexConsumer.addVertex(matrix, x2, y, z1).setColor(color);
vertexConsumer.vertex(matrix, x2, y, z2).color(color); vertexConsumer.addVertex(matrix, x2, y, z2).setColor(color);
vertexConsumer.vertex(matrix, x1, y, z2).color(color); vertexConsumer.addVertex(matrix, x1, y, z2).setColor(color);
vertexConsumer.vertex(matrix, x1, y, z1).color(color); vertexConsumer.addVertex(matrix, x1, y, z1).setColor(color);
} }
@Override @Override
@@ -8,40 +8,40 @@ import io.github.slimeistdev.crystalline_sky.mixin_ducks.ChunkSkyLight_Duck;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import it.unimi.dsi.fastutil.shorts.ShortArrayList; import it.unimi.dsi.fastutil.shorts.ShortArrayList;
import it.unimi.dsi.fastutil.shorts.ShortList; import it.unimi.dsi.fastutil.shorts.ShortList;
import net.minecraft.block.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.util.math.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.util.math.ChunkSectionPos; import net.minecraft.core.SectionPos;
import net.minecraft.util.math.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.BlockView; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.HeightLimitView; import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.chunk.ChunkSection; import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.chunk.light.ChunkSkyLight; import net.minecraft.world.level.lighting.ChunkSkyLightSources;
import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ChunkSkyLight.class) @Mixin(ChunkSkyLightSources.class)
public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck { public abstract class ChunkSkyLightSourcesMixin implements ChunkSkyLight_Duck {
@Shadow @Shadow
@Final @Final
private int minY; private int minY;
@Shadow @Shadow
@Final @Final
private BlockPos.Mutable reusableBlockPos1; private BlockPos.MutableBlockPos mutablePos1;
@Shadow @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"); throw new RuntimeException("Mixin failed to apply");
} }
@Shadow @Shadow
@Final @Final
private BlockPos.Mutable reusableBlockPos2; private BlockPos.MutableBlockPos mutablePos2;
@Unique @Unique
@Final @Final
@@ -54,7 +54,7 @@ public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
private MutableWeepingScanner crystalline_sky$weepingScanner; private MutableWeepingScanner crystalline_sky$weepingScanner;
@Inject(method = "<init>", at = @At("RETURN")) @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$weepingStorage = new IntWeepingStorage(minY + 1);
crystalline_sky$weepingScanner = new MutableWeepingScanner(minY + 1); crystalline_sky$weepingScanner = new MutableWeepingScanner(minY + 1);
} }
@@ -64,13 +64,13 @@ public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
return crystalline_sky$weepingStorage; return crystalline_sky$weepingStorage;
} }
@Inject(method = "refreshSurfaceY", at = @At("HEAD")) @Inject(method = "fillFrom", at = @At("HEAD"))
private void refreshWeepingSurfaceY(Chunk chunk, CallbackInfo ci) { private void refreshWeepingSurfaceY(ChunkAccess chunk, CallbackInfo ci) {
int highestNonEmptySectionIndex = chunk.getHighestNonEmptySection(); int highestNonEmptySectionIndex = chunk.getHighestFilledSectionIndex();
if (highestNonEmptySectionIndex == -1) { if (highestNonEmptySectionIndex == -1) {
crystalline_sky$weepingStorage.clear(); crystalline_sky$weepingStorage.clear();
} else { } else {
int topY = ChunkSectionPos.getBlockCoord(chunk.sectionIndexToCoord(highestNonEmptySectionIndex) + 1); int topY = SectionPos.sectionToBlockCoord(chunk.getSectionYFromSectionIndex(highestNonEmptySectionIndex) + 1);
int weepingMinY = minY + 1; int weepingMinY = minY + 1;
ShortList data = new ShortArrayList(); ShortList data = new ShortArrayList();
@@ -79,18 +79,18 @@ public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
for (int x = 0; x < 16; x++) { for (int x = 0; x < 16; x++) {
data.clear(); data.clear();
BlockPos.Mutable topPos = reusableBlockPos1.set(x, topY, z); BlockPos.MutableBlockPos topPos = mutablePos1.set(x, topY, z);
BlockPos.Mutable bottomPos = reusableBlockPos2.set(x, topY - 1, z); BlockPos.MutableBlockPos bottomPos = mutablePos2.set(x, topY - 1, z);
BlockState topState = Blocks.AIR.getDefaultState(); BlockState topState = Blocks.AIR.defaultBlockState();
short foundSky = -1; short foundSky = -1;
for (int sectionIndex = highestNonEmptySectionIndex; sectionIndex >= 0; sectionIndex--) { for (int sectionIndex = highestNonEmptySectionIndex; sectionIndex >= 0; sectionIndex--) {
ChunkSection section = chunk.getSection(sectionIndex); LevelChunkSection section = chunk.getSection(sectionIndex);
if (section.isEmpty()) { if (section.hasOnlyAir()) {
topState = Blocks.AIR.getDefaultState(); topState = Blocks.AIR.defaultBlockState();
topPos.setY(ChunkSectionPos.getBlockCoord(chunk.sectionIndexToCoord(sectionIndex))); topPos.setY(SectionPos.sectionToBlockCoord(chunk.getSectionYFromSectionIndex(sectionIndex)));
bottomPos.setY(topPos.getY() - 1); bottomPos.setY(topPos.getY() - 1);
} else { } else {
for (int y = 15; y >= 0; y--) { for (int y = 15; y >= 0; y--) {
@@ -100,7 +100,7 @@ public abstract class ChunkSkyLightMixin implements ChunkSkyLight_Duck {
if (foundSky == -1) { if (foundSky == -1) {
foundSky = (short) (bottomPos.getY() - weepingMinY); foundSky = (short) (bottomPos.getY() - weepingMinY);
} }
} else if (faceBlocksLight(chunk, topPos, topState, bottomPos, bottomState)) { } else if (isEdgeOccluded(chunk, topPos, topState, bottomPos, bottomState)) {
if (foundSky != -1) { if (foundSky != -1) {
short lastLitY = (short) (bottomPos.getY() - weepingMinY + 1); short lastLitY = (short) (bottomPos.getY() - weepingMinY + 1);
data.add(foundSky); 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")) @Inject(method = "update(Lnet/minecraft/world/level/BlockGetter;III)Z", at = @At("HEAD"))
private void updateWeepingSkyState(BlockView blockView, int localX, int y, int localZ, CallbackInfoReturnable<Boolean> cir) { private void updateWeepingSkyState(BlockGetter blockView, int localX, int y, int localZ, CallbackInfoReturnable<Boolean> cir) {
BlockPos pos = reusableBlockPos1.set(localX, y, localZ); BlockPos pos = mutablePos1.set(localX, y, localZ);
BlockState state = blockView.getBlockState(pos); BlockState state = blockView.getBlockState(pos);
crystalline_sky$weepingScanner.setBlockView(blockView); 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); crystalline_sky$weepingStorage.insertAir(localX, y - weepingMinY, localZ, crystalline_sky$weepingScanner);
} else if (CrystallineBlocks.isWeepingSky(state)) { } else if (CrystallineBlocks.isWeepingSky(state)) {
crystalline_sky$weepingStorage.insertSky(localX, y - weepingMinY, localZ, crystalline_sky$weepingScanner); 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); 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.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.minecraft.block.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.util.math.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.BlockView; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.chunk.light.ChunkLightProvider; import net.minecraft.world.level.lighting.LightEngine;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@Mixin(ChunkLightProvider.class) @Mixin(LightEngine.class)
public class ChunkLightProviderMixin { public class LightEngineMixin {
@WrapMethod(method = "needsLightUpdate") @WrapMethod(method = "hasDifferentLightProperties")
private static boolean updateSky(BlockView blockView, BlockPos pos, BlockState oldState, BlockState newState, Operation<Boolean> original) { private static boolean updateSky(BlockGetter blockView, BlockPos pos, BlockState oldState, BlockState newState, Operation<Boolean> original) {
return original.call(blockView, pos, oldState, newState) return original.call(blockView, pos, oldState, newState)
|| (CrystallineBlocks.getSkyLightLevel(oldState) != CrystallineBlocks.getSkyLightLevel(newState)) || (CrystallineBlocks.getSkyLightLevel(oldState) != CrystallineBlocks.getSkyLightLevel(newState))
|| (CrystallineBlocks.isWeepingSky(oldState) != CrystallineBlocks.isWeepingSky(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.infrastructure.WeepingStorage;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.ChunkSkyLight_Duck; import io.github.slimeistdev.crystalline_sky.mixin_ducks.ChunkSkyLight_Duck;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks; import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.minecraft.block.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.util.math.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.util.math.ChunkSectionPos; import net.minecraft.core.SectionPos;
import net.minecraft.util.math.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.chunk.ChunkNibbleArray; import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.chunk.ChunkProvider; import net.minecraft.world.level.chunk.LightChunkGetter;
import net.minecraft.world.chunk.ChunkToNibbleArrayMap; import net.minecraft.world.level.lighting.DataLayerStorageMap;
import net.minecraft.world.chunk.light.ChunkLightProvider; import net.minecraft.world.level.lighting.LightEngine;
import net.minecraft.world.chunk.light.ChunkSkyLight; import net.minecraft.world.level.lighting.ChunkSkyLightSources;
import net.minecraft.world.chunk.light.ChunkSkyLightProvider; import net.minecraft.world.level.lighting.SkyLightEngine;
import net.minecraft.world.chunk.light.LightSourceView; import net.minecraft.world.level.chunk.LightChunk;
import net.minecraft.world.chunk.light.LightStorage; import net.minecraft.world.level.lighting.LayerLightSectionStorage;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; 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; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
// todone add ordinal to all name = "..." locals // todone add ordinal to all name = "..." locals
@Mixin(ChunkSkyLightProvider.class) @Mixin(SkyLightEngine.class)
public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap<M>, S extends LightStorage<M>> extends ChunkLightProvider<M, S> { public abstract class SkyLightEngineMixin<M extends DataLayerStorageMap<M>, S extends LayerLightSectionStorage<M>> extends LightEngine<M, S> {
@Shadow @Shadow
@Final @Final
private BlockPos.Mutable scratchPos; private BlockPos.MutableBlockPos mutablePos;
@Shadow @Shadow
private static boolean isMaxLightLevel(int lightLevel) { private static boolean isSourceLevel(int lightLevel) {
throw new RuntimeException("Mixin failed to apply"); throw new RuntimeException("Mixin failed to apply");
} }
@@ -53,18 +53,18 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
@Final @Final
private static long ADD_SKY_SOURCE_ENTRY; private static long ADD_SKY_SOURCE_ENTRY;
protected ChunkSkyLightProviderMixin(ChunkProvider chunkProvider, S lightStorage) { protected SkyLightEngineMixin(LightChunkGetter chunkProvider, S lightStorage) {
super(chunkProvider, 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) { private void emitFromCrystallineSky(long blockPos, CallbackInfo ci) {
BlockState state = getStateForLighting(scratchPos.set(blockPos)); BlockState state = getState(mutablePos.set(blockPos));
int level = CrystallineBlocks.isWeepingSky(state) int level = CrystallineBlocks.isWeepingSky(state)
? 15 ? 15
: CrystallineBlocks.getSkyLightLevel(state); : CrystallineBlocks.getSkyLightLevel(state);
if (level > 0 && ((LightStorageAccessor) lightStorage).crystalline_sky$callIsSectionInEnabledColumn(ChunkSectionPos.fromBlockPos(blockPos))) { if (level > 0 && ((LayerLightSectionStorageAccessor) storage).crystalline_sky$callLightOnInSection(SectionPos.blockToSection(blockPos))) {
enqueueIncrease(blockPos, QueueEntry.increaseLightFromEmission(level, isTrivialForLighting(state))); enqueueIncrease(blockPos, QueueEntry.increaseLightFromEmission(level, isEmptyShape(state)));
} }
} }
@@ -78,14 +78,14 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
return true; 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; if (chunk == null) return false;
ChunkSkyLight chunkSkyLight = chunk.getChunkSkyLight(); ChunkSkyLightSources chunkSkyLight = chunk.getSkyLightSources();
if (chunkSkyLight == null) return false; if (chunkSkyLight == null) return false;
int localX = ChunkSectionPos.getLocalCoord(x); int localX = SectionPos.sectionRelative(x);
int localZ = ChunkSectionPos.getLocalCoord(z); int localZ = SectionPos.sectionRelative(z);
WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage(); WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage();
if (weepingStorage.isColumnEmpty(localX, localZ)) return false; if (weepingStorage.isColumnEmpty(localX, localZ)) return false;
@@ -93,11 +93,11 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
return weepingStorage.isLit(localX, y, localZ); return weepingStorage.isLit(localX, y, localZ);
} }
@WrapOperation(method = "propagateDecrease", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/ChunkSkyLightProvider;enqueueDecrease(JJ)V")) @WrapOperation(method = "propagateDecrease", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/lighting/SkyLightEngine;enqueueDecrease(JJ)V"))
private void decreaseTakesLightIntoAccount1(ChunkSkyLightProvider instance, long blockPos, long flags, private void decreaseTakesLightIntoAccount1(SkyLightEngine instance, long blockPos, long flags,
Operation<Void> original, @Local(name = "k", ordinal = 2) int k) { Operation<Void> original, @Local(name = "k", ordinal = 2) int k) {
// k is the old light level at blockPos // 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); int luminance = CrystallineBlocks.getSkyLightLevel(state);
if (luminance < k) { if (luminance < k) {
@@ -105,16 +105,16 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
} }
if (luminance > 0) { 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")) @WrapOperation(method = "propagateDecrease", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/lighting/SkyLightEngine;propagateFromEmptySections(JLnet/minecraft/core/Direction;IZI)V"))
private void decreaseTakesLightIntoAccount2(ChunkSkyLightProvider instance, long blockPos, Direction direction, private void decreaseTakesLightIntoAccount2(SkyLightEngine instance, long blockPos, Direction direction,
int lightLevel, boolean shouldIncrease, int emptySections, int lightLevel, boolean shouldIncrease, int emptySections,
Operation<Void> original, @Local(name = "k", ordinal = 2) int k) { Operation<Void> original, @Local(name = "k", ordinal = 2) int k) {
// k is the old light level at blockPos // 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); int luminance = CrystallineBlocks.getSkyLightLevel(state);
if (luminance < k) { 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) { private void propagateCrystallineSkyLight(ChunkPos chunkPos, CallbackInfo ci) {
LightSourceView lightSourceView = this.chunkProvider.getChunk(chunkPos.x, chunkPos.z); LightChunk lightSourceView = this.chunkSource.getChunkForLighting(chunkPos.x, chunkPos.z);
if (!(lightSourceView instanceof Chunk chunk)) return; if (!(lightSourceView instanceof ChunkAccess chunk)) return;
chunk.forEachBlockMatchingPredicate(CrystallineBlocks::isCrystallineSky, (pos, state) -> { chunk.findBlocks(CrystallineBlocks::isCrystallineSky, (pos, state) -> {
enqueueIncrease(pos.asLong(), QueueEntry.increaseLightFromEmission(CrystallineBlocks.getSkyLightLevel(state), isTrivialForLighting(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) @Inject(method = "removeSourcesBelow", at = @At("HEAD"), cancellable = true)
private void removeWeepingSourcesBelow(int x, int z, int lowestSourceY, int minY, CallbackInfo ci) { 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; if (chunk == null) return;
ChunkSkyLight chunkSkyLight = chunk.getChunkSkyLight(); ChunkSkyLightSources chunkSkyLight = chunk.getSkyLightSources();
if (chunkSkyLight == null) return; if (chunkSkyLight == null) return;
int localX = ChunkSectionPos.getLocalCoord(x); int localX = SectionPos.sectionRelative(x);
int localZ = ChunkSectionPos.getLocalCoord(z); int localZ = SectionPos.sectionRelative(z);
WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage(); WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage();
if (weepingStorage.isColumnEmpty(localX, localZ) && weepingStorage.hasNoUnlitSplits(localX, localZ)) return; 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 // there's little chance of accidental mixin compatibility anyway, so just cancel
ci.cancel(); ci.cancel();
int sectionX = ChunkSectionPos.getSectionCoord(x); int sectionX = SectionPos.blockToSectionCoord(x);
int sectionZ = ChunkSectionPos.getSectionCoord(z); int sectionZ = SectionPos.blockToSectionCoord(z);
int effectiveLowestSourceY = lowestSourceY <= minY ? Integer.MIN_VALUE : lowestSourceY; 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)) { RunIter: for (WeepingStorage.Run run : weepingStorage.iterateUnlitRuns(localX, localZ, effectiveLowestSourceY)) {
// check lighting state of run // check lighting state of run
int topUnlit = run.topY(); int topUnlit = run.topY();
int bottomUnlit = run.bottomY(); int bottomUnlit = run.bottomY();
for (int sectionY = ChunkSectionPos.getSectionCoord(topUnlit); lightStorageAccessor.crystalline_sky$isAboveMinHeight(sectionY); sectionY--) { for (int sectionY = SectionPos.blockToSectionCoord(topUnlit); lightStorageAccessor.crystalline_sky$isAboveMinHeight(sectionY); sectionY--) {
if (lightStorageAccessor.crystalline_sky$hasSection(ChunkSectionPos.asLong(sectionX, sectionY, sectionZ))) { if (lightStorageAccessor.crystalline_sky$hasSection(SectionPos.asLong(sectionX, sectionY, sectionZ))) {
int minYInSection = ChunkSectionPos.getBlockCoord(sectionY); int minYInSection = SectionPos.sectionToBlockCoord(sectionY);
int maxYInSection = minYInSection + 15; int maxYInSection = minYInSection + 15;
if (maxYInSection < bottomUnlit) { // todone break outer early if we're below bottomUnlit 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--) { 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); 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; continue;
} }
if (!isMaxLightLevel(lightStorageAccessor.crystalline_sky$get(it_pos))) { if (!isSourceLevel(lightStorageAccessor.crystalline_sky$get(it_pos))) {
continue RunIter; 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")) @Inject(method = "addSourcesAbove", at = @At("RETURN"))
private void addAdditionalWeepingSourcesAbove(int x, int z, int lowestSourceY, int minY, CallbackInfo ci, private void addAdditionalWeepingSourcesAbove(int x, int z, int lowestSourceY, int minY, CallbackInfo ci,
@Local(name = "maxAdjacentLowestSourceY", ordinal = 6) int maxAdjacentLowestSourceY) { @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; if (chunk == null) return;
ChunkSkyLight chunkSkyLight = chunk.getChunkSkyLight(); ChunkSkyLightSources chunkSkyLight = chunk.getSkyLightSources();
if (chunkSkyLight == null) return; if (chunkSkyLight == null) return;
int localX = ChunkSectionPos.getLocalCoord(x); int localX = SectionPos.sectionRelative(x);
int localZ = ChunkSectionPos.getLocalCoord(z); int localZ = SectionPos.sectionRelative(z);
WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage(); WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) chunkSkyLight).crystalline_sky$getWeepingStorage();
if (weepingStorage.isColumnEmpty(localX, localZ)) { if (weepingStorage.isColumnEmpty(localX, localZ)) {
@@ -212,8 +216,8 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
return; return;
} }
int sectionX = ChunkSectionPos.getSectionCoord(x); int sectionX = SectionPos.blockToSectionCoord(x);
int sectionZ = ChunkSectionPos.getSectionCoord(z); int sectionZ = SectionPos.blockToSectionCoord(z);
int effectiveLowestSourceY = lowestSourceY <= minY ? Integer.MIN_VALUE : lowestSourceY; int effectiveLowestSourceY = lowestSourceY <= minY ? Integer.MIN_VALUE : lowestSourceY;
if (effectiveLowestSourceY == Integer.MIN_VALUE) { if (effectiveLowestSourceY == Integer.MIN_VALUE) {
@@ -221,7 +225,7 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
return; return;
} }
SkyLightStorageAccessor lightStorageAccessor = (SkyLightStorageAccessor) this.lightStorage; SkyLightSectionStorageAccessor lightStorageAccessor = (SkyLightSectionStorageAccessor) this.storage;
RunIter: for (WeepingStorage.Run run : weepingStorage.iterateLitRuns(localX, localZ, effectiveLowestSourceY)) { RunIter: for (WeepingStorage.Run run : weepingStorage.iterateLitRuns(localX, localZ, effectiveLowestSourceY)) {
if (run.topY() == Integer.MAX_VALUE) { if (run.topY() == Integer.MAX_VALUE) {
@@ -233,12 +237,12 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
} }
int lowestRelevantY = Math.max(run.bottomY(), minY); 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); !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)) { 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; int maxYInSection = minYInSection + 15;
if (minYInSection > run.topY()) { // todone break outer early if we're above run.topY() 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++) { 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); 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; continue;
} }
if (isMaxLightLevel(lightStorageAccessor.crystalline_sky$get(it_pos))) { if (isSourceLevel(lightStorageAccessor.crystalline_sky$get(it_pos))) {
continue RunIter; continue RunIter;
} }
@@ -268,13 +272,13 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
weepingStorage.clearTempRunSplits(localX, localZ); weepingStorage.clearTempRunSplits(localX, localZ);
} }
@Inject(method = "propagateLight", at = @At("RETURN")) @Inject(method = "propagateLightSources", at = @At("RETURN"))
private void propagateWeepingLight(ChunkPos chunkPos, CallbackInfo ci, private void propagateWeepingLight(ChunkPos chunkPos, CallbackInfo ci,
@Local(name = "sourcesO", ordinal = 0) ChunkSkyLight sourcesO, @Local(name = "sourcesO", ordinal = 0) ChunkSkyLightSources sourcesO,
@Local(name = "sourcesZN", ordinal = 1) ChunkSkyLight sourcesZN, @Local(name = "sourcesZN", ordinal = 1) ChunkSkyLightSources sourcesZN,
@Local(name = "sourcesZP", ordinal = 2) ChunkSkyLight sourcesZP, @Local(name = "sourcesZP", ordinal = 2) ChunkSkyLightSources sourcesZP,
@Local(name = "sourcesXN", ordinal = 3) ChunkSkyLight sourcesXN, @Local(name = "sourcesXN", ordinal = 3) ChunkSkyLightSources sourcesXN,
@Local(name = "sourcesXP", ordinal = 4) ChunkSkyLight sourcesXP @Local(name = "sourcesXP", ordinal = 4) ChunkSkyLightSources sourcesXP
) { ) {
WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) sourcesO).crystalline_sky$getWeepingStorage(); WeepingStorage weepingStorage = ((ChunkSkyLight_Duck) sourcesO).crystalline_sky$getWeepingStorage();
if (weepingStorage == null) return; if (weepingStorage == null) return;
@@ -291,19 +295,19 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
if (!hasAny) if (!hasAny)
return; return;
long packedZeroPos = ChunkSectionPos.withZeroY(chunkPos.x, chunkPos.z); long packedZeroPos = SectionPos.getZeroNode(chunkPos.x, chunkPos.z);
SkyLightStorageAccessor lightStorageAccessor = (SkyLightStorageAccessor) this.lightStorage; SkyLightSectionStorageAccessor lightStorageAccessor = (SkyLightSectionStorageAccessor) this.storage;
int topSectionY = lightStorageAccessor.crystalline_sky$getTopSectionForColumn(packedZeroPos); int topSectionY = lightStorageAccessor.crystalline_sky$getTopSectionForColumn(packedZeroPos);
int bottomSectionY = lightStorageAccessor.crystalline_sky$getMinSectionY(); int bottomSectionY = lightStorageAccessor.crystalline_sky$getMinSectionY();
int baseX = ChunkSectionPos.getBlockCoord(chunkPos.x); int baseX = SectionPos.sectionToBlockCoord(chunkPos.x);
int baseZ = ChunkSectionPos.getBlockCoord(chunkPos.z); 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--) { 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); 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++) { for (int localX = 0; localX < 16; localX++) {
if (weepingStorage.isColumnEmpty(localX, localZ)) continue; 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; int effectiveLowestSourceY = lowestSourceY <= minY ? Integer.MIN_VALUE : lowestSourceY;
if (effectiveLowestSourceY == Integer.MIN_VALUE) continue; if (effectiveLowestSourceY == Integer.MIN_VALUE) continue;
int minSourceY_ZN = localZ == 0 ? sourcesZN.get(localX, 15) : sourcesO.get(localX, localZ - 1); int minSourceY_ZN = localZ == 0 ? sourcesZN.getLowestSourceY(localX, 15) : sourcesO.getLowestSourceY(localX, localZ - 1);
int minSourceY_ZP = localZ == 15 ? sourcesZP.get(localX, 0) : sourcesO.get(localX, localZ + 1); int minSourceY_ZP = localZ == 15 ? sourcesZP.getLowestSourceY(localX, 0) : sourcesO.getLowestSourceY(localX, localZ + 1);
int minSourceY_XN = localX == 0 ? sourcesXN.get(15, localZ) : sourcesO.get(localX - 1, localZ); int minSourceY_XN = localX == 0 ? sourcesXN.getLowestSourceY(15, localZ) : sourcesO.getLowestSourceY(localX - 1, localZ);
int minSourceY_XP = localX == 15 ? sourcesXP.get(0, localZ) : sourcesO.get(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)); 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)) { 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); int lowestRelevantY = Math.max(run.bottomY(), minY);
for (int sectionY = ChunkSectionPos.getSectionCoord(lowestRelevantY); sectionY <= topSectionY - 1; sectionY++) { for (int sectionY = SectionPos.blockToSectionCoord(lowestRelevantY); sectionY <= topSectionY - 1; sectionY++) {
ChunkNibbleArray lightArray = lightArrays[sectionY - bottomSectionY]; DataLayer lightArray = lightArrays[sectionY - bottomSectionY];
if (lightArray == null) continue; if (lightArray == null) continue;
int minYInSection = ChunkSectionPos.getBlockCoord(sectionY); int minYInSection = SectionPos.sectionToBlockCoord(sectionY);
int maxYInSection = minYInSection + 15; int maxYInSection = minYInSection + 15;
if (minYInSection > run.topY()) { // todone break outer early if we're above run.topY() 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++) { 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) { if (it_y == lowestRelevantY || it_y < minSourceY_max) {
long it_pos = BlockPos.asLong(baseX + localX, it_y, baseZ + localZ); long it_pos = BlockPos.asLong(baseX + localX, it_y, baseZ + localZ);
@@ -1,20 +1,20 @@
package io.github.slimeistdev.crystalline_sky.mixin; 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.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(SkyLightStorage.class) @Mixin(SkyLightSectionStorage.class)
public interface SkyLightStorageAccessor extends LightStorageAccessor { public interface SkyLightSectionStorageAccessor extends LayerLightSectionStorageAccessor {
@Invoker("isAboveMinHeight") @Invoker("hasLightDataAtOrBelow")
boolean crystalline_sky$isAboveMinHeight(int sectionY); boolean crystalline_sky$isAboveMinHeight(int sectionY);
@Invoker("isAtOrAboveTopmostSection") @Invoker("isAboveData")
boolean crystalline_sky$isAtOrAboveTopmostSection(long sectionPos); boolean crystalline_sky$isAtOrAboveTopmostSection(long sectionPos);
@Invoker("getTopSectionForColumn") @Invoker("getTopSectionY")
int crystalline_sky$getTopSectionForColumn(long columnPos); int crystalline_sky$getTopSectionForColumn(long columnPos);
@Invoker("getMinSectionY") @Invoker("getBottomSectionY")
int crystalline_sky$getMinSectionY(); int crystalline_sky$getMinSectionY();
} }
@@ -1,8 +1,8 @@
package io.github.slimeistdev.crystalline_sky.mixin.client; package io.github.slimeistdev.crystalline_sky.mixin.client;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems; import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.item.Item; import net.minecraft.world.item.Item;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable; 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.HashSet;
import java.util.Set; import java.util.Set;
@Mixin(ClientWorld.class) @Mixin(ClientLevel.class)
public class ClientWorldMixin { public class ClientLevelMixin {
@Shadow @Shadow
@Final @Final
@Mutable @Mutable
private static Set<Item> BLOCK_MARKER_ITEMS; private static Set<Item> MARKER_PARTICLE_ITEMS;
@Inject(method = "<clinit>", at = @At("RETURN")) @Inject(method = "<clinit>", at = @At("RETURN"))
private static void modifyBlockMarkerItems(CallbackInfo ci) { private static void modifyBlockMarkerItems(CallbackInfo ci) {
BLOCK_MARKER_ITEMS = new HashSet<>(BLOCK_MARKER_ITEMS); MARKER_PARTICLE_ITEMS = new HashSet<>(MARKER_PARTICLE_ITEMS);
BLOCK_MARKER_ITEMS.add(CrystallineItems.SKY_LIGHT); MARKER_PARTICLE_ITEMS.add(CrystallineItems.SKY_LIGHT);
BLOCK_MARKER_ITEMS.add(CrystallineItems.WEEPING_SKY_LIGHT); MARKER_PARTICLE_ITEMS.add(CrystallineItems.WEEPING_SKY_LIGHT);
BLOCK_MARKER_ITEMS.add(CrystallineItems.SKY); MARKER_PARTICLE_ITEMS.add(CrystallineItems.SKY);
BLOCK_MARKER_ITEMS.add(CrystallineItems.WEEPING_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.infrastructure.client.WeepingSkyDebugRenderer;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.DebugRenderer_Duck; import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.DebugRenderer_Duck;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.Minecraft;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.render.debug.DebugRenderer; import net.minecraft.client.renderer.debug.DebugRenderer;
import net.minecraft.client.util.math.MatrixStack; import com.mojang.blaze3d.vertex.PoseStack;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Mutable;
@@ -36,19 +36,19 @@ public class DebugRendererMixin implements DebugRenderer_Duck {
} }
@Inject(method = "<init>", at = @At("RETURN")) @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); this.crystalline_sky$weepingSkyDebugRenderer = new WeepingSkyDebugRenderer(client);
} }
@Inject(method = "render", at = @At("RETURN")) @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) { if (crystalline_sky$weepingSkyMode != 0) {
crystalline_sky$weepingSkyDebugRenderer.setLitMode(crystalline_sky$weepingSkyMode == 1); crystalline_sky$weepingSkyDebugRenderer.setLitMode(crystalline_sky$weepingSkyMode == 1);
crystalline_sky$weepingSkyDebugRenderer.render(matrices, vertexConsumers, cameraX, cameraY, cameraZ); 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) { private void reset(CallbackInfo ci) {
crystalline_sky$weepingSkyDebugRenderer.clear(); crystalline_sky$weepingSkyDebugRenderer.clear();
} }
@@ -4,10 +4,10 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineShaderPrograms; import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineShaderPrograms;
import net.minecraft.client.gl.ShaderProgram; import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.client.render.GameRenderer; import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.render.VertexFormats; import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import net.minecraft.resource.ResourceFactory; import net.minecraft.server.packs.resources.ResourceProvider;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@@ -17,18 +17,18 @@ import java.util.function.Consumer;
@Mixin(GameRenderer.class) @Mixin(GameRenderer.class)
public class GameRendererMixin { public class GameRendererMixin {
@WrapOperation(method = "loadPrograms", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 0)) @WrapOperation(method = "reloadShaders", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 0))
private <E extends Pair<ShaderProgram, Consumer<ShaderProgram>>> boolean loadSkyProgram( private <E extends Pair<ShaderInstance, Consumer<ShaderInstance>>> boolean loadSkyProgram(
List<E> instance, List<E> instance,
Object e, Object e,
Operation<Boolean> original, Operation<Boolean> original,
ResourceFactory factory ResourceProvider factory
) throws IOException { ) throws IOException {
original.call(instance, Pair.of(new ShaderProgram( original.call(instance, Pair.of(new ShaderInstance(
factory, factory,
"crystalline_sky_rendertype_sky", "crystalline_sky_rendertype_sky",
VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL DefaultVertexFormat.BLOCK
), (Consumer<ShaderProgram>) program -> CrystallineShaderPrograms.renderTypeSkyProgram = program)); ), (Consumer<ShaderInstance>) program -> CrystallineShaderPrograms.renderTypeSkyProgram = program));
return original.call(instance, e); 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.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.Framebuffer_Duck; 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.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@Mixin(Framebuffer.class) @Mixin(RenderTarget.class)
public class FramebufferMixin implements Framebuffer_Duck { public class RenderTargetMixin implements Framebuffer_Duck {
@Shadow @Shadow
protected int colorAttachment; protected int colorTextureId;
@Shadow @Shadow
public int textureWidth; public int width;
@Shadow @Shadow
public int textureHeight; public int height;
@Shadow @Shadow
public int fbo; public int frameBufferId;
@Override @Override
public void crystalline_sky$copyColorFrom(Framebuffer framebuffer) { public void crystalline_sky$copyColorFrom(RenderTarget framebuffer) {
RenderSystem.assertOnRenderThreadOrInit(); 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"); 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"); throw new IllegalStateException("Trying to copy color texture from a RenderTarget without a color texture");
} else { } else {
GlStateManager._glBindFramebuffer(GlConst.GL_READ_FRAMEBUFFER, framebuffer.fbo); GlStateManager._glBindFramebuffer(GlConst.GL_READ_FRAMEBUFFER, framebuffer.frameBufferId);
GlStateManager._glBindFramebuffer(GlConst.GL_DRAW_FRAMEBUFFER, this.fbo); GlStateManager._glBindFramebuffer(GlConst.GL_DRAW_FRAMEBUFFER, this.frameBufferId);
GlStateManager._glBlitFrameBuffer( GlStateManager._glBlitFrameBuffer(
0, 0, framebuffer.textureWidth, framebuffer.textureHeight, 0, 0, framebuffer.width, framebuffer.height,
0, 0, this.textureWidth, this.textureHeight, 0, 0, this.width, this.height,
GlConst.GL_COLOR_BUFFER_BIT, GlConst.GL_NEAREST 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 com.google.common.collect.ImmutableList;
import io.github.slimeistdev.crystalline_sky.mixin_ducks.client.RenderLayer_Duck; 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.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@Mixin(RenderLayer.class) @Mixin(RenderType.class)
public class RenderLayerMixin implements RenderLayer_Duck { public class RenderTypeMixin implements RenderLayer_Duck {
@Shadow @Shadow
@Final @Final
@Mutable @Mutable
private static ImmutableList<RenderLayer> BLOCK_LAYERS; private static ImmutableList<RenderType> CHUNK_BUFFER_LAYERS;
@Override @Override
public void crystalline_sky$markAsBlockLayer() { public void crystalline_sky$markAsBlockLayer() {
BLOCK_LAYERS = ImmutableList.<RenderLayer>builder() CHUNK_BUFFER_LAYERS = ImmutableList.<RenderType>builder()
.addAll(BLOCK_LAYERS) .addAll(CHUNK_BUFFER_LAYERS)
.add((RenderLayer) (Object) this) .add((RenderType) (Object) this)
.build(); .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.annotation.mixin.ConditionalMixin;
import io.github.slimeistdev.crystalline_sky.compat.Mods; import io.github.slimeistdev.crystalline_sky.compat.Mods;
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderLayers; 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.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
@@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ChunkRenderOverrider.AxiomChunkOverrideLayer.class) @Mixin(ChunkRenderOverrider.AxiomChunkOverrideLayer.class)
public class ChunkRenderOverrider_AxiomChunkOverrideLayerMixin { public class ChunkRenderOverrider_AxiomChunkOverrideLayerMixin {
@Inject(method = "fromVanilla", at = @At("HEAD"), cancellable = true) @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) { if (layer == CrystallineRenderLayers.SKY) {
cir.setReturnValue(ChunkRenderOverrider.AxiomChunkOverrideLayer.CUTOUT_MIPPED); 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.DefaultMaterials;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.Material; 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.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.Mixin;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; 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) @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) { if (layer == CrystallineRenderLayers.SKY) {
cir.setReturnValue(crystalline_sky$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.ChunkShaderOptions;
import net.caffeinemc.mods.sodium.client.render.chunk.shader.ShaderBindingContext; import net.caffeinemc.mods.sodium.client.render.chunk.shader.ShaderBindingContext;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.DefaultMaterials; 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.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@@ -30,8 +30,8 @@ public class ShaderChunkRendererMixin {
return original.call(instance, path, options); 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;")) @WrapOperation(method = "createShader", at = @At(value = "INVOKE", target = "Lnet/minecraft/resources/ResourceLocation;fromNamespaceAndPath(Ljava/lang/String;Ljava/lang/String;)Lnet/minecraft/resources/ResourceLocation;"))
private Identifier redirectShaderNamespace(String namespace, String path, Operation<Identifier> original, String pathArg) { private ResourceLocation redirectShaderNamespace(String namespace, String path, Operation<ResourceLocation> original, String pathArg) {
if (pathArg.equals("sodium_compat/block_layer_sky")) { if (pathArg.equals("sodium_compat/block_layer_sky")) {
namespace = "crystalline_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.ChunkRenderMatrices;
import net.caffeinemc.mods.sodium.client.render.chunk.RenderSectionManager; import net.caffeinemc.mods.sodium.client.render.chunk.RenderSectionManager;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.DefaultMaterials; 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.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@@ -21,7 +21,7 @@ public class SodiumWorldRendererMixin {
private RenderSectionManager renderSectionManager; private RenderSectionManager renderSectionManager;
@Inject(method = "drawChunkLayer", at = @At("RETURN")) @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; if (renderLayer != CrystallineRenderLayers.SKY) return;
renderSectionManager.renderLayer(matrices, DefaultMaterials.forRenderLayer(CrystallineRenderLayers.SKY).pass, x, y, z); 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.annotation.mixin.ConditionalMixin;
import io.github.slimeistdev.crystalline_sky.compat.Mods; import io.github.slimeistdev.crystalline_sky.compat.Mods;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.TerrainRenderPass; 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.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Accessor;
@@ -11,5 +11,5 @@ import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(TerrainRenderPass.class) @Mixin(TerrainRenderPass.class)
public interface TerrainRenderPassAccessor { public interface TerrainRenderPassAccessor {
@Accessor("renderType") @Accessor("renderType")
RenderLayer crystalline_sky$getRenderLayer(); RenderType crystalline_sky$getRenderLayer();
} }
@@ -1,7 +1,7 @@
package io.github.slimeistdev.crystalline_sky.mixin_ducks.client; 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 { 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; 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 { 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.SkyLightBlock;
import io.github.slimeistdev.crystalline_sky.content.blocks.WeepingSkyLightBlock; import io.github.slimeistdev.crystalline_sky.content.blocks.WeepingSkyLightBlock;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.AbstractBlock.Settings; import net.minecraft.world.level.block.Block;
import net.minecraft.registry.Registries; import net.minecraft.world.level.block.Blocks;
import net.minecraft.registry.Registry; import net.minecraft.world.level.block.LightBlock;
import net.minecraft.registry.RegistryKey; import net.minecraft.world.level.block.TransparentBlock;
import net.minecraft.registry.RegistryKeys; import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.sound.BlockSoundGroup; import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
import net.minecraft.state.property.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; import java.util.function.Function;
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
public class CrystallineBlocks { 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) .strength(0.3f)
.sounds(BlockSoundGroup.AMETHYST_BLOCK) .sound(SoundType.AMETHYST)
.nonOpaque() .noOcclusion()
.allowsSpawning(Blocks::never) .isValidSpawn(Blocks::never)
.solidBlock(Blocks::never) .isRedstoneConductor(Blocks::never)
.suffocates(Blocks::never) .isSuffocating(Blocks::never)
.blockVision(Blocks::never) .isViewBlocking(Blocks::never)
.emissiveLighting(Blocks::always)); .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( public static final Block SKY_LIGHT = register(
"sky_light", "sky_light",
SkyLightBlock::new, SkyLightBlock::new,
AbstractBlock.Settings.create() BlockBehaviour.Properties.of()
.replaceable() .replaceable()
.strength(-1.0F, 3600000.8F) .strength(-1.0F, 3600000.8F)
.mapColor(state -> state.get(Properties.WATERLOGGED) ? MapColor.WATER_BLUE : MapColor.CLEAR) .mapColor(state -> state.getValue(BlockStateProperties.WATERLOGGED) ? MapColor.WATER : MapColor.NONE)
.dropsNothing() .noLootTable()
.nonOpaque() .noOcclusion()
); );
public static final Block WEEPING_SKY_LIGHT = register( public static final Block WEEPING_SKY_LIGHT = register(
"weeping_sky_light", "weeping_sky_light",
WeepingSkyLightBlock::new, WeepingSkyLightBlock::new,
AbstractBlock.Settings.create() BlockBehaviour.Properties.of()
.replaceable() .replaceable()
.strength(-1.0F, 3600000.8F) .strength(-1.0F, 3600000.8F)
.mapColor(state -> state.get(Properties.WATERLOGGED) ? MapColor.WATER_BLUE : MapColor.CLEAR) .mapColor(state -> state.getValue(BlockStateProperties.WATERLOGGED) ? MapColor.WATER : MapColor.NONE)
.dropsNothing() .noLootTable()
.nonOpaque() .noOcclusion()
); );
public static void init() {} public static void init() {}
private static <T extends Block> T register(String id, Function<Settings, T> factory, Settings settings) { private static <T extends Block> T register(String id, Function<Properties, T> factory, Properties settings) {
RegistryKey<Block> key = CrystallineSky.key(RegistryKeys.BLOCK, id); ResourceKey<Block> key = CrystallineSky.key(Registries.BLOCK, id);
return Registry.register(Registries.BLOCK, key, factory.apply(settings)); return Registry.register(BuiltInRegistries.BLOCK, key, factory.apply(settings));
} }
public static boolean isCrystallineSky(BlockState state) { public static boolean isCrystallineSky(BlockState state) {
@@ -62,9 +69,9 @@ public class CrystallineBlocks {
} }
public static int getSkyLightLevel(BlockState state) { public static int getSkyLightLevel(BlockState state) {
if (state.isOf(SKY_LIGHT)) { if (state.is(SKY_LIGHT)) {
return state.get(LightBlock.LEVEL_15); return state.getValue(LightBlock.LEVEL);
} else if (state.isOf(SKY)) { // weeping sky explicitly excluded, that's handled differently } else if (state.is(SKY)) { // weeping sky explicitly excluded, that's handled differently
return 15; return 15;
} }
@@ -72,6 +79,6 @@ public class CrystallineBlocks {
} }
public static boolean isWeepingSky(BlockState state) { 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; package io.github.slimeistdev.crystalline_sky.registry;
import io.github.slimeistdev.crystalline_sky.CrystallineSky; import io.github.slimeistdev.crystalline_sky.CrystallineSky;
import net.minecraft.component.ComponentType; import net.minecraft.core.component.DataComponentType;
import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.registry.Registries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.registry.Registry; import net.minecraft.core.Registry;
import net.minecraft.util.Unit; import net.minecraft.util.Unit;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
public class CrystallineDataComponentTypes { 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", "weeping_sky_debug_column_tool",
b -> b b -> b
.packetCodec(PacketCodec.unit(Unit.INSTANCE)) .networkSynchronized(StreamCodec.unit(Unit.INSTANCE))
.codec(Unit.CODEC) .persistent(Unit.CODEC)
); );
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
private static <T> ComponentType<T> register(String id, UnaryOperator<ComponentType.Builder<T>> builderOperator) { private static <T> DataComponentType<T> register(String id, UnaryOperator<DataComponentType.Builder<T>> builderOperator) {
return Registry.register(Registries.DATA_COMPONENT_TYPE, CrystallineSky.id(id), builderOperator.apply(ComponentType.builder()).build()); return Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, CrystallineSky.id(id), builderOperator.apply(DataComponentType.builder()).build());
} }
public static void init() {} 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.blocks.SkyLightBlock;
import io.github.slimeistdev.crystalline_sky.content.items.WeepingSkyBlockItem; import io.github.slimeistdev.crystalline_sky.content.items.WeepingSkyBlockItem;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.minecraft.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.block.LightBlock; import net.minecraft.world.level.block.LightBlock;
import net.minecraft.component.DataComponentTypes; import net.minecraft.core.component.DataComponents;
import net.minecraft.component.type.BlockStateComponent; import net.minecraft.world.item.component.BlockItemStateProperties;
import net.minecraft.item.BlockItem; import net.minecraft.world.item.BlockItem;
import net.minecraft.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.item.ItemGroups; import net.minecraft.world.item.CreativeModeTabs;
import net.minecraft.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.util.Rarity; import net.minecraft.world.item.Rarity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.BiFunction; import java.util.function.BiFunction;
public class CrystallineItems { public class CrystallineItems {
public static final Item SKY = Items.register( public static final Item SKY = Items.registerBlock(
CrystallineBlocks.SKY, CrystallineBlocks.SKY,
settings -> settings.rarity(Rarity.EPIC) settings -> settings.rarity(Rarity.EPIC)
); );
@@ -29,24 +29,24 @@ public class CrystallineItems {
(block, settings) -> new WeepingSkyBlockItem(block, settings.rarity(Rarity.EPIC)) (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, CrystallineBlocks.SKY_LIGHT,
settings -> settings.rarity(Rarity.EPIC) 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, CrystallineBlocks.WEEPING_SKY_LIGHT,
settings -> settings.rarity(Rarity.EPIC) settings -> settings.rarity(Rarity.EPIC)
); );
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
private static Item register(Block block, BiFunction<Block, Item.Settings, BlockItem> factory) { private static Item register(Block block, BiFunction<Block, Item.Properties, BlockItem> factory) {
return Items.register(factory.apply(block, new Item.Settings())); return Items.registerBlock(factory.apply(block, new Item.Properties()));
} }
public static void init() { public static void init() {
ItemGroupEvents.modifyEntriesEvent(ItemGroups.OPERATOR).register(entries -> { ItemGroupEvents.modifyEntriesEvent(CreativeModeTabs.OP_BLOCKS).register(entries -> {
if (!entries.getContext().hasPermissions()) return; if (!entries.getContext().hasPermissions()) return;
List<ItemStack> stacks = new ArrayList<>(); List<ItemStack> stacks = new ArrayList<>();
@@ -55,7 +55,7 @@ public class CrystallineItems {
stacks.add(new ItemStack(WEEPING_SKY)); stacks.add(new ItemStack(WEEPING_SKY));
for (int i = 15; i >= 0; i--) { 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)); 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 io.github.slimeistdev.crystalline_sky.mixin_ducks.client.WorldRenderer_Duck;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.Minecraft;
import net.minecraft.client.render.RenderLayer; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.render.RenderPhase; import net.minecraft.client.renderer.RenderStateShard;
import net.minecraft.client.render.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.render.VertexFormats; import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import static net.minecraft.client.render.RenderLayer.of; import static net.minecraft.client.renderer.RenderType.create;
import static net.minecraft.client.render.RenderPhase.ENABLE_LIGHTMAP; import static net.minecraft.client.renderer.RenderStateShard.LIGHTMAP;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class CrystallineRenderLayers { public class CrystallineRenderLayers {
private static final RenderPhase.TextureBase SKY_TEXTURE = new SkyBufferTexture(); private static final RenderStateShard.EmptyTextureStateShard SKY_TEXTURE = new SkyBufferTexture();
private static final RenderPhase.ShaderProgram SKY_PROGRAM = new RenderPhase.ShaderProgram(CrystallineShaderPrograms::getRenderTypeSkyProgram); 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", "crystalline_sky_sky",
VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL, DefaultVertexFormat.BLOCK,
VertexFormat.DrawMode.QUADS, VertexFormat.Mode.QUADS,
4194304, 4194304,
true, true,
false, false,
RenderLayer.MultiPhaseParameters.builder() RenderType.CompositeState.builder()
.lightmap(ENABLE_LIGHTMAP) .setLightmapState(LIGHTMAP)
.program(SKY_PROGRAM) .setShaderState(SKY_PROGRAM)
.texture(SKY_TEXTURE) .setTextureState(SKY_TEXTURE)
.build(true) .createCompositeState(true)
); );
static { static {
@@ -38,12 +38,12 @@ public class CrystallineRenderLayers {
((RenderLayer_Duck) SKY).crystalline_sky$markAsBlockLayer(); ((RenderLayer_Duck) SKY).crystalline_sky$markAsBlockLayer();
} }
private static class SkyBufferTexture extends RenderPhase.TextureBase { private static class SkyBufferTexture extends RenderStateShard.EmptyTextureStateShard {
public SkyBufferTexture() { public SkyBufferTexture() {
super(() -> { super(() -> {
MinecraftClient mc = MinecraftClient.getInstance(); Minecraft mc = Minecraft.getInstance();
var fb = ((WorldRenderer_Duck) mc.worldRenderer).crystalline_sky$getSkyFramebuffer(); var fb = ((WorldRenderer_Duck) mc.levelRenderer).crystalline_sky$getSkyFramebuffer();
RenderSystem.setShaderTexture(0, fb.getColorAttachment()); RenderSystem.setShaderTexture(0, fb.getColorTextureId());
}, () -> {}); }, () -> {});
} }
} }
@@ -1,14 +1,14 @@
package io.github.slimeistdev.crystalline_sky.registry.client; 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.ApiStatus;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class CrystallineShaderPrograms { public class CrystallineShaderPrograms {
@ApiStatus.Internal @ApiStatus.Internal
public static @Nullable ShaderProgram renderTypeSkyProgram; public static @Nullable ShaderInstance renderTypeSkyProgram;
public static @Nullable ShaderProgram getRenderTypeSkyProgram() { public static @Nullable ShaderInstance getRenderTypeSkyProgram() {
return renderTypeSkyProgram; return renderTypeSkyProgram;
} }
} }
+10 -10
View File
@@ -8,20 +8,20 @@
"plugin": "io.github.slimeistdev.crystalline_sky.mixin.CrystallineSkyMixinPlugin", "plugin": "io.github.slimeistdev.crystalline_sky.mixin.CrystallineSkyMixinPlugin",
"compatibilityLevel": "JAVA_21", "compatibilityLevel": "JAVA_21",
"mixins": [ "mixins": [
"ChunkLightProviderMixin", "LightEngineMixin",
"ChunkSkyLightMixin", "ChunkSkyLightSourcesMixin",
"ChunkSkyLightProviderMixin", "SkyLightEngineMixin",
"LightStorageAccessor", "LayerLightSectionStorageAccessor",
"SkyLightStorageAccessor" "SkyLightSectionStorageAccessor"
], ],
"client": [ "client": [
"client.ClientWorldMixin", "client.ClientLevelMixin",
"client.DebugRendererMixin", "client.DebugRendererMixin",
"client.FramebufferMixin", "client.RenderTargetMixin",
"client.GameRendererMixin", "client.GameRendererMixin",
"client.RenderLayerMixin", "client.RenderTypeMixin",
"client.WorldRenderer_NoSodium_Mixin", "client.LevelRenderer_NoSodium_Mixin",
"client.WorldRendererMixin", "client.LevelRendererMixin",
"client.compat.axiom.ChunkRenderOverrider_AxiomChunkOverrideLayerMixin", "client.compat.axiom.ChunkRenderOverrider_AxiomChunkOverrideLayerMixin",
"client.compat.sodium.DefaultMaterialsMixin", "client.compat.sodium.DefaultMaterialsMixin",
"client.compat.sodium.DefaultTerrainRenderPassesMixin", "client.compat.sodium.DefaultTerrainRenderPassesMixin",