From 5f87489939aa70e0167cfd2cc7414df2f77da9fa Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Wed, 6 Mar 2024 22:10:11 +0100 Subject: [PATCH 01/11] better caching for both appearances and meshed models --- .../java/fr/adrien1106/reframed/ReFramed.java | 6 +- .../reframed/block/ReFramedBlock.java | 21 ++- .../reframed/block/ReFramedDoubleBlock.java | 4 +- .../reframed/block/ReFramedDoubleEntity.java | 2 +- .../block/ReFramedDoubleSlabBlock.java | 19 +- .../block/ReFramedDoubleStairsBlock.java | 24 ++- .../block/ReFramedDoubleStepBlock.java | 16 +- .../reframed/block/ReFramedEntity.java | 8 +- .../reframed/block/ReFramedSlabBlock.java | 10 + .../reframed/block/ReFramedStairsBlock.java | 23 ++- .../reframed/block/ReFramedStepBlock.java | 18 +- .../model/DoubleRetexturingBakedModel.java | 2 +- .../client/model/MultiRetexturableModel.java | 3 +- .../client/model/RetexturingBakedModel.java | 172 +++++++----------- .../model/UnbakedAutoRetexturedModel.java | 2 +- .../model/UnbakedJsonRetexturedModel.java | 2 +- .../model/apperance/CamoAppearance.java | 71 +++++++- .../apperance/CamoAppearanceManager.java | 34 ++-- .../model/apperance/ComputedAppearance.java | 31 +--- .../apperance/SingleSpriteAppearance.java | 26 +-- .../apperance/WeightedComputedAppearance.java | 39 +--- .../reframed/mixin/BlockItemMixin.java | 1 + .../mixin/compat/AthenaBakedModelMixin.java | 2 +- .../AthenaConnectedBlockModelMixin.java | 2 +- .../compat/AthenaWrappedGetterMixin.java | 2 +- .../IndiumTerrainBlockRenderInfoMixin.java | 6 +- .../IndiumTerrainRenderContextMixin.java | 13 +- .../SodiumBlockOcclusionCacheMixin.java | 4 +- .../particles/MixinBlockDustParticle.java | 2 +- .../reframed/mixin/particles/MixinEntity.java | 2 +- .../mixin/particles/MixinLivingEntity.java | 2 +- .../mixin/render/BlockRenderInfoMixin.java | 6 +- .../render/MultipartBakedModelMixin.java | 2 +- .../render/TerrainRenderContextMixin.java | 18 +- .../reframed/mixin/sound/BlockItemMixin.java | 2 +- .../reframed/mixin/sound/EntityMixin.java | 2 +- .../mixin/sound/LivingEntityMixin.java | 2 +- .../mixin/sound/WorldRendererMixin.java | 2 +- .../util/{ => blocks}/BlockHelper.java | 23 ++- .../util/{ => blocks}/BlockProperties.java | 4 +- .../util/{property => blocks}/Corner.java | 2 +- .../{ => blocks}/ReframedInteractible.java | 2 +- .../util/{property => blocks}/StairShape.java | 2 +- .../{ => blocks}/ThemeableBlockEntity.java | 2 +- .../{ => mixin}/IBlockRenderInfoMixin.java | 2 +- .../IMultipartBakedModelMixin.java | 2 +- 46 files changed, 364 insertions(+), 278 deletions(-) rename src/main/java/fr/adrien1106/reframed/util/{ => blocks}/BlockHelper.java (93%) rename src/main/java/fr/adrien1106/reframed/util/{ => blocks}/BlockProperties.java (74%) rename src/main/java/fr/adrien1106/reframed/util/{property => blocks}/Corner.java (98%) rename src/main/java/fr/adrien1106/reframed/util/{ => blocks}/ReframedInteractible.java (93%) rename src/main/java/fr/adrien1106/reframed/util/{property => blocks}/StairShape.java (96%) rename src/main/java/fr/adrien1106/reframed/util/{ => blocks}/ThemeableBlockEntity.java (82%) rename src/main/java/fr/adrien1106/reframed/util/{ => mixin}/IBlockRenderInfoMixin.java (87%) rename src/main/java/fr/adrien1106/reframed/util/{ => mixin}/IMultipartBakedModelMixin.java (81%) diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index f546e28..daee2ba 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -1,7 +1,7 @@ package fr.adrien1106.reframed; import fr.adrien1106.reframed.block.*; -import fr.adrien1106.reframed.util.BlockHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; @@ -26,7 +26,9 @@ import java.util.function.BiConsumer; import java.util.stream.Collectors; /** - * TODO self culling, fix other models, better connected textures, preload items, better cache + * TODO self culling + * TODO fix other models + * TODO better connected textures */ public class ReFramed implements ModInitializer { public static final String MODID = "reframed"; diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java index d1609c3..c75b6a9 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.RecipeSetter; -import fr.adrien1106.reframed.util.BlockHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.*; import net.minecraft.block.entity.BlockEntity; @@ -33,7 +33,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -import static fr.adrien1106.reframed.util.BlockProperties.LIGHT; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; public class ReFramedBlock extends Block implements BlockEntityProvider, RecipeSetter { @@ -41,6 +41,23 @@ public class ReFramedBlock extends Block implements BlockEntityProvider, RecipeS super(settings); setDefaultState(getDefaultState().with(LIGHT, false)); } + + /** + * Generates a record for the key so that it replaces the blockstate + * which may have states that returns same models + * @param state - the state_key to generate the key from + * @return a cache key with only relevant properties + */ + public Object getModelCacheKey(BlockState state) { + return ""; + } + + /** + * @return the amount of models the block can have prevents allocating too much space for a model + */ + public int getModelStateCount() { + return 1; + } //For addon devs: override this so your blocks don't end up trying to place my block entity, my BlockEntityType only handles blocks internal to the mod //Just make your own BlockEntityType, it's fine, you can even use the same ReFramedEntity class diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleBlock.java index 45756b6..cb708b0 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleBlock.java @@ -1,8 +1,8 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; -import fr.adrien1106.reframed.util.BlockHelper; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; import net.minecraft.block.entity.BlockEntity; diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleEntity.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleEntity.java index 5090b0a..cecd4f6 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleEntity.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleEntity.java @@ -44,7 +44,7 @@ public class ReFramedDoubleEntity extends ReFramedEntity { public void readNbt(NbtCompound nbt) { super.readNbt(nbt); - BlockState rendered_state = second_state;// keep previous state to check if rerender is needed + BlockState rendered_state = second_state;// keep previous state_key to check if rerender is needed second_state = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), nbt.getCompound(BLOCKSTATE_KEY + 2)); // Force a chunk remesh on the client if the displayed blockstate has changed diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java index 5f11422..a7f4292 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java @@ -25,25 +25,36 @@ import static net.minecraft.data.client.VariantSettings.Rotation.R90; import static net.minecraft.state.property.Properties.AXIS; public class ReFramedDoubleSlabBlock extends ReFramedDoubleBlock implements BlockStateProvider { + public ReFramedDoubleSlabBlock(Settings settings) { super(settings); - setDefaultState(getDefaultState().with(Properties.AXIS, Direction.Axis.Y)); + setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return state.get(AXIS); + } + + @Override + public int getModelStateCount() { + return 3; } @Override protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder.add(Properties.AXIS)); + super.appendProperties(builder.add(AXIS)); } @Nullable @Override public BlockState getPlacementState(ItemPlacementContext ctx) { - return super.getPlacementState(ctx).with(Properties.AXIS, ctx.getSide().getAxis()); + return super.getPlacementState(ctx).with(AXIS, ctx.getSide().getAxis()); } @Override public VoxelShape getShape(BlockState state, int i) { - return switch (state.get(Properties.AXIS)) { + return switch (state.get(AXIS)) { case Y -> i == 2 ? UP : DOWN; case Z -> i == 2 ? NORTH : SOUTH; case X -> i == 2 ? EAST : WEST; diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java index c7ac022..6dda2df 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java @@ -2,9 +2,9 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.BlockHelper; -import fr.adrien1106.reframed.util.property.Corner; -import fr.adrien1106.reframed.util.property.StairShape; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -28,17 +28,27 @@ import java.util.ArrayList; import java.util.List; import static fr.adrien1106.reframed.block.ReFramedStairsBlock.*; -import static fr.adrien1106.reframed.util.BlockProperties.CORNER; -import static fr.adrien1106.reframed.util.BlockProperties.STAIR_SHAPE; -import static fr.adrien1106.reframed.util.property.StairShape.STRAIGHT; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE; public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements BlockStateProvider { private static final List COMPLEMENT_LIST = new ArrayList<>(52); + private record ModelCacheKey(Corner corner, StairShape shape) {} public ReFramedDoubleStairsBlock(Settings settings) { super(settings); - setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT)); + setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN).with(STAIR_SHAPE, StairShape.STRAIGHT)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(CORNER), state.get(STAIR_SHAPE)); + } + + @Override + public int getModelStateCount() { + return 108; // Has 12 * 9 state combination and 52 models still reduces cache size } @Override diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java index 5e76f44..453dc0f 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java @@ -3,7 +3,9 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.BlockHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -32,11 +34,23 @@ import static net.minecraft.state.property.Properties.AXIS; import static net.minecraft.util.shape.VoxelShapes.empty; public class ReFramedDoubleStepBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { + private record ModelCacheKey(Direction facing, Axis axis) {} + public ReFramedDoubleStepBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(FACING, Direction.DOWN).with(AXIS, Axis.X)); } + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(FACING), state.get(AXIS)); + } + + @Override + public int getModelStateCount() { + return 18; + } + @Override protected void appendProperties(StateManager.Builder builder) { super.appendProperties(builder.add(FACING, AXIS)); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java index cb7bde1..fc70154 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java @@ -1,8 +1,8 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; -import fr.adrien1106.reframed.util.BlockProperties; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.BlockProperties; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.entity.BlockEntity; @@ -27,7 +27,7 @@ import java.util.Objects; //Keeping the weight of this block entity down, both in terms of memory consumption and NBT sync traffic, //is pretty important since players might place a lot of them. There were tons and tons of these at Blanketcon. -//To that end, most of the state has been crammed into a bitfield. +//To that end, most of the state_key has been crammed into a bitfield. public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity { protected BlockState first_state = Blocks.AIR.getDefaultState(); protected byte bit_field = SOLIDITY_MASK; @@ -47,7 +47,7 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity public void readNbt(NbtCompound nbt) { super.readNbt(nbt); - BlockState rendered_state = first_state; // keep previous state to check if rerender is needed + BlockState rendered_state = first_state; // keep previous state_key to check if rerender is needed first_state = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), nbt.getCompound(BLOCKSTATE_KEY + 1)); if (nbt.contains(BITFIELD_KEY)) bit_field = nbt.getByte(BITFIELD_KEY); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedSlabBlock.java index fa65921..751588e 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedSlabBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedSlabBlock.java @@ -38,6 +38,16 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock implements Blo super(settings); setDefaultState(getDefaultState().with(FACING, Direction.DOWN)); } + + @Override + public Object getModelCacheKey(BlockState state) { + return state.get(FACING); + } + + @Override + public int getModelStateCount() { + return 6; + } @Override protected void appendProperties(StateManager.Builder builder) { diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java index ce7283b..3912786 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java @@ -3,10 +3,10 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.BlockHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.VoxelHelper; -import fr.adrien1106.reframed.util.property.Corner; -import fr.adrien1106.reframed.util.property.StairShape; +import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -34,19 +34,30 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; -import static fr.adrien1106.reframed.util.BlockProperties.*; -import static fr.adrien1106.reframed.util.property.StairShape.*; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.*; +import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; -import static fr.adrien1106.reframed.util.property.Corner.*; +import static fr.adrien1106.reframed.util.blocks.Corner.*; public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements BlockStateProvider { public static final List VOXEL_LIST = new ArrayList<>(52); + private record ModelCacheKey(Corner corner, StairShape shape) {} public ReFramedStairsBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT)); } + + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(CORNER), state.get(STAIR_SHAPE)); + } + + @Override + public int getModelStateCount() { + return 108; // Has 12 * 9 state combination and 52 models still reduces cache size + } @Override protected void appendProperties(StateManager.Builder builder) { diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java index a5c7841..8b33b9e 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java @@ -3,9 +3,9 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.BlockHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.VoxelHelper; -import fr.adrien1106.reframed.util.property.Corner; +import fr.adrien1106.reframed.util.blocks.Corner; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -28,8 +28,8 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import static fr.adrien1106.reframed.util.BlockProperties.CORNER; -import static fr.adrien1106.reframed.util.property.Corner.*; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.Corner.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; public class ReFramedStepBlock extends WaterloggableReFramedBlock implements BlockStateProvider { @@ -41,6 +41,16 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN)); } + @Override + public Object getModelCacheKey(BlockState state) { + return state.get(CORNER); + } + + @Override + public int getModelStateCount() { + return 12; + } + @Override protected void appendProperties(StateManager.Builder builder) { super.appendProperties(builder.add(CORNER)); diff --git a/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java index a8bf841..29ff44b 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java @@ -45,7 +45,7 @@ public class DoubleRetexturingBakedModel extends ForwardingBakedModel implements } @Override - public List models() { + public List models() { return List.of(model_1, model_2); } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java b/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java index b1d7cea..bcd46de 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java @@ -1,10 +1,11 @@ package fr.adrien1106.reframed.client.model; +import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.minecraft.client.render.model.BakedModel; import java.util.List; public interface MultiRetexturableModel { - List models(); + List models(); } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java index 548bdd9..0e18f93 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java @@ -1,13 +1,14 @@ package fr.adrien1106.reframed.client.model; +import fr.adrien1106.reframed.block.ReFramedBlock; import fr.adrien1106.reframed.block.ReFramedEntity; import fr.adrien1106.reframed.client.ReFramedClient; -import fr.adrien1106.reframed.client.model.apperance.SpriteProperties; import fr.adrien1106.reframed.mixin.MinecraftAccessor; import fr.adrien1106.reframed.client.model.apperance.CamoAppearance; import fr.adrien1106.reframed.client.model.apperance.CamoAppearanceManager; import fr.adrien1106.reframed.client.model.apperance.WeightedComputedAppearance; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; @@ -26,34 +27,42 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.function.Supplier; public abstract class RetexturingBakedModel extends ForwardingBakedModel { public RetexturingBakedModel(BakedModel base_model, CamoAppearanceManager tam, int theme_index, ModelBakeSettings settings, BlockState item_state, boolean ao) { this.wrapped = base_model; //field from the superclass; vanilla getQuads etc. will delegate through to this - this.tam = tam; + this.appearance_manager = tam; this.theme_index = theme_index; this.uv_lock = settings.isUvLocked(); this.item_state = item_state; this.ao = ao; + + int cache_size = 64; // default is 64 why don't ask me and it should get overwritten + if (item_state.getBlock() instanceof ReFramedBlock frame_block) cache_size = frame_block.getModelStateCount() + 1; + BASE_MESH_CACHE = new Object2ObjectLinkedOpenHashMap<>(cache_size, 0.25f) { + @Override + protected void rehash(int v) {} + }; } - protected final CamoAppearanceManager tam; + protected final CamoAppearanceManager appearance_manager; protected final int theme_index; protected final boolean uv_lock; - protected final BlockState item_state; protected final boolean ao; + protected final BlockState item_state; - /* ----------------------------------------------- CACHE ELEMENT ------------------------------------------------ */ - // TODO make static ? for connected textures ? - protected record MeshCacheKey(BlockState state, TransformCacheKey transform) {} - protected record TransformCacheKey(CamoAppearance appearance, int model_id) {} - protected final ConcurrentMap retextured_transforms = new ConcurrentHashMap<>(); - protected final ConcurrentMap retextured_meshes = new ConcurrentHashMap<>(); //mutable, append-only cache + protected record MeshCacheKey(Object state_key, CamoAppearance appearance, int model_id) {} + /** cache that store retextured models */ + protected final Object2ObjectLinkedOpenHashMap RETEXTURED_MESH_CACHE = + new Object2ObjectLinkedOpenHashMap<>(128, 0.25f) { + @Override + protected void rehash(int v) {} + }; + + /** cache that stores the base meshes which has the size of the amount of models */ + protected final Object2ObjectLinkedOpenHashMap BASE_MESH_CACHE; protected static final Direction[] DIRECTIONS_AND_NULL; static { @@ -62,11 +71,12 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { System.arraycopy(values, 0, DIRECTIONS_AND_NULL, 0, values.length); } - protected final ConcurrentMap jsonToMesh = new ConcurrentHashMap<>(); - - protected Mesh getBaseMesh(BlockState state) { + protected Mesh getBaseMesh(Object key, BlockState state) { //Convert models to re-texturable Meshes lazily, the first time we encounter each blockstate - return jsonToMesh.computeIfAbsent(state, this::convertModel); + if (BASE_MESH_CACHE.containsKey(key)) return BASE_MESH_CACHE.getAndMoveToFirst(key); + Mesh mesh = convertModel(state); + BASE_MESH_CACHE.putAndMoveToFirst(key, mesh); + return mesh; } protected abstract Mesh convertModel(BlockState state); @@ -78,39 +88,42 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { @Override public Sprite getParticleSprite() { - return tam.getDefaultAppearance(theme_index).getSprites(Direction.UP, 0).get(0).sprite(); + return appearance_manager.getDefaultAppearance(theme_index).getSprites(Direction.UP, 0).get(0).sprite(); } @Override public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + // skip render if block not a frame (which should always be the case + if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return; BlockState theme = (world.getBlockEntity(pos) instanceof ThemeableBlockEntity s) ? s.getTheme(theme_index) : null; QuadEmitter quad_emitter = context.getEmitter(); if(theme == null || theme.isAir()) { - getUntintedRetexturedMesh(new MeshCacheKey(state, new TransformCacheKey(tam.getDefaultAppearance(theme_index), 0)), 0).outputTo(quad_emitter); + getRetexturedMesh( + new MeshCacheKey( + frame_block.getModelCacheKey(state), + appearance_manager.getDefaultAppearance(theme_index), + 0 + ), + state + ).outputTo(quad_emitter); return; } if(theme.getBlock() == Blocks.BARRIER) return; - CamoAppearance camo = tam.getCamoAppearance(world, theme, pos, theme_index); + CamoAppearance camo = appearance_manager.getCamoAppearance(world, theme, pos, theme_index); long seed = theme.getRenderingSeed(pos); int model_id = 0; if (camo instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed); - + int tint = 0xFF000000 | MinecraftClient.getInstance().getBlockColors().getColor(theme, world, pos, 0); - Mesh untintedMesh = getUntintedRetexturedMesh( - new MeshCacheKey( - state, - new TransformCacheKey(camo, model_id) - ), - seed - ); + Mesh untintedMesh = getRetexturedMesh(new MeshCacheKey(frame_block.getModelCacheKey(state), camo, model_id), state); //The specific tint might vary a lot; imagine grass color smoothly changing. Trying to bake the tint into //the cached mesh will pollute it with a ton of single-use meshes with only slightly different colors. if(tint == 0xFFFFFFFF) { untintedMesh.outputTo(quad_emitter); } else { - context.pushTransform(new TintingTransformer(camo, tint, seed)); + context.pushTransform(new TintingTransformer(camo, model_id, tint)); untintedMesh.outputTo(quad_emitter); context.popTransform(); } @@ -120,121 +133,68 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { public void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { //cheeky: if the item has NBT data, pluck out the blockstate from it & look up the item color provider //none of this is accessible unless you're in creative mode doing ctrl-pick btw - CamoAppearance nbtAppearance; + CamoAppearance appearance; int tint; BlockState theme = ReFramedEntity.readStateFromItem(stack, theme_index); if(!theme.isAir()) { - nbtAppearance = tam.getCamoAppearance(null, theme, null, theme_index); + appearance = appearance_manager.getCamoAppearance(null, theme, null, theme_index); tint = 0xFF000000 | ((MinecraftAccessor) MinecraftClient.getInstance()).getItemColors().getColor(new ItemStack(theme.getBlock()), 0); } else { - nbtAppearance = tam.getDefaultAppearance(theme_index); + appearance = appearance_manager.getDefaultAppearance(theme_index); tint = 0xFFFFFFFF; } - Mesh untintedMesh = getUntintedRetexturedMesh(new MeshCacheKey(item_state, new TransformCacheKey(nbtAppearance, 0)), 0); + Mesh untintedMesh = getRetexturedMesh(new MeshCacheKey("I", appearance, 0), item_state); QuadEmitter quad_emitter = context.getEmitter(); if(tint == 0xFFFFFFFF) { untintedMesh.outputTo(quad_emitter); } else { - context.pushTransform(new TintingTransformer(nbtAppearance, tint, 0)); + context.pushTransform(new TintingTransformer(appearance, 0, tint)); untintedMesh.outputTo(quad_emitter); context.popTransform(); } } - protected Mesh getUntintedRetexturedMesh(MeshCacheKey key, long seed) { - return retextured_meshes.computeIfAbsent(key, (k) -> createUntintedRetexturedMesh(k, seed)); + protected Mesh getRetexturedMesh(MeshCacheKey key, BlockState state) { + if (RETEXTURED_MESH_CACHE.containsKey(key)) return RETEXTURED_MESH_CACHE.getAndMoveToFirst(key); + Mesh mesh = transformMesh(key, state); + RETEXTURED_MESH_CACHE.putAndMoveToFirst(key, mesh); + return mesh; } - protected Mesh createUntintedRetexturedMesh(MeshCacheKey key, long seed) { - RetexturingTransformer transformer = retextured_transforms.computeIfAbsent(key.transform, (k) -> new RetexturingTransformer(k.appearance, seed)); - return pretransformMesh(getBaseMesh(key.state), transformer); - } - - private static Mesh pretransformMesh(Mesh mesh, RetexturingTransformer transform) { + protected Mesh transformMesh(MeshCacheKey key, BlockState state) { MeshBuilder builder = ReFramedClient.HELPER.getFabricRenderer().meshBuilder(); QuadEmitter emitter = builder.getEmitter(); - mesh.forEach(quad -> { + getBaseMesh(key.state_key, state).forEach(quad -> { int i = -1; do { emitter.copyFrom(quad); - i = transform.transform(emitter, i); + i = key.appearance.transformQuad(emitter, i, key.model_id, ao, uv_lock); } while (i > 0); }); return builder.build(); } - - public class RetexturingTransformer { - private final long seed; - protected RetexturingTransformer(CamoAppearance ta, long seed) { - this.ta = ta; - this.seed = seed; - } - - protected final CamoAppearance ta; - public int transform(QuadEmitter quad, int i) { - if(quad.tag() == 0) return 0; //Pass the quad through unmodified. - - Direction direction = quad.nominalFace(); - List sprites = ta.getSprites(direction, seed); - if (i == -1) i = sprites.size(); - - SpriteProperties properties = sprites.get(sprites.size() - i); - i--; - QuadPosBounds bounds = properties.bounds(); - - if (bounds == null) { // sprite applies anywhere e.g. default behaviour - quad.material(ta.getRenderMaterial(ao)); - quad.spriteBake( - properties.sprite(), - MutableQuadView.BAKE_NORMALIZED - | properties.flags() - | (uv_lock ? MutableQuadView.BAKE_LOCK_UV : 0) - ); - quad.tag(i+1); - quad.emit(); - return i; - } - - // verify if sprite covers the current quad and apply the new size - QuadPosBounds origin_bounds = QuadPosBounds.read(quad, false); - if (!bounds.matches(origin_bounds)) return i; - - // apply new quad shape - quad.material(ta.getRenderMaterial(ao)); - bounds.intersection(origin_bounds, direction.getAxis()).apply(quad, origin_bounds); - quad.spriteBake( // seems to work without the flags and break with it - properties.sprite(), - MutableQuadView.BAKE_NORMALIZED - | MutableQuadView.BAKE_LOCK_UV - ); - quad.tag(i+1); - quad.emit(); - return i; - } - } - protected static class TintingTransformer implements RenderContext.QuadTransform { - private final long seed; - protected TintingTransformer(CamoAppearance ta, int tint, long seed) { - this.ta = ta; + private final CamoAppearance appearance; + private final int model_id; + private final int tint; + + protected TintingTransformer(CamoAppearance appearance, int model_id, int tint) { + this.appearance = appearance; + this.model_id = model_id; this.tint = tint; - this.seed = seed; } - - protected final CamoAppearance ta; - protected final int tint; - + @Override public boolean transform(MutableQuadView quad) { if(quad.tag() == 0) return true; - if(ta.hasColor(quad.nominalFace(), seed, quad.tag())) quad.color(tint, tint, tint, tint); - + if(appearance.hasColor(quad.nominalFace(), model_id, quad.tag())) quad.color(tint, tint, tint, tint); + return true; } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/UnbakedAutoRetexturedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/UnbakedAutoRetexturedModel.java index dba3f74..b789e9f 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/UnbakedAutoRetexturedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/UnbakedAutoRetexturedModel.java @@ -43,7 +43,7 @@ public class UnbakedAutoRetexturedModel extends UnbakedRetexturedModel { Renderer r = ReFramedClient.HELPER.getFabricRenderer(); MeshBuilder builder = r.meshBuilder(); QuadEmitter emitter = builder.getEmitter(); - RenderMaterial mat = tam.getCachedMaterial(state, false); + RenderMaterial mat = appearance_manager.getCachedMaterial(state, false); Random rand = Random.create(42); diff --git a/src/main/java/fr/adrien1106/reframed/client/model/UnbakedJsonRetexturedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/UnbakedJsonRetexturedModel.java index 914ce00..48e5617 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/UnbakedJsonRetexturedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/UnbakedJsonRetexturedModel.java @@ -51,7 +51,7 @@ public class UnbakedJsonRetexturedModel extends UnbakedRetexturedModel { Renderer r = ReFramedClient.HELPER.getFabricRenderer(); MeshBuilder builder = r.meshBuilder(); QuadEmitter emitter = builder.getEmitter(); - RenderMaterial mat = tam.getCachedMaterial(state, false); + RenderMaterial mat = appearance_manager.getCachedMaterial(state, false); Random rand = Random.create(42); diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java index ad219e5..1e71f1b 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java @@ -1,13 +1,76 @@ package fr.adrien1106.reframed.client.model.apperance; +import fr.adrien1106.reframed.client.model.QuadPosBounds; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.minecraft.util.math.Direction; import org.jetbrains.annotations.NotNull; import java.util.List; -public interface CamoAppearance { - @NotNull RenderMaterial getRenderMaterial(boolean ao); - @NotNull List getSprites(Direction dir, long seed); - boolean hasColor(Direction dir, long seed, int index); +public abstract class CamoAppearance { + protected final int id; + protected final RenderMaterial ao_material; + protected final RenderMaterial material; + + protected CamoAppearance(RenderMaterial ao_material, RenderMaterial material, int id) { + this.id = id; + + this.ao_material = ao_material; + this.material = material; + } + + public abstract @NotNull List getSprites(Direction dir, int model_id); + public abstract boolean hasColor(Direction dir, int model_id, int index); + + public @NotNull RenderMaterial getRenderMaterial(boolean ao) { + return ao && ao_material != null? ao_material : material; + } + + public int transformQuad(QuadEmitter quad, int i, int model_id, boolean ao, boolean uv_lock) { + if(quad.tag() == 0) return 0; // Pass the quad through unmodified. + + Direction direction = quad.nominalFace(); + List sprites = getSprites(direction, model_id); + if (i == -1) i = sprites.size(); + + SpriteProperties properties = sprites.get(sprites.size() - i); + i--; + QuadPosBounds bounds = properties.bounds(); + + if (bounds == null) { // sprite applies anywhere e.g. default behaviour + quad.material(getRenderMaterial(ao)); + quad.spriteBake( + properties.sprite(), + MutableQuadView.BAKE_NORMALIZED + | properties.flags() + | (uv_lock ? MutableQuadView.BAKE_LOCK_UV : 0) + ); + quad.tag(i+1); + quad.emit(); + return i; + } + + // verify if sprite covers the current quad and apply the new size + QuadPosBounds origin_bounds = QuadPosBounds.read(quad, false); + if (!bounds.matches(origin_bounds)) return i; + + // apply new quad shape + quad.material(getRenderMaterial(ao)); + bounds.intersection(origin_bounds, direction.getAxis()).apply(quad, origin_bounds); + quad.spriteBake( // seems to work without the flags and break with it + properties.sprite(), + MutableQuadView.BAKE_NORMALIZED + | MutableQuadView.BAKE_LOCK_UV + ); + quad.tag(i+1); + quad.emit(); + return i; + } + + @Override + public int hashCode() { + return id; + } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java index 949545b..ce7515f 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java @@ -5,6 +5,7 @@ import fr.adrien1106.reframed.client.ReFramedClient; import fr.adrien1106.reframed.client.model.DynamicBakedModel; import fr.adrien1106.reframed.client.model.QuadPosBounds; import fr.adrien1106.reframed.mixin.model.WeightedBakedModelAccessor; +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; @@ -29,7 +30,6 @@ import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -40,20 +40,20 @@ public class CamoAppearanceManager { for(BlendMode blend : BlendMode.values()) { finder.clear().disableDiffuse(false).blendMode(blend); - materialsWithoutAo.put(blend, finder.ambientOcclusion(TriState.FALSE).find()); - materialsWithAo.put(blend, finder.ambientOcclusion(TriState.DEFAULT).find()); //not "true" since that *forces* AO, i just want to *allow* AO + materials.put(blend, finder.ambientOcclusion(TriState.FALSE).find()); + ao_materials.put(blend, finder.ambientOcclusion(TriState.DEFAULT).find()); //not "true" since that *forces* AO, i just want to *allow* AO } Sprite sprite = spriteLookup.apply(DEFAULT_SPRITE_MAIN); if(sprite == null) throw new IllegalStateException("Couldn't locate " + DEFAULT_SPRITE_MAIN + " !"); - this.default_appearance = new SingleSpriteAppearance(sprite, materialsWithoutAo.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); + this.default_appearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); sprite = spriteLookup.apply(DEFAULT_SPRITE_SECONDARY); if(sprite == null) throw new IllegalStateException("Couldn't locate " + DEFAULT_SPRITE_MAIN + " !"); - this.accent_appearance = new SingleSpriteAppearance(sprite, materialsWithoutAo.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); + this.accent_appearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); sprite = spriteLookup.apply(BARRIER_SPRITE_ID); - this.barrierItemAppearance = new SingleSpriteAppearance(sprite, materialsWithoutAo.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); + this.barrierItemAppearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); } protected static final SpriteIdentifier DEFAULT_SPRITE_MAIN = new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, new Identifier(ReFramed.MODID, "block/framed_block")); @@ -63,12 +63,16 @@ public class CamoAppearanceManager { private final CamoAppearance default_appearance; private final CamoAppearance accent_appearance; private final CamoAppearance barrierItemAppearance; - - private final ConcurrentHashMap appearanceCache = new ConcurrentHashMap<>(); //Mutable, append-only cache + + private static final Object2ObjectLinkedOpenHashMap APPEARANCE_CACHE = + new Object2ObjectLinkedOpenHashMap<>(2048, 0.25f) { + @Override + protected void rehash(int n) {} + }; private final AtomicInteger serial_number = new AtomicInteger(0); //Mutable - private final EnumMap materialsWithAo = new EnumMap<>(BlendMode.class); - private final EnumMap materialsWithoutAo = new EnumMap<>(BlendMode.class); //Immutable contents + private final EnumMap ao_materials = new EnumMap<>(BlendMode.class); + private final EnumMap materials = new EnumMap<>(BlendMode.class); //Immutable contents public CamoAppearance getDefaultAppearance(int appearance) { return appearance == 2 ? accent_appearance: default_appearance; @@ -81,11 +85,17 @@ public class CamoAppearanceManager { if (model instanceof DynamicBakedModel dynamic_model) { return computeAppearance(dynamic_model.computeQuads(world, state, pos, theme_index), state); } - return appearanceCache.computeIfAbsent(state, block_state -> computeAppearance(model, block_state)); + + // refresh cache + if (APPEARANCE_CACHE.containsKey(state)) return APPEARANCE_CACHE.getAndMoveToFirst(state); + + CamoAppearance appearance = computeAppearance(model, state); + APPEARANCE_CACHE.putAndMoveToFirst(state, appearance); + return appearance; } public RenderMaterial getCachedMaterial(BlockState state, boolean ao) { - Map m = ao ? materialsWithAo : materialsWithoutAo; + Map m = ao ? ao_materials : materials; return m.get(BlendMode.fromRenderLayer(RenderLayers.getBlockLayer(state))); } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java index 52ccee0..24c0806 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java @@ -6,33 +6,22 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -public class ComputedAppearance implements CamoAppearance { +public class ComputedAppearance extends CamoAppearance { private final Appearance appearance; - private final int id; - private final RenderMaterial matWithAo; - private final RenderMaterial matWithoutAo; - public ComputedAppearance(@NotNull Appearance appearance, RenderMaterial withAo, RenderMaterial withoutAo, int id) { + public ComputedAppearance(@NotNull Appearance appearance, RenderMaterial ao_material, RenderMaterial material, int id) { + super(ao_material, material, id); this.appearance = appearance; - this.id = id; - - this.matWithAo = withAo; - this.matWithoutAo = withoutAo; } @Override - public @NotNull RenderMaterial getRenderMaterial(boolean ao) { - return ao ? matWithAo : matWithoutAo; - } - - @Override - public @NotNull List getSprites(Direction dir, long seed) { + public @NotNull List getSprites(Direction dir, int model_id) { return appearance.sprites().get(dir); } @Override - public boolean hasColor(Direction dir, long seed, int index) { - List properties = getSprites(dir, seed); + public boolean hasColor(Direction dir, int model_id, int index) { + List properties = getSprites(dir, model_id); if (index != 0) index = properties.size() - index; return properties.get(index).has_colors(); } @@ -40,13 +29,7 @@ public class ComputedAppearance implements CamoAppearance { @Override public boolean equals(Object o) { if(this == o) return true; - if(o == null || getClass() != o.getClass()) return false; - ComputedAppearance that = (ComputedAppearance) o; + if(!(o instanceof ComputedAppearance that)) return false; return id == that.id; } - - @Override - public int hashCode() { - return id; - } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java index d62e38f..9e384b9 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java @@ -7,47 +7,33 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -public class SingleSpriteAppearance implements CamoAppearance { +public class SingleSpriteAppearance extends CamoAppearance { private final @NotNull Sprite defaultSprite; - private final RenderMaterial mat; - private final int id; public SingleSpriteAppearance(@NotNull Sprite defaultSprite, RenderMaterial mat, int id) { + super(null, mat, id); this.defaultSprite = defaultSprite; - this.mat = mat; - this.id = id; } @Override - public @NotNull RenderMaterial getRenderMaterial(boolean ao) { - return mat; - } - - @Override - public @NotNull List getSprites(Direction dir, long seed) { + public @NotNull List getSprites(Direction dir, int model_id) { return List.of(new SpriteProperties(defaultSprite, 0, null, false)); } @Override - public boolean hasColor(Direction dir, long seed, int index) { + public boolean hasColor(Direction dir, int model_id, int index) { return false; } @Override public boolean equals(Object o) { if(this == o) return true; - if(o == null || getClass() != o.getClass()) return false; - SingleSpriteAppearance that = (SingleSpriteAppearance) o; + if(!(o instanceof SingleSpriteAppearance that)) return false; return id == that.id; } - @Override - public int hashCode() { - return id; - } - @Override public String toString() { - return "SingleSpriteAppearance[defaultSprite=%s, mat=%s, id=%d]".formatted(defaultSprite, mat, id); + return "SingleSpriteAppearance[defaultSprite=%s, mat=%s, id=%d]".formatted(defaultSprite, material, id); } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java index 4751711..b3c3b73 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java @@ -9,25 +9,14 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -public class WeightedComputedAppearance implements CamoAppearance { +public class WeightedComputedAppearance extends CamoAppearance { private final List> appearances; private final int total_weight; - private final int id; - private final RenderMaterial matWithAo; - private final RenderMaterial matWithoutAo; - public WeightedComputedAppearance(@NotNull List> appearances, RenderMaterial withAo, RenderMaterial withoutAo, int id) { + public WeightedComputedAppearance(@NotNull List> appearances, RenderMaterial ao_material, RenderMaterial material, int id) { + super(ao_material, material, id); this.appearances = appearances; this.total_weight = Weighting.getWeightSum(appearances); - this.id = id; - - this.matWithAo = withAo; - this.matWithoutAo = withoutAo; - } - - @Override - public @NotNull RenderMaterial getRenderMaterial(boolean ao) { - return ao ? matWithAo : matWithoutAo; } @@ -37,21 +26,19 @@ public class WeightedComputedAppearance implements CamoAppearance { .map(appearances::indexOf).orElse(0); } - private Appearance getAppearance(long seed) { - Random random = Random.create(seed); - return Weighting.getAt(appearances, Math.abs((int)random.nextLong()) % total_weight) - .map(Weighted.Present::getData).get(); + private Appearance getAppearance(int model_id) { + return appearances.get(model_id).getData(); } @Override - public @NotNull List getSprites(Direction dir, long seed) { - return getAppearance(seed).sprites().get(dir); + public @NotNull List getSprites(Direction dir, int model_id) { + return getAppearance(model_id).sprites().get(dir); } @Override - public boolean hasColor(Direction dir, long seed, int index) { - List properties = getSprites(dir, seed); + public boolean hasColor(Direction dir, int model_id, int index) { + List properties = getSprites(dir, model_id); if (index != 0) index = properties.size() - index; return properties.get(index).has_colors(); } @@ -59,13 +46,7 @@ public class WeightedComputedAppearance implements CamoAppearance { @Override public boolean equals(Object o) { if(this == o) return true; - if(o == null || getClass() != o.getClass()) return false; - WeightedComputedAppearance that = (WeightedComputedAppearance) o; + if(!(o instanceof WeightedComputedAppearance that)) return false; return id == that.id; } - - @Override - public int hashCode() { - return id; - } } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java index 6db8bd1..c233590 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java @@ -41,6 +41,7 @@ public class BlockItemMixin { || !Block.isShapeFullCube(block.getBlock().getDefaultState().getCollisionShape(world, pos)) ) return; NbtCompound new_comp = new NbtCompound(); + player.getOffHandStack().decrement(1); new_comp.put(BLOCKSTATE_KEY + 1, NbtHelper.fromBlockState(block.getBlock().getDefaultState())); compound.set(new_comp); } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java index ba6833d..aac9f62 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java @@ -6,7 +6,7 @@ import earth.terrarium.athena.api.client.models.AthenaBlockModel; import fr.adrien1106.reframed.client.ReFramedClient; import fr.adrien1106.reframed.client.model.DynamicBakedModel; import fr.adrien1106.reframed.compat.RebakedAthenaModel; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaConnectedBlockModelMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaConnectedBlockModelMixin.java index efc633b..ce1e96c 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaConnectedBlockModelMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaConnectedBlockModelMixin.java @@ -3,7 +3,7 @@ package fr.adrien1106.reframed.mixin.compat; import earth.terrarium.athena.api.client.utils.AppearanceAndTintGetter; import earth.terrarium.athena.api.client.utils.CtmUtils; import earth.terrarium.athena.impl.client.models.ConnectedBlockModel; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaWrappedGetterMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaWrappedGetterMixin.java index 73e1ea7..bb31415 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaWrappedGetterMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaWrappedGetterMixin.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.compat; import com.llamalad7.mixinextras.sugar.Local; import earth.terrarium.athena.api.client.fabric.WrappedGetter; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.BlockRenderView; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java index 4f6ec46..6922006 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java @@ -1,8 +1,8 @@ package fr.adrien1106.reframed.mixin.compat; -import fr.adrien1106.reframed.util.BlockHelper; -import fr.adrien1106.reframed.util.IBlockRenderInfoMixin; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import link.infra.indium.renderer.render.BlockRenderInfo; import link.infra.indium.renderer.render.TerrainBlockRenderInfo; import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockOcclusionCache; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java index c7ebd61..fcbce7f 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java @@ -1,11 +1,12 @@ package fr.adrien1106.reframed.mixin.compat; import fr.adrien1106.reframed.client.model.MultiRetexturableModel; -import fr.adrien1106.reframed.util.IBlockRenderInfoMixin; -import fr.adrien1106.reframed.util.IMultipartBakedModelMixin; +import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; +import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin; import link.infra.indium.renderer.render.AbstractBlockRenderContext; import link.infra.indium.renderer.render.TerrainRenderContext; import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockRenderContext; +import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.minecraft.client.render.model.BakedModel; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -29,13 +30,13 @@ public abstract class IndiumTerrainRenderContextMixin extends AbstractBlockRende if (!(ctx.model() instanceof IMultipartBakedModelMixin wrapped) || !(wrapped.getModel(ctx.state()) instanceof MultiRetexturableModel retexturing_model)) return; - List models = retexturing_model.models(); + List models = retexturing_model.models(); int i = 0; - for (BakedModel bakedModel : models) { + for (BakedModel model : models) { i++; aoCalc.clear(); - ((IBlockRenderInfoMixin) blockInfo).prepareForBlock(ctx.state(), ctx.pos(), ctx.seed(), bakedModel.useAmbientOcclusion(), i); - bakedModel.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this); + ((IBlockRenderInfoMixin) blockInfo).prepareForBlock(ctx.state(), ctx.pos(), ctx.seed(), model.useAmbientOcclusion(), i); + model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this); } ci.cancel(); } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/SodiumBlockOcclusionCacheMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/SodiumBlockOcclusionCacheMixin.java index 437f8a7..3e6c28d 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/SodiumBlockOcclusionCacheMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/SodiumBlockOcclusionCacheMixin.java @@ -1,8 +1,8 @@ package fr.adrien1106.reframed.mixin.compat; import com.llamalad7.mixinextras.sugar.Local; -import fr.adrien1106.reframed.util.BlockHelper; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockOcclusionCache; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinBlockDustParticle.java b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinBlockDustParticle.java index 5348a91..95e03c0 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinBlockDustParticle.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinBlockDustParticle.java @@ -1,7 +1,7 @@ package fr.adrien1106.reframed.mixin.particles; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.particle.BlockDustParticle; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinEntity.java b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinEntity.java index bbba8fb..bb1afd1 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinEntity.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinEntity.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.particles; import com.llamalad7.mixinextras.sugar.Local; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinLivingEntity.java b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinLivingEntity.java index d19193f..13dba79 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinLivingEntity.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinLivingEntity.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.particles; import com.llamalad7.mixinextras.sugar.Local; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java index 059fb1c..ee4a624 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java @@ -1,9 +1,9 @@ package fr.adrien1106.reframed.mixin.render; import com.llamalad7.mixinextras.sugar.Local; -import fr.adrien1106.reframed.util.BlockHelper; -import fr.adrien1106.reframed.util.IBlockRenderInfoMixin; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderInfo; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/render/MultipartBakedModelMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/render/MultipartBakedModelMixin.java index 86c1819..2183590 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/render/MultipartBakedModelMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/render/MultipartBakedModelMixin.java @@ -1,6 +1,6 @@ package fr.adrien1106.reframed.mixin.render; -import fr.adrien1106.reframed.util.IMultipartBakedModelMixin; +import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin; import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.MultipartBakedModel; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java index 18eac23..37677d5 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java @@ -1,8 +1,9 @@ package fr.adrien1106.reframed.mixin.render; import fr.adrien1106.reframed.client.model.MultiRetexturableModel; -import fr.adrien1106.reframed.util.IBlockRenderInfoMixin; -import fr.adrien1106.reframed.util.IMultipartBakedModelMixin; +import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; +import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin; +import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractBlockRenderContext; import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainRenderContext; import net.minecraft.block.BlockState; @@ -28,13 +29,18 @@ public abstract class TerrainRenderContextMixin extends AbstractBlockRenderConte if (!(wrapper instanceof IMultipartBakedModelMixin wrapped) || !(wrapped.getModel(state) instanceof MultiRetexturableModel retexturing_model)) return; - List models = retexturing_model.models(); + List models = retexturing_model.models(); +// models.forEach(model -> // TODO self culling here +// model.getWrappedModel().getQuads(state_key, null, blockInfo.randomSupplier.get()) +// .forEach(quad -> QuadPosBounds.read(getEmitter().fromVanilla(quad.getVertexData(), 0)).min_x()) +// ); int i = 0; - for (BakedModel bakedModel : models) { + for (BakedModel model : models) { i++; aoCalc.clear(); - ((IBlockRenderInfoMixin) blockInfo).prepareForBlock(state, pos, bakedModel.useAmbientOcclusion(), i); - bakedModel.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this); + // TODO if (state_key.getBlock() instanceof ReFramedDoubleBlock frame_block) frame_block.getRenderOutline(i); + ((IBlockRenderInfoMixin) blockInfo).prepareForBlock(state, pos, model.useAmbientOcclusion(), i); + model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this); } ci.cancel(); } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java index 2ee7502..739adde 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.sound; import com.llamalad7.mixinextras.sugar.Local; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.item.BlockItem; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java index d00f353..ab882df 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.sound; import com.llamalad7.mixinextras.sugar.Local; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java index 1d63f6a..ffcd7c9 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java @@ -1,7 +1,7 @@ package fr.adrien1106.reframed.mixin.sound; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.entity.LivingEntity; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java index 8d2b11d..7f22f6c 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.sound; import com.llamalad7.mixinextras.sugar.Local; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.client.render.WorldRenderer; diff --git a/src/main/java/fr/adrien1106/reframed/util/BlockHelper.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java similarity index 93% rename from src/main/java/fr/adrien1106/reframed/util/BlockHelper.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java index ca18ffb..a1eea54 100644 --- a/src/main/java/fr/adrien1106/reframed/util/BlockHelper.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java @@ -1,9 +1,8 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.blocks; import fr.adrien1106.reframed.block.ReFramedBlock; import fr.adrien1106.reframed.block.ReFramedEntity; -import fr.adrien1106.reframed.util.property.Corner; -import fr.adrien1106.reframed.util.property.StairShape; +import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap; import net.minecraft.block.Block; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockState; @@ -30,13 +29,25 @@ import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -import static fr.adrien1106.reframed.util.BlockProperties.CORNER; -import static fr.adrien1106.reframed.util.BlockProperties.LIGHT; -import static fr.adrien1106.reframed.util.property.StairShape.*; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; +import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static net.minecraft.util.shape.VoxelShapes.combine; public class BlockHelper { + // self culling cache TODO move + private static final ThreadLocal> INNER_FACE_CULL_MAP = ThreadLocal.withInitial(() -> { + Object2ByteLinkedOpenHashMap object2ByteLinkedOpenHashMap = new Object2ByteLinkedOpenHashMap<>(2048, 0.25F) { + protected void rehash(int newN) { + } + }; + object2ByteLinkedOpenHashMap.defaultReturnValue((byte)0); + return object2ByteLinkedOpenHashMap; + }); + + private record CullElement(BlockState state, int model, Direction side) {} + public static Corner getPlacementCorner(ItemPlacementContext ctx) { Direction side = ctx.getSide().getOpposite(); Vec3d pos = getHitPos(ctx.getHitPos(), ctx.getBlockPos()); diff --git a/src/main/java/fr/adrien1106/reframed/util/BlockProperties.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java similarity index 74% rename from src/main/java/fr/adrien1106/reframed/util/BlockProperties.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java index 11aab58..89d0b8d 100644 --- a/src/main/java/fr/adrien1106/reframed/util/BlockProperties.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java @@ -1,7 +1,5 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.blocks; -import fr.adrien1106.reframed.util.property.Corner; -import fr.adrien1106.reframed.util.property.StairShape; import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.EnumProperty; diff --git a/src/main/java/fr/adrien1106/reframed/util/property/Corner.java b/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java similarity index 98% rename from src/main/java/fr/adrien1106/reframed/util/property/Corner.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java index f95b3d0..6c74e9c 100644 --- a/src/main/java/fr/adrien1106/reframed/util/property/Corner.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util.property; +package fr.adrien1106.reframed.util.blocks; import net.minecraft.util.StringIdentifiable; import net.minecraft.util.math.Direction; diff --git a/src/main/java/fr/adrien1106/reframed/util/ReframedInteractible.java b/src/main/java/fr/adrien1106/reframed/util/blocks/ReframedInteractible.java similarity index 93% rename from src/main/java/fr/adrien1106/reframed/util/ReframedInteractible.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/ReframedInteractible.java index 13a7e72..4209add 100644 --- a/src/main/java/fr/adrien1106/reframed/util/ReframedInteractible.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/ReframedInteractible.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.blocks; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/fr/adrien1106/reframed/util/property/StairShape.java b/src/main/java/fr/adrien1106/reframed/util/blocks/StairShape.java similarity index 96% rename from src/main/java/fr/adrien1106/reframed/util/property/StairShape.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/StairShape.java index eef0c51..5019e89 100644 --- a/src/main/java/fr/adrien1106/reframed/util/property/StairShape.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/StairShape.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util.property; +package fr.adrien1106.reframed.util.blocks; import net.minecraft.util.StringIdentifiable; diff --git a/src/main/java/fr/adrien1106/reframed/util/ThemeableBlockEntity.java b/src/main/java/fr/adrien1106/reframed/util/blocks/ThemeableBlockEntity.java similarity index 82% rename from src/main/java/fr/adrien1106/reframed/util/ThemeableBlockEntity.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/ThemeableBlockEntity.java index 2213826..ace75e0 100644 --- a/src/main/java/fr/adrien1106/reframed/util/ThemeableBlockEntity.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/ThemeableBlockEntity.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.blocks; import net.minecraft.block.BlockState; diff --git a/src/main/java/fr/adrien1106/reframed/util/IBlockRenderInfoMixin.java b/src/main/java/fr/adrien1106/reframed/util/mixin/IBlockRenderInfoMixin.java similarity index 87% rename from src/main/java/fr/adrien1106/reframed/util/IBlockRenderInfoMixin.java rename to src/main/java/fr/adrien1106/reframed/util/mixin/IBlockRenderInfoMixin.java index 69aaeb6..57e8ff4 100644 --- a/src/main/java/fr/adrien1106/reframed/util/IBlockRenderInfoMixin.java +++ b/src/main/java/fr/adrien1106/reframed/util/mixin/IBlockRenderInfoMixin.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.mixin; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/fr/adrien1106/reframed/util/IMultipartBakedModelMixin.java b/src/main/java/fr/adrien1106/reframed/util/mixin/IMultipartBakedModelMixin.java similarity index 81% rename from src/main/java/fr/adrien1106/reframed/util/IMultipartBakedModelMixin.java rename to src/main/java/fr/adrien1106/reframed/util/mixin/IMultipartBakedModelMixin.java index 275f01d..8b7a01c 100644 --- a/src/main/java/fr/adrien1106/reframed/util/IMultipartBakedModelMixin.java +++ b/src/main/java/fr/adrien1106/reframed/util/mixin/IMultipartBakedModelMixin.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.mixin; import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BakedModel; -- 2.39.5 From 239802ce7bf59e7a844d78394540e05fbe03f339 Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Wed, 6 Mar 2024 22:16:43 +0100 Subject: [PATCH 02/11] cleanup --- .../reframed/block/ReFramedDoubleSlabBlock.java | 1 - .../reframed/block/ReFramedDoubleStepBlock.java | 8 +++----- .../client/model/DoubleRetexturingBakedModel.java | 1 - .../reframed/client/model/MultiRetexturableModel.java | 1 - .../java/fr/adrien1106/reframed/mixin/BlockItemMixin.java | 2 -- .../reframed/mixin/render/TerrainRenderContextMixin.java | 1 - 6 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java index a7f4292..56238d3 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java @@ -13,7 +13,6 @@ import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; import net.minecraft.item.ItemPlacementContext; import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.state.StateManager; -import net.minecraft.state.property.Properties; import net.minecraft.util.Identifier; import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java index 453dc0f..f9ef5c3 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java @@ -1,11 +1,9 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; -import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.util.blocks.BlockHelper; -import fr.adrien1106.reframed.util.blocks.Corner; -import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -26,11 +24,11 @@ import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.BlockView; import org.jetbrains.annotations.Nullable; -import static fr.adrien1106.reframed.block.ReFramedSlabBlock.*; +import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape; import static fr.adrien1106.reframed.block.ReFramedStepBlock.STEP_VOXELS; import static net.minecraft.data.client.VariantSettings.Rotation.*; -import static net.minecraft.state.property.Properties.FACING; import static net.minecraft.state.property.Properties.AXIS; +import static net.minecraft.state.property.Properties.FACING; import static net.minecraft.util.shape.VoxelShapes.empty; public class ReFramedDoubleStepBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { diff --git a/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java index 29ff44b..a50806c 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java @@ -5,7 +5,6 @@ import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.minecraft.block.BlockState; -import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.texture.Sprite; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java b/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java index bcd46de..17ea436 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java @@ -1,7 +1,6 @@ package fr.adrien1106.reframed.client.model; import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; -import net.minecraft.client.render.model.BakedModel; import java.util.List; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java index c233590..53f3ea6 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java @@ -23,8 +23,6 @@ import static fr.adrien1106.reframed.block.ReFramedEntity.BLOCKSTATE_KEY; @Mixin(BlockItem.class) public class BlockItemMixin { - @Shadow @Final @Deprecated private Block block; - @Inject( method = "writeNbtToBlockEntity", at = @At( diff --git a/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java index 37677d5..eff178f 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java @@ -38,7 +38,6 @@ public abstract class TerrainRenderContextMixin extends AbstractBlockRenderConte for (BakedModel model : models) { i++; aoCalc.clear(); - // TODO if (state_key.getBlock() instanceof ReFramedDoubleBlock frame_block) frame_block.getRenderOutline(i); ((IBlockRenderInfoMixin) blockInfo).prepareForBlock(state, pos, model.useAmbientOcclusion(), i); model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this); } -- 2.39.5 From e6c9ee63cd5d00982a52ffc312b0ad45bfa22a31 Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Fri, 8 Mar 2024 20:38:14 +0100 Subject: [PATCH 03/11] self culling !! --- .../reframed/client/model/QuadPosBounds.java | 11 +++ .../client/model/RetexturingBakedModel.java | 16 ++-- .../model/apperance/CamoAppearance.java | 7 +- .../reframed/mixin/BlockItemMixin.java | 2 - .../reframed/mixin/CompatMixinPlugin.java | 4 +- ...IndiumAbstractBlockRenderContextMixin.java | 29 +++++++ .../IndiumTerrainBlockRenderInfoMixin.java | 7 +- .../IndiumTerrainRenderContextMixin.java | 2 + .../AbstractBlockRenderContextMixin.java | 36 ++++++++ .../mixin/render/BlockRenderInfoMixin.java | 8 +- .../render/TerrainRenderContextMixin.java | 6 +- .../reframed/util/blocks/BlockHelper.java | 87 ++++++++++++++++--- .../util/mixin/IBlockRenderInfoMixin.java | 2 + src/main/resources/fabric.mod.json | 2 +- src/main/resources/reframed.mixins.json | 2 + 15 files changed, 188 insertions(+), 33 deletions(-) create mode 100644 src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumAbstractBlockRenderContextMixin.java create mode 100644 src/main/java/fr/adrien1106/reframed/mixin/render/AbstractBlockRenderContextMixin.java diff --git a/src/main/java/fr/adrien1106/reframed/client/model/QuadPosBounds.java b/src/main/java/fr/adrien1106/reframed/client/model/QuadPosBounds.java index 392a9f4..87a61c9 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/QuadPosBounds.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/QuadPosBounds.java @@ -76,4 +76,15 @@ public record QuadPosBounds(float min_x, float max_x, float min_y, float max_y, quad.pos(i, pos); } } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof QuadPosBounds other)) return false; + return MathHelper.approximatelyEquals(min_x, other.min_x) + && MathHelper.approximatelyEquals(min_y, other.min_y) + && MathHelper.approximatelyEquals(min_z, other.min_z) + && MathHelper.approximatelyEquals(max_x, other.max_x) + && MathHelper.approximatelyEquals(max_y, other.max_y) + && MathHelper.approximatelyEquals(max_z, other.max_z); + } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java index 0e18f93..a9e1232 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java @@ -9,10 +9,7 @@ import fr.adrien1106.reframed.client.model.apperance.CamoAppearanceManager; import fr.adrien1106.reframed.client.model.apperance.WeightedComputedAppearance; import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; -import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; -import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.renderer.v1.mesh.*; import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.minecraft.block.BlockState; @@ -27,6 +24,7 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; public abstract class RetexturingBakedModel extends ForwardingBakedModel { @@ -167,12 +165,15 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { MeshBuilder builder = ReFramedClient.HELPER.getFabricRenderer().meshBuilder(); QuadEmitter emitter = builder.getEmitter(); + AtomicInteger quad_index = new AtomicInteger(); getBaseMesh(key.state_key, state).forEach(quad -> { int i = -1; do { emitter.copyFrom(quad); - i = key.appearance.transformQuad(emitter, i, key.model_id, ao, uv_lock); + i = key.appearance.transformQuad(emitter, i, quad_index.get(), key.model_id, ao, uv_lock); } while (i > 0); + // kinda weird to do it like that but other directions don't use the quad_index so it doesn't matter + if (quad.cullFace() == null) quad_index.getAndIncrement(); }); return builder.build(); @@ -191,9 +192,10 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { @Override public boolean transform(MutableQuadView quad) { - if(quad.tag() == 0) return true; + int camo_quad_index = quad.tag() - ((quad.tag() >>> 8) << 8); + if(camo_quad_index == 0) return true; - if(appearance.hasColor(quad.nominalFace(), model_id, quad.tag())) quad.color(tint, tint, tint, tint); + if(appearance.hasColor(quad.nominalFace(), model_id, camo_quad_index)) quad.color(tint, tint, tint, tint); return true; } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java index 1e71f1b..9ac9b06 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java @@ -28,7 +28,7 @@ public abstract class CamoAppearance { return ao && ao_material != null? ao_material : material; } - public int transformQuad(QuadEmitter quad, int i, int model_id, boolean ao, boolean uv_lock) { + public int transformQuad(QuadEmitter quad, int i, int quad_index, int model_id, boolean ao, boolean uv_lock) { if(quad.tag() == 0) return 0; // Pass the quad through unmodified. Direction direction = quad.nominalFace(); @@ -36,6 +36,7 @@ public abstract class CamoAppearance { if (i == -1) i = sprites.size(); SpriteProperties properties = sprites.get(sprites.size() - i); + int tag = i + (quad_index << 8); i--; QuadPosBounds bounds = properties.bounds(); @@ -47,7 +48,7 @@ public abstract class CamoAppearance { | properties.flags() | (uv_lock ? MutableQuadView.BAKE_LOCK_UV : 0) ); - quad.tag(i+1); + quad.tag(tag); quad.emit(); return i; } @@ -64,7 +65,7 @@ public abstract class CamoAppearance { MutableQuadView.BAKE_NORMALIZED | MutableQuadView.BAKE_LOCK_UV ); - quad.tag(i+1); + quad.tag(tag); quad.emit(); return i; } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java index 53f3ea6..7e081da 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java @@ -11,9 +11,7 @@ import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtHelper; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -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; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/CompatMixinPlugin.java b/src/main/java/fr/adrien1106/reframed/mixin/CompatMixinPlugin.java index da1115b..a0a36a5 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/CompatMixinPlugin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/CompatMixinPlugin.java @@ -21,9 +21,11 @@ public class CompatMixinPlugin implements IMixinConfigPlugin { "fr.adrien1106.reframed.mixin.compat.AthenaBakedModelMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(0)), "fr.adrien1106.reframed.mixin.compat.AthenaWrappedGetterMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(0)), "fr.adrien1106.reframed.mixin.render.TerrainRenderContextMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)), - "fr.adrien1106.reframed.mixin.compat.IndiumTerrainRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)), "fr.adrien1106.reframed.mixin.render.BlockRenderInfoMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)), + "fr.adrien1106.reframed.mixin.render.AbstractBlockRenderContextMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)), + "fr.adrien1106.reframed.mixin.compat.IndiumTerrainRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)), "fr.adrien1106.reframed.mixin.compat.IndiumTerrainBlockRenderInfoMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)), + "fr.adrien1106.reframed.mixin.compat.IndiumAbstractBlockRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)), "fr.adrien1106.reframed.mixin.compat.SodiumBlockOcclusionCacheMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(2)) ); diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumAbstractBlockRenderContextMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumAbstractBlockRenderContextMixin.java new file mode 100644 index 0000000..e9d2f43 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumAbstractBlockRenderContextMixin.java @@ -0,0 +1,29 @@ +package fr.adrien1106.reframed.mixin.compat; + +import com.llamalad7.mixinextras.sugar.Local; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; +import link.infra.indium.renderer.mesh.MutableQuadViewImpl; +import link.infra.indium.renderer.render.AbstractBlockRenderContext; +import link.infra.indium.renderer.render.BlockRenderInfo; +import net.minecraft.util.math.Direction; +import org.jetbrains.annotations.Nullable; +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.Redirect; + +@Mixin(AbstractBlockRenderContext.class) +public abstract class IndiumAbstractBlockRenderContextMixin { + + @Shadow(remap = false) protected BlockRenderInfo blockInfo; + + @Shadow public abstract boolean isFaceCulled(@Nullable Direction face); + + @Redirect(method = "renderQuad", at = @At(value = "INVOKE", target = "Llink/infra/indium/renderer/render/AbstractBlockRenderContext;isFaceCulled(Lnet/minecraft/util/math/Direction;)Z")) + private boolean shouldDrawInnerQuad(AbstractBlockRenderContext instance, Direction face, @Local(argsOnly = true) MutableQuadViewImpl quad) { + if (face != null || quad.tag() == 0 || !(blockInfo instanceof IBlockRenderInfoMixin info) || info.getThemeIndex() == 0) return isFaceCulled(face); + + return !BlockHelper.shouldDrawInnerFace(blockInfo.blockState, blockInfo.blockView, blockInfo.blockPos, quad.tag() >>> 8, info.getThemeIndex()); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java index 6922006..1fef1c3 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java @@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(TerrainBlockRenderInfo.class) public abstract class IndiumTerrainBlockRenderInfoMixin extends BlockRenderInfo implements IBlockRenderInfoMixin { - @Unique private int theme_index = 1; + @Unique private int theme_index = 0; @Redirect( method = "shouldDrawFaceInner", @@ -40,4 +40,9 @@ public abstract class IndiumTerrainBlockRenderInfoMixin extends BlockRenderInfo this.theme_index = theme_index; prepareForBlock(blockState, blockPos, seed, modelAo); } + + @Override + public int getThemeIndex() { + return theme_index; + } } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java index fcbce7f..42c5534 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java @@ -1,6 +1,7 @@ package fr.adrien1106.reframed.mixin.compat; import fr.adrien1106.reframed.client.model.MultiRetexturableModel; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin; import link.infra.indium.renderer.render.AbstractBlockRenderContext; @@ -31,6 +32,7 @@ public abstract class IndiumTerrainRenderContextMixin extends AbstractBlockRende || !(wrapped.getModel(ctx.state()) instanceof MultiRetexturableModel retexturing_model)) return; List models = retexturing_model.models(); + BlockHelper.computeInnerCull(ctx.state(), models); int i = 0; for (BakedModel model : models) { i++; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/render/AbstractBlockRenderContextMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/render/AbstractBlockRenderContextMixin.java new file mode 100644 index 0000000..6d02c28 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/mixin/render/AbstractBlockRenderContextMixin.java @@ -0,0 +1,36 @@ +package fr.adrien1106.reframed.mixin.render; + +import com.llamalad7.mixinextras.sugar.Local; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; +import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl; +import net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractBlockRenderContext; +import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderInfo; +import net.minecraft.util.math.Direction; +import org.jetbrains.annotations.Nullable; +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; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(AbstractBlockRenderContext.class) +public abstract class AbstractBlockRenderContextMixin { + + @Shadow public abstract boolean isFaceCulled(@Nullable Direction face); + + @Shadow(remap = false) @Final protected BlockRenderInfo blockInfo; + + @Redirect( + method = "renderQuad", + at = @At( + value = "INVOKE", + target = "Lnet/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractBlockRenderContext;isFaceCulled(Lnet/minecraft/util/math/Direction;)Z" + ) + ) + private boolean shouldDrawInnerQuad(AbstractBlockRenderContext instance, Direction face, @Local(argsOnly = true) MutableQuadViewImpl quad) { + if (face != null || quad.tag() == 0 || !(blockInfo instanceof IBlockRenderInfoMixin info) || info.getThemeIndex() == 0) return isFaceCulled(face); + + return !BlockHelper.shouldDrawInnerFace(blockInfo.blockState, blockInfo.blockView, blockInfo.blockPos, quad.tag() >>> 8, info.getThemeIndex()); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java index ee4a624..9a5485c 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java @@ -24,8 +24,7 @@ public abstract class BlockRenderInfoMixin implements IBlockRenderInfoMixin { @Shadow public abstract void prepareForBlock(BlockState blockState, BlockPos blockPos, boolean modelAo); @Shadow public BlockRenderView blockView; - @Unique - private int theme_index = 1; + @Unique private int theme_index = 0; @ModifyArg(method = "prepareForBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/RenderLayers;" + @@ -47,4 +46,9 @@ public abstract class BlockRenderInfoMixin implements IBlockRenderInfoMixin { this.theme_index = theme_index; prepareForBlock(state, pos, ao); } + + @Override + public int getThemeIndex() { + return theme_index; + } } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java index eff178f..ddb93ef 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java @@ -1,6 +1,7 @@ package fr.adrien1106.reframed.mixin.render; import fr.adrien1106.reframed.client.model.MultiRetexturableModel; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin; import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; @@ -30,10 +31,7 @@ public abstract class TerrainRenderContextMixin extends AbstractBlockRenderConte || !(wrapped.getModel(state) instanceof MultiRetexturableModel retexturing_model)) return; List models = retexturing_model.models(); -// models.forEach(model -> // TODO self culling here -// model.getWrappedModel().getQuads(state_key, null, blockInfo.randomSupplier.get()) -// .forEach(quad -> QuadPosBounds.read(getEmitter().fromVanilla(quad.getVertexData(), 0)).min_x()) -// ); + BlockHelper.computeInnerCull(state, models); int i = 0; for (BakedModel model : models) { i++; diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java index a1eea54..99f8652 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java @@ -1,8 +1,15 @@ package fr.adrien1106.reframed.util.blocks; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import fr.adrien1106.reframed.block.ReFramedBlock; import fr.adrien1106.reframed.block.ReFramedEntity; -import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap; +import fr.adrien1106.reframed.client.ReFramedClient; +import fr.adrien1106.reframed.client.model.QuadPosBounds; +import net.fabricmc.fabric.api.renderer.v1.Renderer; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.minecraft.block.Block; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockState; @@ -18,14 +25,17 @@ import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.random.Random; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockRenderView; import net.minecraft.world.BlockView; import net.minecraft.world.World; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -36,17 +46,10 @@ import static net.minecraft.util.shape.VoxelShapes.combine; public class BlockHelper { - // self culling cache TODO move - private static final ThreadLocal> INNER_FACE_CULL_MAP = ThreadLocal.withInitial(() -> { - Object2ByteLinkedOpenHashMap object2ByteLinkedOpenHashMap = new Object2ByteLinkedOpenHashMap<>(2048, 0.25F) { - protected void rehash(int newN) { - } - }; - object2ByteLinkedOpenHashMap.defaultReturnValue((byte)0); - return object2ByteLinkedOpenHashMap; - }); + // self culling cache of the models not made thread local so that it is only computed once + private static final Cache INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).concurrencyLevel().build(); - private record CullElement(BlockState state, int model, Direction side) {} + private record CullElement(Object state_key, int model) {} public static Corner getPlacementCorner(ItemPlacementContext ctx) { Direction side = ctx.getSide().getOpposite(); @@ -69,7 +72,7 @@ public class BlockHelper { Math.abs(axis_1.choose(pos.x, pos.y, pos.z)) > Math.abs(axis_2.choose(pos.x, pos.y, pos.z)) ? axis_1 : axis_2 - ).get(); + ).orElse(null); } public static Vec3d getRelativePos(Vec3d pos, BlockPos block_pos) { @@ -216,6 +219,66 @@ public class BlockHelper { return ActionResult.PASS; } + /** + * compute which quad might cull with another model quad + * @param state - the state of the model + * @param models - list of models on the same block + */ + public static void computeInnerCull(BlockState state, List models) { + if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return; + Object key = frame_block.getModelCacheKey(state); + if (INNER_CULL_MAP.asMap().containsKey(new CullElement(key, 1))) return; + + Renderer r = ReFramedClient.HELPER.getFabricRenderer(); + QuadEmitter quad_emitter = r.meshBuilder().getEmitter(); + RenderMaterial material = r.materialFinder().clear().find(); + Random random = Random.create(); + + List> model_bounds = models.stream() + .map(ForwardingBakedModel::getWrappedModel) + .filter(Objects::nonNull) + .map(wrapped -> wrapped.getQuads(state, null, random)) + .map(quads -> quads.stream().map(quad -> { + quad_emitter.fromVanilla(quad, material, null); + return QuadPosBounds.read(quad_emitter, false); + }).toList()).toList(); + + Integer[] cull_array; + for(int self_id = 1; self_id <= model_bounds.size(); self_id++) { + List self_bounds = model_bounds.get(self_id - 1); + cull_array = new Integer[self_bounds.size()]; + for (int self_quad = 0; self_quad < cull_array.length; self_quad++) { + QuadPosBounds self_bound = self_bounds.get(self_quad); + for(int other_id = 1; other_id <= model_bounds.size(); other_id++) { + if (other_id == self_id) continue; + if (model_bounds.get(other_id - 1).stream().anyMatch(other_bound -> other_bound.equals(self_bound))) { + cull_array[self_quad] = other_id; + break; + } + } + } + INNER_CULL_MAP.put(new CullElement(key, self_id), cull_array); + } + } + + public static boolean shouldDrawInnerFace(BlockState state, BlockRenderView view, BlockPos pos, int quad_index, int theme_index) { + if ( !(state.getBlock() instanceof ReFramedBlock frame_block) + || !(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity) + ) return true; + CullElement key = new CullElement(frame_block.getModelCacheKey(state), theme_index); + if (!INNER_CULL_MAP.asMap().containsKey(key)) return true; + + // needs to be Integer object because array is initialized with null not 0 + Integer cull_theme = Objects.requireNonNull(INNER_CULL_MAP.getIfPresent(key))[quad_index]; + if (cull_theme == null) return true; // no culling possible + + BlockState self_theme = frame_entity.getTheme(theme_index); + BlockState other_theme = frame_entity.getTheme(cull_theme); + + if (self_theme.isSideInvisible(other_theme, null)) return false; + return !self_theme.isOpaque() || !other_theme.isOpaque(); + } + // Doing this method from scratch as it is simpler to do than injecting everywhere public static boolean shouldDrawSide(BlockState self_state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, int theme_index) { ThemeableBlockEntity self = world.getBlockEntity(pos) instanceof ThemeableBlockEntity e ? e : null; diff --git a/src/main/java/fr/adrien1106/reframed/util/mixin/IBlockRenderInfoMixin.java b/src/main/java/fr/adrien1106/reframed/util/mixin/IBlockRenderInfoMixin.java index 57e8ff4..30e0672 100644 --- a/src/main/java/fr/adrien1106/reframed/util/mixin/IBlockRenderInfoMixin.java +++ b/src/main/java/fr/adrien1106/reframed/util/mixin/IBlockRenderInfoMixin.java @@ -8,4 +8,6 @@ public interface IBlockRenderInfoMixin { void prepareForBlock(BlockState state, BlockPos pos, boolean ao, int theme_index); void prepareForBlock(BlockState state, BlockPos pos, long seed, boolean ao, int theme_index); + + int getThemeIndex(); } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index b96c19f..ce39b5b 100755 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -30,7 +30,7 @@ "fabricloader": "^${loader_version}", "fabric-api": "*" }, - "suggest": { + "suggests": { "athena": "^${athena_version}", "sodium": "^${sodium_version}", "indium": "^${indium_version}" diff --git a/src/main/resources/reframed.mixins.json b/src/main/resources/reframed.mixins.json index b0280b4..059e59b 100644 --- a/src/main/resources/reframed.mixins.json +++ b/src/main/resources/reframed.mixins.json @@ -14,6 +14,7 @@ "compat.AthenaBakedModelMixin", "compat.AthenaConnectedBlockModelMixin", "compat.AthenaWrappedGetterMixin", + "compat.IndiumAbstractBlockRenderContextMixin", "compat.IndiumTerrainBlockRenderInfoMixin", "compat.IndiumTerrainRenderContextMixin", "compat.SodiumBlockOcclusionCacheMixin", @@ -21,6 +22,7 @@ "particles.AccessorParticle", "particles.AccessorSpriteBillboardParticle", "particles.MixinBlockDustParticle", + "render.AbstractBlockRenderContextMixin", "render.BlockRenderInfoMixin", "render.MultipartBakedModelMixin", "render.TerrainRenderContextMixin", -- 2.39.5 From 394c75f9edcb8a70b56347e490c17a5a12f99053 Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Fri, 8 Mar 2024 20:45:11 +0100 Subject: [PATCH 04/11] fix error + cleanup --- src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java | 2 +- .../reframed/client/model/UnbakedRetexturedModel.java | 2 +- src/main/java/fr/adrien1106/reframed/generator/GLanguage.java | 4 +--- .../java/fr/adrien1106/reframed/util/blocks/BlockHelper.java | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java index c75b6a9..05e7aef 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java @@ -115,7 +115,7 @@ public class ReFramedBlock extends Block implements BlockEntityProvider, RecipeS && themes.stream().noneMatch(theme -> theme.getLuminance() != 0)) drops.add(new ItemStack(Items.GLOWSTONE_DUST)); if(!frame_entity.isSolid() - && themes.stream().anyMatch(theme -> theme.isSolid())) + && themes.stream().anyMatch(AbstractBlockState::isSolid)) drops.add(new ItemStack(Items.POPPED_CHORUS_FRUIT)); ItemScatterer.spawn(world, pos, drops); diff --git a/src/main/java/fr/adrien1106/reframed/client/model/UnbakedRetexturedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/UnbakedRetexturedModel.java index 8345833..948cd0f 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/UnbakedRetexturedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/UnbakedRetexturedModel.java @@ -14,7 +14,7 @@ public abstract class UnbakedRetexturedModel implements UnbakedModel { protected int theme_index = 1; protected BlockState item_state; - protected boolean ao = true; + protected final boolean ao = true; public UnbakedRetexturedModel(Identifier parent) { this.parent = parent; diff --git a/src/main/java/fr/adrien1106/reframed/generator/GLanguage.java b/src/main/java/fr/adrien1106/reframed/generator/GLanguage.java index 61dc3fb..d9270fb 100644 --- a/src/main/java/fr/adrien1106/reframed/generator/GLanguage.java +++ b/src/main/java/fr/adrien1106/reframed/generator/GLanguage.java @@ -17,9 +17,7 @@ public class GLanguage extends FabricLanguageProvider { public void generateTranslations(TranslationBuilder builder) { builder.add(Registries.ITEM_GROUP.getKey(ReFramed.ITEM_GROUP).get(), "Frames"); builder.add("advancements.reframed.description", "Get all the frame types."); - ReFramed.BLOCKS.forEach(block -> { - builder.add(block, beautify(Registries.BLOCK.getId(block).getPath()) + " Frame"); - }); + ReFramed.BLOCKS.forEach(block -> builder.add(block, beautify(Registries.BLOCK.getId(block).getPath()) + " Frame")); } private static String beautify(String name) { diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java index 99f8652..6450843 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java @@ -47,7 +47,7 @@ import static net.minecraft.util.shape.VoxelShapes.combine; public class BlockHelper { // self culling cache of the models not made thread local so that it is only computed once - private static final Cache INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).concurrencyLevel().build(); + private static final Cache INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).build(); private record CullElement(Object state_key, int model) {} -- 2.39.5 From 96f08bdd3e20e8b5a8f6e23dfc53280fbf11c1c0 Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Fri, 8 Mar 2024 23:50:17 +0100 Subject: [PATCH 05/11] w.i.p more shapes + more coherent properties name (yes changing again) --- .../java/fr/adrien1106/reframed/ReFramed.java | 38 +-- .../reframed/ReFramedDoubleSmallBlock.java | 132 ++++++++++ .../block/ReFramedDoubleStairsBlock.java | 20 +- .../block/ReFramedDoubleStepBlock.java | 5 + .../reframed/block/ReFramedSmallBlock.java | 124 +++++++++ .../reframed/block/ReFramedStairsBlock.java | 236 +++++++++--------- .../reframed/block/ReFramedStepBlock.java | 44 ++-- .../reframed/client/ReFramedClient.java | 4 + .../reframed/client/model/QuadPosBounds.java | 3 + .../reframed/client/model/QuadUvBounds.java | 3 + .../model/apperance/CamoAppearance.java | 3 + .../apperance/CamoAppearanceManager.java | 3 + .../model/apperance/ComputedAppearance.java | 3 + .../apperance/SingleSpriteAppearance.java | 3 + .../apperance/WeightedComputedAppearance.java | 3 + .../reframed/util/blocks/BlockHelper.java | 60 +++-- .../reframed/util/blocks/BlockProperties.java | 1 + .../reframed/util/blocks/Corner.java | 55 ++-- .../adrien1106/reframed/util/blocks/Edge.java | 86 +++++++ .../reframed/models/block/small_cube.json | 35 +++ 20 files changed, 637 insertions(+), 224 deletions(-) create mode 100644 src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java create mode 100644 src/main/java/fr/adrien1106/reframed/block/ReFramedSmallBlock.java create mode 100644 src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java create mode 100644 src/main/resources/assets/reframed/models/block/small_cube.json diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index daee2ba..80b942e 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -1,7 +1,6 @@ package fr.adrien1106.reframed; import fr.adrien1106.reframed.block.*; -import fr.adrien1106.reframed.util.blocks.BlockHelper; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; @@ -25,16 +24,22 @@ import java.util.ArrayList; import java.util.function.BiConsumer; import java.util.stream.Collectors; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; + /** - * TODO self culling - * TODO fix other models + * TODO add Hammer from framed ( removes theme ) for sure + * TODO add screwdriver ( iterate over theme states ) ? + * TODO add blueprint for survival friendly copy paste of a theme. + * TODO fix other models ( + half stair ) + * TODO get better naming for the shapes (will break a lot of already placed blocks) + * TODO put more coherence in the double theme orders / directions * TODO better connected textures */ public class ReFramed implements ModInitializer { public static final String MODID = "reframed"; public static final ArrayList BLOCKS = new ArrayList<>(); - public static Block CUBE, STAIRS, DOUBLE_STAIRS, SLAB, DOUBLE_SLAB, STEP, DOUBLE_STEP; + public static Block CUBE, SMALL_CUBE, DOUBLE_SMALL_CUBE, STAIRS, DOUBLE_STAIRS, SLAB, DOUBLE_SLAB, STEP, DOUBLE_STEP; public static ItemGroup ITEM_GROUP; public static BlockEntityType REFRAMED_BLOCK_ENTITY; @@ -44,18 +49,17 @@ public class ReFramed implements ModInitializer { @Override public void onInitialize() { - //registerReFramed mutates FRAMES as a side effect, which is a List, so order is preserved - //the ordering is used in the creative tab, so they're roughly sorted by encounter order of the - //corresponding vanilla block in the "search" creative tab... with the non-vanilla "post" and - //"vertical slab" inserted where they fit ...and i moved the lever way up next to the pressureplate - //and button, because they're redstoney... hopefully this ordering makes sense lol - CUBE = registerReFramed("cube" , new ReFramedBlock(cp(Blocks.OAK_PLANKS))); - STAIRS = registerReFramed("stairs" , new ReFramedStairsBlock(cp(Blocks.OAK_STAIRS))); - DOUBLE_STAIRS = registerReFramed("double_stairs" , new ReFramedDoubleStairsBlock(cp(Blocks.OAK_STAIRS))); - SLAB = registerReFramed("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB))); - DOUBLE_SLAB = registerReFramed("double_slab" , new ReFramedDoubleSlabBlock(cp(Blocks.OAK_SLAB))); - STEP = registerReFramed("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB))); - DOUBLE_STEP = registerReFramed("double_step" , new ReFramedDoubleStepBlock(cp(Blocks.OAK_SLAB))); + CUBE = registerReFramed("cube" , new ReFramedBlock(cp(Blocks.OAK_PLANKS))); + SMALL_CUBE = registerReFramed("small_cube" , new ReFramedSmallBlock(cp(Blocks.OAK_PLANKS))); + DOUBLE_SMALL_CUBE = registerReFramed("double_small_cube" , new ReFramedDoubleSmallBlock(cp(Blocks.OAK_PLANKS))); + STAIRS = registerReFramed("stairs" , new ReFramedStairsBlock(cp(Blocks.OAK_STAIRS))); + DOUBLE_STAIRS = registerReFramed("double_stairs" , new ReFramedDoubleStairsBlock(cp(Blocks.OAK_STAIRS))); +// CUBE = registerReFramed("half_stairs" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO +// CUBE = registerReFramed("double_half_stairs", new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO + SLAB = registerReFramed("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB))); + DOUBLE_SLAB = registerReFramed("double_slab" , new ReFramedDoubleSlabBlock(cp(Blocks.OAK_SLAB))); + STEP = registerReFramed("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB))); + DOUBLE_STEP = registerReFramed("double_step" , new ReFramedDoubleStepBlock(cp(Blocks.OAK_SLAB))); REFRAMED_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, id("camo"), FabricBlockEntityTypeBuilder.create( @@ -82,7 +86,7 @@ public class ReFramed implements ModInitializer { private static AbstractBlock.Settings cp(Block base) { return AbstractBlock.Settings.copy(base) - .luminance(BlockHelper::luminance) + .luminance(state -> state.contains(LIGHT) && state.get(LIGHT) ? 15 : 0) .nonOpaque() .sounds(BlockSoundGroup.WOOD) .hardness(0.2f) diff --git a/src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java b/src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java new file mode 100644 index 0000000..5951c90 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java @@ -0,0 +1,132 @@ +package fr.adrien1106.reframed; + +import fr.adrien1106.reframed.block.WaterloggableReFramedDoubleBlock; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.generator.GBlockstate; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Edge; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.BlockStateSupplier; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.state.StateManager; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import org.jetbrains.annotations.Nullable; + +import static fr.adrien1106.reframed.block.ReFramedSmallBlock.SMALL_CUBE_VOXELS; +import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; +import static fr.adrien1106.reframed.util.blocks.Edge.*; +import static net.minecraft.data.client.VariantSettings.Rotation.*; + +public class ReFramedDoubleSmallBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { + + public ReFramedDoubleSmallBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return state.get(EDGE); + } + + @Override + public int getModelStateCount() { + return 12; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(EDGE)); + } + + @Nullable + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + return super.getPlacementState(ctx).with(EDGE, BlockHelper.getPlacementEdge(ctx)); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return getStepShape(state.get(EDGE)); + } + + @Override // TODO + public VoxelShape getShape(BlockState state, int i) { + return switch (state.get(EDGE)) { + case NORTH_DOWN -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 3); + case DOWN_SOUTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 1 : 2); + case SOUTH_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 5 : 6); + case UP_NORTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 4 : 7); + case WEST_DOWN -> SMALL_CUBE_VOXELS.get(i == 1 ? 2 : 3); + case DOWN_EAST -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 1); + case EAST_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 4 : 5); + case UP_WEST -> SMALL_CUBE_VOXELS.get(i == 1 ? 6 : 7); + case WEST_NORTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 3 : 7); + case NORTH_EAST -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 4); + case EAST_SOUTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 1 : 5); + case SOUTH_WEST -> SMALL_CUBE_VOXELS.get(i == 1 ? 2 : 6); + }; + } + + @Override + public int getTopThemeIndex(BlockState state) { + return super.getTopThemeIndex(state); // TODO + } + + @Override // TODO + public BlockStateSupplier getMultipart() { + Identifier small_cube_id = ReFramed.id("double_small_cube_special"); + return MultipartBlockStateSupplier.create(this) + /* X AXIS */ + .with(GBlockstate.when(EDGE, DOWN_EAST), + GBlockstate.variant(small_cube_id, true, R0, R0)) + .with(GBlockstate.when(EDGE, EAST_UP), + GBlockstate.variant(small_cube_id, true, R180, R0)) + .with(GBlockstate.when(EDGE, UP_WEST), + GBlockstate.variant(small_cube_id, true, R180, R180)) + .with(GBlockstate.when(EDGE, WEST_DOWN), + GBlockstate.variant(small_cube_id, true, R0, R180)) + /* Y AXIS */ + .with(GBlockstate.when(EDGE, EAST_SOUTH), + GBlockstate.variant(small_cube_id, true, R90, R0)) + .with(GBlockstate.when(EDGE, SOUTH_WEST), + GBlockstate.variant(small_cube_id, true, R90, R90)) + .with(GBlockstate.when(EDGE, WEST_NORTH), + GBlockstate.variant(small_cube_id, true, R90, R180)) + .with(GBlockstate.when(EDGE, NORTH_EAST), + GBlockstate.variant(small_cube_id, true, R90, R270)) + /* Z AXIS */ + .with(GBlockstate.when(EDGE, DOWN_SOUTH), + GBlockstate.variant(small_cube_id, true, R0, R90)) + .with(GBlockstate.when(EDGE, NORTH_DOWN), + GBlockstate.variant(small_cube_id, true, R0, R270)) + .with(GBlockstate.when(EDGE, UP_NORTH), + GBlockstate.variant(small_cube_id, true, R180, R270)) + .with(GBlockstate.when(EDGE, SOUTH_UP), + GBlockstate.variant(small_cube_id, true, R180, R90)); + } + + @Override + public void setRecipe(RecipeExporter exporter) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 4); + ShapedRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, this) + .pattern("II") + .input('I', ReFramed.SMALL_CUBE) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) + .offerTo(exporter); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java index 6dda2df..c018372 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java @@ -3,7 +3,7 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.util.blocks.BlockHelper; -import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.Edge; import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; @@ -28,22 +28,22 @@ import java.util.ArrayList; import java.util.List; import static fr.adrien1106.reframed.block.ReFramedStairsBlock.*; -import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE; public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements BlockStateProvider { private static final List COMPLEMENT_LIST = new ArrayList<>(52); - private record ModelCacheKey(Corner corner, StairShape shape) {} + private record ModelCacheKey(Edge edge, StairShape shape) {} public ReFramedDoubleStairsBlock(Settings settings) { super(settings); - setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN).with(STAIR_SHAPE, StairShape.STRAIGHT)); + setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(STAIR_SHAPE, StairShape.STRAIGHT)); } @Override public Object getModelCacheKey(BlockState state) { - return new ModelCacheKey(state.get(CORNER), state.get(STAIR_SHAPE)); + return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE)); } @Override @@ -53,22 +53,22 @@ public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements Bl @Override protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder.add(CORNER, STAIR_SHAPE)); + super.appendProperties(builder.add(EDGE, STAIR_SHAPE)); } @Override public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighbor_state, WorldAccess world, BlockPos pos, BlockPos moved) { return super.getStateForNeighborUpdate(state, direction, neighbor_state, world, pos, moved) - .with(STAIR_SHAPE, BlockHelper.getStairsShape(this, state.get(CORNER), world, pos)); + .with(STAIR_SHAPE, BlockHelper.getStairsShape(this, state.get(EDGE), world, pos)); } @Nullable @Override public BlockState getPlacementState(ItemPlacementContext ctx) { - Corner face = BlockHelper.getPlacementCorner(ctx); + Edge face = BlockHelper.getPlacementEdge(ctx); StairShape shape = BlockHelper.getStairsShape(this, face, ctx.getWorld(), ctx.getBlockPos()); - return super.getPlacementState(ctx).with(CORNER, face).with(STAIR_SHAPE, shape); + return super.getPlacementState(ctx).with(EDGE, face).with(STAIR_SHAPE, shape); } @Override @@ -85,7 +85,7 @@ public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements Bl private VoxelShape getComplementOutline(BlockState state) { StairShape shape = state.get(STAIR_SHAPE); - Corner direction = state.get(CORNER); + Edge direction = state.get(EDGE); return switch (shape) { case STRAIGHT -> switch (direction) { diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java index f9ef5c3..b64c782 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java @@ -85,6 +85,11 @@ public class ReFramedDoubleStepBlock extends WaterloggableReFramedDoubleBlock im }); } + @Override + public int getTopThemeIndex(BlockState state) { + return 2; + } + @Override public MultipartBlockStateSupplier getMultipart() { Identifier step_id = ReFramed.id("double_step_special"); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallBlock.java new file mode 100644 index 0000000..3d18634 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallBlock.java @@ -0,0 +1,124 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.generator.GBlockstate; +import fr.adrien1106.reframed.util.VoxelHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.BlockStateSupplier; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.state.StateManager; +import net.minecraft.util.Identifier; +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.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.Corner.*; +import static net.minecraft.data.client.VariantSettings.Rotation.*; + +public class ReFramedSmallBlock extends WaterloggableReFramedBlock implements BlockStateProvider { + + public static final List SMALL_CUBE_VOXELS = new ArrayList<>(8); + + public ReFramedSmallBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return state.get(CORNER); + } + + @Override + public int getModelStateCount() { + return 8; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(CORNER)); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + return super.getPlacementState(ctx).with(CORNER, BlockHelper.getPlacementCorner(ctx)); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return switch (state.get(CORNER)) { + case NORTH_EAST_DOWN -> SMALL_CUBE_VOXELS.get(0); + case EAST_SOUTH_DOWN -> SMALL_CUBE_VOXELS.get(1); + case SOUTH_WEST_DOWN -> SMALL_CUBE_VOXELS.get(2); + case WEST_NORTH_DOWN -> SMALL_CUBE_VOXELS.get(3); + case NORTH_EAST_UP -> SMALL_CUBE_VOXELS.get(4); + case EAST_SOUTH_UP -> SMALL_CUBE_VOXELS.get(5); + case SOUTH_WEST_UP -> SMALL_CUBE_VOXELS.get(6); + case WEST_NORTH_UP -> SMALL_CUBE_VOXELS.get(7); + }; + } + + @Override + public BlockStateSupplier getMultipart() { + Identifier small_cube_id = ReFramed.id("small_cube_special"); + return MultipartBlockStateSupplier.create(this) + .with(GBlockstate.when(CORNER, NORTH_EAST_DOWN), + GBlockstate.variant(small_cube_id, true, R0, R0)) + .with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN), + GBlockstate.variant(small_cube_id, true, R0, R90)) + .with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN), + GBlockstate.variant(small_cube_id, true, R0, R180)) + .with(GBlockstate.when(CORNER, WEST_NORTH_DOWN), + GBlockstate.variant(small_cube_id, true, R0, R270)) + .with(GBlockstate.when(CORNER, EAST_SOUTH_UP), + GBlockstate.variant(small_cube_id, true, R180, R0)) + .with(GBlockstate.when(CORNER, SOUTH_WEST_UP), + GBlockstate.variant(small_cube_id, true, R180, R90)) + .with(GBlockstate.when(CORNER, WEST_NORTH_UP), + GBlockstate.variant(small_cube_id, true, R180, R180)) + .with(GBlockstate.when(CORNER, NORTH_EAST_UP), + GBlockstate.variant(small_cube_id, true, R180, R270)); + } + + @Override + public void setRecipe(RecipeExporter exporter) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 8); + ShapelessRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, this, 8) + .input(ReFramed.CUBE) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) + .offerTo(exporter); + } + + static { + final VoxelShape SMALL_CUBE = VoxelShapes.cuboid(.5f, 0f, 0f, 1f, .5f, .5f); + + SMALL_CUBE_VOXELS.add(SMALL_CUBE); + SMALL_CUBE_VOXELS.add(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y)); + SMALL_CUBE_VOXELS.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y)); + SMALL_CUBE_VOXELS.add(VoxelHelper.rotateCounterClockwise(SMALL_CUBE, Direction.Axis.Y)); + + SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(SMALL_CUBE, Direction.Axis.Y)); + SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y)); + SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y), Direction.Axis.Y)); + SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y)); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java index 3912786..3514c44 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java @@ -5,7 +5,7 @@ import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.VoxelHelper; -import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.Edge; import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; @@ -37,21 +37,21 @@ import java.util.stream.Stream; import static fr.adrien1106.reframed.util.blocks.BlockProperties.*; import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; -import static fr.adrien1106.reframed.util.blocks.Corner.*; +import static fr.adrien1106.reframed.util.blocks.Edge.*; public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements BlockStateProvider { public static final List VOXEL_LIST = new ArrayList<>(52); - private record ModelCacheKey(Corner corner, StairShape shape) {} + private record ModelCacheKey(Edge edge, StairShape shape) {} public ReFramedStairsBlock(Settings settings) { super(settings); - setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT)); + setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT)); } @Override public Object getModelCacheKey(BlockState state) { - return new ModelCacheKey(state.get(CORNER), state.get(STAIR_SHAPE)); + return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE)); } @Override @@ -61,21 +61,21 @@ public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements B @Override protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder.add(CORNER, STAIR_SHAPE)); + super.appendProperties(builder.add(EDGE, STAIR_SHAPE)); } @Override public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighbor_state, WorldAccess world, BlockPos pos, BlockPos moved) { return super.getStateForNeighborUpdate(state, direction, neighbor_state, world, pos, moved) - .with(STAIR_SHAPE, BlockHelper.getStairsShape(state.getBlock(), state.get(CORNER), world, pos)); + .with(STAIR_SHAPE, BlockHelper.getStairsShape(state.getBlock(), state.get(EDGE), world, pos)); } @Nullable @Override // Pretty happy of how clean it is (also got it on first try :) ) public BlockState getPlacementState(ItemPlacementContext ctx) { - Corner face = BlockHelper.getPlacementCorner(ctx); + Edge face = BlockHelper.getPlacementEdge(ctx); StairShape shape = BlockHelper.getStairsShape(this, face, ctx.getWorld(), ctx.getBlockPos()); - return super.getPlacementState(ctx).with(CORNER, face).with(STAIR_SHAPE, shape); + return super.getPlacementState(ctx).with(EDGE, face).with(STAIR_SHAPE, shape); } @Override @@ -93,7 +93,7 @@ public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements B public static VoxelShape getOutline(BlockState state) { StairShape shape = state.get(STAIR_SHAPE); - Corner direction = state.get(CORNER); + Edge direction = state.get(EDGE); return switch (shape) { case STRAIGHT -> switch (direction) { @@ -219,217 +219,217 @@ public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements B Identifier outer_side_id = ReFramed.id(prefix + "outer_side_stairs_special"); return MultipartBlockStateSupplier.create(block) /* STRAIGHT X AXIS */ - .with(GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R0, R0)) - .with(GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R180, R0)) - .with(GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R180, R180)) - .with(GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R0, R180)) /* STRAIGHT Y AXIS */ - .with(GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R90, R0)) - .with(GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R90, R90)) - .with(GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R90, R180)) - .with(GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R90, R270)) /* STRAIGHT Z AXIS */ - .with(GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R0, R90)) - .with(GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R0, R270)) - .with(GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R180, R270)) - .with(GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, STRAIGHT), + .with(GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, STRAIGHT), GBlockstate.variant(straight_id, true, R180, R90)) /* INNER BOTTOM */ .with(When.anyOf( - GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, INNER_RIGHT), - GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, INNER_LEFT)), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R0, R180)) .with(When.anyOf( - GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, INNER_RIGHT), - GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, INNER_RIGHT), - GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, INNER_LEFT)), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R0, R270)) .with(When.anyOf( - GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, INNER_RIGHT), - GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, INNER_RIGHT), - GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, INNER_RIGHT)), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R0, R0)) .with(When.anyOf( - GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, INNER_RIGHT), - GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, INNER_RIGHT)), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R0, R90)) /* INNER TOP */ .with(When.anyOf( - GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, INNER_RIGHT)), + GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R180, R0)) .with(When.anyOf( - GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, INNER_RIGHT), - GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, INNER_RIGHT)), + GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R180, R90)) .with(When.anyOf( - GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, INNER_RIGHT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R180, R180)) .with(When.anyOf( - GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, INNER_LEFT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R180, R270)) /* OUTER BOTTOM */ .with(When.anyOf( - GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), - GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT)), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R0, R0)) .with(When.anyOf( - GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT), - GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT)), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT), + GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R0, R90)) .with(When.anyOf( - GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT), - GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT)), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT), + GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R0, R180)) .with(When.anyOf( - GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT), - GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT)), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R0, R270)) /* OUTER TOP */ .with(When.anyOf( - GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), - GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, FIRST_OUTER_LEFT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), + GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R180, R0)) .with(When.anyOf( - GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT), - GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT), + GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R180, R90)) .with(When.anyOf( - GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_LEFT), - GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_LEFT), + GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R180, R180)) .with(When.anyOf( - GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT), - GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT), + GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R180, R270)) /* OUTER EAST */ .with(When.anyOf( - GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), - GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT)), + GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R0, R0)) .with(When.anyOf( - GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT), - GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)), + GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT), + GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R90, R0)) .with(When.anyOf( - GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT), - GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)), + GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT), + GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R180, R0)) .with(When.anyOf( - GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT), - GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT)), + GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R270, R0)) /* OUTER SOUTH */ .with(When.anyOf( - GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT), - GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), + GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R0, R90)) .with(When.anyOf( - GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT), - GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)), + GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R90, R90)) .with(When.anyOf( - GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT), - GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)), + GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R180, R90)) .with(When.anyOf( - GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT), - GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), + GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R270, R90)) /* OUTER WEST */ .with(When.anyOf( - GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), - GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)), + GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), + GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R0, R180)) .with(When.anyOf( - GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT), - GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT)), + GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT), + GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R90, R180)) .with(When.anyOf( - GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT), - GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT)), + GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT), + GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R180, R180)) .with(When.anyOf( - GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT), - GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)), + GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT), + GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R270, R180)) /* OUTER NORTH */ .with(When.anyOf( - GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT), - GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)), + GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R0, R270)) .with(When.anyOf( - GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT), - GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), + GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R90, R270)) .with(When.anyOf( - GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT), - GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), + GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R180, R270)) .with(When.anyOf( - GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT), - GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)), + GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R270, R270)) /* OUTER BOTTOM */ .with(When.anyOf( - GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, OUTER_RIGHT), - GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, OUTER_RIGHT), - GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, OUTER_RIGHT)), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R0)) .with(When.anyOf( - GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, OUTER_LEFT), - GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, OUTER_RIGHT), - GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, OUTER_RIGHT)), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R90)) .with(When.anyOf( - GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, OUTER_LEFT), - GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, OUTER_LEFT), - GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, OUTER_RIGHT)), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R180)) .with(When.anyOf( - GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, OUTER_RIGHT), - GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, OUTER_LEFT), - GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, OUTER_RIGHT)), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R270)) /* OUTER TOP */ .with(When.anyOf( - GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, OUTER_RIGHT), - GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, OUTER_LEFT), - GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, OUTER_LEFT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R0)) .with(When.anyOf( - GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, OUTER_RIGHT), - GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, OUTER_RIGHT), - GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, OUTER_LEFT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R90)) .with(When.anyOf( - GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, OUTER_LEFT), - GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, OUTER_RIGHT), - GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, OUTER_LEFT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R180)) .with(When.anyOf( - GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, OUTER_LEFT), - GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, OUTER_LEFT), - GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, OUTER_LEFT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R270)); } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java index 8b33b9e..3df062c 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java @@ -5,7 +5,7 @@ import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.VoxelHelper; -import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.Edge; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -28,8 +28,8 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; -import static fr.adrien1106.reframed.util.blocks.Corner.*; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; +import static fr.adrien1106.reframed.util.blocks.Edge.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; public class ReFramedStepBlock extends WaterloggableReFramedBlock implements BlockStateProvider { @@ -38,12 +38,12 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo public ReFramedStepBlock(Settings settings) { super(settings); - setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN)); + setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN)); } @Override public Object getModelCacheKey(BlockState state) { - return state.get(CORNER); + return state.get(EDGE); } @Override @@ -53,18 +53,22 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo @Override protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder.add(CORNER)); + super.appendProperties(builder.add(EDGE)); } @Nullable @Override public BlockState getPlacementState(ItemPlacementContext ctx) { - return super.getPlacementState(ctx).with(CORNER, BlockHelper.getPlacementCorner(ctx)); + return super.getPlacementState(ctx).with(EDGE, BlockHelper.getPlacementEdge(ctx)); } @Override public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - return switch (state.get(CORNER)) { + return getStepShape(state.get(EDGE)); + } + + public static VoxelShape getStepShape(Edge edge) { + return switch (edge) { case DOWN_SOUTH -> STEP_VOXELS.get(0); case NORTH_DOWN -> STEP_VOXELS.get(1); case UP_NORTH -> STEP_VOXELS.get(2); @@ -85,31 +89,31 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo Identifier step_id = ReFramed.id("step_special"); return MultipartBlockStateSupplier.create(this) /* X AXIS */ - .with(GBlockstate.when(CORNER, DOWN_EAST), + .with(GBlockstate.when(EDGE, DOWN_EAST), GBlockstate.variant(step_id, true, R0, R0)) - .with(GBlockstate.when(CORNER, EAST_UP), + .with(GBlockstate.when(EDGE, EAST_UP), GBlockstate.variant(step_id, true, R180, R0)) - .with(GBlockstate.when(CORNER, UP_WEST), + .with(GBlockstate.when(EDGE, UP_WEST), GBlockstate.variant(step_id, true, R180, R180)) - .with(GBlockstate.when(CORNER, WEST_DOWN), + .with(GBlockstate.when(EDGE, WEST_DOWN), GBlockstate.variant(step_id, true, R0, R180)) /* Y AXIS */ - .with(GBlockstate.when(CORNER, EAST_SOUTH), + .with(GBlockstate.when(EDGE, EAST_SOUTH), GBlockstate.variant(step_id, true, R90, R0)) - .with(GBlockstate.when(CORNER, SOUTH_WEST), + .with(GBlockstate.when(EDGE, SOUTH_WEST), GBlockstate.variant(step_id, true, R90, R90)) - .with(GBlockstate.when(CORNER, WEST_NORTH), + .with(GBlockstate.when(EDGE, WEST_NORTH), GBlockstate.variant(step_id, true, R90, R180)) - .with(GBlockstate.when(CORNER, NORTH_EAST), + .with(GBlockstate.when(EDGE, NORTH_EAST), GBlockstate.variant(step_id, true, R90, R270)) /* Z AXIS */ - .with(GBlockstate.when(CORNER, DOWN_SOUTH), + .with(GBlockstate.when(EDGE, DOWN_SOUTH), GBlockstate.variant(step_id, true, R0, R90)) - .with(GBlockstate.when(CORNER, NORTH_DOWN), + .with(GBlockstate.when(EDGE, NORTH_DOWN), GBlockstate.variant(step_id, true, R0, R270)) - .with(GBlockstate.when(CORNER, UP_NORTH), + .with(GBlockstate.when(EDGE, UP_NORTH), GBlockstate.variant(step_id, true, R180, R270)) - .with(GBlockstate.when(CORNER, SOUTH_UP), + .with(GBlockstate.when(EDGE, SOUTH_UP), GBlockstate.variant(step_id, true, R180, R90)); } diff --git a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java index a59f789..11460e0 100644 --- a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java +++ b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java @@ -27,6 +27,8 @@ public class ReFramedClient implements ClientModInitializer { BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0])); HELPER.addReFramedModel("cube_special" , HELPER.auto(new Identifier("block/cube"))); + HELPER.addReFramedModel("small_cube_special" , HELPER.auto(ReFramed.id("block/small_cube"))); + HELPER.addReFramedModel("double_small_cube_special" , HELPER.autoDouble(ReFramed.id("block/small_cube"), ReFramed.id("block/small_cube_complement"))); HELPER.addReFramedModel("slab_special" , HELPER.auto(new Identifier("block/slab"))); HELPER.addReFramedModel("double_slab_special" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top"))); HELPER.addReFramedModel("stairs_special" , HELPER.auto(ReFramed.id("block/stairs"))); @@ -45,6 +47,8 @@ public class ReFramedClient implements ClientModInitializer { //item model assignments (in lieu of models/item/___.json) HELPER.assignItemModel("cube_special" , ReFramed.CUBE); + HELPER.assignItemModel("small_cube_special" , ReFramed.SMALL_CUBE); + HELPER.assignItemModel("double_small_cube_special" , ReFramed.DOUBLE_SMALL_CUBE); HELPER.assignItemModel("slab_special" , ReFramed.SLAB); HELPER.assignItemModel("double_slab_special" , ReFramed.DOUBLE_SLAB); HELPER.assignItemModel("stairs_special" , ReFramed.STAIRS); diff --git a/src/main/java/fr/adrien1106/reframed/client/model/QuadPosBounds.java b/src/main/java/fr/adrien1106/reframed/client/model/QuadPosBounds.java index 87a61c9..c6cca3d 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/QuadPosBounds.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/QuadPosBounds.java @@ -1,11 +1,14 @@ package fr.adrien1106.reframed.client.model; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; import org.joml.Vector3f; +@Environment(EnvType.CLIENT) public record QuadPosBounds(float min_x, float max_x, float min_y, float max_y, float min_z, float max_z) { public static QuadPosBounds read(QuadView quad) { diff --git a/src/main/java/fr/adrien1106/reframed/client/model/QuadUvBounds.java b/src/main/java/fr/adrien1106/reframed/client/model/QuadUvBounds.java index b06d9cf..3b314cd 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/QuadUvBounds.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/QuadUvBounds.java @@ -1,10 +1,13 @@ package fr.adrien1106.reframed.client.model; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.client.texture.Sprite; import net.minecraft.util.math.MathHelper; +@Environment(EnvType.CLIENT) public record QuadUvBounds(float minU, float maxU, float minV, float maxV) { public static QuadUvBounds read(QuadView quad) { float u0 = quad.u(0), u1 = quad.u(1), u2 = quad.u(2), u3 = quad.u(3); diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java index 9ac9b06..5fcd555 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java @@ -1,6 +1,8 @@ package fr.adrien1106.reframed.client.model.apperance; import fr.adrien1106.reframed.client.model.QuadPosBounds; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; @@ -9,6 +11,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +@Environment(EnvType.CLIENT) public abstract class CamoAppearance { protected final int id; protected final RenderMaterial ao_material; diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java index ce7515f..22cdd66 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java @@ -6,6 +6,8 @@ import fr.adrien1106.reframed.client.model.DynamicBakedModel; import fr.adrien1106.reframed.client.model.QuadPosBounds; import fr.adrien1106.reframed.mixin.model.WeightedBakedModelAccessor; import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; @@ -33,6 +35,7 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; +@Environment(EnvType.CLIENT) public class CamoAppearanceManager { public CamoAppearanceManager(Function spriteLookup) { diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java index 24c0806..3918144 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java @@ -1,11 +1,14 @@ package fr.adrien1106.reframed.client.model.apperance; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.minecraft.util.math.Direction; import org.jetbrains.annotations.NotNull; import java.util.List; +@Environment(EnvType.CLIENT) public class ComputedAppearance extends CamoAppearance { private final Appearance appearance; diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java index 9e384b9..9c8054a 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java @@ -1,5 +1,7 @@ package fr.adrien1106.reframed.client.model.apperance; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.minecraft.client.texture.Sprite; import net.minecraft.util.math.Direction; @@ -7,6 +9,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +@Environment(EnvType.CLIENT) public class SingleSpriteAppearance extends CamoAppearance { private final @NotNull Sprite defaultSprite; diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java index b3c3b73..443dd92 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java @@ -1,5 +1,7 @@ package fr.adrien1106.reframed.client.model.apperance; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.minecraft.util.collection.Weighted; import net.minecraft.util.collection.Weighting; @@ -9,6 +11,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +@Environment(EnvType.CLIENT) public class WeightedComputedAppearance extends CamoAppearance { private final List> appearances; private final int total_weight; diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java index 6450843..5ff1cc9 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java @@ -6,6 +6,8 @@ import fr.adrien1106.reframed.block.ReFramedBlock; import fr.adrien1106.reframed.block.ReFramedEntity; import fr.adrien1106.reframed.client.ReFramedClient; import fr.adrien1106.reframed.client.model.QuadPosBounds; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; @@ -20,6 +22,7 @@ import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.Pair; import net.minecraft.util.function.BooleanBiFunction; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; @@ -32,14 +35,11 @@ import net.minecraft.world.BlockRenderView; import net.minecraft.world.BlockView; import net.minecraft.world.World; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; -import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static net.minecraft.util.shape.VoxelShapes.combine; @@ -48,22 +48,30 @@ public class BlockHelper { // self culling cache of the models not made thread local so that it is only computed once private static final Cache INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).build(); - private record CullElement(Object state_key, int model) {} public static Corner getPlacementCorner(ItemPlacementContext ctx) { + Direction side = ctx.getSide().getOpposite(); + Vec3d pos = getHitPos(ctx.getHitPos(), ctx.getBlockPos()); + Pair sides = getHitSides(pos, side); + + return Corner.getByDirections(side, sides.getLeft(), sides.getRight()); + } + + private static Pair getHitSides(Vec3d pos, Direction side) { + Iterator axes = Stream.of(Direction.Axis.values()) + .filter(axis -> !axis.equals(side.getAxis())).iterator(); + return new Pair<>(getHitDirection(axes.next(), pos), getHitDirection(axes.next(), pos)); + } + + public static Edge getPlacementEdge(ItemPlacementContext ctx) { Direction side = ctx.getSide().getOpposite(); Vec3d pos = getHitPos(ctx.getHitPos(), ctx.getBlockPos()); Direction.Axis axis = getHitAxis(pos, side); - Direction part_direction = Direction.from( - axis, - axis.choose(pos.x, pos.y, pos.z) > 0 - ? Direction.AxisDirection.POSITIVE - : Direction.AxisDirection.NEGATIVE - ); + Direction part_direction = getHitDirection(axis, pos); - return Corner.getByDirections(side, part_direction); + return Edge.getByDirections(side, part_direction); } public static Direction.Axis getHitAxis(Vec3d pos, Direction side) { @@ -75,6 +83,15 @@ public class BlockHelper { ).orElse(null); } + public static Direction getHitDirection(Direction.Axis axis, Vec3d pos) { + return Direction.from( + axis, + axis.choose(pos.x, pos.y, pos.z) > 0 + ? Direction.AxisDirection.POSITIVE + : Direction.AxisDirection.NEGATIVE + ); + } + public static Vec3d getRelativePos(Vec3d pos, BlockPos block_pos) { return new Vec3d( pos.getX() - block_pos.getX(), @@ -92,7 +109,7 @@ public class BlockHelper { ); } - public static StairShape getStairsShape(Block block, Corner face, BlockView world, BlockPos pos) { + public static StairShape getStairsShape(Block block, Edge face, BlockView world, BlockPos pos) { StairShape shape = STRAIGHT; String sol = getNeighborPos(face, face.getFirstDirection(), true, face.getSecondDirection(), world, pos, block); @@ -128,14 +145,14 @@ public class BlockHelper { return shape; } - public static String getNeighborPos(Corner face, Direction direction, Boolean reverse, Direction reference, BlockView world, BlockPos pos, Block block) { + public static String getNeighborPos(Edge face, Direction direction, Boolean reverse, Direction reference, BlockView world, BlockPos pos, Block block) { BlockState block_state = world.getBlockState( pos.offset(reverse ? direction.getOpposite() : direction) ); - if (block_state.isOf(block) && block_state.get(CORNER).hasDirection(reference)) { - if (block_state.get(CORNER).hasDirection(face.getLeftDirection())) return "left"; - else if (block_state.get(CORNER).hasDirection(face.getRightDirection())) return "right"; + if (block_state.isOf(block) && block_state.get(EDGE).hasDirection(reference)) { + if (block_state.get(EDGE).hasDirection(face.getLeftDirection())) return "left"; + else if (block_state.get(EDGE).hasDirection(face.getRightDirection())) return "right"; } return ""; } @@ -224,6 +241,7 @@ public class BlockHelper { * @param state - the state of the model * @param models - list of models on the same block */ + @Environment(EnvType.CLIENT) public static void computeInnerCull(BlockState state, List models) { if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return; Object key = frame_block.getModelCacheKey(state); @@ -261,6 +279,7 @@ public class BlockHelper { } } + @Environment(EnvType.CLIENT) public static boolean shouldDrawInnerFace(BlockState state, BlockRenderView view, BlockPos pos, int quad_index, int theme_index) { if ( !(state.getBlock() instanceof ReFramedBlock frame_block) || !(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity) @@ -280,6 +299,7 @@ public class BlockHelper { } // Doing this method from scratch as it is simpler to do than injecting everywhere + @Environment(EnvType.CLIENT) public static boolean shouldDrawSide(BlockState self_state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, int theme_index) { ThemeableBlockEntity self = world.getBlockEntity(pos) instanceof ThemeableBlockEntity e ? e : null; ThemeableBlockEntity other = world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity e ? e : null; @@ -372,8 +392,4 @@ public class BlockHelper { .reduce((prev, current) -> prev && current).orElse(false) ); } - - public static int luminance(BlockState state) { - return state.contains(LIGHT) && state.get(LIGHT) ? 15 : 0; - } } diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java index 89d0b8d..c8a9296 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java @@ -5,6 +5,7 @@ import net.minecraft.state.property.EnumProperty; public class BlockProperties { public static final BooleanProperty LIGHT = BooleanProperty.of("emits_light"); + public static final EnumProperty EDGE = EnumProperty.of("edge", Edge.class); public static final EnumProperty CORNER = EnumProperty.of("corner", Corner.class); public static final EnumProperty STAIR_SHAPE = EnumProperty.of("shape", StairShape.class); } diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java b/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java index 6c74e9c..bfa0801 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java @@ -6,32 +6,26 @@ import net.minecraft.util.math.Direction; import java.util.Arrays; public enum Corner implements StringIdentifiable { - NORTH_DOWN("north_down", Direction.NORTH, Direction.DOWN, Direction.EAST, 0), - DOWN_SOUTH("down_south", Direction.DOWN, Direction.SOUTH, Direction.EAST, 1), - SOUTH_UP("south_up", Direction.SOUTH, Direction.UP, Direction.EAST, 2), - UP_NORTH("up_north", Direction.UP, Direction.NORTH, Direction.EAST, 3), - WEST_DOWN("west_down", Direction.WEST, Direction.DOWN, Direction.SOUTH, 4), - DOWN_EAST("down_east", Direction.DOWN, Direction.EAST, Direction.SOUTH, 5), - EAST_UP("east_up", Direction.EAST, Direction.UP, Direction.SOUTH, 6), - UP_WEST("up_west", Direction.UP, Direction.WEST, Direction.SOUTH, 7), - WEST_NORTH("west_north", Direction.WEST, Direction.NORTH, Direction.DOWN, 8), - NORTH_EAST("north_east", Direction.NORTH, Direction.EAST, Direction.DOWN, 9), - EAST_SOUTH("east_south", Direction.EAST, Direction.SOUTH, Direction.DOWN, 10), - SOUTH_WEST("south_west", Direction.SOUTH, Direction.WEST, Direction.DOWN, 11); + NORTH_EAST_DOWN("north_east_down", Direction.NORTH, Direction.EAST, Direction.DOWN, 0), + EAST_SOUTH_DOWN("east_south_down", Direction.EAST, Direction.SOUTH, Direction.DOWN, 1), + SOUTH_WEST_DOWN("south_west_down", Direction.SOUTH, Direction.WEST, Direction.DOWN, 2), + WEST_NORTH_DOWN("west_north_down", Direction.WEST, Direction.NORTH, Direction.DOWN, 3), + NORTH_EAST_UP("north_east_up", Direction.NORTH, Direction.EAST, Direction.UP, 4), + EAST_SOUTH_UP("east_south_up", Direction.EAST, Direction.SOUTH, Direction.UP, 5), + SOUTH_WEST_UP("south_west_up", Direction.SOUTH, Direction.WEST, Direction.UP, 6), + WEST_NORTH_UP("west_north_up", Direction.WEST, Direction.NORTH, Direction.UP, 7); private final String name; private final Direction first_direction; private final Direction second_direction; - private final Direction right_direction; - private final Direction left_direction; + private final Direction third_direction; private final int ID; - Corner(String name, Direction first_direction, Direction second_direction, Direction right_direction, int id) { + Corner(String name, Direction first_direction, Direction second_direction, Direction third_direction, int id) { this.name = name; this.first_direction = first_direction; this.second_direction = second_direction; - this.right_direction = right_direction; - this.left_direction = right_direction.getOpposite(); + this.third_direction = third_direction; this.ID = id; } @@ -43,44 +37,31 @@ public enum Corner implements StringIdentifiable { return asString(); } - public Direction getFirstDirection() { - return first_direction; - } - - public Direction getSecondDirection() { - return second_direction; - } - public Direction getRightDirection() { - return right_direction; - } - public Direction getLeftDirection() { - return left_direction; - } - public boolean hasDirection(Direction direction) { return this.first_direction.equals(direction) - || this.second_direction.equals(direction); + || this.second_direction.equals(direction) + || this.third_direction.equals(direction); } public int getID() { return this.ID; } - public static Corner getByDirections(Direction direction_1, Direction direction_2) { + public static Corner getByDirections(Direction direction_1, Direction direction_2, Direction direction_3) { return Arrays.stream(Corner.values()) - .filter(value -> value.hasDirection(direction_1) && value.hasDirection(direction_2)) - .findFirst().orElse(Corner.NORTH_DOWN); + .filter(value -> value.hasDirection(direction_1) && value.hasDirection(direction_2) && value.hasDirection(direction_3)) + .findFirst().orElse(Corner.NORTH_EAST_DOWN); } public static Corner fromId(int id) { return Arrays.stream(Corner.values()) .filter(value -> value.getID() == id) - .findFirst().orElse(Corner.NORTH_DOWN); + .findFirst().orElse(Corner.NORTH_EAST_DOWN); } public static Corner fromName(String name) { return Arrays.stream(Corner.values()) .filter(value -> value.name().equals(name)) - .findFirst().orElse(Corner.NORTH_DOWN); + .findFirst().orElse(Corner.NORTH_EAST_DOWN); } } diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java b/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java new file mode 100644 index 0000000..f7df0af --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java @@ -0,0 +1,86 @@ +package fr.adrien1106.reframed.util.blocks; + +import net.minecraft.util.StringIdentifiable; +import net.minecraft.util.math.Direction; + +import java.util.Arrays; + +public enum Edge implements StringIdentifiable { + NORTH_DOWN("north_down", Direction.NORTH, Direction.DOWN, Direction.EAST, 0), + DOWN_SOUTH("down_south", Direction.DOWN, Direction.SOUTH, Direction.EAST, 1), + SOUTH_UP("south_up", Direction.SOUTH, Direction.UP, Direction.EAST, 2), + UP_NORTH("up_north", Direction.UP, Direction.NORTH, Direction.EAST, 3), + WEST_DOWN("west_down", Direction.WEST, Direction.DOWN, Direction.SOUTH, 4), + DOWN_EAST("down_east", Direction.DOWN, Direction.EAST, Direction.SOUTH, 5), + EAST_UP("east_up", Direction.EAST, Direction.UP, Direction.SOUTH, 6), + UP_WEST("up_west", Direction.UP, Direction.WEST, Direction.SOUTH, 7), + WEST_NORTH("west_north", Direction.WEST, Direction.NORTH, Direction.DOWN, 8), + NORTH_EAST("north_east", Direction.NORTH, Direction.EAST, Direction.DOWN, 9), + EAST_SOUTH("east_south", Direction.EAST, Direction.SOUTH, Direction.DOWN, 10), + SOUTH_WEST("south_west", Direction.SOUTH, Direction.WEST, Direction.DOWN, 11); + + private final String name; + private final Direction first_direction; + private final Direction second_direction; + private final Direction right_direction; + private final Direction left_direction; + private final int ID; + + Edge(String name, Direction first_direction, Direction second_direction, Direction right_direction, int id) { + this.name = name; + this.first_direction = first_direction; + this.second_direction = second_direction; + this.right_direction = right_direction; + this.left_direction = right_direction.getOpposite(); + this.ID = id; + } + + public String asString() { + return this.name; + } + + public String toString() { + return asString(); + } + + public Direction getFirstDirection() { + return first_direction; + } + + public Direction getSecondDirection() { + return second_direction; + } + public Direction getRightDirection() { + return right_direction; + } + public Direction getLeftDirection() { + return left_direction; + } + + public boolean hasDirection(Direction direction) { + return this.first_direction.equals(direction) + || this.second_direction.equals(direction); + } + + public int getID() { + return this.ID; + } + + public static Edge getByDirections(Direction direction_1, Direction direction_2) { + return Arrays.stream(Edge.values()) + .filter(value -> value.hasDirection(direction_1) && value.hasDirection(direction_2)) + .findFirst().orElse(Edge.NORTH_DOWN); + } + + public static Edge fromId(int id) { + return Arrays.stream(Edge.values()) + .filter(value -> value.getID() == id) + .findFirst().orElse(Edge.NORTH_DOWN); + } + + public static Edge fromName(String name) { + return Arrays.stream(Edge.values()) + .filter(value -> value.name().equals(name)) + .findFirst().orElse(Edge.NORTH_DOWN); + } +} diff --git a/src/main/resources/assets/reframed/models/block/small_cube.json b/src/main/resources/assets/reframed/models/block/small_cube.json new file mode 100644 index 0000000..81d3699 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/small_cube.json @@ -0,0 +1,35 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [8, 0, 0], + "to": [16, 8, 8], + "faces": { + "north": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 8, 16, 16], "texture": "#side"}, + "west": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#top"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#bottom", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file -- 2.39.5 From bd412bfccdf9f5551cc7b6c2a5b40a9966dc83da Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Fri, 8 Mar 2024 23:50:50 +0100 Subject: [PATCH 06/11] added missing shape --- .../models/block/small_cube_complement.json | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/resources/assets/reframed/models/block/small_cube_complement.json diff --git a/src/main/resources/assets/reframed/models/block/small_cube_complement.json b/src/main/resources/assets/reframed/models/block/small_cube_complement.json new file mode 100644 index 0000000..e30b52e --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/small_cube_complement.json @@ -0,0 +1,35 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [8, 0, 8], + "to": [16, 8, 16], + "faces": { + "north": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "east": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#top"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#bottom", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file -- 2.39.5 From 5fcb983592609e795915d1524b0fd5ea0a95d6ee Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Sat, 9 Mar 2024 15:26:50 +0100 Subject: [PATCH 07/11] fixed small cube and caching for dynamic models items because items rerender often --- .../java/fr/adrien1106/reframed/ReFramed.java | 2 +- .../reframed/ReFramedDoubleSmallBlock.java | 20 +++++++---- .../client/model/RetexturingBakedModel.java | 4 +-- .../apperance/CamoAppearanceManager.java | 23 +++++++------ .../mixin/compat/AthenaBakedModelMixin.java | 3 +- .../reframed/util/blocks/BlockHelper.java | 33 +++++++------------ 6 files changed, 41 insertions(+), 44 deletions(-) diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index 80b942e..954c421 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -30,7 +30,7 @@ import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; * TODO add Hammer from framed ( removes theme ) for sure * TODO add screwdriver ( iterate over theme states ) ? * TODO add blueprint for survival friendly copy paste of a theme. - * TODO fix other models ( + half stair ) + * TODO fix other models ( + half stair + layers ) * TODO get better naming for the shapes (will break a lot of already placed blocks) * TODO put more coherence in the double theme orders / directions * TODO better connected textures diff --git a/src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java b/src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java index 5951c90..90c145a 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java @@ -28,6 +28,7 @@ import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape; import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; import static fr.adrien1106.reframed.util.blocks.Edge.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; +import static net.minecraft.util.shape.VoxelShapes.empty; public class ReFramedDoubleSmallBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { @@ -57,22 +58,27 @@ public class ReFramedDoubleSmallBlock extends WaterloggableReFramedDoubleBlock i return super.getPlacementState(ctx).with(EDGE, BlockHelper.getPlacementEdge(ctx)); } + @Override + public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) { + return isGhost(view, pos) ? empty(): getStepShape(state.get(EDGE)); + } + @Override public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { return getStepShape(state.get(EDGE)); } - @Override // TODO + @Override public VoxelShape getShape(BlockState state, int i) { return switch (state.get(EDGE)) { - case NORTH_DOWN -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 3); + case NORTH_DOWN -> SMALL_CUBE_VOXELS.get(i == 1 ? 3 : 0); case DOWN_SOUTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 1 : 2); - case SOUTH_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 5 : 6); + case SOUTH_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 6 : 5); case UP_NORTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 4 : 7); case WEST_DOWN -> SMALL_CUBE_VOXELS.get(i == 1 ? 2 : 3); case DOWN_EAST -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 1); - case EAST_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 4 : 5); - case UP_WEST -> SMALL_CUBE_VOXELS.get(i == 1 ? 6 : 7); + case EAST_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 5 : 4); + case UP_WEST -> SMALL_CUBE_VOXELS.get(i == 1 ? 7 : 6); case WEST_NORTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 3 : 7); case NORTH_EAST -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 4); case EAST_SOUTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 1 : 5); @@ -82,10 +88,10 @@ public class ReFramedDoubleSmallBlock extends WaterloggableReFramedDoubleBlock i @Override public int getTopThemeIndex(BlockState state) { - return super.getTopThemeIndex(state); // TODO + return 2; } - @Override // TODO + @Override public BlockStateSupplier getMultipart() { Identifier small_cube_id = ReFramed.id("double_small_cube_special"); return MultipartBlockStateSupplier.create(this) diff --git a/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java index a9e1232..5ce4b48 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java @@ -108,7 +108,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { } if(theme.getBlock() == Blocks.BARRIER) return; - CamoAppearance camo = appearance_manager.getCamoAppearance(world, theme, pos, theme_index); + CamoAppearance camo = appearance_manager.getCamoAppearance(world, theme, pos, theme_index, false); long seed = theme.getRenderingSeed(pos); int model_id = 0; if (camo instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed); @@ -135,7 +135,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { int tint; BlockState theme = ReFramedEntity.readStateFromItem(stack, theme_index); if(!theme.isAir()) { - appearance = appearance_manager.getCamoAppearance(null, theme, null, theme_index); + appearance = appearance_manager.getCamoAppearance(null, theme, null, theme_index, true); tint = 0xFF000000 | ((MinecraftAccessor) MinecraftClient.getInstance()).getItemColors().getColor(new ItemStack(theme.getBlock()), 0); } else { appearance = appearance_manager.getDefaultAppearance(theme_index); diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java index 22cdd66..f6a5c64 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java @@ -1,11 +1,12 @@ package fr.adrien1106.reframed.client.model.apperance; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.client.ReFramedClient; import fr.adrien1106.reframed.client.model.DynamicBakedModel; import fr.adrien1106.reframed.client.model.QuadPosBounds; import fr.adrien1106.reframed.mixin.model.WeightedBakedModelAccessor; -import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.renderer.v1.Renderer; @@ -67,11 +68,8 @@ public class CamoAppearanceManager { private final CamoAppearance accent_appearance; private final CamoAppearance barrierItemAppearance; - private static final Object2ObjectLinkedOpenHashMap APPEARANCE_CACHE = - new Object2ObjectLinkedOpenHashMap<>(2048, 0.25f) { - @Override - protected void rehash(int n) {} - }; + private static final Cache APPEARANCE_CACHE = CacheBuilder.newBuilder().maximumSize(2048).build(); + private final AtomicInteger serial_number = new AtomicInteger(0); //Mutable private final EnumMap ao_materials = new EnumMap<>(BlendMode.class); @@ -81,19 +79,24 @@ public class CamoAppearanceManager { return appearance == 2 ? accent_appearance: default_appearance; } - public CamoAppearance getCamoAppearance(BlockRenderView world, BlockState state, BlockPos pos, int theme_index) { + public CamoAppearance getCamoAppearance(BlockRenderView world, BlockState state, BlockPos pos, int theme_index, boolean item) { BakedModel model = MinecraftClient.getInstance().getBlockRenderManager().getModel(state); // add support for connected textures and more generally any compatible models injected so that they return baked quads if (model instanceof DynamicBakedModel dynamic_model) { - return computeAppearance(dynamic_model.computeQuads(world, state, pos, theme_index), state); + // cache items as they get rendered more often + if (item && APPEARANCE_CACHE.asMap().containsKey(state)) return APPEARANCE_CACHE.getIfPresent(state); + + CamoAppearance appearance = computeAppearance(dynamic_model.computeQuads(world, state, pos, theme_index), state); + if (item) APPEARANCE_CACHE.put(state, appearance); + return appearance; } // refresh cache - if (APPEARANCE_CACHE.containsKey(state)) return APPEARANCE_CACHE.getAndMoveToFirst(state); + if (APPEARANCE_CACHE.asMap().containsKey(state)) return APPEARANCE_CACHE.getIfPresent(state); CamoAppearance appearance = computeAppearance(model, state); - APPEARANCE_CACHE.putAndMoveToFirst(state, appearance); + APPEARANCE_CACHE.put(state, appearance); return appearance; } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java index aac9f62..2bbcb90 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java @@ -56,8 +56,7 @@ public abstract class AthenaBakedModelMixin implements DynamicBakedModel, BakedM level.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity ? framed_entity.getTheme(theme_index) : state, pos, direction) - ) - .forEach(sprite -> face_quads.computeIfPresent(direction, (d, quads) -> { + ).forEach(sprite -> face_quads.computeIfPresent(direction, (d, quads) -> { Sprite texture = textures.get(sprite.sprite()); if (texture == null) return quads; emitter.square(direction, sprite.left(), sprite.bottom(), sprite.right(), sprite.top(), sprite.depth()); diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java index 5ff1cc9..fd9cb55 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java @@ -48,7 +48,7 @@ public class BlockHelper { // self culling cache of the models not made thread local so that it is only computed once private static final Cache INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).build(); - private record CullElement(Object state_key, int model) {} + private record CullElement(Block block, Object state_key, int model) {} public static Corner getPlacementCorner(ItemPlacementContext ctx) { Direction side = ctx.getSide().getOpposite(); @@ -172,17 +172,18 @@ public class BlockHelper { // check for default light emission if (placement_state.getLuminance() > 0 - && themes.stream().noneMatch(theme -> theme.getLuminance() > 0)) - if (block_entity.emitsLight()) Block.dropStack(world, pos, new ItemStack(Items.GLOWSTONE_DUST)); - else block_entity.toggleLight(); + && themes.stream().noneMatch(theme -> theme.getLuminance() > 0) + && !block_entity.emitsLight() + ) + block_entity.toggleLight(); world.setBlockState(pos, state.with(LIGHT, block_entity.emitsLight())); // check for default redstone emission if (placement_state.getWeakRedstonePower(world, pos, Direction.NORTH) > 0 - && themes.stream().noneMatch(theme -> theme.getWeakRedstonePower(world, pos, Direction.NORTH) > 0)) - if (block_entity.emitsRedstone()) Block.dropStack(world, pos, new ItemStack(Items.GLOWSTONE_DUST)); - else block_entity.toggleRedstone(); + && themes.stream().noneMatch(theme -> theme.getWeakRedstonePower(world, pos, Direction.NORTH) > 0) + && !block_entity.emitsRedstone() + ) block_entity.toggleRedstone(); if(!player.isCreative()) held.decrement(1); world.playSound(player, pos, placement_state.getSoundGroup().getPlaceSound(), SoundCategory.BLOCKS, 1f, 1.1f); @@ -203,10 +204,6 @@ public class BlockHelper { if(state.contains(LIGHT) && held.getItem() == Items.GLOWSTONE_DUST) { block_entity.toggleLight(); world.setBlockState(pos, state.with(LIGHT, block_entity.emitsLight())); - - if(!player.isCreative()) - if (block_entity.emitsLight()) held.decrement(1); - else held.increment(1); world.playSound(player, pos, SoundEvents.BLOCK_GLASS_HIT, SoundCategory.BLOCKS, 1f, 1f); return ActionResult.SUCCESS; } @@ -214,10 +211,6 @@ public class BlockHelper { // frame will emit redstone if applied with redstone torch can deactivate redstone block camo emission if(held.getItem() == Items.REDSTONE_TORCH && ext.canAddRedstoneEmission(state, world, pos)) { block_entity.toggleRedstone(); - - if(!player.isCreative()) - if (block_entity.emitsRedstone()) held.decrement(1); - else held.increment(1); world.playSound(player, pos, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 1f, 1f); return ActionResult.SUCCESS; } @@ -225,10 +218,6 @@ public class BlockHelper { // Frame will lose its collision if applied with popped chorus fruit if(held.getItem() == Items.POPPED_CHORUS_FRUIT && ext.canRemoveCollision(state, world, pos)) { block_entity.toggleSolidity(); - - if(!player.isCreative()) - if (!block_entity.isSolid()) held.decrement(1); - else held.increment(1); world.playSound(player, pos, SoundEvents.ITEM_CHORUS_FRUIT_TELEPORT, SoundCategory.BLOCKS, 1f, 1f); return ActionResult.SUCCESS; } @@ -245,7 +234,7 @@ public class BlockHelper { public static void computeInnerCull(BlockState state, List models) { if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return; Object key = frame_block.getModelCacheKey(state); - if (INNER_CULL_MAP.asMap().containsKey(new CullElement(key, 1))) return; + if (INNER_CULL_MAP.asMap().containsKey(new CullElement(frame_block, key, 1))) return; Renderer r = ReFramedClient.HELPER.getFabricRenderer(); QuadEmitter quad_emitter = r.meshBuilder().getEmitter(); @@ -275,7 +264,7 @@ public class BlockHelper { } } } - INNER_CULL_MAP.put(new CullElement(key, self_id), cull_array); + INNER_CULL_MAP.put(new CullElement(frame_block, key, self_id), cull_array); } } @@ -284,7 +273,7 @@ public class BlockHelper { if ( !(state.getBlock() instanceof ReFramedBlock frame_block) || !(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity) ) return true; - CullElement key = new CullElement(frame_block.getModelCacheKey(state), theme_index); + CullElement key = new CullElement(frame_block, frame_block.getModelCacheKey(state), theme_index); if (!INNER_CULL_MAP.asMap().containsKey(key)) return true; // needs to be Integer object because array is initialized with null not 0 -- 2.39.5 From c207fb5ae6eef7de1c191971ef36ee411d5410a6 Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Sun, 10 Mar 2024 15:26:29 +0100 Subject: [PATCH 08/11] renamed blocks for more clarity and expandability --- .../java/fr/adrien1106/reframed/ReFramed.java | 19 ++++++++++--------- ...Block.java => ReFramedSlabsCubeBlock.java} | 4 ++-- ...Block.java => ReFramedSmallCubeBlock.java} | 4 ++-- .../ReFramedSmallCubesStepBlock.java} | 10 +++++----- ...airsBlock.java => ReFramedStairBlock.java} | 4 ++-- ...lock.java => ReFramedStairsCubeBlock.java} | 8 ++++---- ...Block.java => ReFramedStepsSlabBlock.java} | 4 ++-- .../reframed/client/ReFramedClient.java | 10 +++++----- 8 files changed, 32 insertions(+), 31 deletions(-) rename src/main/java/fr/adrien1106/reframed/block/{ReFramedDoubleSlabBlock.java => ReFramedSlabsCubeBlock.java} (95%) rename src/main/java/fr/adrien1106/reframed/block/{ReFramedSmallBlock.java => ReFramedSmallCubeBlock.java} (97%) rename src/main/java/fr/adrien1106/reframed/{ReFramedDoubleSmallBlock.java => block/ReFramedSmallCubesStepBlock.java} (94%) rename src/main/java/fr/adrien1106/reframed/block/{ReFramedStairsBlock.java => ReFramedStairBlock.java} (99%) rename src/main/java/fr/adrien1106/reframed/block/{ReFramedDoubleStairsBlock.java => ReFramedStairsCubeBlock.java} (97%) rename src/main/java/fr/adrien1106/reframed/block/{ReFramedDoubleStepBlock.java => ReFramedStepsSlabBlock.java} (97%) diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index 954c421..84c5d05 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -39,7 +39,7 @@ public class ReFramed implements ModInitializer { public static final String MODID = "reframed"; public static final ArrayList BLOCKS = new ArrayList<>(); - public static Block CUBE, SMALL_CUBE, DOUBLE_SMALL_CUBE, STAIRS, DOUBLE_STAIRS, SLAB, DOUBLE_SLAB, STEP, DOUBLE_STEP; + public static Block CUBE, SMALL_CUBE, SMALL_CUBES_STEP, STAIR, STAIRS_CUBE, SLAB, SLABS_CUBE, STEP, STEPS_SLAB; public static ItemGroup ITEM_GROUP; public static BlockEntityType REFRAMED_BLOCK_ENTITY; @@ -50,16 +50,17 @@ public class ReFramed implements ModInitializer { @Override public void onInitialize() { CUBE = registerReFramed("cube" , new ReFramedBlock(cp(Blocks.OAK_PLANKS))); - SMALL_CUBE = registerReFramed("small_cube" , new ReFramedSmallBlock(cp(Blocks.OAK_PLANKS))); - DOUBLE_SMALL_CUBE = registerReFramed("double_small_cube" , new ReFramedDoubleSmallBlock(cp(Blocks.OAK_PLANKS))); - STAIRS = registerReFramed("stairs" , new ReFramedStairsBlock(cp(Blocks.OAK_STAIRS))); - DOUBLE_STAIRS = registerReFramed("double_stairs" , new ReFramedDoubleStairsBlock(cp(Blocks.OAK_STAIRS))); -// CUBE = registerReFramed("half_stairs" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO -// CUBE = registerReFramed("double_half_stairs", new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO + SMALL_CUBE = registerReFramed("small_cube" , new ReFramedSmallCubeBlock(cp(Blocks.OAK_PLANKS))); + SMALL_CUBES_STEP = registerReFramed("small_cubes_step" , new ReFramedSmallCubesStepBlock(cp(Blocks.OAK_PLANKS))); + STAIR = registerReFramed("stair" , new ReFramedStairBlock(cp(Blocks.OAK_STAIRS))); + STAIRS_CUBE = registerReFramed("stairs_cube" , new ReFramedStairsCubeBlock(cp(Blocks.OAK_STAIRS))); +// CUBE = registerReFramed("half_stair" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO +// CUBE = registerReFramed("half_stairs_stair" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO +// CUBE = registerReFramed("half_stairs_slab" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO SLAB = registerReFramed("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB))); - DOUBLE_SLAB = registerReFramed("double_slab" , new ReFramedDoubleSlabBlock(cp(Blocks.OAK_SLAB))); + SLABS_CUBE = registerReFramed("slabs_cube" , new ReFramedSlabsCubeBlock(cp(Blocks.OAK_SLAB))); STEP = registerReFramed("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB))); - DOUBLE_STEP = registerReFramed("double_step" , new ReFramedDoubleStepBlock(cp(Blocks.OAK_SLAB))); + STEPS_SLAB = registerReFramed("steps_slab" , new ReFramedStepsSlabBlock(cp(Blocks.OAK_SLAB))); REFRAMED_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, id("camo"), FabricBlockEntityTypeBuilder.create( diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedSlabsCubeBlock.java similarity index 95% rename from src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java rename to src/main/java/fr/adrien1106/reframed/block/ReFramedSlabsCubeBlock.java index 56238d3..42aa1c1 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedSlabsCubeBlock.java @@ -23,9 +23,9 @@ import static net.minecraft.data.client.VariantSettings.Rotation.R0; import static net.minecraft.data.client.VariantSettings.Rotation.R90; import static net.minecraft.state.property.Properties.AXIS; -public class ReFramedDoubleSlabBlock extends ReFramedDoubleBlock implements BlockStateProvider { +public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock implements BlockStateProvider { - public ReFramedDoubleSlabBlock(Settings settings) { + public ReFramedSlabsCubeBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y)); } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java similarity index 97% rename from src/main/java/fr/adrien1106/reframed/block/ReFramedSmallBlock.java rename to src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java index 3d18634..1e43fa0 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java @@ -32,11 +32,11 @@ import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; import static fr.adrien1106.reframed.util.blocks.Corner.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; -public class ReFramedSmallBlock extends WaterloggableReFramedBlock implements BlockStateProvider { +public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock implements BlockStateProvider { public static final List SMALL_CUBE_VOXELS = new ArrayList<>(8); - public ReFramedSmallBlock(Settings settings) { + public ReFramedSmallCubeBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN)); } diff --git a/src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java similarity index 94% rename from src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java rename to src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java index 90c145a..7a50811 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramedDoubleSmallBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java @@ -1,6 +1,6 @@ -package fr.adrien1106.reframed; +package fr.adrien1106.reframed.block; -import fr.adrien1106.reframed.block.WaterloggableReFramedDoubleBlock; +import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.util.blocks.BlockHelper; @@ -23,16 +23,16 @@ import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.BlockView; import org.jetbrains.annotations.Nullable; -import static fr.adrien1106.reframed.block.ReFramedSmallBlock.SMALL_CUBE_VOXELS; +import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.SMALL_CUBE_VOXELS; import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape; import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; import static fr.adrien1106.reframed.util.blocks.Edge.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; import static net.minecraft.util.shape.VoxelShapes.empty; -public class ReFramedDoubleSmallBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { +public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { - public ReFramedDoubleSmallBlock(Settings settings) { + public ReFramedSmallCubesStepBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN)); } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java similarity index 99% rename from src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java rename to src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java index 3514c44..3908e53 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java @@ -39,12 +39,12 @@ import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; import static fr.adrien1106.reframed.util.blocks.Edge.*; -public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements BlockStateProvider { +public class ReFramedStairBlock extends WaterloggableReFramedBlock implements BlockStateProvider { public static final List VOXEL_LIST = new ArrayList<>(52); private record ModelCacheKey(Edge edge, StairShape shape) {} - public ReFramedStairsBlock(Settings settings) { + public ReFramedStairBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT)); } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java similarity index 97% rename from src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java rename to src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java index c018372..c909f8a 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java @@ -27,16 +27,16 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import static fr.adrien1106.reframed.block.ReFramedStairsBlock.*; +import static fr.adrien1106.reframed.block.ReFramedStairBlock.*; import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE; -public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements BlockStateProvider { +public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements BlockStateProvider { private static final List COMPLEMENT_LIST = new ArrayList<>(52); private record ModelCacheKey(Edge edge, StairShape shape) {} - public ReFramedDoubleStairsBlock(Settings settings) { + public ReFramedStairsCubeBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(STAIR_SHAPE, StairShape.STRAIGHT)); } @@ -207,7 +207,7 @@ public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements Bl RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE); ShapelessRecipeJsonBuilder .create(RecipeCategory.BUILDING_BLOCKS, this) - .input(ReFramed.STAIRS) + .input(ReFramed.STAIR) .input(ReFramed.STEP) .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java similarity index 97% rename from src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java rename to src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java index b64c782..3b65d2f 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java @@ -31,10 +31,10 @@ import static net.minecraft.state.property.Properties.AXIS; import static net.minecraft.state.property.Properties.FACING; import static net.minecraft.util.shape.VoxelShapes.empty; -public class ReFramedDoubleStepBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { +public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { private record ModelCacheKey(Direction facing, Axis axis) {} - public ReFramedDoubleStepBlock(Settings settings) { + public ReFramedStepsSlabBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(FACING, Direction.DOWN).with(AXIS, Axis.X)); } diff --git a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java index 11460e0..329cde9 100644 --- a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java +++ b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java @@ -48,13 +48,13 @@ public class ReFramedClient implements ClientModInitializer { //item model assignments (in lieu of models/item/___.json) HELPER.assignItemModel("cube_special" , ReFramed.CUBE); HELPER.assignItemModel("small_cube_special" , ReFramed.SMALL_CUBE); - HELPER.assignItemModel("double_small_cube_special" , ReFramed.DOUBLE_SMALL_CUBE); + HELPER.assignItemModel("double_small_cube_special" , ReFramed.SMALL_CUBES_STEP); HELPER.assignItemModel("slab_special" , ReFramed.SLAB); - HELPER.assignItemModel("double_slab_special" , ReFramed.DOUBLE_SLAB); - HELPER.assignItemModel("stairs_special" , ReFramed.STAIRS); - HELPER.assignItemModel("double_stairs_special" , ReFramed.DOUBLE_STAIRS); + HELPER.assignItemModel("double_slab_special" , ReFramed.SLABS_CUBE); + HELPER.assignItemModel("stairs_special" , ReFramed.STAIR); + HELPER.assignItemModel("double_stairs_special" , ReFramed.STAIRS_CUBE); HELPER.assignItemModel("step_special" , ReFramed.STEP); - HELPER.assignItemModel("double_step_special" , ReFramed.DOUBLE_STEP); + HELPER.assignItemModel("double_step_special" , ReFramed.STEPS_SLAB); } private void privateInit() { -- 2.39.5 From b1ba784ee3a9d7b257fff33d226d8897534e5d54 Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Sun, 10 Mar 2024 15:43:06 +0100 Subject: [PATCH 09/11] made stairs connect when 2 different instance are used + organized todos --- .../java/fr/adrien1106/reframed/ReFramed.java | 13 ++++++------ .../reframed/block/ReFramedStairBlock.java | 4 ++-- .../block/ReFramedStairsCubeBlock.java | 4 ++-- .../reframed/util/blocks/BlockHelper.java | 21 ++++++++++++------- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index 84c5d05..9a18713 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -27,13 +27,13 @@ import java.util.stream.Collectors; import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; /** - * TODO add Hammer from framed ( removes theme ) for sure + * TODO add Hammer from framed ( removes theme ) -> for v1.5.5 * TODO add screwdriver ( iterate over theme states ) ? - * TODO add blueprint for survival friendly copy paste of a theme. - * TODO fix other models ( + half stair + layers ) - * TODO get better naming for the shapes (will break a lot of already placed blocks) - * TODO put more coherence in the double theme orders / directions - * TODO better connected textures + * TODO add blueprint for survival friendly copy paste of a theme. -> for v1.5.5 + * TODO add minecraft models like wall fence etc -> for v1.6 + * TODO ( + half stair + layers ) -> priority for v1.5 + * TODO put more coherence in the double theme orders / directions -> maybe v1.6 ? + * TODO better connected textures -> maybe v1.6 ? */ public class ReFramed implements ModInitializer { public static final String MODID = "reframed"; @@ -57,6 +57,7 @@ public class ReFramed implements ModInitializer { // CUBE = registerReFramed("half_stair" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO // CUBE = registerReFramed("half_stairs_stair" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO // CUBE = registerReFramed("half_stairs_slab" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO +// CUBE = registerReFramed("layer" , new ReFramedBlock(cp(Blocks.OAK_SLAB))); // TODO SLAB = registerReFramed("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB))); SLABS_CUBE = registerReFramed("slabs_cube" , new ReFramedSlabsCubeBlock(cp(Blocks.OAK_SLAB))); STEP = registerReFramed("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB))); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java index 3908e53..a4386c8 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java @@ -67,14 +67,14 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl @Override public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighbor_state, WorldAccess world, BlockPos pos, BlockPos moved) { return super.getStateForNeighborUpdate(state, direction, neighbor_state, world, pos, moved) - .with(STAIR_SHAPE, BlockHelper.getStairsShape(state.getBlock(), state.get(EDGE), world, pos)); + .with(STAIR_SHAPE, BlockHelper.getStairsShape(state.get(EDGE), world, pos)); } @Nullable @Override // Pretty happy of how clean it is (also got it on first try :) ) public BlockState getPlacementState(ItemPlacementContext ctx) { Edge face = BlockHelper.getPlacementEdge(ctx); - StairShape shape = BlockHelper.getStairsShape(this, face, ctx.getWorld(), ctx.getBlockPos()); + StairShape shape = BlockHelper.getStairsShape(face, ctx.getWorld(), ctx.getBlockPos()); return super.getPlacementState(ctx).with(EDGE, face).with(STAIR_SHAPE, shape); } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java index c909f8a..8af13f1 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java @@ -59,7 +59,7 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements Bloc @Override public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighbor_state, WorldAccess world, BlockPos pos, BlockPos moved) { return super.getStateForNeighborUpdate(state, direction, neighbor_state, world, pos, moved) - .with(STAIR_SHAPE, BlockHelper.getStairsShape(this, state.get(EDGE), world, pos)); + .with(STAIR_SHAPE, BlockHelper.getStairsShape(state.get(EDGE), world, pos)); } @@ -67,7 +67,7 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements Bloc @Override public BlockState getPlacementState(ItemPlacementContext ctx) { Edge face = BlockHelper.getPlacementEdge(ctx); - StairShape shape = BlockHelper.getStairsShape(this, face, ctx.getWorld(), ctx.getBlockPos()); + StairShape shape = BlockHelper.getStairsShape(face, ctx.getWorld(), ctx.getBlockPos()); return super.getPlacementState(ctx).with(EDGE, face).with(STAIR_SHAPE, shape); } diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java index fd9cb55..df7037d 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java @@ -4,6 +4,8 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import fr.adrien1106.reframed.block.ReFramedBlock; import fr.adrien1106.reframed.block.ReFramedEntity; +import fr.adrien1106.reframed.block.ReFramedStairBlock; +import fr.adrien1106.reframed.block.ReFramedStairsCubeBlock; import fr.adrien1106.reframed.client.ReFramedClient; import fr.adrien1106.reframed.client.model.QuadPosBounds; import net.fabricmc.api.EnvType; @@ -109,28 +111,28 @@ public class BlockHelper { ); } - public static StairShape getStairsShape(Block block, Edge face, BlockView world, BlockPos pos) { + public static StairShape getStairsShape(Edge face, BlockView world, BlockPos pos) { StairShape shape = STRAIGHT; - String sol = getNeighborPos(face, face.getFirstDirection(), true, face.getSecondDirection(), world, pos, block); + String sol = getNeighborPos(face, face.getFirstDirection(), true, face.getSecondDirection(), world, pos); switch (sol) { case "right": return INNER_RIGHT; case "left": return INNER_LEFT; } - sol = getNeighborPos(face, face.getSecondDirection(), true, face.getFirstDirection(), world, pos, block); + sol = getNeighborPos(face, face.getSecondDirection(), true, face.getFirstDirection(), world, pos); switch (sol) { case "right": return INNER_RIGHT; case "left": return INNER_LEFT; } - sol = getNeighborPos(face, face.getFirstDirection(), false, face.getSecondDirection(), world, pos, block); + sol = getNeighborPos(face, face.getFirstDirection(), false, face.getSecondDirection(), world, pos); switch (sol) { case "right" -> shape = FIRST_OUTER_RIGHT; case "left" -> shape = FIRST_OUTER_LEFT; } - sol = getNeighborPos(face, face.getSecondDirection(), false, face.getFirstDirection(), world, pos, block); + sol = getNeighborPos(face, face.getSecondDirection(), false, face.getFirstDirection(), world, pos); switch (sol) { case "right" -> { if (shape.equals(STRAIGHT)) shape = SECOND_OUTER_RIGHT; @@ -145,18 +147,23 @@ public class BlockHelper { return shape; } - public static String getNeighborPos(Edge face, Direction direction, Boolean reverse, Direction reference, BlockView world, BlockPos pos, Block block) { + public static String getNeighborPos(Edge face, Direction direction, Boolean reverse, Direction reference, BlockView world, BlockPos pos) { BlockState block_state = world.getBlockState( pos.offset(reverse ? direction.getOpposite() : direction) ); - if (block_state.isOf(block) && block_state.get(EDGE).hasDirection(reference)) { + if (isStair(block_state) && block_state.get(EDGE).hasDirection(reference)) { if (block_state.get(EDGE).hasDirection(face.getLeftDirection())) return "left"; else if (block_state.get(EDGE).hasDirection(face.getRightDirection())) return "right"; } return ""; } + public static boolean isStair(BlockState state) { + return state.getBlock() instanceof ReFramedStairBlock + || state.getBlock() instanceof ReFramedStairsCubeBlock; + } + public static ActionResult useCamo(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, int theme_index) { if(!(world.getBlockEntity(pos) instanceof ReFramedEntity block_entity)) return ActionResult.PASS; -- 2.39.5 From 6922dcc9d975980c72688a4c6a49dfa36340b66b Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Thu, 14 Mar 2024 22:05:14 +0100 Subject: [PATCH 10/11] improved naming + added new voxel list builder + Half Stairs Slab + Half Stairs Stair + Layer + coherence in model orientations --- .../java/fr/adrien1106/reframed/ReFramed.java | 12 +- .../block/ReFramedHalfStairBlock.java | 194 +++++++++ .../block/ReFramedHalfStairsSlabBlock.java | 103 +++++ .../block/ReFramedHalfStairsStairBlock.java | 138 +++++++ .../reframed/block/ReFramedLayerBlock.java | 117 ++++++ .../block/ReFramedSmallCubeBlock.java | 35 +- .../block/ReFramedSmallCubesStepBlock.java | 57 ++- .../reframed/block/ReFramedStairBlock.java | 385 +++++++----------- .../block/ReFramedStairsCubeBlock.java | 128 +----- .../reframed/block/ReFramedStepBlock.java | 83 ++-- .../block/ReFramedStepsSlabBlock.java | 31 +- .../reframed/client/ReFramedClient.java | 77 +++- .../adrien1106/reframed/util/VoxelHelper.java | 235 ++++++++--- .../reframed/util/blocks/BlockProperties.java | 2 + .../reframed/util/blocks/Corner.java | 30 ++ .../adrien1106/reframed/util/blocks/Edge.java | 44 +- .../models/block/half_stair/down.json | 55 +++ .../models/block/half_stair/side.json | 55 +++ .../models/block/half_stair/slab/down.json | 35 ++ .../models/block/half_stair/slab/side.json | 35 ++ .../models/block/half_stair/stair/down.json | 55 +++ .../models/block/half_stair/stair/side.json | 55 +++ .../{small_cube.json => small_cube/base.json} | 0 .../step/base.json} | 0 .../cube/double_outer.json} | 0 .../cube/inner.json} | 0 .../cube/outer.json} | 0 .../cube/outer_side.json} | 0 .../cube/straight.json} | 0 .../double_outer.json} | 0 .../{inner_stairs.json => stair/inner.json} | 0 .../{outer_stairs.json => stair/outer.json} | 0 .../outer_side.json} | 0 .../{stairs.json => stair/straight.json} | 0 .../block/{step.json => step/down.json} | 0 .../block/{step_side.json => step/side.json} | 0 .../slab/down.json} | 0 .../slab/side.json} | 0 38 files changed, 1376 insertions(+), 585 deletions(-) create mode 100644 src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairBlock.java create mode 100644 src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsSlabBlock.java create mode 100644 src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsStairBlock.java create mode 100644 src/main/java/fr/adrien1106/reframed/block/ReFramedLayerBlock.java create mode 100644 src/main/resources/assets/reframed/models/block/half_stair/down.json create mode 100644 src/main/resources/assets/reframed/models/block/half_stair/side.json create mode 100644 src/main/resources/assets/reframed/models/block/half_stair/slab/down.json create mode 100644 src/main/resources/assets/reframed/models/block/half_stair/slab/side.json create mode 100644 src/main/resources/assets/reframed/models/block/half_stair/stair/down.json create mode 100644 src/main/resources/assets/reframed/models/block/half_stair/stair/side.json rename src/main/resources/assets/reframed/models/block/{small_cube.json => small_cube/base.json} (100%) rename src/main/resources/assets/reframed/models/block/{small_cube_complement.json => small_cube/step/base.json} (100%) rename src/main/resources/assets/reframed/models/block/{double_outer_stairs_complement.json => stair/cube/double_outer.json} (100%) rename src/main/resources/assets/reframed/models/block/{inner_stairs_complement.json => stair/cube/inner.json} (100%) rename src/main/resources/assets/reframed/models/block/{outer_stairs_complement.json => stair/cube/outer.json} (100%) rename src/main/resources/assets/reframed/models/block/{outer_side_stairs_complement.json => stair/cube/outer_side.json} (100%) rename src/main/resources/assets/reframed/models/block/{stairs_complement.json => stair/cube/straight.json} (100%) rename src/main/resources/assets/reframed/models/block/{double_outer_stairs.json => stair/double_outer.json} (100%) rename src/main/resources/assets/reframed/models/block/{inner_stairs.json => stair/inner.json} (100%) rename src/main/resources/assets/reframed/models/block/{outer_stairs.json => stair/outer.json} (100%) rename src/main/resources/assets/reframed/models/block/{outer_side_stairs.json => stair/outer_side.json} (100%) rename src/main/resources/assets/reframed/models/block/{stairs.json => stair/straight.json} (100%) rename src/main/resources/assets/reframed/models/block/{step.json => step/down.json} (100%) rename src/main/resources/assets/reframed/models/block/{step_side.json => step/side.json} (100%) rename src/main/resources/assets/reframed/models/block/{step_complement_slab.json => step/slab/down.json} (100%) rename src/main/resources/assets/reframed/models/block/{step_side_complement_slab.json => step/slab/side.json} (100%) diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index 9a18713..393fa13 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -31,15 +31,13 @@ import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; * TODO add screwdriver ( iterate over theme states ) ? * TODO add blueprint for survival friendly copy paste of a theme. -> for v1.5.5 * TODO add minecraft models like wall fence etc -> for v1.6 - * TODO ( + half stair + layers ) -> priority for v1.5 - * TODO put more coherence in the double theme orders / directions -> maybe v1.6 ? * TODO better connected textures -> maybe v1.6 ? */ public class ReFramed implements ModInitializer { public static final String MODID = "reframed"; public static final ArrayList BLOCKS = new ArrayList<>(); - public static Block CUBE, SMALL_CUBE, SMALL_CUBES_STEP, STAIR, STAIRS_CUBE, SLAB, SLABS_CUBE, STEP, STEPS_SLAB; + public static Block CUBE, SMALL_CUBE, SMALL_CUBES_STEP, STAIR, HALF_STAIR, STAIRS_CUBE, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, SLAB, SLABS_CUBE, STEP, STEPS_SLAB, LAYER; public static ItemGroup ITEM_GROUP; public static BlockEntityType REFRAMED_BLOCK_ENTITY; @@ -54,10 +52,10 @@ public class ReFramed implements ModInitializer { SMALL_CUBES_STEP = registerReFramed("small_cubes_step" , new ReFramedSmallCubesStepBlock(cp(Blocks.OAK_PLANKS))); STAIR = registerReFramed("stair" , new ReFramedStairBlock(cp(Blocks.OAK_STAIRS))); STAIRS_CUBE = registerReFramed("stairs_cube" , new ReFramedStairsCubeBlock(cp(Blocks.OAK_STAIRS))); -// CUBE = registerReFramed("half_stair" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO -// CUBE = registerReFramed("half_stairs_stair" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO -// CUBE = registerReFramed("half_stairs_slab" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO -// CUBE = registerReFramed("layer" , new ReFramedBlock(cp(Blocks.OAK_SLAB))); // TODO + HALF_STAIR = registerReFramed("half_stair" , new ReFramedHalfStairBlock(cp(Blocks.OAK_STAIRS))); + HALF_STAIRS_SLAB = registerReFramed("half_stairs_slab" , new ReFramedHalfStairsSlabBlock(cp(Blocks.OAK_STAIRS))); + HALF_STAIRS_STAIR = registerReFramed("half_stairs_stair" , new ReFramedHalfStairsStairBlock(cp(Blocks.OAK_STAIRS))); + LAYER = registerReFramed("layer" , new ReFramedLayerBlock(cp(Blocks.OAK_SLAB))); SLAB = registerReFramed("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB))); SLABS_CUBE = registerReFramed("slabs_cube" , new ReFramedSlabsCubeBlock(cp(Blocks.OAK_SLAB))); STEP = registerReFramed("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB))); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairBlock.java new file mode 100644 index 0000000..cb1ca8a --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairBlock.java @@ -0,0 +1,194 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.generator.GBlockstate; +import fr.adrien1106.reframed.util.VoxelHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.BlockStateSupplier; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.state.StateManager; +import net.minecraft.util.Identifier; +import net.minecraft.util.function.BooleanBiFunction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import org.jetbrains.annotations.Nullable; + +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE; +import static fr.adrien1106.reframed.util.blocks.Corner.*; +import static net.minecraft.data.client.VariantSettings.Rotation.*; + +public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock implements BlockStateProvider { + + public static final VoxelShape[] HALF_STAIR_VOXELS; + + private record ModelCacheKey(Corner corner, int face) {} + + public ReFramedHalfStairBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN).with(CORNER_FACE, 0)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE)); + } + + @Override + public int getModelStateCount() { + return 24; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(CORNER,CORNER_FACE)); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + Corner corner = BlockHelper.getPlacementCorner(ctx); + return super.getPlacementState(ctx) + .with(CORNER, corner) + .with(CORNER_FACE, corner.getDirectionIndex(ctx.getSide().getOpposite())); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return HALF_STAIR_VOXELS[state.get(CORNER_FACE) + state.get(CORNER).getID() * 3]; + } + + @Override + public BlockStateSupplier getMultipart() { + return getHalfStairMultipart( + this, + ReFramed.id("half_stair_down_special"), + ReFramed.id("half_stair_side_special") + ); + } + + public static BlockStateSupplier getHalfStairMultipart(Block block, Identifier model_down, Identifier model_side) { + return MultipartBlockStateSupplier.create(block) + .with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R0, R0)) + .with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R90, R270)) + .with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R0, R0)) + + .with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R0, R90)) + .with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R90, R0)) + .with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R0, R90)) + + .with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R0, R180)) + .with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R90, R90)) + .with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R0, R180)) + + .with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R0, R270)) + .with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R90, R180)) + .with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R0, R270)) + + .with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R180, R0)) + .with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R270, R90)) + .with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R180, R0)) + + .with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R180, R90)) + .with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R270, R180)) + .with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R180, R90)) + + .with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R180, R180)) + .with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R270, R270)) + .with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R180, R180)) + + .with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R180, R270)) + .with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R270, R0)) + .with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R180, R270)); + } + + @Override + public void setRecipe(RecipeExporter exporter) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2); + ShapedRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, this, 4) + .pattern("I ") + .pattern("II ") + .input('I', ReFramed.CUBE) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) + .offerTo(exporter); + } + + static { + final VoxelShape HALF_STAIR = VoxelShapes.combineAndSimplify( + createCuboidShape(8, 0, 0, 16, 16, 8), + createCuboidShape(0, 0, 0, 8, 8, 8), + BooleanBiFunction.OR + ); + HALF_STAIR_VOXELS = VoxelListBuilder.create(HALF_STAIR, 24) + .add(0 , VoxelHelper::rotateY, VoxelHelper::mirrorZ) + .add(0 , VoxelHelper::rotateCX, VoxelHelper::mirrorZ) + + .add(0 , VoxelHelper::rotateY) + .add(1 , VoxelHelper::rotateY) + .add(2 , VoxelHelper::rotateY) + + .add(3 , VoxelHelper::rotateY) + .add(4 , VoxelHelper::rotateY) + .add(5 , VoxelHelper::rotateY) + + .add(6 , VoxelHelper::rotateY) + .add(7 , VoxelHelper::rotateY) + .add(8 , VoxelHelper::rotateY) + + .add(0 , VoxelHelper::mirrorY) + .add(1 , VoxelHelper::mirrorY) + .add(2 , VoxelHelper::mirrorY) + + .add(12, VoxelHelper::rotateY) + .add(13, VoxelHelper::rotateY) + .add(14, VoxelHelper::rotateY) + + .add(15, VoxelHelper::rotateY) + .add(16, VoxelHelper::rotateY) + .add(17, VoxelHelper::rotateY) + + .add(18, VoxelHelper::rotateY) + .add(19, VoxelHelper::rotateY) + .add(20, VoxelHelper::rotateY) + .build(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsSlabBlock.java new file mode 100644 index 0000000..e0c6c41 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsSlabBlock.java @@ -0,0 +1,103 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.BlockStateSupplier; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.state.StateManager; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import org.jetbrains.annotations.Nullable; + +import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.HALF_STAIR_VOXELS; +import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairMultipart; +import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape; +import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.SMALL_CUBE_VOXELS; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE; +import static fr.adrien1106.reframed.util.blocks.Corner.NORTH_EAST_DOWN; +import static net.minecraft.util.shape.VoxelShapes.empty; + +public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { + + private record ModelCacheKey(Corner corner, int face) {} + + public ReFramedHalfStairsSlabBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN).with(CORNER_FACE, 0)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE)); + } + + @Override + public int getModelStateCount() { + return 24; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(CORNER,CORNER_FACE)); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + Corner corner = BlockHelper.getPlacementCorner(ctx); + return super.getPlacementState(ctx) + .with(CORNER, corner) + .with(CORNER_FACE, corner.getDirectionIndex(ctx.getSide().getOpposite())); + } + + @Override + public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) { + return isGhost(view, pos) ? empty(): getSlabShape(state.get(CORNER).getDirection(state.get(CORNER_FACE))); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return getSlabShape(state.get(CORNER).getDirection(state.get(CORNER_FACE))); + } + + @Override + public VoxelShape getShape(BlockState state, int i) { + Corner corner = state.get(CORNER); + int face = state.get(CORNER_FACE); + return i == 2 + ? SMALL_CUBE_VOXELS[corner.getOpposite(face).getID()] + : HALF_STAIR_VOXELS[face + corner.getID() * 3]; + } + + @Override + public BlockStateSupplier getMultipart() { + return getHalfStairMultipart( + this, + ReFramed.id("half_stairs_slab_down_special"), + ReFramed.id("half_stairs_slab_side_special") + ); + } + + @Override + public void setRecipe(RecipeExporter exporter) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2); + ShapelessRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, this) + .input(ReFramed.HALF_STAIR) + .input(ReFramed.SMALL_CUBE) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) + .offerTo(exporter); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsStairBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsStairBlock.java new file mode 100644 index 0000000..d645df0 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsStairBlock.java @@ -0,0 +1,138 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.generator.GBlockstate; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.Edge; +import fr.adrien1106.reframed.util.blocks.StairShape; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.BlockStateSupplier; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.state.StateManager; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import org.jetbrains.annotations.Nullable; + +import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.HALF_STAIR_VOXELS; +import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; +import static fr.adrien1106.reframed.util.blocks.Edge.*; +import static net.minecraft.data.client.VariantSettings.Rotation.*; +import static net.minecraft.util.shape.VoxelShapes.empty; + +public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { + public ReFramedHalfStairsStairBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(EDGE, NORTH_DOWN)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return state.get(EDGE); + } + + @Override + public int getModelStateCount() { + return 12; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(EDGE)); + } + + @Nullable + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + return super.getPlacementState(ctx).with(EDGE, BlockHelper.getPlacementEdge(ctx)); + } + + @Override + public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) { + return isGhost(view, pos) ? empty(): getStairShape(state.get(EDGE), StairShape.STRAIGHT); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return getStairShape(state.get(EDGE), StairShape.STRAIGHT); + } + + @Override + public VoxelShape getShape(BlockState state, int i) { + Edge edge = state.get(EDGE); + Direction side = i == 1 + ? edge.getRightDirection() + : edge.getLeftDirection(); + Corner corner = Corner.getByDirections( + edge.getFirstDirection(), + edge.getSecondDirection(), + side + + ); + return HALF_STAIR_VOXELS[corner.getID() * 3 + corner.getDirectionIndex(side)]; + } + + @Override + public int getTopThemeIndex(BlockState state) { + return 2; + } + + @Override + public BlockStateSupplier getMultipart() { + Identifier model_id = ReFramed.id("half_stairs_stair_down_special"); + Identifier side_model_id = ReFramed.id("half_stairs_stair_side_special"); + Identifier reverse_model_id = ReFramed.id("half_stairs_stair_reverse_special"); + return MultipartBlockStateSupplier.create(this) + /* X AXIS */ + .with(GBlockstate.when(EDGE, NORTH_DOWN), + GBlockstate.variant(side_model_id, true, R90, R180)) + .with(GBlockstate.when(EDGE, DOWN_SOUTH), + GBlockstate.variant(side_model_id, true, R0, R180)) + .with(GBlockstate.when(EDGE, SOUTH_UP), + GBlockstate.variant(side_model_id, true, R270, R180)) + .with(GBlockstate.when(EDGE, UP_NORTH), + GBlockstate.variant(side_model_id, true, R180, R180)) + /* Y AXIS */ + .with(GBlockstate.when(EDGE, NORTH_EAST), + GBlockstate.variant(model_id, true, R0, R0)) + .with(GBlockstate.when(EDGE, EAST_SOUTH), + GBlockstate.variant(model_id, true, R0, R90)) + .with(GBlockstate.when(EDGE, SOUTH_WEST), + GBlockstate.variant(model_id, true, R0, R180)) + .with(GBlockstate.when(EDGE, WEST_NORTH), + GBlockstate.variant(model_id, true, R0, R270)) + /* Z AXIS */ + .with(GBlockstate.when(EDGE, DOWN_EAST), + GBlockstate.variant(side_model_id, true, R0, R90)) + .with(GBlockstate.when(EDGE, EAST_UP), + GBlockstate.variant(reverse_model_id, true, R180, R270)) + .with(GBlockstate.when(EDGE, UP_WEST), + GBlockstate.variant(side_model_id, true, R180, R90)) + .with(GBlockstate.when(EDGE, WEST_DOWN), + GBlockstate.variant(reverse_model_id, true, R0, R270)); + } + + @Override + public void setRecipe(RecipeExporter exporter) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2); + ShapelessRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, this) + .input(ReFramed.HALF_STAIR, 2) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) + .offerTo(exporter); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedLayerBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedLayerBlock.java new file mode 100644 index 0000000..e7e8be5 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedLayerBlock.java @@ -0,0 +1,117 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.GBlockstate; +import fr.adrien1106.reframed.util.VoxelHelper; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.state.StateManager; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import org.jetbrains.annotations.Nullable; + +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; +import static net.minecraft.data.client.VariantSettings.Rotation.*; +import static net.minecraft.state.property.Properties.FACING; +import static net.minecraft.state.property.Properties.LAYERS; + +public class ReFramedLayerBlock extends ReFramedSlabBlock { + + public static final VoxelShape[] LAYER_VOXELS; + private record ModelCacheKey(Direction face, int layer) {} + + public ReFramedLayerBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(LAYERS, 1)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(FACING), state.get(LAYERS)); + } + + @Override + public int getModelStateCount() { + return 48; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(LAYERS)); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return LAYER_VOXELS[state.get(FACING).getId() * 8 + state.get(LAYERS) - 1]; + } + + @Override + public boolean canReplace(BlockState state, ItemPlacementContext ctx) { + return !(!state.isOf(this) || ctx.getPlayer().isSneaking() || state.get(LAYERS) == 8); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos()); + if (!previous.isOf(this)) return super.getPlacementState(ctx); + return previous.with(LAYERS, previous.get(LAYERS) + 1); + } + + @Override + public MultipartBlockStateSupplier getMultipart() { + String model_pattern = "layer_x_special"; + MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(this); + for (int i = 1; i <= 8; i++) { + Identifier model = ReFramed.id(model_pattern.replace("x", i + "")); + supplier + .with(GBlockstate.when(FACING, Direction.DOWN, LAYERS, i), + GBlockstate.variant(model, true, R0, R0)) + .with(GBlockstate.when(FACING, Direction.SOUTH, LAYERS, i), + GBlockstate.variant(model, true, R90, R0)) + .with(GBlockstate.when(FACING, Direction.UP, LAYERS, i), + GBlockstate.variant(model, true, R180, R0)) + .with(GBlockstate.when(FACING, Direction.NORTH, LAYERS, i), + GBlockstate.variant(model, true, R270, R0)) + .with(GBlockstate.when(FACING, Direction.WEST, LAYERS, i), + GBlockstate.variant(model, true, R90, R90)) + .with(GBlockstate.when(FACING, Direction.EAST, LAYERS, i), + GBlockstate.variant(model, true, R90, R270)); + } + return supplier; + } + + static { + VoxelListBuilder builder = VoxelListBuilder.create(createCuboidShape(0, 0, 0, 16, 2, 16), 48) + .add(createCuboidShape(0, 0, 0, 16, 4, 16)) + .add(createCuboidShape(0, 0, 0, 16, 6, 16)) + .add(createCuboidShape(0, 0, 0, 16, 8, 16)) + .add(createCuboidShape(0, 0, 0, 16, 10, 16)) + .add(createCuboidShape(0, 0, 0, 16, 12, 16)) + .add(createCuboidShape(0, 0, 0, 16, 14, 16)) + .add(createCuboidShape(0, 0, 0, 16, 16, 16)); + + for (int i = 0; i < 8; i++) { + builder.add(i, VoxelHelper::mirrorY); + } + for (int i = 0; i < 8; i++) { + builder.add(i, VoxelHelper::rotateX); + } + for (int i = 0; i < 8; i++) { + builder.add(i, VoxelHelper::rotateCX); + } + for (int i = 0; i < 8; i++) { + builder.add(i, VoxelHelper::rotateCZ); + } + for (int i = 0; i < 8; i++) { + builder.add(i, VoxelHelper::rotateZ); + } + + LAYER_VOXELS = builder.build(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java index 1e43fa0..bce79f6 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java @@ -19,22 +19,19 @@ import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.state.StateManager; import net.minecraft.util.Identifier; 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.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; import static fr.adrien1106.reframed.util.blocks.Corner.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock implements BlockStateProvider { - public static final List SMALL_CUBE_VOXELS = new ArrayList<>(8); + public static final VoxelShape[] SMALL_CUBE_VOXELS; public ReFramedSmallCubeBlock(Settings settings) { super(settings); @@ -63,16 +60,7 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock implement @Override public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - return switch (state.get(CORNER)) { - case NORTH_EAST_DOWN -> SMALL_CUBE_VOXELS.get(0); - case EAST_SOUTH_DOWN -> SMALL_CUBE_VOXELS.get(1); - case SOUTH_WEST_DOWN -> SMALL_CUBE_VOXELS.get(2); - case WEST_NORTH_DOWN -> SMALL_CUBE_VOXELS.get(3); - case NORTH_EAST_UP -> SMALL_CUBE_VOXELS.get(4); - case EAST_SOUTH_UP -> SMALL_CUBE_VOXELS.get(5); - case SOUTH_WEST_UP -> SMALL_CUBE_VOXELS.get(6); - case WEST_NORTH_UP -> SMALL_CUBE_VOXELS.get(7); - }; + return SMALL_CUBE_VOXELS[state.get(CORNER).getID()]; } @Override @@ -111,14 +99,15 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock implement static { final VoxelShape SMALL_CUBE = VoxelShapes.cuboid(.5f, 0f, 0f, 1f, .5f, .5f); - SMALL_CUBE_VOXELS.add(SMALL_CUBE); - SMALL_CUBE_VOXELS.add(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y)); - SMALL_CUBE_VOXELS.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y)); - SMALL_CUBE_VOXELS.add(VoxelHelper.rotateCounterClockwise(SMALL_CUBE, Direction.Axis.Y)); + SMALL_CUBE_VOXELS = VoxelListBuilder.create(SMALL_CUBE, 8) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) - SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(SMALL_CUBE, Direction.Axis.Y)); - SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y)); - SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y), Direction.Axis.Y)); - SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y)); + .add(SMALL_CUBE, VoxelHelper::mirrorY) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) + .build(); } } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java index 7a50811..cf663bd 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java @@ -4,6 +4,7 @@ import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; import fr.adrien1106.reframed.util.blocks.Edge; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; @@ -13,7 +14,7 @@ import net.minecraft.data.client.BlockStateSupplier; import net.minecraft.data.client.MultipartBlockStateSupplier; import net.minecraft.data.server.recipe.RecipeExporter; import net.minecraft.data.server.recipe.RecipeProvider; -import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; import net.minecraft.item.ItemPlacementContext; import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.state.StateManager; @@ -70,20 +71,14 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc @Override public VoxelShape getShape(BlockState state, int i) { - return switch (state.get(EDGE)) { - case NORTH_DOWN -> SMALL_CUBE_VOXELS.get(i == 1 ? 3 : 0); - case DOWN_SOUTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 1 : 2); - case SOUTH_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 6 : 5); - case UP_NORTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 4 : 7); - case WEST_DOWN -> SMALL_CUBE_VOXELS.get(i == 1 ? 2 : 3); - case DOWN_EAST -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 1); - case EAST_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 5 : 4); - case UP_WEST -> SMALL_CUBE_VOXELS.get(i == 1 ? 7 : 6); - case WEST_NORTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 3 : 7); - case NORTH_EAST -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 4); - case EAST_SOUTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 1 : 5); - case SOUTH_WEST -> SMALL_CUBE_VOXELS.get(i == 1 ? 2 : 6); - }; + Edge edge = state.get(EDGE); + return SMALL_CUBE_VOXELS[Corner.getByDirections( + edge.getFirstDirection(), + edge.getSecondDirection(), + i == 1 + ? edge.getRightDirection() + : edge.getLeftDirection() + ).getID()]; } @Override @@ -93,44 +88,44 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc @Override public BlockStateSupplier getMultipart() { - Identifier small_cube_id = ReFramed.id("double_small_cube_special"); + Identifier model_id = ReFramed.id("small_cubes_step_special"); + Identifier reverse_model_id = ReFramed.id("small_cubes_step_reverse_special"); return MultipartBlockStateSupplier.create(this) /* X AXIS */ .with(GBlockstate.when(EDGE, DOWN_EAST), - GBlockstate.variant(small_cube_id, true, R0, R0)) + GBlockstate.variant(reverse_model_id, true, R0, R0)) .with(GBlockstate.when(EDGE, EAST_UP), - GBlockstate.variant(small_cube_id, true, R180, R0)) + GBlockstate.variant(model_id, true, R180, R0)) .with(GBlockstate.when(EDGE, UP_WEST), - GBlockstate.variant(small_cube_id, true, R180, R180)) + GBlockstate.variant(reverse_model_id, true, R180, R180)) .with(GBlockstate.when(EDGE, WEST_DOWN), - GBlockstate.variant(small_cube_id, true, R0, R180)) + GBlockstate.variant(model_id, true, R0, R180)) /* Y AXIS */ .with(GBlockstate.when(EDGE, EAST_SOUTH), - GBlockstate.variant(small_cube_id, true, R90, R0)) + GBlockstate.variant(model_id, true, R90, R0)) .with(GBlockstate.when(EDGE, SOUTH_WEST), - GBlockstate.variant(small_cube_id, true, R90, R90)) + GBlockstate.variant(model_id, true, R90, R90)) .with(GBlockstate.when(EDGE, WEST_NORTH), - GBlockstate.variant(small_cube_id, true, R90, R180)) + GBlockstate.variant(model_id, true, R90, R180)) .with(GBlockstate.when(EDGE, NORTH_EAST), - GBlockstate.variant(small_cube_id, true, R90, R270)) + GBlockstate.variant(model_id, true, R90, R270)) /* Z AXIS */ .with(GBlockstate.when(EDGE, DOWN_SOUTH), - GBlockstate.variant(small_cube_id, true, R0, R90)) + GBlockstate.variant(reverse_model_id, true, R0, R90)) .with(GBlockstate.when(EDGE, NORTH_DOWN), - GBlockstate.variant(small_cube_id, true, R0, R270)) + GBlockstate.variant(model_id, true, R0, R270)) .with(GBlockstate.when(EDGE, UP_NORTH), - GBlockstate.variant(small_cube_id, true, R180, R270)) + GBlockstate.variant(reverse_model_id, true, R180, R270)) .with(GBlockstate.when(EDGE, SOUTH_UP), - GBlockstate.variant(small_cube_id, true, R180, R90)); + GBlockstate.variant(model_id, true, R180, R90)); } @Override public void setRecipe(RecipeExporter exporter) { RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 4); - ShapedRecipeJsonBuilder + ShapelessRecipeJsonBuilder .create(RecipeCategory.BUILDING_BLOCKS, this) - .pattern("II") - .input('I', ReFramed.SMALL_CUBE) + .input(ReFramed.SMALL_CUBE, 2) .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) .offerTo(exporter); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java index a4386c8..452fe21 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java @@ -1,17 +1,18 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; -import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.util.VoxelHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.blocks.Edge; import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; -import net.minecraft.data.client.*; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.data.client.When; import net.minecraft.data.server.recipe.RecipeExporter; import net.minecraft.data.server.recipe.RecipeProvider; import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; @@ -22,7 +23,6 @@ import net.minecraft.util.Identifier; import net.minecraft.util.function.BooleanBiFunction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Direction.Axis; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; @@ -30,18 +30,17 @@ import net.minecraft.world.World; import net.minecraft.world.WorldAccess; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; import java.util.stream.Stream; -import static fr.adrien1106.reframed.util.blocks.BlockProperties.*; +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE; +import static fr.adrien1106.reframed.util.blocks.Edge.*; import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; -import static fr.adrien1106.reframed.util.blocks.Edge.*; public class ReFramedStairBlock extends WaterloggableReFramedBlock implements BlockStateProvider { - - public static final List VOXEL_LIST = new ArrayList<>(52); + public static final VoxelShape[] STAIR_VOXELS; private record ModelCacheKey(Edge edge, StairShape shape) {} public ReFramedStairBlock(Settings settings) { @@ -85,124 +84,13 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos); } - /* ---------------------------------- DON'T GO FURTHER IF YOU LIKE HAVING EYES ---------------------------------- */ @Override public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - return getOutline(state); + return getStairShape(state.get(EDGE), state.get(STAIR_SHAPE)); } - public static VoxelShape getOutline(BlockState state) { - StairShape shape = state.get(STAIR_SHAPE); - Edge direction = state.get(EDGE); - return switch (shape) { - case STRAIGHT -> - switch (direction) { - case DOWN_SOUTH -> VOXEL_LIST.get(0); - case NORTH_DOWN -> VOXEL_LIST.get(1); - case UP_NORTH -> VOXEL_LIST.get(2); - case SOUTH_UP -> VOXEL_LIST.get(3); - case DOWN_EAST -> VOXEL_LIST.get(4); - case WEST_DOWN -> VOXEL_LIST.get(5); - case UP_WEST -> VOXEL_LIST.get(6); - case EAST_UP -> VOXEL_LIST.get(7); - case NORTH_EAST -> VOXEL_LIST.get(8); - case EAST_SOUTH -> VOXEL_LIST.get(9); - case SOUTH_WEST -> VOXEL_LIST.get(10); - case WEST_NORTH -> VOXEL_LIST.get(11); - }; - case INNER_LEFT -> - switch (direction) { - case WEST_DOWN, NORTH_DOWN -> VOXEL_LIST.get(44); - case DOWN_EAST -> VOXEL_LIST.get(45); - case DOWN_SOUTH -> VOXEL_LIST.get(47); - case UP_WEST, UP_NORTH, WEST_NORTH -> VOXEL_LIST.get(48); - case EAST_UP, NORTH_EAST -> VOXEL_LIST.get(49); - case EAST_SOUTH -> VOXEL_LIST.get(50); - case SOUTH_UP, SOUTH_WEST -> VOXEL_LIST.get(51); - }; - case INNER_RIGHT -> - switch (direction) { - case WEST_NORTH -> VOXEL_LIST.get(44); - case NORTH_DOWN, NORTH_EAST -> VOXEL_LIST.get(45); - case DOWN_EAST, DOWN_SOUTH, EAST_SOUTH -> VOXEL_LIST.get(46); - case WEST_DOWN, SOUTH_WEST -> VOXEL_LIST.get(47); - case UP_NORTH -> VOXEL_LIST.get(49); - case EAST_UP, SOUTH_UP -> VOXEL_LIST.get(50); - case UP_WEST -> VOXEL_LIST.get(51); - }; - case OUTER_LEFT -> - switch (direction) { - case DOWN_EAST -> VOXEL_LIST.get(43); - case WEST_DOWN, NORTH_DOWN -> VOXEL_LIST.get(42); - case DOWN_SOUTH -> VOXEL_LIST.get(41); - case EAST_UP, NORTH_EAST -> VOXEL_LIST.get(39); - case UP_WEST, UP_NORTH, WEST_NORTH -> VOXEL_LIST.get(38); - case SOUTH_UP, SOUTH_WEST -> VOXEL_LIST.get(37); - case EAST_SOUTH -> VOXEL_LIST.get(36); - }; - case OUTER_RIGHT -> - switch (direction) { - case NORTH_DOWN, NORTH_EAST -> VOXEL_LIST.get(43); - case WEST_NORTH -> VOXEL_LIST.get(42); - case WEST_DOWN, SOUTH_WEST -> VOXEL_LIST.get(41); - case DOWN_EAST, DOWN_SOUTH, EAST_SOUTH -> VOXEL_LIST.get(40); - case UP_NORTH -> VOXEL_LIST.get(39); - case UP_WEST -> VOXEL_LIST.get(37); - case EAST_UP, SOUTH_UP -> VOXEL_LIST.get(36); - }; - case FIRST_OUTER_LEFT -> - switch (direction) { - case WEST_DOWN, NORTH_DOWN -> VOXEL_LIST.get(14); - case SOUTH_UP -> VOXEL_LIST.get(17); - case EAST_UP -> VOXEL_LIST.get(19); - case EAST_SOUTH -> VOXEL_LIST.get(20); - case DOWN_SOUTH -> VOXEL_LIST.get(22); - case UP_NORTH, WEST_NORTH -> VOXEL_LIST.get(25); - case SOUTH_WEST -> VOXEL_LIST.get(28); - case UP_WEST -> VOXEL_LIST.get(31); - case DOWN_EAST -> VOXEL_LIST.get(34); - case NORTH_EAST -> VOXEL_LIST.get(35); - }; - case FIRST_OUTER_RIGHT -> - switch (direction) { - case NORTH_DOWN -> VOXEL_LIST.get(15); - case SOUTH_UP, EAST_UP -> VOXEL_LIST.get(16); - case WEST_DOWN -> VOXEL_LIST.get(13); - case DOWN_SOUTH, EAST_SOUTH -> VOXEL_LIST.get(23); - case UP_NORTH -> VOXEL_LIST.get(24); - case WEST_NORTH -> VOXEL_LIST.get(26); - case UP_WEST -> VOXEL_LIST.get(28); - case SOUTH_WEST -> VOXEL_LIST.get(29); - case DOWN_EAST -> VOXEL_LIST.get(33); - case NORTH_EAST -> VOXEL_LIST.get(34); - }; - case SECOND_OUTER_LEFT -> - switch (direction) { - case DOWN_EAST -> VOXEL_LIST.get(15); - case DOWN_SOUTH -> VOXEL_LIST.get(13); - case UP_WEST, UP_NORTH -> VOXEL_LIST.get(18); - case SOUTH_UP, SOUTH_WEST -> VOXEL_LIST.get(21); - case NORTH_EAST -> VOXEL_LIST.get(24); - case NORTH_DOWN -> VOXEL_LIST.get(26); - case WEST_DOWN -> VOXEL_LIST.get(30); - case WEST_NORTH -> VOXEL_LIST.get(31); - case EAST_SOUTH -> VOXEL_LIST.get(32); - case EAST_UP -> VOXEL_LIST.get(35); - }; - case SECOND_OUTER_RIGHT -> - switch (direction) { - case DOWN_SOUTH, DOWN_EAST -> VOXEL_LIST.get(12); - case UP_WEST -> VOXEL_LIST.get(17); - case UP_NORTH -> VOXEL_LIST.get(19); - case SOUTH_UP -> VOXEL_LIST.get(20); - case SOUTH_WEST -> VOXEL_LIST.get(22); - case NORTH_EAST, NORTH_DOWN -> VOXEL_LIST.get(27); - case WEST_DOWN -> VOXEL_LIST.get(29); - case WEST_NORTH -> VOXEL_LIST.get(30); - case EAST_UP -> VOXEL_LIST.get(32); - case EAST_SOUTH -> VOXEL_LIST.get(33); - }; - }; + public static VoxelShape getStairShape(Edge edge, StairShape shape) { + return STAIR_VOXELS[edge.getID() * 9 + shape.getID()]; } @Override @@ -211,12 +99,12 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl } public static MultipartBlockStateSupplier getStairMultipart(Block block, boolean is_double) { - String prefix = is_double ? "double_" : ""; - Identifier straight_id = ReFramed.id(prefix + "stairs_special"); - Identifier double_outer_id = ReFramed.id(prefix + "outers_stairs_special"); - Identifier inner_id = ReFramed.id(prefix + "inner_stairs_special"); - Identifier outer_id = ReFramed.id(prefix + "outer_stairs_special"); - Identifier outer_side_id = ReFramed.id(prefix + "outer_side_stairs_special"); + String infix = is_double ? "s_cube" : ""; + Identifier straight_id = ReFramed.id("stair" + infix + "_special"); + Identifier double_outer_id = ReFramed.id("outers_stair" + infix + "_special"); + Identifier inner_id = ReFramed.id("inner_stair" + infix + "_special"); + Identifier outer_id = ReFramed.id("outer_stair" + infix + "_special"); + Identifier outer_side_id = ReFramed.id("outer_side_stair" + infix + "_special"); return MultipartBlockStateSupplier.create(block) /* STRAIGHT X AXIS */ .with(GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, STRAIGHT), @@ -247,22 +135,22 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl GBlockstate.variant(straight_id, true, R180, R90)) /* INNER BOTTOM */ .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R0, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R0, R270)) .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R0, R0)) .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R0, R90)) @@ -270,55 +158,55 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl .with(When.anyOf( GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_RIGHT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R180, R0)) .with(When.anyOf( GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_RIGHT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R180, R90)) .with(When.anyOf( - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R180, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R180, R270)) /* OUTER BOTTOM */ .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R0, R0)) .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R0, R90)) .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R0, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R0, R270)) /* OUTER TOP */ .with(When.anyOf( - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R180, R0)) .with(When.anyOf( - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_LEFT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R180, R90)) .with(When.anyOf( - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_LEFT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R180, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R180, R270)) /* OUTER EAST */ @@ -341,19 +229,19 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl /* OUTER SOUTH */ .with(When.anyOf( GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT), - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R0, R90)) .with(When.anyOf( GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT), - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R90, R90)) .with(When.anyOf( GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT), - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R180, R90)) .with(When.anyOf( GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT), - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R270, R90)) /* OUTER WEST */ .with(When.anyOf( @@ -375,59 +263,59 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl /* OUTER NORTH */ .with(When.anyOf( GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT), - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R0, R270)) .with(When.anyOf( GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT), - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R90, R270)) .with(When.anyOf( GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT), - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R180, R270)) .with(When.anyOf( GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT), - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R270, R270)) /* OUTER BOTTOM */ .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R0)) .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R90)) .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R270)) /* OUTER TOP */ .with(When.anyOf( - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R0)) .with(When.anyOf( - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R90)) .with(When.anyOf( - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R270)); @@ -448,89 +336,98 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl } static { - final VoxelShape STRAIGHT = Stream.of( - VoxelShapes.cuboid(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f), - VoxelShapes.cuboid(0.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f) - ).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get(); - final VoxelShape JUNCTION = Stream.of( - VoxelShapes.cuboid(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f), - VoxelShapes.cuboid(0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f) - ).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get(); - final VoxelShape OUTER = Stream.of( - VoxelShapes.cuboid(0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f), - VoxelShapes.cuboid(0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.5f), - VoxelShapes.cuboid(0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f), - VoxelShapes.cuboid(0.5f, 0.0f, 0.5f, 1.0f, 0.5f, 1.0f) - ).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get(); + final VoxelShape STRAIGHT = VoxelShapes.combineAndSimplify( + createCuboidShape(0, 8, 0, 16, 16, 8), + createCuboidShape(0, 0, 0, 16, 8, 16), + BooleanBiFunction.OR + ); final VoxelShape INNER = Stream.of( - VoxelShapes.cuboid(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f), - VoxelShapes.cuboid(0.0f, 0.5f, 0.0f, 0.5f, 1.0f, 1.0f), - VoxelShapes.cuboid(0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.5f) - ).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get(); + createCuboidShape(0, 8, 0, 16, 16, 8), + createCuboidShape(0, 8, 8, 8, 16, 16), + createCuboidShape(0, 0, 0, 16, 8, 16) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, BooleanBiFunction.OR)).get(); + final VoxelShape OUTER = Stream.of( + createCuboidShape(0, 8, 0, 8, 16, 8), + createCuboidShape(8, 0, 0, 16, 8, 8), + createCuboidShape(0, 0, 0, 8, 8, 16) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, BooleanBiFunction.OR)).get(); + final VoxelShape JUNCTION = VoxelShapes.combineAndSimplify( + createCuboidShape(0, 8, 0, 8, 16, 8), + createCuboidShape(0, 0, 0, 16, 8, 16), + BooleanBiFunction.OR + ); - VOXEL_LIST.add(STRAIGHT); - VOXEL_LIST.add(VoxelHelper.mirror(STRAIGHT, Axis.Z)); - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.X), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.X)); - - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y), Axis.X)); - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y), Axis.Z), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y), Axis.Z)); - - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z), Axis.Y), Axis.Z)); - - VOXEL_LIST.add(JUNCTION); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(JUNCTION, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(JUNCTION, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.Y)); - - VOXEL_LIST.add(VoxelHelper.mirror(JUNCTION, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(JUNCTION, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.mirror(JUNCTION, Axis.Y), Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(JUNCTION, Axis.Y), Axis.Y)); - - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z)); - - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z)); - - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X)); - - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X)); - - VOXEL_LIST.add(OUTER); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(OUTER, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(OUTER, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(OUTER, Axis.Y)); - - VOXEL_LIST.add(VoxelHelper.mirror(OUTER, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(OUTER, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(OUTER, Axis.Y), Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(OUTER, Axis.Y), Axis.Y)); - - VOXEL_LIST.add(INNER); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(INNER, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(INNER, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(INNER, Axis.Y)); - - VOXEL_LIST.add(VoxelHelper.mirror(INNER, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(INNER, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(INNER, Axis.Y), Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(INNER, Axis.Y), Axis.Y)); + STAIR_VOXELS = VoxelListBuilder.create(STRAIGHT, 108) + .add(INNER).add(VoxelHelper::rotateY) + .add(OUTER).add(VoxelHelper::rotateY) + .add(JUNCTION).add(VoxelHelper::rotateY) + .add(JUNCTION, VoxelHelper::rotateX, VoxelHelper::rotateZ).add(VoxelHelper::rotateZ) + // DOWN_SOUTH + .add(0, VoxelHelper::rotateCX) + .add(1, VoxelHelper::rotateCX).add(2, VoxelHelper::rotateCX) + .add(3, VoxelHelper::rotateCX).add(4, VoxelHelper::rotateCX) + .add(5, VoxelHelper::rotateCX).add(6, VoxelHelper::rotateCX) + .add(7, VoxelHelper::rotateCX).add(8, VoxelHelper::rotateCX) + // SOUTH_UP + .add(9, VoxelHelper::rotateCX) + .add(10, VoxelHelper::rotateCX).add(11, VoxelHelper::rotateCX) + .add(12, VoxelHelper::rotateCX).add(13, VoxelHelper::rotateCX) + .add(14, VoxelHelper::rotateCX).add(15, VoxelHelper::rotateCX) + .add(16, VoxelHelper::rotateCX).add(17, VoxelHelper::rotateCX) + // UP_NORTH + .add(18, VoxelHelper::rotateCX) + .add(19, VoxelHelper::rotateCX).add(20, VoxelHelper::rotateCX) + .add(21, VoxelHelper::rotateCX).add(22, VoxelHelper::rotateCX) + .add(23, VoxelHelper::rotateCX).add(24, VoxelHelper::rotateCX) + .add(25, VoxelHelper::rotateCX).add(26, VoxelHelper::rotateCX) + // WEST_DOWN + .add(0, VoxelHelper::rotateCY) + .add(10).add(1) + .add(12).add(3) + .add(16).add(5) + .add(7, VoxelHelper::rotateCY).add(8, VoxelHelper::rotateCY) + // DOWN_EAST + .add(36, VoxelHelper::rotateZ) + .add(11).add(2) + .add(13).add(4) + .add(41, VoxelHelper::rotateZ).add(42, VoxelHelper::rotateZ) + .add(17).add(6) + // EAST_UP + .add(45, VoxelHelper::rotateZ) + .add(20).add(29) + .add(22).add(31) + .add(24).add(35) + .add(52, VoxelHelper::rotateZ).add(53, VoxelHelper::rotateZ) + // UP_WEST + .add(54, VoxelHelper::rotateZ) + .add(19).add(28) + .add(21).add(30) + .add(59, VoxelHelper::rotateZ).add(60, VoxelHelper::rotateZ) + .add(23).add(34) + // WEST_NORTH + .add(0, VoxelHelper::rotateCZ) + .add(1).add(28) + .add(3).add(30) + .add(7).add(32) + .add(44).add(69) + // NORTH_EAST + .add(72, VoxelHelper::rotateY) + .add(2).add(29) + .add(4).add(31) + .add(51).add(62) + .add(8).add(33) + // EAST_SOUTH + .add(81, VoxelHelper::rotateY) + .add(11).add(20) + .add(13).add(22) + .add(15).add(26) + .add(50).add(61) + // SOUTH_WEST + .add(90, VoxelHelper::rotateY) + .add(10).add(19) + .add(12).add(21) + .add(43).add(68) + .add(14).add(25) + .build(); } } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java index 8af13f1..60b44f9 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java @@ -15,25 +15,21 @@ import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; import net.minecraft.item.ItemPlacementContext; import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.state.StateManager; -import net.minecraft.util.function.BooleanBiFunction; 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.World; import net.minecraft.world.WorldAccess; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - import static fr.adrien1106.reframed.block.ReFramedStairBlock.*; +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE; public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements BlockStateProvider { - private static final List COMPLEMENT_LIST = new ArrayList<>(52); + private static final VoxelShape[] STAIRS_CUBE_VOXELS = VoxelListBuilder.buildFrom(STAIR_VOXELS); private record ModelCacheKey(Edge edge, StairShape shape) {} public ReFramedStairsCubeBlock(Settings settings) { @@ -80,121 +76,9 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements Bloc @Override public VoxelShape getShape(BlockState state, int i) { - return i == 2 ? getComplementOutline(state) : getOutline(state); - } - - private VoxelShape getComplementOutline(BlockState state) { + Edge edge = state.get(EDGE); StairShape shape = state.get(STAIR_SHAPE); - Edge direction = state.get(EDGE); - return switch (shape) { - case STRAIGHT -> - switch (direction) { - case DOWN_SOUTH -> COMPLEMENT_LIST.get(0); - case NORTH_DOWN -> COMPLEMENT_LIST.get(1); - case UP_NORTH -> COMPLEMENT_LIST.get(2); - case SOUTH_UP -> COMPLEMENT_LIST.get(3); - case DOWN_EAST -> COMPLEMENT_LIST.get(4); - case WEST_DOWN -> COMPLEMENT_LIST.get(5); - case UP_WEST -> COMPLEMENT_LIST.get(6); - case EAST_UP -> COMPLEMENT_LIST.get(7); - case NORTH_EAST -> COMPLEMENT_LIST.get(8); - case EAST_SOUTH -> COMPLEMENT_LIST.get(9); - case SOUTH_WEST -> COMPLEMENT_LIST.get(10); - case WEST_NORTH -> COMPLEMENT_LIST.get(11); - }; - case INNER_LEFT -> - switch (direction) { - case WEST_DOWN, NORTH_DOWN -> COMPLEMENT_LIST.get(44); - case DOWN_EAST -> COMPLEMENT_LIST.get(45); - case DOWN_SOUTH -> COMPLEMENT_LIST.get(47); - case UP_WEST, UP_NORTH, WEST_NORTH -> COMPLEMENT_LIST.get(48); - case EAST_UP, NORTH_EAST -> COMPLEMENT_LIST.get(49); - case EAST_SOUTH -> COMPLEMENT_LIST.get(50); - case SOUTH_UP, SOUTH_WEST -> COMPLEMENT_LIST.get(51); - }; - case INNER_RIGHT -> - switch (direction) { - case WEST_NORTH -> COMPLEMENT_LIST.get(44); - case NORTH_DOWN, NORTH_EAST -> COMPLEMENT_LIST.get(45); - case DOWN_EAST, DOWN_SOUTH, EAST_SOUTH -> COMPLEMENT_LIST.get(46); - case WEST_DOWN, SOUTH_WEST -> COMPLEMENT_LIST.get(47); - case UP_NORTH -> COMPLEMENT_LIST.get(49); - case EAST_UP, SOUTH_UP -> COMPLEMENT_LIST.get(50); - case UP_WEST -> COMPLEMENT_LIST.get(51); - }; - case OUTER_LEFT -> - switch (direction) { - case DOWN_EAST -> COMPLEMENT_LIST.get(43); - case WEST_DOWN, NORTH_DOWN -> COMPLEMENT_LIST.get(42); - case DOWN_SOUTH -> COMPLEMENT_LIST.get(41); - case EAST_UP, NORTH_EAST -> COMPLEMENT_LIST.get(39); - case UP_WEST, UP_NORTH, WEST_NORTH -> COMPLEMENT_LIST.get(38); - case SOUTH_UP, SOUTH_WEST -> COMPLEMENT_LIST.get(37); - case EAST_SOUTH -> COMPLEMENT_LIST.get(36); - }; - case OUTER_RIGHT -> - switch (direction) { - case NORTH_DOWN, NORTH_EAST -> COMPLEMENT_LIST.get(43); - case WEST_NORTH -> COMPLEMENT_LIST.get(42); - case WEST_DOWN, SOUTH_WEST -> COMPLEMENT_LIST.get(41); - case DOWN_EAST, DOWN_SOUTH, EAST_SOUTH -> COMPLEMENT_LIST.get(40); - case UP_NORTH -> COMPLEMENT_LIST.get(39); - case UP_WEST -> COMPLEMENT_LIST.get(37); - case EAST_UP, SOUTH_UP -> COMPLEMENT_LIST.get(36); - }; - case FIRST_OUTER_LEFT -> - switch (direction) { - case WEST_DOWN, NORTH_DOWN -> COMPLEMENT_LIST.get(14); - case SOUTH_UP -> COMPLEMENT_LIST.get(17); - case EAST_UP -> COMPLEMENT_LIST.get(19); - case EAST_SOUTH -> COMPLEMENT_LIST.get(20); - case DOWN_SOUTH -> COMPLEMENT_LIST.get(22); - case UP_NORTH, WEST_NORTH -> COMPLEMENT_LIST.get(25); - case SOUTH_WEST -> COMPLEMENT_LIST.get(28); - case UP_WEST -> COMPLEMENT_LIST.get(31); - case DOWN_EAST -> COMPLEMENT_LIST.get(34); - case NORTH_EAST -> COMPLEMENT_LIST.get(35); - }; - case FIRST_OUTER_RIGHT -> - switch (direction) { - case NORTH_DOWN -> COMPLEMENT_LIST.get(15); - case SOUTH_UP, EAST_UP -> COMPLEMENT_LIST.get(16); - case WEST_DOWN -> COMPLEMENT_LIST.get(13); - case DOWN_SOUTH, EAST_SOUTH -> COMPLEMENT_LIST.get(23); - case UP_NORTH -> COMPLEMENT_LIST.get(24); - case WEST_NORTH -> COMPLEMENT_LIST.get(26); - case UP_WEST -> COMPLEMENT_LIST.get(28); - case SOUTH_WEST -> COMPLEMENT_LIST.get(29); - case DOWN_EAST -> COMPLEMENT_LIST.get(33); - case NORTH_EAST -> COMPLEMENT_LIST.get(34); - }; - case SECOND_OUTER_LEFT -> - switch (direction) { - case DOWN_EAST -> COMPLEMENT_LIST.get(15); - case DOWN_SOUTH -> COMPLEMENT_LIST.get(13); - case UP_WEST, UP_NORTH -> COMPLEMENT_LIST.get(18); - case SOUTH_UP, SOUTH_WEST -> COMPLEMENT_LIST.get(21); - case NORTH_EAST -> COMPLEMENT_LIST.get(24); - case NORTH_DOWN -> COMPLEMENT_LIST.get(26); - case WEST_DOWN -> COMPLEMENT_LIST.get(30); - case WEST_NORTH -> COMPLEMENT_LIST.get(31); - case EAST_SOUTH -> COMPLEMENT_LIST.get(32); - case EAST_UP -> COMPLEMENT_LIST.get(35); - }; - case SECOND_OUTER_RIGHT -> - switch (direction) { - case DOWN_SOUTH, DOWN_EAST -> COMPLEMENT_LIST.get(12); - case UP_WEST -> COMPLEMENT_LIST.get(17); - case UP_NORTH -> COMPLEMENT_LIST.get(19); - case SOUTH_UP -> COMPLEMENT_LIST.get(20); - case SOUTH_WEST -> COMPLEMENT_LIST.get(22); - case NORTH_EAST, NORTH_DOWN -> COMPLEMENT_LIST.get(27); - case WEST_DOWN -> COMPLEMENT_LIST.get(29); - case WEST_NORTH -> COMPLEMENT_LIST.get(30); - case EAST_UP -> COMPLEMENT_LIST.get(32); - case EAST_SOUTH -> COMPLEMENT_LIST.get(33); - }; - }; + return i == 2 ? STAIRS_CUBE_VOXELS[edge.getID() * 9 + shape.getID()] : getStairShape(edge, shape); } @Override @@ -213,8 +97,4 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements Bloc .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) .offerTo(exporter); } - - static { - VOXEL_LIST.forEach(shape -> COMPLEMENT_LIST.add(VoxelShapes.combineAndSimplify(VoxelShapes.fullCube(), shape, BooleanBiFunction.ONLY_FIRST))); - } } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java index 3df062c..fa7f969 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java @@ -1,15 +1,16 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; -import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.util.VoxelHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.blocks.Edge; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.BlockStateSupplier; import net.minecraft.data.client.MultipartBlockStateSupplier; import net.minecraft.data.server.recipe.RecipeExporter; import net.minecraft.data.server.recipe.RecipeProvider; @@ -19,22 +20,18 @@ import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.state.StateManager; import net.minecraft.util.Identifier; 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.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; import static fr.adrien1106.reframed.util.blocks.Edge.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; public class ReFramedStepBlock extends WaterloggableReFramedBlock implements BlockStateProvider { - public static final List STEP_VOXELS = new ArrayList<>(12); + public static final VoxelShape[] STEP_VOXELS; public ReFramedStepBlock(Settings settings) { super(settings); @@ -68,53 +65,40 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo } public static VoxelShape getStepShape(Edge edge) { - return switch (edge) { - case DOWN_SOUTH -> STEP_VOXELS.get(0); - case NORTH_DOWN -> STEP_VOXELS.get(1); - case UP_NORTH -> STEP_VOXELS.get(2); - case SOUTH_UP -> STEP_VOXELS.get(3); - case DOWN_EAST -> STEP_VOXELS.get(4); - case WEST_DOWN -> STEP_VOXELS.get(5); - case UP_WEST -> STEP_VOXELS.get(6); - case EAST_UP -> STEP_VOXELS.get(7); - case NORTH_EAST -> STEP_VOXELS.get(8); - case EAST_SOUTH -> STEP_VOXELS.get(9); - case SOUTH_WEST -> STEP_VOXELS.get(10); - case WEST_NORTH -> STEP_VOXELS.get(11); - }; + return STEP_VOXELS[edge.getID()]; } @Override - public MultipartBlockStateSupplier getMultipart() { - Identifier step_id = ReFramed.id("step_special"); + public BlockStateSupplier getMultipart() { + Identifier model_id = ReFramed.id("step_special"); return MultipartBlockStateSupplier.create(this) /* X AXIS */ .with(GBlockstate.when(EDGE, DOWN_EAST), - GBlockstate.variant(step_id, true, R0, R0)) + GBlockstate.variant(model_id, true, R0, R0)) .with(GBlockstate.when(EDGE, EAST_UP), - GBlockstate.variant(step_id, true, R180, R0)) + GBlockstate.variant(model_id, true, R180, R0)) .with(GBlockstate.when(EDGE, UP_WEST), - GBlockstate.variant(step_id, true, R180, R180)) + GBlockstate.variant(model_id, true, R180, R180)) .with(GBlockstate.when(EDGE, WEST_DOWN), - GBlockstate.variant(step_id, true, R0, R180)) + GBlockstate.variant(model_id, true, R0, R180)) /* Y AXIS */ .with(GBlockstate.when(EDGE, EAST_SOUTH), - GBlockstate.variant(step_id, true, R90, R0)) + GBlockstate.variant(model_id, true, R90, R0)) .with(GBlockstate.when(EDGE, SOUTH_WEST), - GBlockstate.variant(step_id, true, R90, R90)) + GBlockstate.variant(model_id, true, R90, R90)) .with(GBlockstate.when(EDGE, WEST_NORTH), - GBlockstate.variant(step_id, true, R90, R180)) + GBlockstate.variant(model_id, true, R90, R180)) .with(GBlockstate.when(EDGE, NORTH_EAST), - GBlockstate.variant(step_id, true, R90, R270)) + GBlockstate.variant(model_id, true, R90, R270)) /* Z AXIS */ .with(GBlockstate.when(EDGE, DOWN_SOUTH), - GBlockstate.variant(step_id, true, R0, R90)) + GBlockstate.variant(model_id, true, R0, R90)) .with(GBlockstate.when(EDGE, NORTH_DOWN), - GBlockstate.variant(step_id, true, R0, R270)) + GBlockstate.variant(model_id, true, R0, R270)) .with(GBlockstate.when(EDGE, UP_NORTH), - GBlockstate.variant(step_id, true, R180, R270)) + GBlockstate.variant(model_id, true, R180, R270)) .with(GBlockstate.when(EDGE, SOUTH_UP), - GBlockstate.variant(step_id, true, R180, R90)); + GBlockstate.variant(model_id, true, R180, R90)); } @Override @@ -130,21 +114,22 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo } static { - final VoxelShape STEP = VoxelShapes.cuboid(0f, 0f, .5f, 1f, .5f, 1f); + final VoxelShape STEP = createCuboidShape(0, 0, 0, 16, 8, 8); - STEP_VOXELS.add(STEP); - STEP_VOXELS.add(VoxelHelper.mirror(STEP, Direction.Axis.Z)); - STEP_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.X), Direction.Axis.Z)); - STEP_VOXELS.add(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.X)); + STEP_VOXELS = VoxelListBuilder.create(STEP, 12) + .add(VoxelHelper::rotateCX) + .add(VoxelHelper::rotateCX) + .add(VoxelHelper::rotateCX) - STEP_VOXELS.add(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.Y)); - STEP_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.Y), Direction.Axis.X)); - STEP_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.Y), Direction.Axis.Z), Direction.Axis.X)); - STEP_VOXELS.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.Y), Direction.Axis.Z)); + .add(STEP, VoxelHelper::rotateCY) + .add(VoxelHelper::rotateZ) + .add(VoxelHelper::rotateZ) + .add(VoxelHelper::rotateZ) - STEP_VOXELS.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateClockwise(STEP, Direction.Axis.Z), Direction.Axis.Y)); - STEP_VOXELS.add(VoxelHelper.rotateClockwise(STEP, Direction.Axis.Z)); - STEP_VOXELS.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(STEP, Direction.Axis.Z), Direction.Axis.Y)); - STEP_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(STEP, Direction.Axis.Z), Direction.Axis.Y), Direction.Axis.Z)); + .add(STEP, VoxelHelper::rotateCZ) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) + .build(); } } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java index 3b65d2f..c86688e 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java @@ -4,6 +4,7 @@ import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Edge; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -25,7 +26,7 @@ import net.minecraft.world.BlockView; import org.jetbrains.annotations.Nullable; import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape; -import static fr.adrien1106.reframed.block.ReFramedStepBlock.STEP_VOXELS; +import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape; import static net.minecraft.data.client.VariantSettings.Rotation.*; import static net.minecraft.state.property.Properties.AXIS; import static net.minecraft.state.property.Properties.FACING; @@ -75,14 +76,14 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock imp @Override public VoxelShape getShape(BlockState state, int i) { Axis axis = state.get(AXIS); - return STEP_VOXELS.get(switch (state.get(FACING)) { - case DOWN -> axis == Axis.Z ? (i == 1 ? 0 : 1): (i == 1 ? 4 : 5 ); - case UP -> axis == Axis.Z ? (i == 1 ? 3 : 2): (i == 1 ? 7 : 6 ); - case NORTH -> axis == Axis.Y ? (i == 1 ? 1 : 2): (i == 1 ? 11 : 8 ); - case SOUTH -> axis == Axis.Y ? (i == 1 ? 0 : 3): (i == 1 ? 9 : 10); - case EAST -> axis == Axis.Y ? (i == 1 ? 4 : 7): (i == 1 ? 8 : 9 ); - case WEST -> axis == Axis.Y ? (i == 1 ? 5 : 6): (i == 1 ? 10 : 11); - }); + return getStepShape(Edge.getByDirections( + state.get(FACING), + switch (axis) { + case X -> i == 1 ? Direction.WEST : Direction.EAST; + case Y -> i == 1 ? Direction.DOWN : Direction.UP; + case Z -> i == 1 ? Direction.SOUTH : Direction.NORTH; + } + )); } @Override @@ -92,24 +93,24 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock imp @Override public MultipartBlockStateSupplier getMultipart() { - Identifier step_id = ReFramed.id("double_step_special"); - Identifier step_side_id = ReFramed.id("double_step_side_special"); + Identifier step_id = ReFramed.id("steps_slab_special"); + Identifier step_side_id = ReFramed.id("steps_slab_side_special"); return MultipartBlockStateSupplier.create(this) .with(GBlockstate.when(FACING, Direction.DOWN, AXIS, Axis.X), - GBlockstate.variant(step_id, true, R0, R0)) + GBlockstate.variant(step_id, true, R0, R180)) .with(GBlockstate.when(FACING, Direction.DOWN, AXIS, Axis.Z), GBlockstate.variant(step_id, true, R0, R90)) .with(GBlockstate.when(FACING, Direction.UP, AXIS, Axis.X), - GBlockstate.variant(step_id, true, R180, R0)) + GBlockstate.variant(step_id, true, R180, R180)) .with(GBlockstate.when(FACING, Direction.UP, AXIS, Axis.Z), GBlockstate.variant(step_id, true, R180, R90)) .with(GBlockstate.when(FACING, Direction.EAST, AXIS, Axis.Z), - GBlockstate.variant(step_side_id, true, R0, R0)) + GBlockstate.variant(step_side_id, true, R180, R0)) .with(GBlockstate.when(FACING, Direction.EAST, AXIS, Axis.Y), GBlockstate.variant(step_side_id, true, R90, R0)) .with(GBlockstate.when(FACING, Direction.SOUTH, AXIS, Axis.X), - GBlockstate.variant(step_side_id, true, R0, R90)) + GBlockstate.variant(step_side_id, true, R180, R90)) .with(GBlockstate.when(FACING, Direction.SOUTH, AXIS, Axis.Y), GBlockstate.variant(step_side_id, true, R90, R90)) .with(GBlockstate.when(FACING, Direction.WEST, AXIS, Axis.Z), diff --git a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java index 329cde9..59e08fb 100644 --- a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java +++ b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java @@ -26,35 +26,68 @@ public class ReFramedClient implements ClientModInitializer { //all frames mustn't be on the SOLID layer because they are not opaque! BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0])); - HELPER.addReFramedModel("cube_special" , HELPER.auto(new Identifier("block/cube"))); - HELPER.addReFramedModel("small_cube_special" , HELPER.auto(ReFramed.id("block/small_cube"))); - HELPER.addReFramedModel("double_small_cube_special" , HELPER.autoDouble(ReFramed.id("block/small_cube"), ReFramed.id("block/small_cube_complement"))); - HELPER.addReFramedModel("slab_special" , HELPER.auto(new Identifier("block/slab"))); - HELPER.addReFramedModel("double_slab_special" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top"))); - HELPER.addReFramedModel("stairs_special" , HELPER.auto(ReFramed.id("block/stairs"))); - HELPER.addReFramedModel("outers_stairs_special" , HELPER.auto(ReFramed.id("block/double_outer_stairs"))); - HELPER.addReFramedModel("inner_stairs_special" , HELPER.auto(ReFramed.id("block/inner_stairs"))); - HELPER.addReFramedModel("outer_stairs_special" , HELPER.auto(ReFramed.id("block/outer_stairs"))); - HELPER.addReFramedModel("outer_side_stairs_special" , HELPER.auto(ReFramed.id("block/outer_side_stairs"))); - HELPER.addReFramedModel("double_stairs_special" , HELPER.autoDouble(ReFramed.id("block/stairs"), ReFramed.id("block/stairs_complement"))); - HELPER.addReFramedModel("double_outers_stairs_special" , HELPER.autoDouble(ReFramed.id("block/double_outer_stairs"), ReFramed.id("block/double_outer_stairs_complement"))); - HELPER.addReFramedModel("double_inner_stairs_special" , HELPER.autoDouble(ReFramed.id("block/inner_stairs"), ReFramed.id("block/inner_stairs_complement"))); - HELPER.addReFramedModel("double_outer_stairs_special" , HELPER.autoDouble(ReFramed.id("block/outer_stairs"), ReFramed.id("block/outer_stairs_complement"))); - HELPER.addReFramedModel("double_outer_side_stairs_special", HELPER.autoDouble(ReFramed.id("block/outer_side_stairs"), ReFramed.id("block/outer_side_stairs_complement"))); - HELPER.addReFramedModel("step_special" , HELPER.auto(ReFramed.id("block/step"))); - HELPER.addReFramedModel("double_step_special" , HELPER.autoDouble(ReFramed.id("block/step"), ReFramed.id("block/step_complement_slab"))); - HELPER.addReFramedModel("double_step_side_special" , HELPER.autoDouble(ReFramed.id("block/step_side"), ReFramed.id("block/step_side_complement_slab"))); + // CUBE + HELPER.addReFramedModel("cube_special" , HELPER.auto(new Identifier("block/cube"))); + // SMALL_CUBE + HELPER.addReFramedModel("small_cube_special" , HELPER.auto(ReFramed.id("block/small_cube/base"))); + // SMALL_CUBES_STEP + HELPER.addReFramedModel("small_cubes_step_special" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base"))); + HELPER.addReFramedModel("small_cubes_step_reverse_special" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base"))); + // SLAB + HELPER.addReFramedModel("slab_special" , HELPER.auto(new Identifier("block/slab"))); + // SLAB_CUBE + HELPER.addReFramedModel("double_slab_special" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top"))); + // STAIR + HELPER.addReFramedModel("stair_special" , HELPER.auto(ReFramed.id("block/stair/straight"))); + HELPER.addReFramedModel("outers_stair_special" , HELPER.auto(ReFramed.id("block/stair/double_outer"))); + HELPER.addReFramedModel("inner_stair_special" , HELPER.auto(ReFramed.id("block/stair/inner"))); + HELPER.addReFramedModel("outer_stair_special" , HELPER.auto(ReFramed.id("block/stair/outer"))); + HELPER.addReFramedModel("outer_side_stair_special" , HELPER.auto(ReFramed.id("block/stair/outer_side"))); + // STAIRS_CUBE + HELPER.addReFramedModel("stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight"))); + HELPER.addReFramedModel("outers_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer"))); + HELPER.addReFramedModel("inner_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner"))); + HELPER.addReFramedModel("outer_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer"))); + HELPER.addReFramedModel("outer_side_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side"))); + // HALF_STAIR + HELPER.addReFramedModel("half_stair_down_special" , HELPER.auto(ReFramed.id("block/half_stair/down"))); + HELPER.addReFramedModel("half_stair_side_special" , HELPER.auto(ReFramed.id("block/half_stair/side"))); + // HALF_STAIRS_SLAB + HELPER.addReFramedModel("half_stairs_slab_down_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down"))); + HELPER.addReFramedModel("half_stairs_slab_side_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side"))); + // HALF_STAIRS_STAIR + HELPER.addReFramedModel("half_stairs_stair_down_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down"))); + HELPER.addReFramedModel("half_stairs_stair_side_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side"))); + HELPER.addReFramedModel("half_stairs_stair_reverse_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side"))); + // STEP + HELPER.addReFramedModel("step_special" , HELPER.auto(ReFramed.id("block/step/down"))); + // STEPS_SLAB + HELPER.addReFramedModel("steps_slab_special" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down"))); + HELPER.addReFramedModel("steps_slab_side_special" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side"))); + // LAYER + HELPER.addReFramedModel("layer_1_special" , HELPER.auto(new Identifier("block/snow_height2"))); + HELPER.addReFramedModel("layer_2_special" , HELPER.auto(new Identifier("block/snow_height4"))); + HELPER.addReFramedModel("layer_3_special" , HELPER.auto(new Identifier("block/snow_height6"))); + HELPER.addReFramedModel("layer_4_special" , HELPER.auto(new Identifier("block/snow_height8"))); + HELPER.addReFramedModel("layer_5_special" , HELPER.auto(new Identifier("block/snow_height10"))); + HELPER.addReFramedModel("layer_6_special" , HELPER.auto(new Identifier("block/snow_height12"))); + HELPER.addReFramedModel("layer_7_special" , HELPER.auto(new Identifier("block/snow_height14"))); + HELPER.addReFramedModel("layer_8_special" , HELPER.auto(new Identifier("block/cube"))); //item model assignments (in lieu of models/item/___.json) HELPER.assignItemModel("cube_special" , ReFramed.CUBE); HELPER.assignItemModel("small_cube_special" , ReFramed.SMALL_CUBE); - HELPER.assignItemModel("double_small_cube_special" , ReFramed.SMALL_CUBES_STEP); + HELPER.assignItemModel("small_cubes_step_special" , ReFramed.SMALL_CUBES_STEP); HELPER.assignItemModel("slab_special" , ReFramed.SLAB); HELPER.assignItemModel("double_slab_special" , ReFramed.SLABS_CUBE); - HELPER.assignItemModel("stairs_special" , ReFramed.STAIR); - HELPER.assignItemModel("double_stairs_special" , ReFramed.STAIRS_CUBE); + HELPER.assignItemModel("stair_special" , ReFramed.STAIR); + HELPER.assignItemModel("stairs_cube_special" , ReFramed.STAIRS_CUBE); + HELPER.assignItemModel("half_stair_down_special" , ReFramed.HALF_STAIR); + HELPER.assignItemModel("half_stairs_slab_down_special" , ReFramed.HALF_STAIRS_SLAB); + HELPER.assignItemModel("half_stairs_stair_down_special", ReFramed.HALF_STAIRS_STAIR); HELPER.assignItemModel("step_special" , ReFramed.STEP); - HELPER.assignItemModel("double_step_special" , ReFramed.STEPS_SLAB); + HELPER.assignItemModel("steps_slab_special" , ReFramed.STEPS_SLAB); + HELPER.assignItemModel("layer_1_special" , ReFramed.LAYER); } private void privateInit() { diff --git a/src/main/java/fr/adrien1106/reframed/util/VoxelHelper.java b/src/main/java/fr/adrien1106/reframed/util/VoxelHelper.java index 885e552..ba4d0d8 100644 --- a/src/main/java/fr/adrien1106/reframed/util/VoxelHelper.java +++ b/src/main/java/fr/adrien1106/reframed/util/VoxelHelper.java @@ -5,68 +5,201 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; + +import static net.minecraft.util.shape.VoxelShapes.*; + public class VoxelHelper { + + /* ---------------------------------------- Methods for VoxelListBuilder ---------------------------------------- */ + public static VoxelShape rotateX(VoxelShape shape) { + return rotateClockwise(shape, Direction.Axis.X); + } + + public static VoxelShape rotateY(VoxelShape shape) { + return rotateClockwise(shape, Direction.Axis.Y); + } + public static VoxelShape rotateZ(VoxelShape shape) { + return rotateClockwise(shape, Direction.Axis.Z); + } + + public static VoxelShape rotateCX(VoxelShape shape) { + return rotateCounterClockwise(shape, Direction.Axis.X); + } + + public static VoxelShape rotateCY(VoxelShape shape) { + return rotateCounterClockwise(shape, Direction.Axis.Y); + } + public static VoxelShape rotateCZ(VoxelShape shape) { + return rotateCounterClockwise(shape, Direction.Axis.Z); + } + + public static VoxelShape mirrorX(VoxelShape shape) { + return mirror(shape, Direction.Axis.X); + } + + public static VoxelShape mirrorY(VoxelShape shape) { + return mirror(shape, Direction.Axis.Y); + } + public static VoxelShape mirrorZ(VoxelShape shape) { + return mirror(shape, Direction.Axis.Z); + } + public static VoxelShape rotateClockwise(VoxelShape shape, Direction.Axis axis) { - VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() }; - switch (axis) { - case Y: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( 1 - maxZ, minY, minX, 1 - minZ, maxY, maxX), BooleanBiFunction.OR)); - break; - case X: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, 1 - maxZ, minY, maxX, 1 - minZ, maxY), BooleanBiFunction.OR)); - break; - case Z: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( 1 - maxY, minX, minZ, 1 - minY, maxX, maxZ), BooleanBiFunction.OR)); - break; - } - return buffer[1]; + AtomicReference new_shape = new AtomicReference<>(empty()); + shape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> + new_shape.getAndUpdate(s -> + combineAndSimplify( + s, + switch (axis) { + case Y -> cuboid(1 - maxZ, minY, minX, 1 - minZ, maxY, maxX); + case X -> cuboid(minX, 1 - maxZ, minY, maxX, 1 - minZ, maxY); + case Z -> cuboid(1 - maxY, minX, minZ, 1 - minY, maxX, maxZ); + }, + BooleanBiFunction.OR + ) + ) + ); + return new_shape.get(); } public static VoxelShape rotateCounterClockwise(VoxelShape shape, Direction.Axis axis) { - VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() }; - switch (axis) { - case Y: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minZ, minY, 1 - maxX, maxZ, maxY, 1 - minX), BooleanBiFunction.OR)); - break; - case X: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, minZ, 1 - maxY, maxX, maxZ, 1 - minY), BooleanBiFunction.OR)); - break; - case Z: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minY, 1 - maxX, minZ, maxY, 1 - minX, maxZ), BooleanBiFunction.OR)); - break; - } - return buffer[1]; + AtomicReference new_shape = new AtomicReference<>(empty()); + shape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> + new_shape.getAndUpdate(s -> + combineAndSimplify( + s, + switch (axis) { + case Y -> cuboid(minZ, minY, 1 - maxX, maxZ, maxY, 1 - minX); + case X -> cuboid(minX, minZ, 1 - maxY, maxX, maxZ, 1 - minY); + case Z -> cuboid(minY, 1 - maxX, minZ, maxY, 1 - minX, maxZ); + }, + BooleanBiFunction.OR + ) + ) + ); + return new_shape.get(); } public static VoxelShape mirror(VoxelShape shape, Direction.Axis axis) { - VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() }; - switch (axis) { - case Y: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, 1 - maxY, minZ, maxX, 1 - minY, maxZ), BooleanBiFunction.OR)); - break; - case X: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( 1 - maxX, minY, minZ, 1 - minX, maxY, maxZ), BooleanBiFunction.OR)); - break; - case Z: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, minY, 1 - maxZ, maxX, maxY, 1 - minZ), BooleanBiFunction.OR)); - break; - } - return buffer[1]; + AtomicReference new_shape = new AtomicReference<>(empty()); + shape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> + new_shape.getAndUpdate(s -> + combineAndSimplify( + s, + switch (axis) { + case Y -> cuboid(minX, 1 - maxY, minZ, maxX, 1 - minY, maxZ); + case X -> cuboid(1 - maxX, minY, minZ, 1 - minX, maxY, maxZ); + case Z -> cuboid(minX, minY, 1 - maxZ, maxX, maxY, 1 - minZ); + }, + BooleanBiFunction.OR + ) + ) + ); + return new_shape.get(); } public static VoxelShape offset(VoxelShape shape, Direction.Axis axis, float offset) { - VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() }; - switch (axis) { - case Y: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, offset + minY, minZ, maxX, offset + maxY, maxZ), BooleanBiFunction.OR)); - break; - case X: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( offset + minX, minY, minZ, offset + maxX, maxY, maxZ), BooleanBiFunction.OR)); - break; - case Z: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, minY, offset + minZ, maxX, maxY, offset + maxZ), BooleanBiFunction.OR)); - break; + AtomicReference new_shape = new AtomicReference<>(empty()); + shape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> + new_shape.getAndUpdate(s -> + combineAndSimplify( + s, + switch (axis) { + case Y -> cuboid(minX, offset + minY, minZ, maxX, offset + maxY, maxZ); + case X -> cuboid(offset + minX, minY, minZ, offset + maxX, maxY, maxZ); + case Z -> cuboid(minX, minY, offset + minZ, maxX, maxY, offset + maxZ); + }, + BooleanBiFunction.OR + ) + ) + ); + return new_shape.get(); + } + + public static class VoxelListBuilder { + private final List voxels; + + /** + * A simple class that helps to get cleaner shape list generation (Hopefully) + * @param base_shape - the shape to start with + * @param size - the amount of shapes expected + */ + private VoxelListBuilder(VoxelShape base_shape, int size) { + voxels = new ArrayList<>(size); + voxels.add(base_shape); + } + + public static VoxelListBuilder create(VoxelShape base_shape, int size) { + return new VoxelListBuilder(base_shape, size); + } + + /** + * Add shape by applying modification to previous shape + * @param modifications - the modifications to apply @See {@link VoxelHelper} methods + * @return this instance + */ + @SafeVarargs + public final VoxelListBuilder add(Function... modifications) { + return add(voxels.size() - 1, modifications); + } + + /** + * Add shape by applying modifications to given shape + * @param ref - the index of the reference shape + * @param modifications - the modifications to apply @See {@link VoxelHelper} methods + * @return this instance + */ + @SafeVarargs + public final VoxelListBuilder add(int ref, Function... modifications) { + return add(voxels.get(ref), modifications); + } + + /** + * Add shape by applying modifications to given shape + * @param ref - the shape you want to add and apply modifications if present + * @param modifications - the modifications to apply @See {@link VoxelHelper} methods + * @return this instance + */ + @SafeVarargs + public final VoxelListBuilder add(VoxelShape ref, Function... modifications) { + for(Function modif: modifications) { + ref = modif.apply(ref); + } + voxels.add(ref); + return this; + } + + /** + * @return the final array of voxel shapes + */ + public VoxelShape[] build() { + return voxels.toArray(new VoxelShape[0]); + } + + /** + * build a new set of voxels based on th negation of the references and a full cube + * @param ref_voxels - the reference to subtract from the wanted shape + * @return the array of complementary voxels + */ + public static VoxelShape[] buildFrom(VoxelShape[] ref_voxels) { + return buildFrom(VoxelShapes.fullCube(), ref_voxels); + } + + /** + * build a new set of voxels based on th negation of the references and a wanted_shape + * @param ref_voxels - the reference to subtract from the wanted shape + * @return the array of complementary voxels + */ + public static VoxelShape[] buildFrom(VoxelShape wanted_shape, VoxelShape[] ref_voxels) { + VoxelShape[] shapes = new VoxelShape[ref_voxels.length]; + for (int i = 0; i < shapes.length; i++) { + shapes[i] = VoxelShapes.combineAndSimplify(wanted_shape, ref_voxels[i], BooleanBiFunction.ONLY_FIRST); + } + return shapes; } - return buffer[1]; } } diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java index c8a9296..a53ea94 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java @@ -2,10 +2,12 @@ package fr.adrien1106.reframed.util.blocks; import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.EnumProperty; +import net.minecraft.state.property.IntProperty; public class BlockProperties { public static final BooleanProperty LIGHT = BooleanProperty.of("emits_light"); public static final EnumProperty EDGE = EnumProperty.of("edge", Edge.class); public static final EnumProperty CORNER = EnumProperty.of("corner", Corner.class); + public static final IntProperty CORNER_FACE = IntProperty.of("face", 0, 2); public static final EnumProperty STAIR_SHAPE = EnumProperty.of("shape", StairShape.class); } diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java b/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java index bfa0801..1b16ea4 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java @@ -64,4 +64,34 @@ public enum Corner implements StringIdentifiable { .filter(value -> value.name().equals(name)) .findFirst().orElse(Corner.NORTH_EAST_DOWN); } + + public int getDirectionIndex(Direction side) { + return side == second_direction ? 1 : side == third_direction ? 2 : 0; + } + + public Direction getDirection(int index) { + return index == 1 ? second_direction : index == 2 ? third_direction : first_direction; + } + + public Corner getOpposite() { + return getByDirections(first_direction.getOpposite(), second_direction.getOpposite(), third_direction.getOpposite()); + } + + /** + * @param index - an index of the direction to keep and use as reference + * @return the opposite corner on same direction plane + */ + public Corner getOpposite(int index) { + return getOpposite(getDirection(index)); + } + + /** + * @param direction - a direction to keep and use as reference + * @return the opposite corner on same direction plane + */ + public Corner getOpposite(Direction direction) { + Direction other_1 = first_direction == direction ? second_direction : first_direction; + Direction other_2 = second_direction == direction || first_direction == direction ? third_direction : second_direction; + return getByDirections(direction, other_1.getOpposite(), other_2.getOpposite()); + } } diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java b/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java index f7df0af..3b23296 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java @@ -6,32 +6,30 @@ import net.minecraft.util.math.Direction; import java.util.Arrays; public enum Edge implements StringIdentifiable { - NORTH_DOWN("north_down", Direction.NORTH, Direction.DOWN, Direction.EAST, 0), - DOWN_SOUTH("down_south", Direction.DOWN, Direction.SOUTH, Direction.EAST, 1), - SOUTH_UP("south_up", Direction.SOUTH, Direction.UP, Direction.EAST, 2), - UP_NORTH("up_north", Direction.UP, Direction.NORTH, Direction.EAST, 3), - WEST_DOWN("west_down", Direction.WEST, Direction.DOWN, Direction.SOUTH, 4), - DOWN_EAST("down_east", Direction.DOWN, Direction.EAST, Direction.SOUTH, 5), - EAST_UP("east_up", Direction.EAST, Direction.UP, Direction.SOUTH, 6), - UP_WEST("up_west", Direction.UP, Direction.WEST, Direction.SOUTH, 7), - WEST_NORTH("west_north", Direction.WEST, Direction.NORTH, Direction.DOWN, 8), - NORTH_EAST("north_east", Direction.NORTH, Direction.EAST, Direction.DOWN, 9), - EAST_SOUTH("east_south", Direction.EAST, Direction.SOUTH, Direction.DOWN, 10), - SOUTH_WEST("south_west", Direction.SOUTH, Direction.WEST, Direction.DOWN, 11); + NORTH_DOWN("north_down", Direction.NORTH, Direction.DOWN, Direction.Axis.X, 0), + DOWN_SOUTH("down_south", Direction.DOWN, Direction.SOUTH, Direction.Axis.X, 1), + SOUTH_UP("south_up", Direction.SOUTH, Direction.UP, Direction.Axis.X, 2), + UP_NORTH("up_north", Direction.UP, Direction.NORTH, Direction.Axis.X, 3), + WEST_DOWN("west_down", Direction.WEST, Direction.DOWN, Direction.Axis.Z, 4), + DOWN_EAST("down_east", Direction.DOWN, Direction.EAST, Direction.Axis.Z, 5), + EAST_UP("east_up", Direction.EAST, Direction.UP, Direction.Axis.Z, 6), + UP_WEST("up_west", Direction.UP, Direction.WEST, Direction.Axis.Z, 7), + WEST_NORTH("west_north", Direction.WEST, Direction.NORTH, Direction.Axis.Y, 8), + NORTH_EAST("north_east", Direction.NORTH, Direction.EAST, Direction.Axis.Y, 9), + EAST_SOUTH("east_south", Direction.EAST, Direction.SOUTH, Direction.Axis.Y, 10), + SOUTH_WEST("south_west", Direction.SOUTH, Direction.WEST, Direction.Axis.Y, 11); private final String name; private final Direction first_direction; private final Direction second_direction; - private final Direction right_direction; - private final Direction left_direction; + private final Direction.Axis axis; private final int ID; - Edge(String name, Direction first_direction, Direction second_direction, Direction right_direction, int id) { + Edge(String name, Direction first_direction, Direction second_direction, Direction.Axis axis, int id) { this.name = name; this.first_direction = first_direction; this.second_direction = second_direction; - this.right_direction = right_direction; - this.left_direction = right_direction.getOpposite(); + this.axis = axis; this.ID = id; } @@ -51,10 +49,18 @@ public enum Edge implements StringIdentifiable { return second_direction; } public Direction getRightDirection() { - return right_direction; + return switch (axis) { + case X -> Direction.WEST; + case Y -> Direction.DOWN; + case Z -> Direction.SOUTH; + }; } public Direction getLeftDirection() { - return left_direction; + return switch (axis) { + case X -> Direction.EAST; + case Y -> Direction.UP; + case Z -> Direction.NORTH; + }; } public boolean hasDirection(Direction direction) { diff --git a/src/main/resources/assets/reframed/models/block/half_stair/down.json b/src/main/resources/assets/reframed/models/block/half_stair/down.json new file mode 100644 index 0000000..2df9bc2 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/down.json @@ -0,0 +1,55 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [8, 0, 8], + "to": [16, 8, 16], + "faces": { + "east": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 8, 16, 16], "texture": "#side"}, + "up": {"uv": [8, 8, 16, 16], "texture": "#top"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [8, 0, 0], + "to": [16, 8, 8], + "faces": { + "north": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "east"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#top"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [0, 0, 0], + "to": [8, 8, 8], + "faces": { + "north": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "north"}, + "south": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "west": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 0, 8, 8], "texture": "#top"}, + "down": {"uv": [0, 8, 8, 16], "texture": "#bottom", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_stair/side.json b/src/main/resources/assets/reframed/models/block/half_stair/side.json new file mode 100644 index 0000000..039ea0d --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/side.json @@ -0,0 +1,55 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [8, 8, 0], + "to": [16, 16, 8], + "faces": { + "north": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 0, 16, 8], "texture": "#side"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#side"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#top", "cullface": "up"} + } + }, + { + "from": [8, 0, 0], + "to": [16, 8, 8], + "faces": { + "north": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "east"}, + "west": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [8, 0, 8], + "to": [16, 8, 16], + "faces": { + "east": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 8, 16, 16], "texture": "#side"}, + "up": {"uv": [8, 8, 16, 16], "texture": "#top"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#bottom", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_stair/slab/down.json b/src/main/resources/assets/reframed/models/block/half_stair/slab/down.json new file mode 100644 index 0000000..b56aa5e --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/slab/down.json @@ -0,0 +1,35 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [0, 0, 8], + "to": [8, 8, 16], + "faces": { + "north": {"uv": [8, 8, 16, 16], "texture": "#side"}, + "east": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "south": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 8, 8, 16], "texture": "#top"}, + "down": {"uv": [0, 0, 8, 8], "texture": "#bottom", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_stair/slab/side.json b/src/main/resources/assets/reframed/models/block/half_stair/slab/side.json new file mode 100644 index 0000000..ca813e3 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/slab/side.json @@ -0,0 +1,35 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [8, 8, 8], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 0, 8, 8], "texture": "#side"}, + "east": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 0, 16, 8], "texture": "#side"}, + "up": {"uv": [8, 8, 16, 16], "texture": "#top", "cullface": "up"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#bottom"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_stair/stair/down.json b/src/main/resources/assets/reframed/models/block/half_stair/stair/down.json new file mode 100644 index 0000000..adba846 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/stair/down.json @@ -0,0 +1,55 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [8, 8, 8], + "to": [16, 16, 16], + "faces": { + "east": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 0, 16, 8], "texture": "#side"}, + "up": {"uv": [8, 8, 16, 16], "texture": "#top", "cullface": "up"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#bottom"} + } + }, + { + "from": [8, 8, 0], + "to": [16, 16, 8], + "faces": { + "north": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "east"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#top", "cullface": "up"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#bottom"} + } + }, + { + "from": [0, 8, 0], + "to": [8, 16, 8], + "faces": { + "north": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "north"}, + "south": {"uv": [0, 0, 8, 8], "texture": "#side"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 0, 8, 8], "texture": "#top", "cullface": "up"}, + "down": {"uv": [0, 8, 8, 16], "texture": "#bottom"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_stair/stair/side.json b/src/main/resources/assets/reframed/models/block/half_stair/stair/side.json new file mode 100644 index 0000000..f917223 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/stair/side.json @@ -0,0 +1,55 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [0, 8, 0], + "to": [8, 16, 8], + "faces": { + "north": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 0, 16, 8], "texture": "#side"}, + "south": {"uv": [0, 0, 8, 8], "texture": "#side"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 0, 8, 8], "texture": "#top", "cullface": "up"} + } + }, + { + "from": [0, 0, 0], + "to": [8, 8, 8], + "faces": { + "north": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 8, 16, 16], "texture": "#side"}, + "west": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "west"}, + "down": {"uv": [0, 8, 8, 16], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [0, 0, 8], + "to": [8, 8, 16], + "faces": { + "east": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "south": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 8, 8, 16], "texture": "#top"}, + "down": {"uv": [0, 0, 8, 8], "texture": "#bottom", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/small_cube.json b/src/main/resources/assets/reframed/models/block/small_cube/base.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/small_cube.json rename to src/main/resources/assets/reframed/models/block/small_cube/base.json diff --git a/src/main/resources/assets/reframed/models/block/small_cube_complement.json b/src/main/resources/assets/reframed/models/block/small_cube/step/base.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/small_cube_complement.json rename to src/main/resources/assets/reframed/models/block/small_cube/step/base.json diff --git a/src/main/resources/assets/reframed/models/block/double_outer_stairs_complement.json b/src/main/resources/assets/reframed/models/block/stair/cube/double_outer.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/double_outer_stairs_complement.json rename to src/main/resources/assets/reframed/models/block/stair/cube/double_outer.json diff --git a/src/main/resources/assets/reframed/models/block/inner_stairs_complement.json b/src/main/resources/assets/reframed/models/block/stair/cube/inner.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/inner_stairs_complement.json rename to src/main/resources/assets/reframed/models/block/stair/cube/inner.json diff --git a/src/main/resources/assets/reframed/models/block/outer_stairs_complement.json b/src/main/resources/assets/reframed/models/block/stair/cube/outer.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/outer_stairs_complement.json rename to src/main/resources/assets/reframed/models/block/stair/cube/outer.json diff --git a/src/main/resources/assets/reframed/models/block/outer_side_stairs_complement.json b/src/main/resources/assets/reframed/models/block/stair/cube/outer_side.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/outer_side_stairs_complement.json rename to src/main/resources/assets/reframed/models/block/stair/cube/outer_side.json diff --git a/src/main/resources/assets/reframed/models/block/stairs_complement.json b/src/main/resources/assets/reframed/models/block/stair/cube/straight.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/stairs_complement.json rename to src/main/resources/assets/reframed/models/block/stair/cube/straight.json diff --git a/src/main/resources/assets/reframed/models/block/double_outer_stairs.json b/src/main/resources/assets/reframed/models/block/stair/double_outer.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/double_outer_stairs.json rename to src/main/resources/assets/reframed/models/block/stair/double_outer.json diff --git a/src/main/resources/assets/reframed/models/block/inner_stairs.json b/src/main/resources/assets/reframed/models/block/stair/inner.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/inner_stairs.json rename to src/main/resources/assets/reframed/models/block/stair/inner.json diff --git a/src/main/resources/assets/reframed/models/block/outer_stairs.json b/src/main/resources/assets/reframed/models/block/stair/outer.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/outer_stairs.json rename to src/main/resources/assets/reframed/models/block/stair/outer.json diff --git a/src/main/resources/assets/reframed/models/block/outer_side_stairs.json b/src/main/resources/assets/reframed/models/block/stair/outer_side.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/outer_side_stairs.json rename to src/main/resources/assets/reframed/models/block/stair/outer_side.json diff --git a/src/main/resources/assets/reframed/models/block/stairs.json b/src/main/resources/assets/reframed/models/block/stair/straight.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/stairs.json rename to src/main/resources/assets/reframed/models/block/stair/straight.json diff --git a/src/main/resources/assets/reframed/models/block/step.json b/src/main/resources/assets/reframed/models/block/step/down.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/step.json rename to src/main/resources/assets/reframed/models/block/step/down.json diff --git a/src/main/resources/assets/reframed/models/block/step_side.json b/src/main/resources/assets/reframed/models/block/step/side.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/step_side.json rename to src/main/resources/assets/reframed/models/block/step/side.json diff --git a/src/main/resources/assets/reframed/models/block/step_complement_slab.json b/src/main/resources/assets/reframed/models/block/step/slab/down.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/step_complement_slab.json rename to src/main/resources/assets/reframed/models/block/step/slab/down.json diff --git a/src/main/resources/assets/reframed/models/block/step_side_complement_slab.json b/src/main/resources/assets/reframed/models/block/step/slab/side.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/step_side_complement_slab.json rename to src/main/resources/assets/reframed/models/block/step/slab/side.json -- 2.39.5 From 08bde119b24ceb9978be39becfb8784f18dca776 Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Thu, 14 Mar 2024 22:28:45 +0100 Subject: [PATCH 11/11] updated version for publish --- gradle.properties | 2 +- src/main/java/fr/adrien1106/reframed/ReFramed.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index c2dd688..77a6cd7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ loader_version=0.15.6 # Mod Properties modrinth_id = jCpoCBpn -mod_version = 1.4 +mod_version = 1.5 maven_group = fr.adrien1106 archives_base_name = ReFramed mod_id = reframed diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index 393fa13..8886e19 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -27,6 +27,7 @@ import java.util.stream.Collectors; import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; /** + * TODO make block pairable by right click -> for v1.6 * TODO add Hammer from framed ( removes theme ) -> for v1.5.5 * TODO add screwdriver ( iterate over theme states ) ? * TODO add blueprint for survival friendly copy paste of a theme. -> for v1.5.5 @@ -76,7 +77,7 @@ public class ReFramed implements ModInitializer { .filter(block -> block instanceof ReFramedDoubleBlock) .toArray(Block[]::new)).build(null) ); - + ITEM_GROUP = Registry.register(Registries.ITEM_GROUP, id("tab"), FabricItemGroup.builder() .displayName(Text.translatable("itemGroup.reframed.tab")) .icon(() -> new ItemStack(SLAB)) -- 2.39.5