diff --git a/README.md b/README.md index 7f0f146..3ddd190 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ or based on preferences add the person(s) to the project ### What Shapes are planed to be added Currently, the list of shapes to be added is pretty simple as the mod is still under development: - Fence -- Button - Pressure Plate - Carpet (maybe redundant with Layer) - Post diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index 3e9b5f9..f3dca2c 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -37,7 +37,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, SMALL_CUBES_STEP, STAIR, HALF_STAIR, STAIRS_CUBE, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, SLAB, SLABS_CUBE, STEP, STEPS_SLAB, LAYER, PILLAR, PILLARS_WALL, WALL, PANE, TRAPDOOR, DOOR; + 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, PILLAR, PILLARS_WALL, WALL, PANE, TRAPDOOR, DOOR, BUTTON; public static final ArrayList ITEMS = new ArrayList<>(); public static Item HAMMER, SCREWDRIVER, BLUEPRINT, BLUEPRINT_WRITTEN; @@ -70,6 +70,7 @@ public class ReFramed implements ModInitializer { PANE = registerBlock("pane" , new ReFramedPaneBlock(cp(Blocks.OAK_FENCE))); TRAPDOOR = registerBlock("trapdoor" , new ReFramedTrapdoorBlock(cp(Blocks.OAK_TRAPDOOR))); DOOR = registerBlock("door" , new ReFramedDoorBlock(cp(Blocks.OAK_DOOR))); + BUTTON = registerBlock("button" , new ReFramedButtonBlock(cp(Blocks.OAK_BUTTON))); HAMMER = registerItem("hammer" , new ReFramedHammerItem(new Item.Settings().maxCount(1))); SCREWDRIVER = registerItem("screwdriver" , new ReFramedScrewdriverItem(new Item.Settings().maxCount(1))); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java index 236d4eb..ceac63c 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java @@ -72,8 +72,8 @@ public class ReFramedBlock extends Block implements BlockEntityProvider { } @Override - public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { - if(!(newState.getBlock() instanceof ReFramedBlock) && + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) { + if(!(new_state.getBlock() instanceof ReFramedBlock) && world.getBlockEntity(pos) instanceof ReFramedEntity frame_entity && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS) ) { @@ -86,7 +86,7 @@ public class ReFramedBlock extends Block implements BlockEntityProvider { ItemScatterer.spawn(world, pos, drops); } - super.onStateReplaced(state, world, pos, newState, moved); + super.onStateReplaced(state, world, pos, new_state, moved); } public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack, BlockState old_state, BlockEntity old_entity) { diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedButtonBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedButtonBlock.java new file mode 100644 index 0000000..15d8f9b --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedButtonBlock.java @@ -0,0 +1,238 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.util.VoxelHelper; +import net.minecraft.block.*; +import net.minecraft.block.enums.BlockFace; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.PersistentProjectileEntity; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.state.StateManager; +import net.minecraft.util.ActionResult; +import net.minecraft.util.BlockMirror; +import net.minecraft.util.BlockRotation; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; +import net.minecraft.world.WorldView; +import net.minecraft.world.event.GameEvent; +import net.minecraft.world.explosion.Explosion; +import org.jetbrains.annotations.Nullable; + +import java.util.function.BiConsumer; + +import static net.minecraft.state.property.Properties.*; + +public class ReFramedButtonBlock extends WaterloggableReFramedBlock { + + public static final VoxelShape[] BUTTON_VOXELS; + + public ReFramedButtonBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState() + .with(HORIZONTAL_FACING, Direction.NORTH) + .with(BLOCK_FACE, BlockFace.WALL) + .with(POWERED, false) + ); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(HORIZONTAL_FACING, BLOCK_FACE, POWERED)); + } + + @Override + public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) { + return canPlaceAt(world, pos, getDirection(state).getOpposite()); + } + + public static boolean canPlaceAt(WorldView world, BlockPos pos, Direction direction) { + BlockPos other_pos = pos.offset(direction); + return world.getBlockState(other_pos).isSideSolidFullSquare(world, other_pos, direction.getOpposite()); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + BlockState state = super.getPlacementState(ctx); + Direction side = ctx.getSide(); + return state + .with(HORIZONTAL_FACING, side.getAxis() == Direction.Axis.Y + ? ctx.getHorizontalPlayerFacing() + : side + ) + .with(BLOCK_FACE, side.getAxis() != Direction.Axis.Y + ? BlockFace.WALL + : side == Direction.UP ? BlockFace.FLOOR : BlockFace.CEILING + ); + } + + @Override + public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState other_state, WorldAccess world, BlockPos pos, BlockPos other_pos) { + return getDirection(state).getOpposite() == direction && !state.canPlaceAt(world, pos) + ? Blocks.AIR.getDefaultState() + : super.getStateForNeighborUpdate(state, direction, other_state, world, pos, other_pos); + } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + ActionResult result = super.onUse(state, world, pos, player, hand, hit); + if (result.isAccepted()) return result; + + if (state.get(POWERED)) return ActionResult.CONSUME; + powerOn(state, world, pos); + playClickSound(player, world, pos, true); + world.emitGameEvent(player, GameEvent.BLOCK_ACTIVATE, pos); + + return ActionResult.success(world.isClient); + } + + @Override + public void onExploded(BlockState state, World world, BlockPos pos, Explosion explosion, BiConsumer stackMerger) { + if (explosion.getDestructionType() == Explosion.DestructionType.TRIGGER_BLOCK && !world.isClient() && !(Boolean)state.get(POWERED)) { + powerOn(state, world, pos); + } + + super.onExploded(state, world, pos, explosion, stackMerger); + } + + public void powerOn(BlockState state, World world, BlockPos pos) { + world.setBlockState(pos, state.with(POWERED, true), 3); + updateNeighbors(state, world, pos); + world.scheduleBlockTick(pos, this, 30); + } + + protected void playClickSound(@Nullable PlayerEntity player, WorldAccess world, BlockPos pos, boolean powered) { + world.playSound( + powered ? player : null, + pos, + powered ? BlockSetType.OAK.buttonClickOn() : BlockSetType.OAK.buttonClickOff(), + SoundCategory.BLOCKS + ); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return BUTTON_VOXELS[ + (state.get(POWERED) ? 12 : 0) + + (4 * state.get(BLOCK_FACE).ordinal()) + + state.get(HORIZONTAL_FACING).ordinal() - 2 + ]; + } + + @Override + public BlockState rotate(BlockState state, BlockRotation rotation) { + return state.with(HORIZONTAL_FACING, rotation.rotate(state.get(HORIZONTAL_FACING))); + } + + @Override + public BlockState mirror(BlockState state, BlockMirror mirror) { + return state.with(HORIZONTAL_FACING, mirror.apply(state.get(HORIZONTAL_FACING))); + } + + @Override + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) { + super.onStateReplaced(state, world, pos, new_state, false); + + if(!state.isOf(new_state.getBlock())) { + if (!moved && state.get(POWERED)) updateNeighbors(state, world, pos); + world.removeBlockEntity(pos); + } + } + + @Override + public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) { + return state.get(POWERED) ? 15 : super.getWeakRedstonePower(state, view, pos, dir); + } + + @Override + public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) { + return dir == getDirection(state) ? state.getWeakRedstonePower(view, pos, dir) : 0; + } + + @Override + public boolean emitsRedstonePower(BlockState state) { + return true; + } + + @Override + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + if (state.get(POWERED)) tryPowerWithProjectiles(state, world, pos); + } + + @Override + public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { + if (!world.isClient && !state.get(POWERED)) tryPowerWithProjectiles(state, world, pos); + } + + protected void tryPowerWithProjectiles(BlockState state, World world, BlockPos pos) { + PersistentProjectileEntity projectile = world.getNonSpectatingEntities( + PersistentProjectileEntity.class, + state.getOutlineShape(world, pos).getBoundingBox().offset(pos) + ).stream().findFirst().orElse(null); + boolean has_projectile = projectile != null; + if (has_projectile != state.get(POWERED)) { + world.setBlockState(pos, state.with(POWERED, has_projectile), 3); + this.updateNeighbors(state, world, pos); + this.playClickSound(null, world, pos, has_projectile); + world.emitGameEvent(projectile, has_projectile ? GameEvent.BLOCK_ACTIVATE : GameEvent.BLOCK_DEACTIVATE, pos); + } + + if (has_projectile) { + world.scheduleBlockTick(pos, this, 30); + } + + } + + private void updateNeighbors(BlockState state, World world, BlockPos pos) { + world.updateNeighborsAlways(pos, this); + world.updateNeighborsAlways(pos.offset(getDirection(state).getOpposite()), this); + } + + protected static Direction getDirection(BlockState state) { + return switch (state.get(BLOCK_FACE)) { + case CEILING -> Direction.DOWN; + case FLOOR -> Direction.UP; + default -> state.get(HORIZONTAL_FACING); + }; + } + + + static { + VoxelShape SHAPE = createCuboidShape(5, 0, 6, 11, 2, 10); + VoxelShape POWERED_SHAPE = createCuboidShape(5, 0, 6, 11, 1, 10); + BUTTON_VOXELS = VoxelHelper.VoxelListBuilder.create(SHAPE, 24) + .add() + .add(0, VoxelHelper::rotateY) + .add() + .add(VoxelHelper::rotateZ, VoxelHelper::rotateY) + .add(VoxelHelper::mirrorZ) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::mirrorX) + .add(0, VoxelHelper::mirrorY) + .add() + .add(2, VoxelHelper::mirrorY) + .add() + .add(POWERED_SHAPE) + .add() + .add(12, VoxelHelper::rotateY) + .add() + .add(VoxelHelper::rotateZ, VoxelHelper::rotateY) + .add(VoxelHelper::mirrorZ) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::mirrorX) + .add(12, VoxelHelper::mirrorY) + .add() + .add(13, VoxelHelper::mirrorY) + .add() + .build(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoorBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoorBlock.java index 3c587b3..4cc239f 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoorBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoorBlock.java @@ -127,10 +127,10 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock { } @Override - public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { - super.onStateReplaced(state, world, pos, newState, moved); + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) { + super.onStateReplaced(state, world, pos, new_state, moved); - if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos); + if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos); } @Override diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedPaneBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedPaneBlock.java index a800d1c..6ea5dd2 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedPaneBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedPaneBlock.java @@ -73,10 +73,10 @@ public class ReFramedPaneBlock extends WaterloggableReFramedBlock { } @Override - public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { - super.onStateReplaced(state, world, pos, newState, moved); + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) { + super.onStateReplaced(state, world, pos, new_state, moved); - if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos); + if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos); } @Override diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedPillarsWallBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedPillarsWallBlock.java index 952fc7e..1896945 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedPillarsWallBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedPillarsWallBlock.java @@ -72,10 +72,10 @@ public class ReFramedPillarsWallBlock extends WaterloggableReFramedDoubleBlock { } @Override - public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { - super.onStateReplaced(state, world, pos, newState, moved); + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) { + super.onStateReplaced(state, world, pos, new_state, moved); - if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos); + if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos); } @Override diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java index 522edfd..60f7601 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java @@ -87,10 +87,10 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock { } @Override - public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { - super.onStateReplaced(state, world, pos, newState, moved); + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) { + super.onStateReplaced(state, world, pos, new_state, moved); - if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos); + if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos); } @Override diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java index b1dcb6f..ab16582 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java @@ -77,10 +77,10 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock { } @Override - public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { - super.onStateReplaced(state, world, pos, newState, moved); + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) { + super.onStateReplaced(state, world, pos, new_state, moved); - if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos); + if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos); } @Override diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedTrapdoorBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedTrapdoorBlock.java index d2a2c09..3ae4785 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedTrapdoorBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedTrapdoorBlock.java @@ -84,10 +84,10 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock { } @Override - public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { - super.onStateReplaced(state, world, pos, newState, moved); + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) { + super.onStateReplaced(state, world, pos, new_state, moved); - if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos); + if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos); } @Override diff --git a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java index a4a8520..6aed4ed 100644 --- a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java +++ b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java @@ -130,6 +130,10 @@ public class ReFramedClient implements ClientModInitializer { HELPER.addReFramedModel("trapdoor_top" , HELPER.auto(new Identifier("block/oak_trapdoor_top"))); // DOOR HELPER.addReFramedModel("door_inventory" , HELPER.auto(ReFramed.id("block/door"))); + // BUTTON + HELPER.addReFramedModel("button_inventory" , HELPER.auto(new Identifier("block/button_inventory"))); + HELPER.addReFramedModel("button" , HELPER.auto(new Identifier("block/button"))); + HELPER.addReFramedModel("button_pressed" , HELPER.auto(new Identifier("block/button_pressed"))); //item model assignments (in lieu of models/item/___.json) @@ -152,6 +156,7 @@ public class ReFramedClient implements ClientModInitializer { HELPER.assignItemModel("pane_inventory" , ReFramed.PANE); HELPER.assignItemModel("trapdoor_bottom" , ReFramed.TRAPDOOR); HELPER.assignItemModel("door_inventory" , ReFramed.DOOR); + HELPER.assignItemModel("button_inventory" , ReFramed.BUTTON); } private void privateInit() { diff --git a/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java b/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java index d111af5..4b0c049 100644 --- a/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java +++ b/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java @@ -37,6 +37,7 @@ public class GBlockstate extends FabricModelProvider { providers.put(ReFramedPaneBlock.class, new Pane()); providers.put(ReFramedTrapdoorBlock.class, new Trapdoor()); providers.put(ReFramedDoorBlock.class, new Door()); + providers.put(ReFramedButtonBlock.class, new Button()); } public GBlockstate(FabricDataOutput output) { diff --git a/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java b/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java index 7ac1beb..ed156b1 100644 --- a/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java +++ b/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java @@ -39,6 +39,7 @@ public class GRecipe extends FabricRecipeProvider { providers.put(ReFramedPaneBlock.class, new Pane()); providers.put(ReFramedTrapdoorBlock.class, new Trapdoor()); providers.put(ReFramedDoorBlock.class, new Door()); + providers.put(ReFramedButtonBlock.class, new Button()); providers.put(ReFramedBlueprintItem.class, new Blueprint()); providers.put(ReFramedHammerItem.class, new Hammer()); providers.put(ReFramedScrewdriverItem.class, new Screwdriver()); diff --git a/src/main/java/fr/adrien1106/reframed/generator/block/Button.java b/src/main/java/fr/adrien1106/reframed/generator/block/Button.java new file mode 100644 index 0000000..2ad3e8d --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/generator/block/Button.java @@ -0,0 +1,95 @@ +package fr.adrien1106.reframed.generator.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.generator.GBlockstate; +import fr.adrien1106.reframed.generator.RecipeSetter; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +import net.minecraft.block.enums.BlockFace; +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.ItemConvertible; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.Direction; + +import static net.minecraft.data.client.VariantSettings.Rotation.*; +import static net.minecraft.state.property.Properties.*; + +public class Button implements RecipeSetter, BlockStateProvider { + + @Override + public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 8); + ShapelessRecipeJsonBuilder.create(RecipeCategory.BUILDING_BLOCKS, convertible, 1) + .input(ReFramed.CUBE, 1) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible)) + .offerTo(exporter); + } + + @Override + public BlockStateSupplier getMultipart(Block block) { + Identifier button = ReFramed.id("button_special"); + Identifier button_pressed = ReFramed.id("button_pressed_special"); + return MultipartBlockStateSupplier.create(block) + // FLOOR OFF + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.FLOOR), + GBlockstate.variant(button, true, R0, R0)) + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.FLOOR), + GBlockstate.variant(button, true, R0, R90)) + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.FLOOR), + GBlockstate.variant(button, true, R0, R180)) + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.FLOOR), + GBlockstate.variant(button, true, R0, R270)) + // CEILING OFF + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.CEILING), + GBlockstate.variant(button, true, R180, R0)) + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.CEILING), + GBlockstate.variant(button, true, R180, R90)) + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.CEILING), + GBlockstate.variant(button, true, R180, R180)) + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.CEILING), + GBlockstate.variant(button, true, R180, R270)) + // WALL OFF + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.WALL), + GBlockstate.variant(button, true, R90, R0)) + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.WALL), + GBlockstate.variant(button, true, R90, R90)) + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.WALL), + GBlockstate.variant(button, true, R90, R180)) + .with(GBlockstate.when(POWERED, false, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.WALL), + GBlockstate.variant(button, true, R90, R270)) + // FLOOR ON + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.FLOOR), + GBlockstate.variant(button_pressed, true, R0, R0)) + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.FLOOR), + GBlockstate.variant(button_pressed, true, R0, R90)) + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.FLOOR), + GBlockstate.variant(button_pressed, true, R0, R180)) + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.FLOOR), + GBlockstate.variant(button_pressed, true, R0, R270)) + // CEILING ON + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.CEILING), + GBlockstate.variant(button_pressed, true, R180, R0)) + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.CEILING), + GBlockstate.variant(button_pressed, true, R180, R90)) + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.CEILING), + GBlockstate.variant(button_pressed, true, R180, R180)) + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.CEILING), + GBlockstate.variant(button_pressed, true, R180, R270)) + // WALL ON + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.NORTH, BLOCK_FACE, BlockFace.WALL), + GBlockstate.variant(button_pressed, true, R90, R0)) + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.EAST, BLOCK_FACE, BlockFace.WALL), + GBlockstate.variant(button_pressed, true, R90, R90)) + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.SOUTH, BLOCK_FACE, BlockFace.WALL), + GBlockstate.variant(button_pressed, true, R90, R180)) + .with(GBlockstate.when(POWERED, true, HORIZONTAL_FACING, Direction.WEST, BLOCK_FACE, BlockFace.WALL), + GBlockstate.variant(button_pressed, true, R90, R270)); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/AxiomChunkedBlockRegionMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/AxiomChunkedBlockRegionMixin.java index b221fb3..c0b4689 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/AxiomChunkedBlockRegionMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/AxiomChunkedBlockRegionMixin.java @@ -38,7 +38,7 @@ import java.util.stream.Stream; import static fr.adrien1106.reframed.block.ReFramedEntity.BLOCKSTATE_KEY; -@Mixin(ChunkedBlockRegion.class) +@Mixin(ChunkedBlockRegion.class) // TODO: Look here for better rotation/flip support public class AxiomChunkedBlockRegionMixin implements IAxiomChunkedBlockRegionMixin { @Shadow