diff --git a/src/test/java/net/modificationstation/sltest/block/Blocks.java b/src/test/java/net/modificationstation/sltest/block/Blocks.java index d0c7e41f1..74e38e182 100644 --- a/src/test/java/net/modificationstation/sltest/block/Blocks.java +++ b/src/test/java/net/modificationstation/sltest/block/Blocks.java @@ -21,7 +21,8 @@ public enum Blocks { CUSTOM_MODEL_BLOCK("farlands_block", "farlands_block", id -> new ModdedModelBlock(id, Material.DIRT).setHardness(1)), FREEZER("freezer", "freezer", id -> new BlockFreezer(id).setHardness(2.5F).setSounds(TemplateBlockBase.STONE_SOUNDS)), ALTAR("altar", "altar", id -> new BlockAltar(id, Material.STONE).setHardness(3)), - VARIATION_BLOCK("variation_block", "variationBlock", id -> new VariationBlock(id, Material.STONE).setHardness(.5F).setSounds(BlockBase.STONE_SOUNDS).disableAutomaticBlockItemRegistration()); + VARIATION_BLOCK("variation_block", "variationBlock", id -> new VariationBlock(id, Material.STONE).setHardness(.5F).setSounds(BlockBase.STONE_SOUNDS).disableAutomaticBlockItemRegistration()), + EMISSION_CHECKER("emission_checker", "emissionChecker", LampBlock::new); private final Runnable register; private BlockBase block; diff --git a/src/test/java/net/modificationstation/sltest/block/LampBlock.java b/src/test/java/net/modificationstation/sltest/block/LampBlock.java new file mode 100644 index 000000000..cdf7694d8 --- /dev/null +++ b/src/test/java/net/modificationstation/sltest/block/LampBlock.java @@ -0,0 +1,52 @@ +package net.modificationstation.sltest.block; + +import net.minecraft.block.BlockBase; +import net.minecraft.block.material.Material; +import net.minecraft.entity.player.PlayerBase; +import net.minecraft.level.BlockView; +import net.minecraft.level.Level; +import net.modificationstation.stationapi.api.block.BlockState; +import net.modificationstation.stationapi.api.registry.Identifier; +import net.modificationstation.stationapi.api.state.StateManager.Builder; +import net.modificationstation.stationapi.api.state.property.BooleanProperty; +import net.modificationstation.stationapi.api.template.block.TemplateBlockBase; +import net.modificationstation.stationapi.api.world.BlockStateView; + +public class LampBlock extends TemplateBlockBase { + private static final BooleanProperty ACTIVE = BooleanProperty.of("active"); + + public LampBlock(Identifier id) { + super(id, Material.WOOD); + setLuminance(state -> state.get(ACTIVE) ? 15 : 0); + setTranslationKey(id); + setSounds(WOOD_SOUNDS); + setDefaultState(getDefaultState().with(ACTIVE, false)); + } + + @Override + public void appendProperties(Builder builder) { + super.appendProperties(builder); + builder.add(ACTIVE); + } + + @Override + public int getTextureForSide(BlockView view, int x, int y, int z, int side) { + if (view instanceof BlockStateView stateView) { + return stateView.getBlockState(x, y, z).get(ACTIVE) ? STILL_LAVA.texture : OBSIDIAN.texture; + } + return OBSIDIAN.texture; + } + + @Override + public int getTextureForSide(int side) { + return OBSIDIAN.texture; + } + + @Override + public boolean canUse(Level level, int x, int y, int z, PlayerBase player) { + BlockState state = level.getBlockState(x, y, z); + state = state.with(ACTIVE, !state.get(ACTIVE)); + level.setBlockState(x, y, z, state); + return super.canUse(level, x, y, z, player); + } +} diff --git a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/api/block/AbstractBlockState.java b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/api/block/AbstractBlockState.java index 304e04eb0..8ed56ca68 100644 --- a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/api/block/AbstractBlockState.java +++ b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/api/block/AbstractBlockState.java @@ -16,6 +16,7 @@ import net.modificationstation.stationapi.api.state.property.Property; import net.modificationstation.stationapi.api.tag.TagKey; import net.modificationstation.stationapi.api.util.math.MathHelper; +import net.modificationstation.stationapi.impl.block.StationFlatteningBlockInternal; import java.util.function.Predicate; import java.util.stream.Stream; @@ -26,6 +27,7 @@ public abstract class AbstractBlockState extends State { private final MaterialColour materialColor; private final boolean toolRequired; private final boolean opaque; + private int luminance = -1; protected AbstractBlockState(BlockBase block, ImmutableMap, Comparable> propertyMap, MapCodec mapCodec) { super(block, propertyMap, mapCodec); @@ -48,7 +50,9 @@ public Material getMaterial() { * Returns the light level emitted by this block state. */ public int getLuminance() { - return BlockBase.EMITTANCE[owner.id]; + return luminance == -1 ? + luminance = ((StationFlatteningBlockInternal) owner).stationapi_getLuminanceProvider().applyAsInt(asBlockState()) : + luminance; } public boolean isAir() { diff --git a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/api/block/StationFlatteningBlock.java b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/api/block/StationFlatteningBlock.java index 31d1203b5..46688bef1 100644 --- a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/api/block/StationFlatteningBlock.java +++ b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/api/block/StationFlatteningBlock.java @@ -17,6 +17,7 @@ import org.jetbrains.annotations.ApiStatus; import java.util.List; +import java.util.function.ToIntFunction; public interface StationFlatteningBlock extends RemappableRawIdHolder, @@ -103,4 +104,8 @@ default boolean canReplace(BlockState state, ItemPlacementContext context) { default void onBlockPlaced(Level world, int x, int y, int z, BlockState replacedState) { Util.assertImpl(); } + + default BlockBase setLuminance(ToIntFunction provider) { + return Util.assertImpl(); + } } diff --git a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/impl/block/BlockBrightness.java b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/impl/block/BlockBrightness.java new file mode 100644 index 000000000..a4b519004 --- /dev/null +++ b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/impl/block/BlockBrightness.java @@ -0,0 +1,9 @@ +package net.modificationstation.stationapi.impl.block; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class BlockBrightness { + public static int light; +} diff --git a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/impl/block/StationFlatteningBlockInternal.java b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/impl/block/StationFlatteningBlockInternal.java new file mode 100644 index 000000000..7e5bfb9c0 --- /dev/null +++ b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/impl/block/StationFlatteningBlockInternal.java @@ -0,0 +1,9 @@ +package net.modificationstation.stationapi.impl.block; + +import net.modificationstation.stationapi.api.block.BlockState; + +import java.util.function.ToIntFunction; + +public interface StationFlatteningBlockInternal { + ToIntFunction stationapi_getLuminanceProvider(); +} diff --git a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinBlockBase.java b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinBlockBase.java index 803885fe3..0b8f019ba 100644 --- a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinBlockBase.java +++ b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinBlockBase.java @@ -1,5 +1,7 @@ package net.modificationstation.stationapi.mixin.flattening; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.block.BlockBase; import net.minecraft.block.material.Material; import net.minecraft.entity.player.PlayerBase; @@ -19,16 +21,19 @@ import net.modificationstation.stationapi.api.registry.RegistryEntry; import net.modificationstation.stationapi.api.registry.sync.trackers.*; import net.modificationstation.stationapi.api.state.StateManager; +import net.modificationstation.stationapi.impl.block.BlockBrightness; import net.modificationstation.stationapi.impl.block.BlockDropListImpl; +import net.modificationstation.stationapi.impl.block.StationFlatteningBlockInternal; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.*; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; +import java.util.function.ToIntFunction; @Mixin(BlockBase.class) -public abstract class MixinBlockBase implements StationFlatteningBlock { +public abstract class MixinBlockBase implements StationFlatteningBlock, StationFlatteningBlockInternal { @Shadow public abstract void beforeDestroyedByExplosion(Level arg, int i, int j, int k, int l, float f); @@ -318,4 +323,28 @@ private int ensureCapacity(int rawId) { private static ItemBase onlyUnderShift(ItemBase[] array, int index) { return index < ItemRegistry.ID_SHIFT ? array[index] : null; } + + @Unique private ToIntFunction stationapi_luminance = state -> BlockBase.EMITTANCE[state.getBlock().id]; + + @Override + public BlockBase setLuminance(ToIntFunction provider) { + stationapi_luminance = provider; + + // Need for proper functionality of LevelMixin + BlockBase.EMITTANCE[id] = 15; + + return BlockBase.class.cast(this); + } + + @Override + @Unique + public ToIntFunction stationapi_getLuminanceProvider() { + return stationapi_luminance; + } + + @Environment(value= EnvType.CLIENT) + @ModifyArg(method = "getBrightness", at = @At(value = "INVOKE", target = "Lnet/minecraft/level/BlockView;method_1784(IIII)F"), index = 3) + private int getStateBrightness(int original) { + return BlockBrightness.light; + } } diff --git a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinClass417.java b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinClass417.java index b2443896f..32052a76a 100644 --- a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinClass417.java +++ b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinClass417.java @@ -1,13 +1,11 @@ package net.modificationstation.stationapi.mixin.flattening; +import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.class_417; import net.minecraft.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Constant; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyConstant; +import org.spongepowered.asm.mixin.injection.*; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(class_417.class) @@ -21,7 +19,6 @@ private void method_1869(Level level, CallbackInfo info) { minBlock = (short) level.getBottomY(); } - @SuppressWarnings("MixinAnnotationTarget") @ModifyConstant(method = "method_1402(Lnet/minecraft/level/Level;)V", constant = @Constant(expandZeroConditions = Constant.Condition.GREATER_THAN_OR_EQUAL_TO_ZERO, ordinal = 0)) private int changeMinHeight(int value) { return minBlock; @@ -41,4 +38,16 @@ private int changeMaxHeight(int value) { private int changeMaxHeightFallback(int value) { return maxBlock - 1; } + + @ModifyVariable( + method = "method_1402(Lnet/minecraft/level/Level;)V", + at = @At( + value = "STORE", + ordinal = 2 + ), + index = 20 + ) + private int getStateLuminance(int original, @Local Level level, @Local(index = 10) int x, @Local(index = 15) int y, @Local(index = 11) int z) { + return level.getBlockState(x, y, z).getLuminance(); + } } diff --git a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinLevel.java b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinLevel.java index 00ede8e46..dc03b491c 100644 --- a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinLevel.java +++ b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/MixinLevel.java @@ -214,4 +214,17 @@ public int getBottomY() { private BlockBase accountForAirBlock(BlockBase value) { return value == States.AIR.get().getBlock() ? null : value; } + + @ModifyVariable( + method = "method_165(Lnet/minecraft/level/LightType;IIII)V", + at = @At( + value = "STORE", + ordinal = 1 + ), + index = 5, + argsOnly = true + ) + private int getStateLuminance(int original, @Local(index = 2) int x, @Local(index = 3) int y, @Local(index = 4) int z, @Local(index = 5) int light) { + return Math.max(getBlockState(x, y, z).getLuminance(), light); + } } diff --git a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/client/MixinBlockRenderer.java b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/client/MixinBlockRenderer.java new file mode 100644 index 000000000..07cc3a2a4 --- /dev/null +++ b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/client/MixinBlockRenderer.java @@ -0,0 +1,27 @@ +package net.modificationstation.stationapi.mixin.flattening.client; + +import net.minecraft.block.BlockBase; +import net.minecraft.client.render.block.BlockRenderer; +import net.minecraft.level.BlockView; +import net.modificationstation.stationapi.api.block.BlockState; +import net.modificationstation.stationapi.api.world.BlockStateView; +import net.modificationstation.stationapi.impl.block.BlockBrightness; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(value = BlockRenderer.class, priority = 500) +public class MixinBlockRenderer { + @Shadow private BlockView blockView; + + @Inject(method = "render", at = @At("HEAD")) + private void captureLightEmission(BlockBase block, int x, int y, int z, CallbackInfoReturnable info) { + if (blockView instanceof BlockStateView stateView) { + BlockState state = stateView.getBlockState(x, y, z); + BlockBrightness.light = state.getLuminance(); + } + else BlockBrightness.light = BlockBase.EMITTANCE[block.id]; + } +} diff --git a/station-flattening-v0/src/main/resources/station-flattening-v0.mixins.json b/station-flattening-v0/src/main/resources/station-flattening-v0.mixins.json index 70daffa1d..478387a2f 100644 --- a/station-flattening-v0/src/main/resources/station-flattening-v0.mixins.json +++ b/station-flattening-v0/src/main/resources/station-flattening-v0.mixins.json @@ -34,6 +34,8 @@ "RegionFileAccessor" ], "client": [ + "client.MixinBaseClientInteractionManager", + "client.MixinBlockRenderer", "client.MixinClientLevel", "client.MixinInGame", "client.MixinMinecraft", @@ -41,8 +43,7 @@ "client.MixinMultiPlayerClientInteractionManager", "client.MixinPlayerRenderer", "client.MixinSinglePlayerClientInteractionManager", - "client.MixinWorldRenderer", - "client.MixinBaseClientInteractionManager" + "client.MixinWorldRenderer" ], "injectors": { "defaultRequire": 1