Merge pull request 'Visual fixes' (#25) from dev into master
All checks were successful
deploy / deploy (push) Successful in 5m54s
All checks were successful
deploy / deploy (push) Successful in 5m54s
Reviewed-on: #25
This commit was merged in pull request #25.
This commit is contained in:
@@ -9,7 +9,7 @@ loader_version=0.15.11
|
|||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
modrinth_id = jCpoCBpn
|
modrinth_id = jCpoCBpn
|
||||||
mod_version = 1.6.6
|
mod_version = 1.6.7
|
||||||
maven_group = fr.adrien1106
|
maven_group = fr.adrien1106
|
||||||
archives_base_name = ReFramed
|
archives_base_name = ReFramed
|
||||||
mod_id = reframed
|
mod_id = reframed
|
||||||
|
|||||||
@@ -135,11 +135,11 @@ public class ReFramed implements ModInitializer {
|
|||||||
private static AbstractBlock.Settings cp(Block base) {
|
private static AbstractBlock.Settings cp(Block base) {
|
||||||
return AbstractBlock.Settings.copy(base)
|
return AbstractBlock.Settings.copy(base)
|
||||||
.luminance(state -> state.contains(LIGHT) && state.get(LIGHT) ? 15 : 0)
|
.luminance(state -> state.contains(LIGHT) && state.get(LIGHT) ? 15 : 0)
|
||||||
.nonOpaque()
|
|
||||||
.sounds(BlockSoundGroup.WOOD)
|
.sounds(BlockSoundGroup.WOOD)
|
||||||
.hardness(0.2f)
|
.hardness(0.2f)
|
||||||
.suffocates((a,b,c) -> false)
|
.suffocates(Blocks::never)
|
||||||
.blockVision((a,b,c) -> false);
|
.solidBlock(Blocks::always)
|
||||||
|
.blockVision(Blocks::always);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <I extends Item> I registerItem(String path, I item) {
|
private static <I extends Item> I registerItem(String path, I item) {
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package fr.adrien1106.reframed.block;
|
|||||||
|
|
||||||
import fr.adrien1106.reframed.ReFramed;
|
import fr.adrien1106.reframed.ReFramed;
|
||||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||||
|
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.ai.pathing.NavigationType;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.BlockItem;
|
import net.minecraft.item.BlockItem;
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
@@ -17,6 +19,7 @@ import net.minecraft.util.ActionResult;
|
|||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.ItemScatterer;
|
import net.minecraft.util.ItemScatterer;
|
||||||
import net.minecraft.util.collection.DefaultedList;
|
import net.minecraft.util.collection.DefaultedList;
|
||||||
|
import net.minecraft.util.function.BooleanBiFunction;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
@@ -31,6 +34,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import static fr.adrien1106.reframed.block.ReFramedEntity.BLOCKSTATE_KEY;
|
import static fr.adrien1106.reframed.block.ReFramedEntity.BLOCKSTATE_KEY;
|
||||||
@@ -39,10 +43,26 @@ import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT;
|
|||||||
public class ReFramedBlock extends Block implements BlockEntityProvider {
|
public class ReFramedBlock extends Block implements BlockEntityProvider {
|
||||||
|
|
||||||
public ReFramedBlock(Settings settings) {
|
public ReFramedBlock(Settings settings) {
|
||||||
super(settings);
|
super(settings.dynamicBounds());
|
||||||
setDefaultState(getDefaultState().with(LIGHT, false));
|
setDefaultState(getDefaultState().with(LIGHT, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public int getOpacity(BlockState state, BlockView world, BlockPos pos) {
|
||||||
|
if (state.get(LIGHT)) return 0;
|
||||||
|
if (!(world.getBlockEntity(pos) instanceof ReFramedEntity frame_entity)
|
||||||
|
|| frame_entity.getTheme(0).isOpaque())
|
||||||
|
return world.getMaxLightLevel();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||||
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
|
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
|
||||||
@@ -208,4 +228,17 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
|
|||||||
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
|
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
|
||||||
return Map.of();
|
return Map.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VoxelShape getShadingShape(BlockState state, BlockView world, BlockPos pos) {
|
||||||
|
if (!(world.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity)) return this.getCollisionShape(state, world, pos, ShapeContext.absent());
|
||||||
|
|
||||||
|
AtomicInteger i = new AtomicInteger(1);
|
||||||
|
return framed_entity.getThemes().stream().map((theme) -> {
|
||||||
|
int index = i.getAndIncrement();
|
||||||
|
return theme.isTransparent(world, pos) ? VoxelShapes.empty() : this.getShape(state, index);
|
||||||
|
}).reduce(
|
||||||
|
VoxelShapes.empty(),
|
||||||
|
(prev, current) -> VoxelShapes.combine(prev, current, BooleanBiFunction.OR)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity
|
|||||||
protected BlockState first_state = Blocks.AIR.getDefaultState();
|
protected BlockState first_state = Blocks.AIR.getDefaultState();
|
||||||
protected byte bit_field = SOLIDITY_MASK;
|
protected byte bit_field = SOLIDITY_MASK;
|
||||||
|
|
||||||
protected static final byte LIGHT_MASK = 0b001;
|
public static final byte LIGHT_MASK = 0b001;
|
||||||
protected static final byte REDSTONE_MASK = 0b010;
|
public static final byte REDSTONE_MASK = 0b010;
|
||||||
protected static final byte SOLIDITY_MASK = 0b100;
|
public static final byte SOLIDITY_MASK = 0b100;
|
||||||
|
|
||||||
public static final String BLOCKSTATE_KEY = "s";
|
public static final String BLOCKSTATE_KEY = "s";
|
||||||
protected static final String BITFIELD_KEY = "b";
|
public static final String BITFIELD_KEY = "b";
|
||||||
|
|
||||||
public ReFramedEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public ReFramedEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
@@ -145,7 +145,10 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity
|
|||||||
if (isSolid()) bit_field &= ~SOLIDITY_MASK;
|
if (isSolid()) bit_field &= ~SOLIDITY_MASK;
|
||||||
else bit_field |= SOLIDITY_MASK;
|
else bit_field |= SOLIDITY_MASK;
|
||||||
|
|
||||||
if(world != null) world.setBlockState(pos, getCachedState());
|
if(world != null) {
|
||||||
|
world.setBlockState(pos, getCachedState());
|
||||||
|
ReFramed.chunkRerenderProxy.accept(world, pos);
|
||||||
|
}
|
||||||
markDirtyAndDispatch();
|
markDirtyAndDispatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,13 @@ public class WaterloggableReFramedBlock extends ReFramedBlock implements Waterlo
|
|||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(Properties.WATERLOGGED));
|
super.appendProperties(builder.add(Properties.WATERLOGGED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public boolean hasSidedTransparency(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class CamoAppearanceManager {
|
|||||||
for(BlendMode blend : BlendMode.values()) {
|
for(BlendMode blend : BlendMode.values()) {
|
||||||
finder.clear().disableDiffuse(false).blendMode(blend);
|
finder.clear().disableDiffuse(false).blendMode(blend);
|
||||||
|
|
||||||
materials.put(blend, finder.ambientOcclusion(TriState.FALSE).find());
|
materials.put(blend, finder.ambientOcclusion(TriState.TRUE).find());
|
||||||
ao_materials.put(blend, finder.ambientOcclusion(TriState.DEFAULT).find()); //not "true" since that *forces* AO, i just want to *allow* AO
|
ao_materials.put(blend, finder.ambientOcclusion(TriState.DEFAULT).find()); //not "true" since that *forces* AO, i just want to *allow* AO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,11 @@ public class RenderHelper {
|
|||||||
BlockState self_theme = frame_entity.getTheme(theme_index);
|
BlockState self_theme = frame_entity.getTheme(theme_index);
|
||||||
BlockState other_theme = frame_entity.getTheme(cull_theme);
|
BlockState other_theme = frame_entity.getTheme(cull_theme);
|
||||||
|
|
||||||
if (self_theme.isSideInvisible(other_theme, null)) return false;
|
try {
|
||||||
|
if (self_theme.isSideInvisible(other_theme, null)) return false;
|
||||||
|
} catch (NullPointerException e) { // this can happen if mod haven't thought about inner faces
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return !self_theme.isOpaque() || !other_theme.isOpaque();
|
return !self_theme.isOpaque() || !other_theme.isOpaque();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +108,7 @@ public class RenderHelper {
|
|||||||
? e : null;
|
? e : null;
|
||||||
|
|
||||||
// normal behaviour
|
// normal behaviour
|
||||||
if (theme_index == 0 || (self == null && other == null))
|
if ((theme_index == 0 && self != null) || (self == null && other == null))
|
||||||
return Block.shouldDrawSide(self_state, world, pos, side, other_pos);
|
return Block.shouldDrawSide(self_state, world, pos, side, other_pos);
|
||||||
|
|
||||||
// self is a normal Block
|
// self is a normal Block
|
||||||
@@ -116,7 +120,7 @@ public class RenderHelper {
|
|||||||
VoxelShape other_shape = VoxelShapes.empty();
|
VoxelShape other_shape = VoxelShapes.empty();
|
||||||
for (BlockState s: other.getThemes()) {
|
for (BlockState s: other.getThemes()) {
|
||||||
i++;
|
i++;
|
||||||
if (self_state.isSideInvisible(s, side) || s.isOpaque())
|
if (self_state.isSideInvisible(s, side) || (s.isOpaque() && (other.isSolid() || self_state.isTransparent(world ,pos))))
|
||||||
other_shape = combine(
|
other_shape = combine(
|
||||||
other_shape,
|
other_shape,
|
||||||
other_block
|
other_block
|
||||||
@@ -137,7 +141,7 @@ public class RenderHelper {
|
|||||||
if (self_theme.isSideInvisible(other_state, side)) return false;
|
if (self_theme.isSideInvisible(other_state, side)) return false;
|
||||||
|
|
||||||
// Opaque is also simple as each model are rendered one by one
|
// Opaque is also simple as each model are rendered one by one
|
||||||
if (other_state.isOpaque()) {
|
if (other_state.isOpaque() && self.isSolid()) {
|
||||||
// no cache section :( because it differs between each instance of the frame
|
// no cache section :( because it differs between each instance of the frame
|
||||||
VoxelShape self_shape = self_block.getShape(self_state, theme_index).getFace(side);
|
VoxelShape self_shape = self_block.getShape(self_state, theme_index).getFace(side);
|
||||||
if (self_shape.isEmpty()) return true;
|
if (self_shape.isEmpty()) return true;
|
||||||
@@ -160,7 +164,7 @@ public class RenderHelper {
|
|||||||
VoxelShape other_shape = VoxelShapes.empty();
|
VoxelShape other_shape = VoxelShapes.empty();
|
||||||
for (BlockState s: other.getThemes()) {
|
for (BlockState s: other.getThemes()) {
|
||||||
i++;
|
i++;
|
||||||
if (self_theme.isSideInvisible(s, side) || s.isOpaque())
|
if (self_theme.isSideInvisible(s, side) || (s.isOpaque() && (!self.isSolid() || (other.isSolid() == self.isSolid()))))
|
||||||
other_shape = combine(
|
other_shape = combine(
|
||||||
other_shape,
|
other_shape,
|
||||||
other_block
|
other_block
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ public class BlockItemMixin {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private static void placeBlockWithOffHandCamo(World world, PlayerEntity player, BlockPos pos, ItemStack stack, CallbackInfoReturnable<Boolean> cir, @Local LocalRef<NbtCompound> compound) {
|
private static void placeBlockWithOffHandCamo(World world, PlayerEntity player, BlockPos pos, ItemStack stack, CallbackInfoReturnable<Boolean> cir, @Local LocalRef<NbtCompound> compound) {
|
||||||
if (compound.get() != null
|
if (player == null
|
||||||
|
|| compound.get() != null
|
||||||
|| player.getOffHandStack().isEmpty()
|
|| player.getOffHandStack().isEmpty()
|
||||||
|| player.getMainHandStack().isEmpty()
|
|| player.getMainHandStack().isEmpty()
|
||||||
|| !(player.getMainHandStack().getItem() instanceof BlockItem frame)
|
|| !(player.getMainHandStack().getItem() instanceof BlockItem frame)
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ public class CompatMixinPlugin implements IMixinConfigPlugin {
|
|||||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumNonTerrainBlockRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumNonTerrainBlockRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.render.BlockRenderContextMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
CONDITIONS.put("fr.adrien1106.reframed.mixin.render.BlockRenderContextMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.SodiumBlockOcclusionCacheMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(2)));
|
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.SodiumBlockOcclusionCacheMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(2)));
|
||||||
|
CONDITIONS.put("fr.adrien1106.reframed.mixin.render.FluidRendererMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(2)));
|
||||||
|
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.SodiumFluidRendererMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(2)));
|
||||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityConnectionPredicateMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityConnectionPredicateMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
||||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityCTMBakedModelMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityCTMBakedModelMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
||||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityCTMQuadTransformMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityCTMQuadTransformMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package fr.adrien1106.reframed.mixin.compat;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
|
import fr.adrien1106.reframed.block.ReFramedBlock;
|
||||||
|
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||||
|
import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.FluidRenderer;
|
||||||
|
import me.jellysquid.mods.sodium.client.world.WorldSlice;
|
||||||
|
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
|
||||||
|
import net.minecraft.block.*;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
@Mixin(FluidRenderer.class)
|
||||||
|
public abstract class SodiumFluidRendererMixin {
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "isSideExposed",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/block/BlockState;isOpaque()Z"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private boolean isSideOpaqueExposed(BlockState state) {
|
||||||
|
if (!(state.getBlock() instanceof ReFramedBlock)) return state.isOpaque();
|
||||||
|
return true; // forces to compute correct shape
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "isSideExposed",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/block/BlockState;getCullingShape(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/util/shape/VoxelShape;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private VoxelShape isSideShapeExposed(BlockState state, BlockView world, BlockPos pos) {
|
||||||
|
if (!(state.getBlock() instanceof ReFramedBlock block)) return state.getCullingShape(world, pos);
|
||||||
|
return block.getShadingShape(state, world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "render",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/fabricmc/fabric/api/client/render/fluid/v1/FluidRenderHandlerRegistry;isBlockTransparent(Lnet/minecraft/block/Block;)Z"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private boolean getThemeState(FluidRenderHandlerRegistry fluid_handler, Block block, @Local(argsOnly = true) WorldSlice world, @Local(ordinal = 2) BlockPos pos, @Local BlockState state, @Local Direction dir) {
|
||||||
|
if (!(block instanceof ReFramedBlock rfblock && world.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity)) return fluid_handler.isBlockTransparent(block);
|
||||||
|
return !VoxelShapes.isSideCovered(VoxelShapes.fullCube(), rfblock.getShadingShape(state, world, pos), dir)
|
||||||
|
&& framed_entity.getThemes().stream()
|
||||||
|
.anyMatch(s -> s.getBlock() instanceof LeavesBlock
|
||||||
|
|| s.getBlock() instanceof TranslucentBlock
|
||||||
|
|| s.getBlock() instanceof AirBlock
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package fr.adrien1106.reframed.mixin.render;
|
||||||
|
|
||||||
|
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||||
|
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(Block.class)
|
||||||
|
public abstract class BlockMixin {
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "shouldDrawSide",
|
||||||
|
at = @At("HEAD"),
|
||||||
|
cancellable = true
|
||||||
|
) // serves as a safety sometimes mods implements culling cache and hence will break some injections...
|
||||||
|
private static void shouldDrawSide(BlockState state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
if (!(world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity)) return;
|
||||||
|
cir.setReturnValue(RenderHelper.shouldDrawSide(state, world, pos, side, other_pos, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package fr.adrien1106.reframed.mixin.render;
|
||||||
|
|
||||||
|
import fr.adrien1106.reframed.block.ReFramedBlock;
|
||||||
|
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||||
|
import net.minecraft.block.*;
|
||||||
|
import net.minecraft.client.render.block.FluidRenderer;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
|
import net.minecraft.world.BlockRenderView;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(FluidRenderer.class)
|
||||||
|
public abstract class FluidRendererMixin {
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "isSideCovered(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/Direction;FLnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z",
|
||||||
|
at = @At("HEAD"),
|
||||||
|
cancellable = true
|
||||||
|
) // force dynamic water side rendering
|
||||||
|
private static void isSameSideCovered(BlockView world, Direction direction, float height, BlockPos pos, BlockState state, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
if (!(state.getBlock() instanceof ReFramedBlock block)
|
||||||
|
) return;
|
||||||
|
|
||||||
|
boolean is_covered = VoxelShapes.isSideCovered(
|
||||||
|
VoxelShapes.cuboid(0.0, 0.0, 0.0, 1.0, height, 1.0),
|
||||||
|
block.getShadingShape(state, world, pos),
|
||||||
|
direction
|
||||||
|
);
|
||||||
|
cir.setReturnValue(is_covered);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "render",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/world/BlockRenderView;getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;",
|
||||||
|
ordinal = 7
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private BlockState getThemeState(BlockRenderView world, BlockPos pos) {
|
||||||
|
if (!(world.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity)) return world.getBlockState(pos);
|
||||||
|
return framed_entity.getThemes().stream()
|
||||||
|
.anyMatch(state -> state.getBlock() instanceof LeavesBlock
|
||||||
|
|| state.getBlock() instanceof TranslucentBlock
|
||||||
|
|| state.getBlock() instanceof AirBlock
|
||||||
|
)
|
||||||
|
? Blocks.GLASS.getDefaultState()
|
||||||
|
: world.getBlockState(pos) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,4 +10,6 @@ public interface ThemeableBlockEntity {
|
|||||||
void setTheme(BlockState state, int i);
|
void setTheme(BlockState state, int i);
|
||||||
|
|
||||||
List<BlockState> getThemes();
|
List<BlockState> getThemes();
|
||||||
|
|
||||||
|
boolean isSolid();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,11 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static fr.adrien1106.reframed.block.ReFramedEntity.BLOCKSTATE_KEY;
|
import static fr.adrien1106.reframed.block.ReFramedEntity.*;
|
||||||
|
|
||||||
public class ThemedBlockEntity extends BlockEntity implements ThemeableBlockEntity {
|
public class ThemedBlockEntity extends BlockEntity implements ThemeableBlockEntity {
|
||||||
private final List<BlockState> themes;
|
private final List<BlockState> themes;
|
||||||
|
private final boolean isSolid;
|
||||||
|
|
||||||
public ThemedBlockEntity(NbtCompound compound, BlockPos pos, BlockState state) {
|
public ThemedBlockEntity(NbtCompound compound, BlockPos pos, BlockState state) {
|
||||||
super(null, pos, state);
|
super(null, pos, state);
|
||||||
@@ -26,6 +27,7 @@ public class ThemedBlockEntity extends BlockEntity implements ThemeableBlockEnti
|
|||||||
compound.getCompound(BLOCKSTATE_KEY + i)
|
compound.getCompound(BLOCKSTATE_KEY + i)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
isSolid = !compound.contains(BITFIELD_KEY) || (compound.getByte(BITFIELD_KEY) & SOLIDITY_MASK) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -47,4 +49,9 @@ public class ThemedBlockEntity extends BlockEntity implements ThemeableBlockEnti
|
|||||||
public List<BlockState> getThemes() {
|
public List<BlockState> getThemes() {
|
||||||
return themes;
|
return themes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSolid() {
|
||||||
|
return isSolid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,14 +33,17 @@
|
|||||||
"compat.IndiumNonTerrainBlockRenderContextMixin",
|
"compat.IndiumNonTerrainBlockRenderContextMixin",
|
||||||
"compat.IndiumTerrainRenderContextMixin",
|
"compat.IndiumTerrainRenderContextMixin",
|
||||||
"compat.SodiumBlockOcclusionCacheMixin",
|
"compat.SodiumBlockOcclusionCacheMixin",
|
||||||
|
"compat.SodiumFluidRendererMixin",
|
||||||
"model.WeightedBakedModelAccessor",
|
"model.WeightedBakedModelAccessor",
|
||||||
"particles.AccessorParticle",
|
"particles.AccessorParticle",
|
||||||
"particles.AccessorSpriteBillboardParticle",
|
"particles.AccessorSpriteBillboardParticle",
|
||||||
"particles.MixinBlockDustParticle",
|
"particles.MixinBlockDustParticle",
|
||||||
"render.AbstractBlockRenderContextMixin",
|
"render.AbstractBlockRenderContextMixin",
|
||||||
|
"render.BlockMixin",
|
||||||
"render.BlockModelRendererMixin",
|
"render.BlockModelRendererMixin",
|
||||||
"render.BlockRenderContextMixin",
|
"render.BlockRenderContextMixin",
|
||||||
"render.BlockRenderInfoMixin",
|
"render.BlockRenderInfoMixin",
|
||||||
|
"render.FluidRendererMixin",
|
||||||
"render.MultipartBakedModelMixin",
|
"render.MultipartBakedModelMixin",
|
||||||
"render.TerrainRenderContextMixin",
|
"render.TerrainRenderContextMixin",
|
||||||
"render.WorldRendererMixin",
|
"render.WorldRendererMixin",
|
||||||
|
|||||||
Reference in New Issue
Block a user