add sky light (like vanilla light)
@@ -89,6 +89,13 @@ loom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fabricApi {
|
||||||
|
configureDataGeneration {
|
||||||
|
client = true
|
||||||
|
outputDirectory = file("src/generated/resources")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile).configureEach {
|
tasks.withType(JavaCompile).configureEach {
|
||||||
it.options.encoding = "UTF-8"
|
it.options.encoding = "UTF-8"
|
||||||
it.options.release = 21
|
it.options.release = 21
|
||||||
|
|||||||
@@ -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 {
|
public class ChunkLightProviderMixin {
|
||||||
@WrapMethod(method = "needsLightUpdate")
|
@WrapMethod(method = "needsLightUpdate")
|
||||||
private static boolean updateSky(BlockState oldState, BlockState newState, Operation<Boolean> original) {
|
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 io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.ChunkPos;
|
||||||
import net.minecraft.util.math.ChunkSectionPos;
|
import net.minecraft.util.math.ChunkSectionPos;
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraft.world.chunk.ChunkProvider;
|
import net.minecraft.world.chunk.ChunkProvider;
|
||||||
import net.minecraft.world.chunk.ChunkToNibbleArrayMap;
|
import net.minecraft.world.chunk.ChunkToNibbleArrayMap;
|
||||||
import net.minecraft.world.chunk.light.ChunkLightProvider;
|
import net.minecraft.world.chunk.light.ChunkLightProvider;
|
||||||
import net.minecraft.world.chunk.light.ChunkSkyLightProvider;
|
import net.minecraft.world.chunk.light.ChunkSkyLightProvider;
|
||||||
|
import net.minecraft.world.chunk.light.LightSourceView;
|
||||||
import net.minecraft.world.chunk.light.LightStorage;
|
import net.minecraft.world.chunk.light.LightStorage;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
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"))
|
@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));
|
BlockState state = getStateForLighting(scratchPos.set(blockPos));
|
||||||
if (state.isOf(CrystallineBlocks.SKY) && ((LightStorageAccessor) lightStorage).crystalline_sky$callIsSectionInEnabledColumn(ChunkSectionPos.fromBlockPos(blockPos))) {
|
int level = CrystallineBlocks.getSkyLightLevel(state);
|
||||||
enqueueIncrease(blockPos, QueueEntry.increaseLightFromEmission(15, isTrivialForLighting(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;
|
package io.github.slimeistdev.crystalline_sky.registry;
|
||||||
|
|
||||||
import io.github.slimeistdev.crystalline_sky.CrystallineSky;
|
import io.github.slimeistdev.crystalline_sky.CrystallineSky;
|
||||||
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.AbstractBlock.Settings;
|
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.Registries;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.registry.RegistryKey;
|
import net.minecraft.registry.RegistryKey;
|
||||||
import net.minecraft.registry.RegistryKeys;
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
import net.minecraft.sound.BlockSoundGroup;
|
||||||
|
import net.minecraft.state.property.Properties;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
@@ -24,10 +23,35 @@ public class CrystallineBlocks {
|
|||||||
.suffocates(Blocks::never)
|
.suffocates(Blocks::never)
|
||||||
.blockVision(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() {}
|
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<Settings, T> factory, Settings settings) {
|
||||||
RegistryKey<Block> key = CrystallineSky.key(RegistryKeys.BLOCK, id);
|
RegistryKey<Block> key = CrystallineSky.key(RegistryKeys.BLOCK, id);
|
||||||
return Registry.register(Registries.BLOCK, key, factory.apply(settings.registryKey(key)));
|
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;
|
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.Item;
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.util.Rarity;
|
||||||
|
|
||||||
public class CrystallineItems {
|
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() {}
|
public static void init() {}
|
||||||
}
|
}
|
||||||
|
|||||||
|
After Width: | Height: | Size: 616 B |
|
After Width: | Height: | Size: 789 B |
|
After Width: | Height: | Size: 739 B |
|
After Width: | Height: | Size: 764 B |
|
After Width: | Height: | Size: 764 B |
|
After Width: | Height: | Size: 735 B |
|
After Width: | Height: | Size: 809 B |
|
After Width: | Height: | Size: 805 B |
|
After Width: | Height: | Size: 858 B |
|
After Width: | Height: | Size: 820 B |
|
After Width: | Height: | Size: 842 B |
|
After Width: | Height: | Size: 848 B |
|
After Width: | Height: | Size: 859 B |
|
After Width: | Height: | Size: 847 B |
|
After Width: | Height: | Size: 832 B |
|
After Width: | Height: | Size: 773 B |
|
After Width: | Height: | Size: 732 B |
@@ -12,6 +12,7 @@
|
|||||||
"LightStorageAccessor"
|
"LightStorageAccessor"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
|
"client.ClientWorldMixin"
|
||||||
],
|
],
|
||||||
"server": [
|
"server": [
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -32,6 +32,9 @@
|
|||||||
"io.github.slimeistdev.crystalline_sky.CrystallineSky"
|
"io.github.slimeistdev.crystalline_sky.CrystallineSky"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
|
],
|
||||||
|
"fabric-datagen": [
|
||||||
|
"io.github.slimeistdev.crystalline_sky.datagen.CrystallineSkyDataGenerator"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||