add sky light (like vanilla light)

This commit is contained in:
techno-sam
2025-08-24 20:58:53 +02:00
parent ca168f1bb3
commit dd531bb773
27 changed files with 164 additions and 8 deletions
@@ -0,0 +1,14 @@
package io.github.slimeistdev.crystalline_sky.datagen;
import io.github.slimeistdev.crystalline_sky.datagen.providers.CrystallineSkyModelProvider;
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
public class CrystallineSkyDataGenerator implements DataGeneratorEntrypoint {
@Override
public void onInitializeDataGenerator(FabricDataGenerator gen) {
FabricDataGenerator.Pack pack = gen.createPack();
pack.addProvider(CrystallineSkyModelProvider::new);
}
}
@@ -0,0 +1,58 @@
package io.github.slimeistdev.crystalline_sky.datagen.providers;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.fabricmc.fabric.api.client.datagen.v1.provider.FabricModelProvider;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.minecraft.block.LightBlock;
import net.minecraft.client.data.*;
import net.minecraft.client.render.item.model.ItemModel;
import net.minecraft.client.render.model.json.WeightedVariant;
import net.minecraft.state.property.Properties;
import net.minecraft.util.Identifier;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import static net.minecraft.client.data.BlockStateModelGenerator.createWeightedVariant;
public class CrystallineSkyModelProvider extends FabricModelProvider {
public CrystallineSkyModelProvider(FabricDataOutput output) {
super(output);
}
@Override
public void generateBlockStateModels(BlockStateModelGenerator gen) {
gen.registerBuiltinWithParticle(CrystallineBlocks.SKY, CrystallineItems.SKY);
gen.registerItemModel(CrystallineItems.SKY);
registerSkyLightBlock(gen);
}
private void registerSkyLightBlock(BlockStateModelGenerator gen) {
ItemModel.Unbaked fallback = ItemModels.basic(gen.uploadItemModel(CrystallineItems.SKY_LIGHT));
Map<Integer, ItemModel.Unbaked> itemModels = new HashMap<>(16);
BlockStateVariantMap.SingleProperty<WeightedVariant, Integer> levelProp = BlockStateVariantMap.models(Properties.LEVEL_15);
for (int level = 0; level <= 15; level++) {
String suffix = String.format(Locale.ROOT, "_%02d", level);
Identifier texture = TextureMap.getSubId(CrystallineItems.SKY_LIGHT, suffix);
levelProp.register(level, createWeightedVariant(Models.PARTICLE.upload(CrystallineBlocks.SKY_LIGHT, suffix, TextureMap.particle(texture), gen.modelCollector)));
ItemModel.Unbaked levelItemModel = ItemModels.basic(Models.GENERATED.upload(
ModelIds.getItemSubModelId(CrystallineItems.SKY_LIGHT, suffix),
TextureMap.layer0(texture),
gen.modelCollector
));
itemModels.put(level, levelItemModel);
}
gen.itemModelOutput.accept(CrystallineItems.SKY_LIGHT, ItemModels.select(LightBlock.LEVEL_15, fallback, itemModels));
gen.blockStateCollector.accept(VariantsBlockModelDefinitionCreator.of(CrystallineBlocks.SKY_LIGHT).with(levelProp));
}
@Override
public void generateItemModels(ItemModelGenerator gen) {}
}
@@ -11,6 +11,6 @@ import org.spongepowered.asm.mixin.Mixin;
public class ChunkLightProviderMixin {
@WrapMethod(method = "needsLightUpdate")
private static boolean updateSky(BlockState oldState, BlockState newState, Operation<Boolean> original) {
return original.call(oldState, newState) || (oldState.isOf(CrystallineBlocks.SKY) != newState.isOf(CrystallineBlocks.SKY));
return original.call(oldState, newState) || (CrystallineBlocks.getSkyLightLevel(oldState) != CrystallineBlocks.getSkyLightLevel(newState));
}
}
@@ -3,11 +3,14 @@ package io.github.slimeistdev.crystalline_sky.mixin;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.ChunkSectionPos;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkProvider;
import net.minecraft.world.chunk.ChunkToNibbleArrayMap;
import net.minecraft.world.chunk.light.ChunkLightProvider;
import net.minecraft.world.chunk.light.ChunkSkyLightProvider;
import net.minecraft.world.chunk.light.LightSourceView;
import net.minecraft.world.chunk.light.LightStorage;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@@ -27,10 +30,21 @@ public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap
}
@Inject(method = "checkNode", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/SkyLightStorage;get(J)I"))
private void emitFromSky(long blockPos, CallbackInfo ci) {
private void emitFromCrystallineSky(long blockPos, CallbackInfo ci) {
BlockState state = getStateForLighting(scratchPos.set(blockPos));
if (state.isOf(CrystallineBlocks.SKY) && ((LightStorageAccessor) lightStorage).crystalline_sky$callIsSectionInEnabledColumn(ChunkSectionPos.fromBlockPos(blockPos))) {
enqueueIncrease(blockPos, QueueEntry.increaseLightFromEmission(15, isTrivialForLighting(state)));
int level = CrystallineBlocks.getSkyLightLevel(state);
if (level > 0 && ((LightStorageAccessor) lightStorage).crystalline_sky$callIsSectionInEnabledColumn(ChunkSectionPos.fromBlockPos(blockPos))) {
enqueueIncrease(blockPos, QueueEntry.increaseLightFromEmission(level, isTrivialForLighting(state)));
}
}
@Inject(method = "propagateLight", at = @At("RETURN"))
private void propagateCrystallineSkyLight(ChunkPos chunkPos, CallbackInfo ci) {
LightSourceView lightSourceView = this.chunkProvider.getChunk(chunkPos.x, chunkPos.z);
if (!(lightSourceView instanceof Chunk chunk)) return;
chunk.forEachBlockMatchingPredicate(CrystallineBlocks::isCrystallineSky, (pos, state) -> {
enqueueIncrease(pos.asLong(), QueueEntry.increaseLightFromEmission(CrystallineBlocks.getSkyLightLevel(state), isTrivialForLighting(state)));
});
}
}
@@ -0,0 +1,22 @@
package io.github.slimeistdev.crystalline_sky.mixin.client;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.item.Item;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import java.util.HashSet;
import java.util.Set;
@Mixin(ClientWorld.class)
public class ClientWorldMixin {
@ModifyExpressionValue(method = "<clinit>", at = @At(value = "FIELD", target = "Lnet/minecraft/client/world/ClientWorld;BLOCK_MARKER_ITEMS:Ljava/util/Set;", opcode = Opcodes.PUTSTATIC))
private static Set<Item> modifyBlockMarkerItems(Set<Item> original) {
Set<Item> extended = new HashSet<>(original);
extended.add(CrystallineItems.SKY_LIGHT);
return Set.copyOf(extended);
}
}
@@ -1,15 +1,14 @@
package io.github.slimeistdev.crystalline_sky.registry;
import io.github.slimeistdev.crystalline_sky.CrystallineSky;
import net.minecraft.block.*;
import net.minecraft.block.AbstractBlock.Settings;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.TransparentBlock;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.state.property.Properties;
import java.util.function.Function;
@@ -24,10 +23,35 @@ public class CrystallineBlocks {
.suffocates(Blocks::never)
.blockVision(Blocks::never));
public static final Block SKY_LIGHT = register(
"sky_light",
LightBlock::new,
AbstractBlock.Settings.create()
.replaceable()
.strength(-1.0F, 3600000.8F)
.mapColor(state -> state.get(Properties.WATERLOGGED) ? MapColor.WATER_BLUE : MapColor.CLEAR)
.dropsNothing()
.nonOpaque()
);
public static void init() {}
private static <T extends Block> T register(String id, Function<Settings, T> factory, Settings settings) {
RegistryKey<Block> key = CrystallineSky.key(RegistryKeys.BLOCK, id);
return Registry.register(Registries.BLOCK, key, factory.apply(settings.registryKey(key)));
}
public static boolean isCrystallineSky(BlockState state) {
return getSkyLightLevel(state) > 0;
}
public static int getSkyLightLevel(BlockState state) {
if (state.isOf(SKY_LIGHT)) {
return state.get(LightBlock.LEVEL_15);
} else if (state.isOf(SKY)) {
return 15;
}
return 0;
}
}
@@ -1,10 +1,23 @@
package io.github.slimeistdev.crystalline_sky.registry;
import net.minecraft.block.LightBlock;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.BlockStateComponent;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.util.Rarity;
public class CrystallineItems {
public static final Item SKY = Items.register(CrystallineBlocks.SKY);
public static final Item SKY = Items.register(
CrystallineBlocks.SKY,
settings -> settings.rarity(Rarity.EPIC)
);
public static final Item SKY_LIGHT = Items.register(
CrystallineBlocks.SKY_LIGHT,
settings -> settings.rarity(Rarity.EPIC)
.component(DataComponentTypes.BLOCK_STATE, BlockStateComponent.DEFAULT.with(LightBlock.LEVEL_15, 15))
);
public static void init() {}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 B

@@ -12,6 +12,7 @@
"LightStorageAccessor"
],
"client": [
"client.ClientWorldMixin"
],
"server": [
],
+3
View File
@@ -32,6 +32,9 @@
"io.github.slimeistdev.crystalline_sky.CrystallineSky"
],
"client": [
],
"fabric-datagen": [
"io.github.slimeistdev.crystalline_sky.datagen.CrystallineSkyDataGenerator"
]
}
}