diff --git a/src/generated/resources/assets/anvilcraft/lang/en_ud.json b/src/generated/resources/assets/anvilcraft/lang/en_ud.json index 9f083e793e..c952825f34 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_ud.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_ud.json @@ -533,6 +533,7 @@ "block.anvilcraft.white_chocolate_slab": "qɐןS ǝʇɐןoɔoɥƆ ǝʇıɥM", "block.anvilcraft.white_chocolate_stairs": "sɹıɐʇS ǝʇɐןoɔoɥƆ ǝʇıɥM", "block.anvilcraft.white_hole": "ǝןoH ǝʇıɥM", + "block.anvilcraft.workshop": "doɥsʞɹoM", "block.anvilcraft.yellow_cement": "ʇuǝɯǝƆ ʍoןןǝʎ", "block.anvilcraft.yellow_cement_cauldron": "uoɹpןnɐƆ ʇuǝɯǝƆ ʍoןןǝʎ", "block.anvilcraft.zinc_block": "ɔuıZ ɟo ʞɔoןᗺ", diff --git a/src/generated/resources/assets/anvilcraft/lang/en_us.json b/src/generated/resources/assets/anvilcraft/lang/en_us.json index 37047d82b5..0dd76f7ec8 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_us.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_us.json @@ -533,6 +533,7 @@ "block.anvilcraft.white_chocolate_slab": "White Chocolate Slab", "block.anvilcraft.white_chocolate_stairs": "White Chocolate Stairs", "block.anvilcraft.white_hole": "White Hole", + "block.anvilcraft.workshop": "Workshop", "block.anvilcraft.yellow_cement": "Yellow Cement", "block.anvilcraft.yellow_cement_cauldron": "Yellow Cement Cauldron", "block.anvilcraft.zinc_block": "Block of Zinc", diff --git a/src/generated/resources/assets/anvilcraft/models/item/workshop.json b/src/generated/resources/assets/anvilcraft/models/item/workshop.json new file mode 100644 index 0000000000..4179a302cd --- /dev/null +++ b/src/generated/resources/assets/anvilcraft/models/item/workshop.json @@ -0,0 +1,3 @@ +{ + "parent": "anvilcraft:block/workshop" +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/recipes/multiblock_conversion/giant_anvil_1.json b/src/generated/resources/data/anvilcraft/advancement/recipes/multiblock/workshop.json similarity index 68% rename from src/generated/resources/data/anvilcraft/advancement/recipes/multiblock_conversion/giant_anvil_1.json rename to src/generated/resources/data/anvilcraft/advancement/recipes/multiblock/workshop.json index 8aaa20c7f3..80b54a23ef 100644 --- a/src/generated/resources/data/anvilcraft/advancement/recipes/multiblock_conversion/giant_anvil_1.json +++ b/src/generated/resources/data/anvilcraft/advancement/recipes/multiblock/workshop.json @@ -3,7 +3,7 @@ "criteria": { "has_the_recipe": { "conditions": { - "recipe": "anvilcraft:multiblock_conversion/giant_anvil_1" + "recipe": "anvilcraft:multiblock/workshop" }, "trigger": "minecraft:recipe_unlocked" } @@ -15,7 +15,7 @@ ], "rewards": { "recipes": [ - "anvilcraft:multiblock_conversion/giant_anvil_1" + "anvilcraft:multiblock/workshop" ] } } \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/recipes/multiblock_conversion/workshop.json b/src/generated/resources/data/anvilcraft/advancement/recipes/multiblock_conversion/workshop.json new file mode 100644 index 0000000000..d5b4b0b2c7 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/recipes/multiblock_conversion/workshop.json @@ -0,0 +1,21 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": { + "recipe": "anvilcraft:multiblock_conversion/workshop" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "anvilcraft:multiblock_conversion/workshop" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/loot_table/blocks/workshop.json b/src/generated/resources/data/anvilcraft/loot_table/blocks/workshop.json new file mode 100644 index 0000000000..2f99cd0287 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/loot_table/blocks/workshop.json @@ -0,0 +1,30 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "block": "anvilcraft:workshop", + "condition": "minecraft:block_state_property", + "properties": { + "part": "bottom_center" + } + } + ], + "name": "anvilcraft:workshop" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "anvilcraft:blocks/workshop" +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/recipe/multiblock/workshop.json b/src/generated/resources/data/anvilcraft/recipe/multiblock/workshop.json new file mode 100644 index 0000000000..392f2710ab --- /dev/null +++ b/src/generated/resources/data/anvilcraft/recipe/multiblock/workshop.json @@ -0,0 +1,73 @@ +{ + "type": "anvilcraft:multiblock", + "pattern": { + "layers": [ + [ + "AAA", + "AAA", + "AAA" + ], + [ + "B ", + "C ", + "DEF" + ], + [ + "G ", + "G ", + "HHH" + ] + ], + "symbols": { + "A": { + "block": "minecraft:smooth_stone" + }, + "B": { + "block": "minecraft:stonecutter", + "properties": { + "facing": "east" + } + }, + "C": { + "block": "anvilcraft:jewelcrafting_table", + "properties": { + "facing": "east" + } + }, + "D": { + "block": "minecraft:cartography_table" + }, + "E": { + "block": "minecraft:crafting_table" + }, + "F": { + "block": "minecraft:loom", + "properties": { + "facing": "north" + } + }, + "G": { + "block": "minecraft:spruce_trapdoor", + "properties": { + "facing": "east", + "half": "bottom", + "open": "true", + "waterlogged": "false" + } + }, + "H": { + "block": "minecraft:spruce_trapdoor", + "properties": { + "facing": "north", + "half": "bottom", + "open": "true", + "waterlogged": "false" + } + } + } + }, + "result": { + "count": 1, + "id": "anvilcraft:workshop" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/recipe/multiblock_conversion/giant_anvil_1.json b/src/generated/resources/data/anvilcraft/recipe/multiblock_conversion/giant_anvil_1.json deleted file mode 100644 index 73f02d7bdb..0000000000 --- a/src/generated/resources/data/anvilcraft/recipe/multiblock_conversion/giant_anvil_1.json +++ /dev/null @@ -1,291 +0,0 @@ -{ - "type": "anvilcraft:multiblock_conversion", - "inputPattern": { - "layers": [ - [ - "ABA", - "CDE", - "AFA" - ], - [ - " ", - " D ", - " " - ], - [ - "GHG", - "IGI", - "GHG" - ] - ], - "symbols": { - "A": { - "block": "anvilcraft:cut_heavy_iron_slab", - "properties": { - "type": "bottom", - "waterlogged": "false" - } - }, - "B": { - "block": "anvilcraft:cut_heavy_iron_stairs", - "properties": { - "facing": "south", - "half": "bottom", - "waterlogged": "false" - } - }, - "C": { - "block": "anvilcraft:cut_heavy_iron_stairs", - "properties": { - "facing": "east", - "half": "bottom", - "waterlogged": "false" - } - }, - "D": { - "block": "anvilcraft:heavy_iron_column" - }, - "E": { - "block": "anvilcraft:cut_heavy_iron_stairs", - "properties": { - "facing": "west", - "half": "bottom", - "waterlogged": "false" - } - }, - "F": { - "block": "anvilcraft:cut_heavy_iron_stairs", - "properties": { - "facing": "north", - "half": "bottom", - "waterlogged": "false" - } - }, - "G": { - "block": "anvilcraft:polished_heavy_iron_block" - }, - "H": { - "block": "anvilcraft:heavy_iron_beam", - "properties": { - "axis": "z" - } - }, - "I": { - "block": "anvilcraft:heavy_iron_beam", - "properties": { - "axis": "x" - } - } - } - }, - "outputPattern": { - "layers": [ - [ - "ABC", - "DEF", - "GHI" - ], - [ - "JKL", - "MNO", - "PQR" - ], - [ - "STU", - "VWX", - "YZ[" - ] - ], - "symbols": { - "A": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "bottom_wn" - } - }, - "B": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "bottom_n" - } - }, - "C": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "bottom_en" - } - }, - "D": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "bottom_w" - } - }, - "E": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "bottom_center" - } - }, - "F": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "bottom_e" - } - }, - "G": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "bottom_ws" - } - }, - "H": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "bottom_s" - } - }, - "I": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "bottom_es" - } - }, - "J": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "mid_wn" - } - }, - "K": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "mid_n" - } - }, - "L": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "mid_en" - } - }, - "M": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "mid_w" - } - }, - "N": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "center", - "half": "mid_center" - } - }, - "O": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "mid_e" - } - }, - "P": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "mid_ws" - } - }, - "Q": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "mid_s" - } - }, - "R": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "mid_es" - } - }, - "S": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "top_wn" - } - }, - "T": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "top_n" - } - }, - "U": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "top_en" - } - }, - "V": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "top_w" - } - }, - "W": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "top_center" - } - }, - "X": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "top_e" - } - }, - "Y": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "top_ws" - } - }, - "Z": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "top_s" - } - }, - "[": { - "block": "anvilcraft:giant_anvil", - "properties": { - "cube": "corner", - "half": "top_es" - } - } - } - } -} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/recipe/multiblock_conversion/giant_anvil_2.json b/src/generated/resources/data/anvilcraft/recipe/multiblock_conversion/giant_anvil_2.json index b4f26af45e..73f02d7bdb 100644 --- a/src/generated/resources/data/anvilcraft/recipe/multiblock_conversion/giant_anvil_2.json +++ b/src/generated/resources/data/anvilcraft/recipe/multiblock_conversion/giant_anvil_2.json @@ -3,30 +3,78 @@ "inputPattern": { "layers": [ [ - "AAA", - "AAA", - "AAA" + "ABA", + "CDE", + "AFA" ], [ " ", - " B ", + " D ", " " ], [ - "CCC", - "CCC", - "CCC" + "GHG", + "IGI", + "GHG" ] ], "symbols": { "A": { - "block": "anvilcraft:cut_heavy_iron_block" + "block": "anvilcraft:cut_heavy_iron_slab", + "properties": { + "type": "bottom", + "waterlogged": "false" + } }, "B": { - "block": "anvilcraft:heavy_iron_column" + "block": "anvilcraft:cut_heavy_iron_stairs", + "properties": { + "facing": "south", + "half": "bottom", + "waterlogged": "false" + } }, "C": { + "block": "anvilcraft:cut_heavy_iron_stairs", + "properties": { + "facing": "east", + "half": "bottom", + "waterlogged": "false" + } + }, + "D": { + "block": "anvilcraft:heavy_iron_column" + }, + "E": { + "block": "anvilcraft:cut_heavy_iron_stairs", + "properties": { + "facing": "west", + "half": "bottom", + "waterlogged": "false" + } + }, + "F": { + "block": "anvilcraft:cut_heavy_iron_stairs", + "properties": { + "facing": "north", + "half": "bottom", + "waterlogged": "false" + } + }, + "G": { "block": "anvilcraft:polished_heavy_iron_block" + }, + "H": { + "block": "anvilcraft:heavy_iron_beam", + "properties": { + "axis": "z" + } + }, + "I": { + "block": "anvilcraft:heavy_iron_beam", + "properties": { + "axis": "x" + } } } }, diff --git a/src/generated/resources/data/anvilcraft/recipe/multiblock_conversion/workshop.json b/src/generated/resources/data/anvilcraft/recipe/multiblock_conversion/workshop.json new file mode 100644 index 0000000000..28db949793 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/recipe/multiblock_conversion/workshop.json @@ -0,0 +1,306 @@ +{ + "type": "anvilcraft:multiblock_conversion", + "inputPattern": { + "layers": [ + [ + "AAA", + "AAA", + "AAA" + ], + [ + "B ", + "C ", + "DEF" + ], + [ + "G ", + "G ", + "HHH" + ] + ], + "symbols": { + "A": { + "block": "minecraft:smooth_stone" + }, + "B": { + "block": "minecraft:stonecutter", + "properties": { + "facing": "east" + } + }, + "C": { + "block": "anvilcraft:jewelcrafting_table", + "properties": { + "facing": "east" + } + }, + "D": { + "block": "minecraft:cartography_table" + }, + "E": { + "block": "minecraft:crafting_table" + }, + "F": { + "block": "minecraft:loom", + "properties": { + "facing": "north" + } + }, + "G": { + "block": "minecraft:spruce_trapdoor", + "properties": { + "facing": "east", + "half": "bottom", + "open": "true", + "waterlogged": "false" + } + }, + "H": { + "block": "minecraft:spruce_trapdoor", + "properties": { + "facing": "north", + "half": "bottom", + "open": "true", + "waterlogged": "false" + } + } + } + }, + "outputPattern": { + "layers": [ + [ + "ABC", + "DEF", + "GHI" + ], + [ + "JKL", + "MNO", + "PQR" + ], + [ + "STU", + "VWX", + "YZ[" + ] + ], + "symbols": { + "A": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "bottom_wn" + } + }, + "B": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "bottom_n" + } + }, + "C": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "bottom_en" + } + }, + "D": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "bottom_w" + } + }, + "E": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "bottom_center" + } + }, + "F": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "bottom_e" + } + }, + "G": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "bottom_ws" + } + }, + "H": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "bottom_s" + } + }, + "I": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "bottom_es" + } + }, + "J": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "mid_wn" + } + }, + "K": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "mid_n" + } + }, + "L": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "mid_en" + } + }, + "M": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "mid_w" + } + }, + "N": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "center", + "facing": "north", + "part": "mid_center" + } + }, + "O": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "mid_e" + } + }, + "P": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "mid_ws" + } + }, + "Q": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "mid_s" + } + }, + "R": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "mid_es" + } + }, + "S": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "top_wn" + } + }, + "T": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "top_n" + } + }, + "U": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "top_en" + } + }, + "V": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "top_w" + } + }, + "W": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "top_center" + } + }, + "X": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "top_e" + } + }, + "Y": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "top_ws" + } + }, + "Z": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "top_s" + } + }, + "[": { + "block": "anvilcraft:workshop", + "properties": { + "cube": "corner", + "facing": "north", + "part": "top_es" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json index 3c1e0d18b2..e1986bf1ac 100644 --- a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json +++ b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json @@ -7,6 +7,7 @@ "anvilcraft:crushing_table", "anvilcraft:corrupted_beacon", "anvilcraft:giant_anvil", + "anvilcraft:workshop", "anvilcraft:spectral_anvil", "anvilcraft:royal_anvil", "anvilcraft:royal_grindstone", diff --git a/src/main/java/dev/dubhe/anvilcraft/block/WorkshopBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/WorkshopBlock.java new file mode 100644 index 0000000000..82b3ee8dd4 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/block/WorkshopBlock.java @@ -0,0 +1,225 @@ +package dev.dubhe.anvilcraft.block; + +import com.google.common.collect.ImmutableMap; +import dev.dubhe.anvilcraft.block.multipart.SimpleMultiPartBlock; +import dev.dubhe.anvilcraft.block.state.Cube3x3PartHalf; +import dev.dubhe.anvilcraft.block.state.WorkshopCube; +import dev.dubhe.anvilcraft.init.ModMenuTypes; +import dev.dubhe.anvilcraft.inventory.WorkshopMenu; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.SimpleMenuProvider; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.Property; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.BooleanOp; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.Objects; + +public class WorkshopBlock extends SimpleMultiPartBlock { + public static final EnumProperty PART = EnumProperty.create("part", Cube3x3PartHalf.class); + public static final EnumProperty CUBE = EnumProperty.create("cube", WorkshopCube.class); + public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; + private static final Map> SHAPES; + + static { + ImmutableMap.Builder> directionBuilder = ImmutableMap.builder(); + for (Direction direction : Direction.Plane.HORIZONTAL) { + VoxelShape baseShape = makeShape(direction); + ImmutableMap.Builder partBuilder = ImmutableMap.builder(); + for (Cube3x3PartHalf part : Cube3x3PartHalf.values()) { + partBuilder.put(part, baseShape.move(-part.getOffsetX(), 1 - part.getOffsetY(), -part.getOffsetZ())); + } + directionBuilder.put(direction, partBuilder.build()); + } + SHAPES = directionBuilder.build(); + } + + public WorkshopBlock(Properties properties) { + super(properties); + this.registerDefaultState(this.stateDefinition.any() + .setValue(PART, Cube3x3PartHalf.BOTTOM_CENTER) + .setValue(CUBE, WorkshopCube.CORNER) + .setValue(FACING, Direction.NORTH)); + } + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (level.isClientSide()) return InteractionResult.SUCCESS; + ModMenuTypes.open((ServerPlayer) player, Objects.requireNonNull(this.getMenuProvider(state, level, pos))); + return InteractionResult.sidedSuccess(level.isClientSide()); + } + + @Override + public BlockState placedState(Cube3x3PartHalf part, BlockState state) { + return super.placedState(part, state) + .setValue(CUBE, part == Cube3x3PartHalf.MID_CENTER ? WorkshopCube.CENTER : WorkshopCube.CORNER); + } + + @Override + protected @Nullable MenuProvider getMenuProvider(BlockState state, Level level, BlockPos pos) { + return new SimpleMenuProvider( + (id, inventory, player) -> new WorkshopMenu( + ModMenuTypes.WORKSHOP.get(), + id, + inventory, + ContainerLevelAccess.create(level, pos) + ), + getName() + ); + } + + @Nullable + @Override + public BlockState getPlacementState(BlockPlaceContext context) { + BlockState state = super.getPlacementState(context); + return state == null ? null : state.setValue(FACING, context.getHorizontalDirection().getOpposite()); + } + + @Override + public Property getPart() { + return PART; + } + + @Override + public Cube3x3PartHalf[] getParts() { + return Cube3x3PartHalf.values(); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(PART, CUBE, FACING); + } + + @Override + protected boolean isPathfindable(BlockState state, PathComputationType pathComputationType) { + return false; + } + + @Override + protected BlockState rotate(BlockState state, Rotation rotation) { + return state.setValue(FACING, rotation.rotate(state.getValue(FACING))) + .setValue(PART, state.getValue(PART).rotate(rotation)); + } + + @Override + protected BlockState mirror(BlockState state, Mirror mirror) { + return state.setValue(FACING, mirror.mirror(state.getValue(FACING))) + .setValue(PART, state.getValue(PART).mirror(mirror)); + } + + @Override + public float getShadeBrightness(BlockState state, BlockGetter level, BlockPos pos) { + return 1.0F; + } + + @Override + public boolean propagatesSkylightDown(BlockState state, BlockGetter level, BlockPos pos) { + return true; + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { + return SHAPES.get(state.getValue(FACING)).get(state.getValue(PART)); + } + + public static VoxelShape makeShape(Direction direction) { + VoxelShape shape = Shapes.empty(); + shape = Shapes.join(shape, box(-1, -1, -1, 2, -0.5, 2, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(0.0625, -0.5, 1.125, 0.1875, 0.1875, 1.8125, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(1.125, -0.5, 1.125, 2, 0.1875, 1.8125, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-1, -0.5, 1.8125, 2, 0.1875, 2, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-1, 0.1875, 1.125, 2, 0.375, 2, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.5, 0.5625, 1.875, 2, 1.5625, 2, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(1.8125, 0.375, 1.875, 1.9375, 0.5625, 2, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.4375, 0.375, 1.875, -0.3125, 0.5625, 2, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(0.3125, 0.375, 1.875, 0.4375, 0.5625, 2, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(1.0625, 0.375, 1.875, 1.1875, 0.5625, 2, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(0.1875, -0.125, 1.1875, 1.125, 0, 1.8125, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(0.1875, -0.4375, 1.1875, 1.125, -0.3125, 1.8125, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-1, -0.5, 1.125, -0.875, 0.1875, 1.8125, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.875, -0.375, -0.875, 0, 0.125, 1.375, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-1, 0.3125, -1, -0.875, 1.5625, 1, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-1, -0.5, -0.875, -0.875, 0.3125, -0.75, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-1, -0.5, 0.75, -0.875, 0.3125, 0.875, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.1875, -0.5, -0.875, 0, -0.375, -0.6875, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.875, -0.5, -0.875, -0.6875, -0.375, -0.6875, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.1875, -0.5, -0.1875, 0, -0.375, 0, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.875, -0.5, -0.1875, -0.6875, -0.375, 0, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.1875, -0.5, 0.5, 0, -0.375, 0.6875, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.875, -0.5, 0.5, -0.6875, -0.375, 0.6875, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.1875, -0.5, 1.1875, 0, -0.375, 1.375, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.875, -0.5, 1.1875, -0.6875, -0.375, 1.375, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.6875, 0.125, -0.75, -0.1875, 0.625, 0.125, direction), BooleanOp.OR); + shape = Shapes.join(shape, box(-0.4375, 0.125, -0.6875, -0.4375, 0.5, 0.0625, direction), BooleanOp.OR); + return shape; + } + + @SuppressWarnings("checkstyle:MultipleVariableDeclarations") + private static VoxelShape box(double x1, double y1, double z1, double x2, double y2, double z2, Direction direction) { + double cx = 0.5; + double cz = 0.5; + + double x1r = x1 - cx; + double z1r = z1 - cz; + double x2r = x2 - cx; + double z2r = z2 - cz; + + double nx1, nz1, nx2, nz2; + + switch (direction) { + case EAST: + nx1 = -z1r; + nz1 = x1r; + nx2 = -z2r; + nz2 = x2r; + break; + case SOUTH: + nx1 = -x1r; + nz1 = -z1r; + nx2 = -x2r; + nz2 = -z2r; + break; + case WEST: + nx1 = z1r; + nz1 = -x1r; + nx2 = z2r; + nz2 = -x2r; + break; + default: + nx1 = x1r; + nz1 = z1r; + nx2 = x2r; + nz2 = z2r; + break; + } + + nx1 += cx; + nz1 += cz; + nx2 += cx; + nz2 += cz; + + return Shapes.box(Math.min(nx1, nx2), y1, Math.min(nz1, nz2), Math.max(nx1, nx2), y2, Math.max(nz1, nz2)); + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/WorkshopBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/WorkshopBlockEntity.java new file mode 100644 index 0000000000..82b82b390b --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/WorkshopBlockEntity.java @@ -0,0 +1,83 @@ +package dev.dubhe.anvilcraft.block.entity; + +import dev.dubhe.anvilcraft.init.ModMenuTypes; +import dev.dubhe.anvilcraft.init.block.ModBlockEntities; +import dev.dubhe.anvilcraft.inventory.WorkshopMenu; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.items.ItemStackHandler; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class WorkshopBlockEntity extends BlockEntity implements MenuProvider { + private final ItemStackHandler inputHandler = new ItemStackHandler(9) { + @Override + protected void onContentsChanged(int slot) { + setChanged(); + } + }; + private final ItemStackHandler outputHandler = new ItemStackHandler(1) { + @Override + protected void onContentsChanged(int slot) { + setChanged(); + } + }; + private final ItemStackHandler templateHandler = new ItemStackHandler(1) { + @Override + protected void onContentsChanged(int slot) { + setChanged(); + } + }; + + public WorkshopBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(ModBlockEntities.WORKSHOP.get(), pos, state); + } + + @Override + public @NotNull Component getDisplayName() { + return Component.translatable("container.anvilcraft.workshop"); + } + + @Override + public @Nullable AbstractContainerMenu createMenu(int containerId, @NotNull Inventory inventory, @NotNull Player player) { + return new WorkshopMenu(ModMenuTypes.WORKSHOP.get(), containerId, inventory, ContainerLevelAccess.NULL); + } + + @Override + protected void saveAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) { + super.saveAdditional(tag, registries); + tag.put("Input", inputHandler.serializeNBT(registries)); + tag.put("Output", outputHandler.serializeNBT(registries)); + tag.put("Template", templateHandler.serializeNBT(registries)); + } + + @Override + protected void loadAdditional(@NotNull CompoundTag tag, HolderLookup.@NotNull Provider registries) { + super.loadAdditional(tag, registries); + inputHandler.deserializeNBT(registries, tag.getCompound("Input")); + outputHandler.deserializeNBT(registries, tag.getCompound("Output")); + templateHandler.deserializeNBT(registries, tag.getCompound("Template")); + } + + public ItemStackHandler getInputHandler() { + return inputHandler; + } + + public ItemStackHandler getOutputHandler() { + return outputHandler; + } + + public ItemStackHandler getTemplateHandler() { + return templateHandler; + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/block/state/WorkshopCube.java b/src/main/java/dev/dubhe/anvilcraft/block/state/WorkshopCube.java new file mode 100644 index 0000000000..bc9da98636 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/block/state/WorkshopCube.java @@ -0,0 +1,23 @@ +package dev.dubhe.anvilcraft.block.state; + +import net.minecraft.util.StringRepresentable; + +public enum WorkshopCube implements StringRepresentable { + CORNER("corner"), + CENTER("center"); + + private final String name; + + WorkshopCube(String name) { + this.name = name; + } + + public String toString() { + return this.name; + } + + @Override + public String getSerializedName() { + return this.name; + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/client/screen/WorkshopScreen.java b/src/main/java/dev/dubhe/anvilcraft/client/screen/WorkshopScreen.java new file mode 100644 index 0000000000..f15c6bae3a --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/client/screen/WorkshopScreen.java @@ -0,0 +1,32 @@ +package dev.dubhe.anvilcraft.client.screen; + +import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.inventory.WorkshopMenu; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import org.jetbrains.annotations.NotNull; + +public class WorkshopScreen extends AbstractContainerScreen { + private static final ResourceLocation CONTAINER_LOCATION = AnvilCraft.of("textures/gui/container/jewelcrafting/workshop.png"); + + public WorkshopScreen(WorkshopMenu menu, Inventory playerInventory, Component title) { + super(menu, playerInventory, title); + } + + @Override + protected void renderBg(GuiGraphics guiGraphics, float partialTick, int mouseX, int mouseY) { + int i = (this.width - this.imageWidth) / 2; + int j = (this.height - this.imageHeight) / 2; + guiGraphics.blit(CONTAINER_LOCATION, i, j, 0, 0, this.imageWidth, this.imageHeight); + } + + @Override + public void render(@NotNull GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + this.renderBackground(guiGraphics, mouseX, mouseY, partialTick); + super.render(guiGraphics, mouseX, mouseY, partialTick); + this.renderTooltip(guiGraphics, mouseX, mouseY); + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/data/recipe/MultiBlockConversionRecipeLoader.java b/src/main/java/dev/dubhe/anvilcraft/data/recipe/MultiBlockConversionRecipeLoader.java index f70e785966..28d4cbcc7e 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/recipe/MultiBlockConversionRecipeLoader.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/recipe/MultiBlockConversionRecipeLoader.java @@ -6,9 +6,11 @@ import dev.dubhe.anvilcraft.block.GiantAnvilBlock; import dev.dubhe.anvilcraft.block.HeavyIronBeamBlock; import dev.dubhe.anvilcraft.block.LargeCakeBlock; +import dev.dubhe.anvilcraft.block.WorkshopBlock; import dev.dubhe.anvilcraft.block.state.Cube3x3PartHalf; import dev.dubhe.anvilcraft.block.state.DirectionCube3x3PartHalf; import dev.dubhe.anvilcraft.block.state.GiantAnvilCube; +import dev.dubhe.anvilcraft.block.state.WorkshopCube; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.multiblock.BlockPredicateWithState; import dev.dubhe.anvilcraft.recipe.multiblock.ModifySpawnerAction; @@ -300,126 +302,6 @@ public static void init(RegistrateRecipeProvider provider) { .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.TOP_ES) .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) ) - .save(provider, AnvilCraft.of("multiblock_conversion/giant_anvil_1")); - - MultiblockConversionRecipe.builder() - .inputLayer("AAA", "AAA", "AAA") - .inputLayer(" ", " B ", " ") - .inputLayer("CCC", "CCC", "CCC") - .inputSymbol('A', ModBlocks.CUT_HEAVY_IRON_BLOCK) - .inputSymbol('B', ModBlocks.HEAVY_IRON_COLUMN) - .inputSymbol('C', ModBlocks.POLISHED_HEAVY_IRON_BLOCK) - .outputLayer("ABC", "DEF", "GHI") - .outputLayer("JKL", "MNO", "PQR") - .outputLayer("STU", "VWX", "YZ[") - .outputSymbol('A', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.BOTTOM_WN) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('B', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.BOTTOM_N) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('C', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.BOTTOM_EN) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('D', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.BOTTOM_W) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('E', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.BOTTOM_CENTER) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('F', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.BOTTOM_E) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('G', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.BOTTOM_WS) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('H', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.BOTTOM_S) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('I', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.BOTTOM_ES) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('J', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.MID_WN) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('K', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.MID_N) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('L', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.MID_EN) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('M', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.MID_W) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('N', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.MID_CENTER) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CENTER) - ) - .outputSymbol('O', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.MID_E) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('P', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.MID_WS) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('Q', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.MID_S) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('R', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.MID_ES) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('S', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.TOP_WN) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('T', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.TOP_N) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('U', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.TOP_EN) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('V', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.TOP_W) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('W', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.TOP_CENTER) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('X', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.TOP_E) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('Y', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.TOP_WS) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('Z', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.TOP_S) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) - .outputSymbol('[', BlockPredicateWithState.of(ModBlocks.GIANT_ANVIL) - .hasState(GiantAnvilBlock.HALF, Cube3x3PartHalf.TOP_ES) - .hasState(GiantAnvilBlock.CUBE, GiantAnvilCube.CORNER) - ) .save(provider, AnvilCraft.of("multiblock_conversion/giant_anvil_2")); MultiblockConversionRecipe.builder() @@ -715,5 +597,173 @@ public static void init(RegistrateRecipeProvider provider) { .hasState("facing", "down") ) .save(provider, AnvilCraft.of("multiblock_conversion/deflection_ring")); + + MultiblockConversionRecipe.builder() + .inputLayer("AAA", "AAA", "AAA") + .inputLayer("B ", "C ", "DEF") + .inputLayer("G ", "G ", "HHH") + .inputSymbol('A', "minecraft:smooth_stone") + .inputSymbol('B', BlockPredicateWithState.of("minecraft:stonecutter") + .hasState("facing", "east") + ) + .inputSymbol('C', BlockPredicateWithState.of("anvilcraft:jewelcrafting_table") + .hasState("facing", "east") + ) + .inputSymbol('D', "minecraft:cartography_table") + .inputSymbol('E', "minecraft:crafting_table") + .inputSymbol('F', BlockPredicateWithState.of("minecraft:loom") + .hasState("facing", "north") + ) + .inputSymbol('G', BlockPredicateWithState.of("minecraft:spruce_trapdoor") + .hasState("half", "bottom") + .hasState("open", "true") + .hasState("facing", "east") + .hasState("waterlogged", "false") + ) + .inputSymbol('H', BlockPredicateWithState.of("minecraft:spruce_trapdoor") + .hasState("half", "bottom") + .hasState("open", "true") + .hasState("facing", "north") + .hasState("waterlogged", "false") + ) + .outputLayer("ABC", "DEF", "GHI") + .outputLayer("JKL", "MNO", "PQR") + .outputLayer("STU", "VWX", "YZ[") + .outputSymbol('A', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.BOTTOM_WN) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('B', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.BOTTOM_N) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('C', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.BOTTOM_EN) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('D', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.BOTTOM_W) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('E', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.BOTTOM_CENTER) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('F', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.BOTTOM_E) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('G', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.BOTTOM_WS) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('H', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.BOTTOM_S) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('I', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.BOTTOM_ES) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('J', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.MID_WN) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('K', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.MID_N) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('L', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.MID_EN) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('M', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.MID_W) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('N', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.MID_CENTER) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CENTER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('O', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.MID_E) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('P', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.MID_WS) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('Q', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.MID_S) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('R', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.MID_ES) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('S', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.TOP_WN) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('T', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.TOP_N) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('U', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.TOP_EN) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('V', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.TOP_W) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('W', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.TOP_CENTER) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('X', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.TOP_E) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('Y', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.TOP_WS) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('Z', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.TOP_S) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .outputSymbol('[', BlockPredicateWithState.of(ModBlocks.WORKSHOP) + .hasState(WorkshopBlock.PART, Cube3x3PartHalf.TOP_ES) + .hasState(WorkshopBlock.CUBE, WorkshopCube.CORNER) + .hasState(WorkshopBlock.FACING, Direction.NORTH) + ) + .save(provider, AnvilCraft.of("multiblock_conversion/workshop")); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/data/recipe/MultiBlockRecipeLoader.java b/src/main/java/dev/dubhe/anvilcraft/data/recipe/MultiBlockRecipeLoader.java index 5bd77defc0..d1a56c5573 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/recipe/MultiBlockRecipeLoader.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/recipe/MultiBlockRecipeLoader.java @@ -204,5 +204,35 @@ public static void init(RegistrateRecipeProvider provider) { .symbol('C', "anvilcraft:magnetoelectric_core") .symbol('D', "anvilcraft:tungsten_block") .save(provider); + + MultiblockRecipe.builder("anvilcraft:workshop", 1) + .layer("AAA", "AAA", "AAA") + .layer("B ", "C ", "DEF") + .layer("G ", "G ", "HHH") + .symbol('A', "minecraft:smooth_stone") + .symbol('B', BlockPredicateWithState.of("minecraft:stonecutter") + .hasState("facing", "east") + ) + .symbol('C', BlockPredicateWithState.of("anvilcraft:jewelcrafting_table") + .hasState("facing", "east") + ) + .symbol('D', "minecraft:cartography_table") + .symbol('E', "minecraft:crafting_table") + .symbol('F', BlockPredicateWithState.of("minecraft:loom") + .hasState("facing", "north") + ) + .symbol('G', BlockPredicateWithState.of("minecraft:spruce_trapdoor") + .hasState("half", "bottom") + .hasState("open", "true") + .hasState("facing", "east") + .hasState("waterlogged", "false") + ) + .symbol('H', BlockPredicateWithState.of("minecraft:spruce_trapdoor") + .hasState("half", "bottom") + .hasState("open", "true") + .hasState("facing", "north") + .hasState("waterlogged", "false") + ) + .save(provider); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/init/ModMenuTypes.java b/src/main/java/dev/dubhe/anvilcraft/init/ModMenuTypes.java index 30f6e3175c..90b7859108 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/ModMenuTypes.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/ModMenuTypes.java @@ -24,6 +24,7 @@ import dev.dubhe.anvilcraft.client.gui.screen.StructureToolScreen; import dev.dubhe.anvilcraft.client.gui.screen.TeslaTowerScreen; import dev.dubhe.anvilcraft.client.gui.screen.TranscendenceAnvilScreen; +import dev.dubhe.anvilcraft.client.screen.WorkshopScreen; import dev.dubhe.anvilcraft.inventory.ActiveSilencerMenu; import dev.dubhe.anvilcraft.inventory.AdvancedComparatorMenu; import dev.dubhe.anvilcraft.inventory.BatchCrafterMenu; @@ -47,6 +48,7 @@ import dev.dubhe.anvilcraft.inventory.StructureToolMenu; import dev.dubhe.anvilcraft.inventory.TeslaTowerMenu; import dev.dubhe.anvilcraft.inventory.TranscendenceAnvilMenu; +import dev.dubhe.anvilcraft.inventory.WorkshopMenu; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.MenuProvider; @@ -158,6 +160,10 @@ public class ModMenuTypes { () -> FrostSmithingScreen::new) .register(); + public static final MenuEntry WORKSHOP = REGISTRATE + .menu("workshop", (type, id, inv) -> new WorkshopMenu(type, id, inv), () -> WorkshopScreen::new) + .register(); + public static void register() { } diff --git a/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlockEntities.java b/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlockEntities.java index 7a20581f83..d7fd0b57f9 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlockEntities.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlockEntities.java @@ -43,6 +43,7 @@ import dev.dubhe.anvilcraft.block.entity.TransmissionPoleBlockEntity; import dev.dubhe.anvilcraft.block.entity.VoidEnergyCollectorBlockEntity; import dev.dubhe.anvilcraft.block.entity.WhiteHoleBlockEntity; +import dev.dubhe.anvilcraft.block.entity.WorkshopBlockEntity; import dev.dubhe.anvilcraft.block.entity.heatable.GlowingBlockEntity; import dev.dubhe.anvilcraft.block.entity.heatable.HeatedBlockEntity; import dev.dubhe.anvilcraft.block.entity.heatable.IncandescentBlockEntity; @@ -304,6 +305,11 @@ public class ModBlockEntities { .validBlocks(ModBlocks.NEUTRON_IRRADIATOR) .register(); + public static final BlockEntityEntry WORKSHOP = REGISTRATE + .blockEntity("workshop", WorkshopBlockEntity::new) + .validBlocks(ModBlocks.WORKSHOP) + .register(); + public static void register() { } } diff --git a/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java b/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java index cc74adb801..8b05d9adfc 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java @@ -125,6 +125,7 @@ import dev.dubhe.anvilcraft.block.VoidEnergyCollectorBlock; import dev.dubhe.anvilcraft.block.VoidMatterBlock; import dev.dubhe.anvilcraft.block.WhiteHoleBlock; +import dev.dubhe.anvilcraft.block.WorkshopBlock; import dev.dubhe.anvilcraft.block.heatable.GlowingBlock; import dev.dubhe.anvilcraft.block.heatable.HeatedBlock; import dev.dubhe.anvilcraft.block.heatable.IncandescentBlock; @@ -381,6 +382,19 @@ public class ModBlocks { .tag(BlockTags.MINEABLE_WITH_PICKAXE) .register(); + public static final BlockEntry WORKSHOP = REGISTRATE.block("workshop", WorkshopBlock::new) + .initialProperties(() -> Blocks.IRON_BLOCK) + .properties(p -> p.noOcclusion() + .isValidSpawn(Blocks::never) + .strength(4.0F)) + .loot(SimpleMultiPartBlock::loot) + .item(SimpleMultiPartBlockItem::new) + .properties((properties) -> properties.stacksTo(16)) + .build() + .blockstate(DataGenUtil::noExtraModelOrState) + .tag(BlockTags.MINEABLE_WITH_PICKAXE) + .register(); + public static final BlockEntry NEUTRON_IRRADIATOR = REGISTRATE.block("neutron_irradiator", NeutronIrradiatorBlock::new) .initialProperties(() -> Blocks.IRON_BLOCK) .blockstate(DataGenUtil::noExtraModelOrState) diff --git a/src/main/java/dev/dubhe/anvilcraft/inventory/WorkshopMenu.java b/src/main/java/dev/dubhe/anvilcraft/inventory/WorkshopMenu.java new file mode 100644 index 0000000000..f2a7e511b8 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/inventory/WorkshopMenu.java @@ -0,0 +1,65 @@ +package dev.dubhe.anvilcraft.inventory; + +import dev.dubhe.anvilcraft.init.block.ModBlocks; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +public class WorkshopMenu extends AbstractContainerMenu { + private final ContainerLevelAccess access; + private final Player player; + + public WorkshopMenu(@Nullable MenuType menuType, int containerId, Inventory inventory) { + this(menuType, containerId, inventory, ContainerLevelAccess.NULL); + } + + public WorkshopMenu(@Nullable MenuType menuType, int containerId, Inventory inventory, ContainerLevelAccess access) { + super(menuType, containerId); + this.access = access; + this.player = inventory.player; + addPlayerInventory(inventory); + addPlayerHotbar(inventory); + } + + private void addPlayerInventory(Inventory playerInventory) { + } + + private void addPlayerHotbar(Inventory playerInventory) { + } + + @Override + public ItemStack quickMoveStack(Player player, int index) { + Slot sourceSlot = slots.get(index); + if (sourceSlot == null || !sourceSlot.hasItem()) { + return ItemStack.EMPTY; + } + ItemStack sourceStack = sourceSlot.getItem(); + ItemStack copyOfSourceStack = sourceStack.copy(); + + if (index < 11) { + if (!moveItemStackTo(sourceStack, 11, 47, true)) { + return ItemStack.EMPTY; + } + } else if (!moveItemStackTo(sourceStack, 0, 11, false)) { + return ItemStack.EMPTY; + } + + if (sourceStack.getCount() == 0) { + sourceSlot.set(ItemStack.EMPTY); + } else { + sourceSlot.setChanged(); + } + sourceSlot.onTake(player, sourceStack); + return copyOfSourceStack; + } + + @Override + public boolean stillValid(Player player) { + return stillValid(access, player, ModBlocks.WORKSHOP.get()); + } +} diff --git a/src/main/resources/assets/anvilcraft/blockstates/workshop.json b/src/main/resources/assets/anvilcraft/blockstates/workshop.json new file mode 100644 index 0000000000..25adebb510 --- /dev/null +++ b/src/main/resources/assets/anvilcraft/blockstates/workshop.json @@ -0,0 +1,36 @@ +{ + "multipart": [ + { + "when": { "facing": "north", "cube": "center" }, + "apply": { "model": "anvilcraft:block/workshop" } + }, + { + "when": { "facing": "east", "cube": "center" }, + "apply": { "model": "anvilcraft:block/workshop", "y": 90 } + }, + { + "when": { "facing": "south", "cube": "center" }, + "apply": { "model": "anvilcraft:block/workshop", "y": 180 } + }, + { + "when": { "facing": "west", "cube": "center" }, + "apply": { "model": "anvilcraft:block/workshop", "y": 270 } + }, + { + "when": { "facing": "north", "cube": "corner" }, + "apply": { "model": "anvilcraft:block/workshop_part" } + }, + { + "when": { "facing": "east", "cube": "corner" }, + "apply": { "model": "anvilcraft:block/workshop_part", "y": 90 } + }, + { + "when": { "facing": "south", "cube": "corner" }, + "apply": { "model": "anvilcraft:block/workshop_part", "y": 180 } + }, + { + "when": { "facing": "west", "cube": "corner" }, + "apply": { "model": "anvilcraft:block/workshop_part", "y": 270 } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft/models/block/workshop_part.json b/src/main/resources/assets/anvilcraft/models/block/workshop_part.json new file mode 100644 index 0000000000..a258e940cc --- /dev/null +++ b/src/main/resources/assets/anvilcraft/models/block/workshop_part.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "particle": "anvilcraft:block/workshop" + } +} \ No newline at end of file