diff --git a/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/HammerManager.java b/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/HammerManager.java new file mode 100644 index 000000000..b5ff930b9 --- /dev/null +++ b/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/HammerManager.java @@ -0,0 +1,28 @@ +package dev.dubhe.anvilcraft.api.hammer; + +import net.minecraft.world.level.block.Block; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +@SuppressWarnings("unused") +public class HammerManager { + private static final Map, IHammerChangeable> INIT_CHANGE = new HashMap<>(); + private static final Map CHANGE = new HashMap<>(); + + public static void registerChange(Supplier block, IHammerChangeable changeable) { + HammerManager.INIT_CHANGE.put(block, changeable); + } + + public static IHammerChangeable getChange(Block block) { + if (block instanceof IHammerChangeable changeable) return changeable; + return HammerManager.CHANGE.getOrDefault(block, IHammerChangeableBlock.EMPTY); + } + + public static void register() { + for (Map.Entry, IHammerChangeable> entry : INIT_CHANGE.entrySet()) { + HammerManager.CHANGE.put(entry.getKey().get(), entry.getValue()); + } + } +} diff --git a/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/IHammerChangeable.java b/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/IHammerChangeable.java new file mode 100644 index 000000000..d2dd6fa87 --- /dev/null +++ b/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/IHammerChangeable.java @@ -0,0 +1,21 @@ +package dev.dubhe.anvilcraft.api.hammer; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface IHammerChangeable { + /** + * 改变状态 + * + * @param player 玩家 + * @param blockPos 坐标 + * @param level 世界 + * @param anvilHammer 铁砧锤物品 + * @return 是否改变成功 + */ + boolean change(Player player, BlockPos blockPos, @NotNull Level level, ItemStack anvilHammer); +} diff --git a/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/IHammerChangeableBlock.java b/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/IHammerChangeableBlock.java new file mode 100644 index 000000000..73d29bc95 --- /dev/null +++ b/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/IHammerChangeableBlock.java @@ -0,0 +1,63 @@ +package dev.dubhe.anvilcraft.api.hammer; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("unused") +public interface IHammerChangeableBlock extends IHammerChangeable { + DirectionProperty FACING_HOPPER = BlockStateProperties.FACING_HOPPER; + DirectionProperty FACING = BlockStateProperties.FACING; + DirectionProperty HORIZONTAL_FACING = BlockStateProperties.HORIZONTAL_FACING; + IHammerChangeableBlock DEFAULT = new IHammerChangeableBlock() { + }; + IHammerChangeableBlock EMPTY = new IHammerChangeableBlock() { + public boolean change(Player player, BlockPos blockPos, @NotNull Level level, ItemStack anvilHammer) { + return false; + } + }; + + @Override + default boolean change(Player player, BlockPos blockPos, @NotNull Level level, ItemStack anvilHammer) { + BlockState state = level.getBlockState(blockPos); + if (state.hasProperty(FACING)) { + state = IHammerChangeableBlock.rotate(state); + } else if (state.hasProperty(FACING_HOPPER)) { + state = IHammerChangeableBlock.hopperRotate(state); + } else if (state.hasProperty(HORIZONTAL_FACING)) { + state = IHammerChangeableBlock.horizontalRotate(state); + } + level.setBlockAndUpdate(blockPos, state); + return true; + } + + private static @NotNull BlockState rotate(@NotNull BlockState state) { + Direction direction = state.getValue(FACING); + return switch (direction) { + case WEST -> state.setValue(FACING, Direction.UP); + case UP -> state.setValue(FACING, Direction.DOWN); + case DOWN -> state.setValue(FACING, Direction.NORTH); + default -> state.setValue(FACING, direction.getClockWise()); + }; + } + + private static @NotNull BlockState hopperRotate(@NotNull BlockState state) { + Direction direction = state.getValue(FACING_HOPPER); + return switch (direction) { + case WEST -> state.setValue(FACING_HOPPER, Direction.DOWN); + case DOWN -> state.setValue(FACING_HOPPER, Direction.NORTH); + default -> state.setValue(FACING_HOPPER, direction.getClockWise()); + }; + } + + @SuppressWarnings("SameParameterValue") + private static @NotNull BlockState horizontalRotate(@NotNull BlockState state) { + return state.setValue(HORIZONTAL_FACING, state.getValue(HORIZONTAL_FACING).getClockWise()); + } +} diff --git a/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/IHammerRemovable.java b/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/IHammerRemovable.java new file mode 100644 index 000000000..6d92fab59 --- /dev/null +++ b/common/src/main/java/dev/dubhe/anvilcraft/api/hammer/IHammerRemovable.java @@ -0,0 +1,4 @@ +package dev.dubhe.anvilcraft.api.hammer; + +public interface IHammerRemovable { +} diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/AutoCrafterBlock.java b/common/src/main/java/dev/dubhe/anvilcraft/block/AutoCrafterBlock.java index 4f593e688..43a00e144 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/AutoCrafterBlock.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/AutoCrafterBlock.java @@ -1,6 +1,8 @@ package dev.dubhe.anvilcraft.block; import dev.dubhe.anvilcraft.api.depository.FilteredItemDepository; +import dev.dubhe.anvilcraft.api.hammer.IHammerChangeableBlock; +import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; import dev.dubhe.anvilcraft.block.entity.AutoCrafterBlockEntity; import dev.dubhe.anvilcraft.init.ModBlockEntities; import dev.dubhe.anvilcraft.init.ModMenuTypes; @@ -38,7 +40,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class AutoCrafterBlock extends BaseEntityBlock { +public class AutoCrafterBlock extends BaseEntityBlock implements IHammerChangeableBlock, IHammerRemovable { public static final DirectionProperty FACING = DirectionalBlock.FACING; public static final BooleanProperty LIT = RedstoneTorchBlock.LIT; diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/ChuteBlock.java b/common/src/main/java/dev/dubhe/anvilcraft/block/ChuteBlock.java index cbca4595b..a8688ec9d 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/ChuteBlock.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/ChuteBlock.java @@ -1,6 +1,8 @@ package dev.dubhe.anvilcraft.block; import dev.dubhe.anvilcraft.api.depository.FilteredItemDepository; +import dev.dubhe.anvilcraft.api.hammer.IHammerChangeableBlock; +import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; import dev.dubhe.anvilcraft.block.entity.ChuteBlockEntity; import dev.dubhe.anvilcraft.init.ModBlockEntities; import dev.dubhe.anvilcraft.init.ModBlocks; @@ -46,7 +48,7 @@ import javax.annotation.Nonnull; import java.util.stream.Stream; -public class ChuteBlock extends BaseEntityBlock { +public class ChuteBlock extends BaseEntityBlock implements IHammerChangeableBlock, IHammerRemovable { public static final DirectionProperty FACING = BlockStateProperties.FACING_HOPPER; public static final BooleanProperty ENABLED = BlockStateProperties.ENABLED; @@ -259,4 +261,18 @@ public static boolean hasChuteFacing(Level level, BlockPos pos) { } return false; } + +// @Override +// public boolean change(Player player, BlockPos pos, @NotNull Level level, ItemStack anvilHammer) { +// BlockState state = level.getBlockState(pos); +// BlockState facingState = level.getBlockState(pos.relative(state.getValue(FACING))); +// if (facingState.is(ModBlocks.CHUTE.get()) || facingState.is(ModBlocks.SIMPLE_CHUTE.get())) { +// if (facingState.getValue(FACING).getOpposite() == state.getValue(FACING)) { +// level.destroyBlock(pos, true); +// return true; +// } +// } +// IHammerChangeableBlock.DEFAULT.change(player, pos, level, anvilHammer); +// return true; +// } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalAnvilBlock.java b/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalAnvilBlock.java index c4c332955..485014796 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalAnvilBlock.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalAnvilBlock.java @@ -1,5 +1,6 @@ package dev.dubhe.anvilcraft.block; +import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; import dev.dubhe.anvilcraft.init.ModMenuTypes; import dev.dubhe.anvilcraft.inventory.RoyalAnvilMenu; import net.minecraft.core.BlockPos; @@ -28,7 +29,7 @@ import javax.annotation.Nonnull; -public class RoyalAnvilBlock extends AnvilBlock { +public class RoyalAnvilBlock extends AnvilBlock implements IHammerRemovable { private static final VoxelShape BASE = Block.box(2.0, 0.0, 2.0, 14.0, 4.0, 14.0); private static final VoxelShape X_LEG1 = Block.box(4.0, 4.0, 5.0, 12.0, 10.0, 11.0); private static final VoxelShape X_TOP = Block.box(0.0, 10.0, 3.0, 16.0, 16.0, 13.0); diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalGrindstone.java b/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalGrindstone.java index 16c6b89d8..134a59883 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalGrindstone.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalGrindstone.java @@ -1,5 +1,6 @@ package dev.dubhe.anvilcraft.block; +import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; import dev.dubhe.anvilcraft.init.ModMenuTypes; import dev.dubhe.anvilcraft.inventory.RoyalGrindstoneMenu; import net.minecraft.core.BlockPos; @@ -18,7 +19,7 @@ import net.minecraft.world.phys.BlockHitResult; import org.jetbrains.annotations.NotNull; -public class RoyalGrindstone extends GrindstoneBlock { +public class RoyalGrindstone extends GrindstoneBlock implements IHammerRemovable { private static final Component CONTAINER_TITLE = Component.translatable("container.grindstone_title"); @@ -33,6 +34,7 @@ public RoyalGrindstone(Properties properties) { player.awardStat(Stats.INTERACT_WITH_GRINDSTONE); return InteractionResult.CONSUME; } + @Override public MenuProvider getMenuProvider(@NotNull BlockState state, @NotNull Level level, @NotNull BlockPos pos) { return new SimpleMenuProvider((i, inventory, player) -> new RoyalGrindstoneMenu(i, inventory, ContainerLevelAccess.create(level, pos)), CONTAINER_TITLE); diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalSmithingTableBlock.java b/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalSmithingTableBlock.java index f7e6788ec..89bb35111 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalSmithingTableBlock.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/RoyalSmithingTableBlock.java @@ -1,5 +1,6 @@ package dev.dubhe.anvilcraft.block; +import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; import dev.dubhe.anvilcraft.init.ModMenuTypes; import dev.dubhe.anvilcraft.inventory.RoyalSmithingMenu; import net.minecraft.core.BlockPos; @@ -18,7 +19,7 @@ import net.minecraft.world.phys.BlockHitResult; import org.jetbrains.annotations.NotNull; -public class RoyalSmithingTableBlock extends SmithingTableBlock { +public class RoyalSmithingTableBlock extends SmithingTableBlock implements IHammerRemovable { private static final Component CONTAINER_TITLE = Component.translatable("container.upgrade"); public RoyalSmithingTableBlock(Properties properties) { diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/SimpleChuteBlock.java b/common/src/main/java/dev/dubhe/anvilcraft/block/SimpleChuteBlock.java index 305a7c452..81677f1ef 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/SimpleChuteBlock.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/SimpleChuteBlock.java @@ -1,6 +1,9 @@ package dev.dubhe.anvilcraft.block; import dev.dubhe.anvilcraft.api.depository.ItemDepository; +import dev.dubhe.anvilcraft.api.hammer.IHammerChangeable; +import dev.dubhe.anvilcraft.api.hammer.IHammerChangeableBlock; +import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; import dev.dubhe.anvilcraft.block.entity.SimpleChuteBlockEntity; import dev.dubhe.anvilcraft.init.ModBlockEntities; import dev.dubhe.anvilcraft.init.ModBlocks; @@ -9,6 +12,8 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; import net.minecraft.world.Containers; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BaseEntityBlock; @@ -35,7 +40,7 @@ import javax.annotation.Nonnull; -public class SimpleChuteBlock extends BaseEntityBlock implements SimpleWaterloggedBlock { +public class SimpleChuteBlock extends BaseEntityBlock implements SimpleWaterloggedBlock, IHammerChangeable, IHammerRemovable { public static final DirectionProperty FACING = BlockStateProperties.FACING_HOPPER; public static final BooleanProperty ENABLED = BlockStateProperties.ENABLED; public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; @@ -184,4 +189,18 @@ public int getAnalogOutputSignal(@NotNull BlockState blockState, @NotNull Level public FluidState getFluidState(BlockState state) { return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } + + @Override + public boolean change(Player player, BlockPos pos, @NotNull Level level, ItemStack anvilHammer) { + IHammerChangeableBlock.DEFAULT.change(player, pos, level, anvilHammer); + BlockState state = level.getBlockState(pos); + BlockState facingState = level.getBlockState(pos.relative(state.getValue(FACING))); + if (facingState.is(ModBlocks.CHUTE.get()) || facingState.is(ModBlocks.SIMPLE_CHUTE.get())) { + if (facingState.getValue(FACING).getOpposite() == state.getValue(FACING)) { + level.destroyBlock(pos, true); + return true; + } + } + return true; + } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/StampingPlatformBlock.java b/common/src/main/java/dev/dubhe/anvilcraft/block/StampingPlatformBlock.java index bd9169893..f0c21127a 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/StampingPlatformBlock.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/StampingPlatformBlock.java @@ -1,5 +1,6 @@ package dev.dubhe.anvilcraft.block; +import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.item.context.BlockPlaceContext; @@ -19,7 +20,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; import org.jetbrains.annotations.NotNull; -public class StampingPlatformBlock extends Block implements SimpleWaterloggedBlock { +public class StampingPlatformBlock extends Block implements SimpleWaterloggedBlock, IHammerRemovable { public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; private static final VoxelShape REDUCE_AABB = Shapes.or( Block.box(2.0, 12.0, 2.0, 14.0, 16.0, 14.0), diff --git a/common/src/main/java/dev/dubhe/anvilcraft/data/generator/tags/BlockTagLoader.java b/common/src/main/java/dev/dubhe/anvilcraft/data/generator/tags/BlockTagLoader.java index dc374e38f..0550640ff 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/data/generator/tags/BlockTagLoader.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/data/generator/tags/BlockTagLoader.java @@ -2,7 +2,6 @@ import com.tterrag.registrate.providers.RegistrateTagsProvider; import dev.dubhe.anvilcraft.init.ModBlockTags; -import dev.dubhe.anvilcraft.init.ModBlocks; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import org.jetbrains.annotations.NotNull; @@ -16,7 +15,13 @@ public static void init(@NotNull RegistrateTagsProvider provider) { .add(Blocks.BROWN_MUSHROOM_BLOCK) .add(Blocks.RED_MUSHROOM_BLOCK) .add(Blocks.MUSHROOM_STEM); - provider.addTag(ModBlockTags.REMOVABLE).setReplace(false) + provider.addTag(ModBlockTags.HAMMER_CHANGEABLE).setReplace(false) + .add(Blocks.OBSERVER) + .add(Blocks.HOPPER) + .add(Blocks.DROPPER) + .add(Blocks.DISPENSER) + .add(Blocks.LIGHTNING_ROD); + provider.addTag(ModBlockTags.HAMMER_REMOVABLE).setReplace(false) .add(Blocks.BELL) .add(Blocks.REDSTONE_LAMP) .add(Blocks.IRON_DOOR) @@ -61,12 +66,6 @@ public static void init(@NotNull RegistrateTagsProvider provider) { .add(Blocks.CAMPFIRE) .add(Blocks.ANVIL) .add(Blocks.CHIPPED_ANVIL) - .add(Blocks.DAMAGED_ANVIL) - .add(ModBlocks.ROYAL_SMITHING_TABLE.getId()) - .add(ModBlocks.AUTO_CRAFTER.getId()) - .add(ModBlocks.CHUTE.getId()) - .add(ModBlocks.STAMPING_PLATFORM.getId()) - .add(ModBlocks.ROYAL_ANVIL.getId()) - .add(ModBlocks.ROYAL_GRINDSTONE.getId()); + .add(Blocks.DAMAGED_ANVIL); } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/event/ServerEventListener.java b/common/src/main/java/dev/dubhe/anvilcraft/event/ServerEventListener.java index 6a817e383..7a4f3b342 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/event/ServerEventListener.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/event/ServerEventListener.java @@ -6,10 +6,12 @@ import dev.dubhe.anvilcraft.api.event.SubscribeEvent; import dev.dubhe.anvilcraft.api.event.server.ServerEndDataPackReloadEvent; import dev.dubhe.anvilcraft.api.event.server.ServerStartedEvent; +import dev.dubhe.anvilcraft.api.hammer.HammerManager; import dev.dubhe.anvilcraft.data.recipe.anvil.AnvilRecipe; import dev.dubhe.anvilcraft.data.recipe.anvil.outcome.SpawnItem; import dev.dubhe.anvilcraft.data.recipe.anvil.predicate.HasBlock; import dev.dubhe.anvilcraft.data.recipe.anvil.predicate.HasItemIngredient; +import dev.dubhe.anvilcraft.init.ModHammerInits; import net.minecraft.advancements.critereon.BlockPredicate; import net.minecraft.core.NonNullList; import net.minecraft.core.RegistryAccess; @@ -36,6 +38,8 @@ public class ServerEventListener { public void onServerStarted(@NotNull ServerStartedEvent event) { MinecraftServer server = event.getServer(); ServerEventListener.processRecipes(server); + ModHammerInits.init(); + HammerManager.register(); } @SubscribeEvent diff --git a/common/src/main/java/dev/dubhe/anvilcraft/init/ModBlockTags.java b/common/src/main/java/dev/dubhe/anvilcraft/init/ModBlockTags.java index f39adb084..4c8ef21ed 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/init/ModBlockTags.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/init/ModBlockTags.java @@ -12,7 +12,8 @@ public class ModBlockTags { public static final TagKey REDSTONE_TORCH = bind("redstone_torch"); public static final TagKey MUSHROOM_BLOCK = bind("mushroom_block"); public static final TagKey CANT_BROKEN_ANVIL = bind("cant_broken_anvil"); - public static final TagKey REMOVABLE = bind("removable"); + public static final TagKey HAMMER_REMOVABLE = bind("hammer_removable"); + public static final TagKey HAMMER_CHANGEABLE = bind("hammer_changeable"); private static @NotNull TagKey bindC(String id) { return TagKey.create(Registries.BLOCK, new ResourceLocation("c", id)); diff --git a/common/src/main/java/dev/dubhe/anvilcraft/init/ModHammerInits.java b/common/src/main/java/dev/dubhe/anvilcraft/init/ModHammerInits.java new file mode 100644 index 000000000..6faa67bf3 --- /dev/null +++ b/common/src/main/java/dev/dubhe/anvilcraft/init/ModHammerInits.java @@ -0,0 +1,16 @@ +package dev.dubhe.anvilcraft.init; + +import dev.dubhe.anvilcraft.api.hammer.HammerManager; +import dev.dubhe.anvilcraft.api.hammer.IHammerChangeableBlock; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.level.block.Block; + +public class ModHammerInits { + @SuppressWarnings("deprecation") + public static void init() { + for (Block block : BuiltInRegistries.BLOCK) { + if (!block.builtInRegistryHolder().is(ModBlockTags.HAMMER_CHANGEABLE)) continue; + HammerManager.registerChange(() -> block, IHammerChangeableBlock.DEFAULT); + } + } +} diff --git a/common/src/main/java/dev/dubhe/anvilcraft/init/ModItems.java b/common/src/main/java/dev/dubhe/anvilcraft/init/ModItems.java index 448226ce8..33c17fa6c 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/init/ModItems.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/init/ModItems.java @@ -5,7 +5,7 @@ import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.data.generator.AnvilCraftDatagen; import dev.dubhe.anvilcraft.data.recipe.crafting_table.ShapedTagRecipeBuilder; -import dev.dubhe.anvilcraft.item.AnvilHammer; +import dev.dubhe.anvilcraft.item.AnvilHammerItem; import dev.dubhe.anvilcraft.item.CursedItem; import dev.dubhe.anvilcraft.item.GeodeItem; import dev.dubhe.anvilcraft.item.MagnetItem; @@ -222,7 +222,7 @@ public void appendHoverText(@NotNull ItemStack stack, @Nullable Level level, @No .register(); public static final ItemEntry BEEF_MUSHROOM_STEW_RAW = REGISTRATE .item("beef_mushroom_stew_raw", Item::new) - .properties(properties->properties.stacksTo(1)) + .properties(properties -> properties.stacksTo(1)) .recipe((ctx, provider) -> ShapelessRecipeBuilder.shapeless(RecipeCategory.FOOD, ctx.get()) .requires(Items.BEEF) .requires(Items.BROWN_MUSHROOM) @@ -234,7 +234,7 @@ public void appendHoverText(@NotNull ItemStack stack, @Nullable Level level, @No .register(); public static final ItemEntry BEEF_MUSHROOM_STEW = REGISTRATE .item("beef_mushroom_stew", p -> new BowlFoodItem(p.food(ModFoods.BEEF_MUSHROOM_STEW))) - .properties(properties->properties.stacksTo(1)) + .properties(properties -> properties.stacksTo(1)) .tag(ModItemTags.FOODS) .register(); public static final ItemEntry UTUSAN_RAW = REGISTRATE @@ -422,9 +422,12 @@ public void appendHoverText(@NotNull ItemStack stack, @Nullable Level level, @No .save(provider) ) .register(); - public static final ItemEntry ANVIL_HAMMER = REGISTRATE - .item("anvil_hammer", properties -> new AnvilHammer(properties.durability(35))) + public static final ItemEntry ANVIL_HAMMER = REGISTRATE + .item("anvil_hammer", properties -> new AnvilHammerItem(properties.durability(35))) + .model((ctx, provider) -> { + }) .register(); + public static void register() { } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/item/AnvilHammer.java b/common/src/main/java/dev/dubhe/anvilcraft/item/AnvilHammerItem.java similarity index 52% rename from common/src/main/java/dev/dubhe/anvilcraft/item/AnvilHammer.java rename to common/src/main/java/dev/dubhe/anvilcraft/item/AnvilHammerItem.java index 93f82224a..b21ab1389 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/item/AnvilHammer.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/item/AnvilHammerItem.java @@ -4,11 +4,10 @@ import com.google.common.collect.Multimap; import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.api.event.entity.AnvilFallOnLandEvent; +import dev.dubhe.anvilcraft.api.hammer.HammerManager; +import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; import dev.dubhe.anvilcraft.init.ModBlockTags; -import net.minecraft.Util; import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; @@ -20,7 +19,6 @@ import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.item.FallingBlockEntity; -import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -29,20 +27,13 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.Property; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; - -public class AnvilHammer extends Item implements Vanishable { +public class AnvilHammerItem extends Item implements Vanishable { private long lastDropAnvilTime = 0; - private final HashSet stateNames = new HashSet<>(List.of("facing", "axis", "rotation")); private final Multimap defaultModifiers; - public AnvilHammer(Item.Properties properties) { + + public AnvilHammerItem(Item.Properties properties) { super(properties); ImmutableMultimap.Builder builder = ImmutableMultimap.builder(); builder.put(Attributes.ATTACK_DAMAGE, new AttributeModifier(BASE_ATTACK_DAMAGE_UUID, "Weapon modifier", 5, AttributeModifier.Operation.ADDITION)); @@ -50,77 +41,50 @@ public AnvilHammer(Item.Properties properties) { this.defaultModifiers = builder.build(); } - private void breakBlock(Player player, BlockPos blockPos, Level level){ - if (level.isClientSide) return; + private void breakBlock(Player player, BlockPos blockPos, @NotNull Level level) { + if (!(player instanceof ServerPlayer serverPlayer)) return; BlockState blockState = level.getBlockState(blockPos); - if (!blockState.is(ModBlockTags.REMOVABLE)) return; Block block = blockState.getBlock(); + if (!blockState.is(ModBlockTags.HAMMER_REMOVABLE) && !(block instanceof IHammerRemovable)) return; level.destroyBlock(blockPos, false); - if (!player.isAlive() || player instanceof ServerPlayer && ((ServerPlayer) player).hasDisconnected()) { - player.drop(new ItemStack(block.asItem()), false); - } - else if (!player.isCreative()){ - Inventory inventory = player.getInventory(); - if (inventory.player instanceof ServerPlayer) { - inventory.placeItemBackInInventory(new ItemStack(block.asItem())); - } - - + if (!serverPlayer.isAlive() && serverPlayer.hasDisconnected()) { + serverPlayer.drop(new ItemStack(block.asItem()), false); + return; } + if (serverPlayer.isCreative()) return; + serverPlayer.getInventory().placeItemBackInInventory(new ItemStack(block.asItem())); } - private boolean changeBlockState(Player player, BlockPos blockPos, Level level, ItemStack anvilHammer){ + + private boolean changeBlockState(Player player, BlockPos blockPos, @NotNull Level level, ItemStack anvilHammer) { if (level.isClientSide) return false; Block block = level.getBlockState(blockPos).getBlock(); - StateDefinition stateDefinition = block.getStateDefinition(); - Collection> collection = stateDefinition.getProperties(); - String string = BuiltInRegistries.BLOCK.getKey(block).toString(); - if (collection.isEmpty()) return false; - CompoundTag compoundTag = anvilHammer.getOrCreateTagElement("DebugProperty"); - String string2 = compoundTag.getString(string); - Property property = stateDefinition.getProperty(string2); - if (property == null) { - for (Property tempProperty : collection.stream().toList()) { - if (stateNames.contains(tempProperty.getName())) { - property = tempProperty; - break; - } - } - if (property == null) return false; - } - BlockState blockState = cycleState(level.getBlockState(blockPos), property, player.isSecondaryUseActive()); - level.setBlock(blockPos, blockState, 18); - return true; + return HammerManager.getChange(block).change(player, blockPos, level, anvilHammer); } - private static > BlockState cycleState(BlockState state, Property property, boolean backwards) { - return state.setValue(property, getRelative(property.getPossibleValues(), state.getValue(property), backwards)); - } - private static T getRelative(Iterable allowedValues, @Nullable T currentValue, boolean backwards) { - return backwards ? Util.findPreviousInIterable(allowedValues, currentValue) : Util.findNextInIterable(allowedValues, currentValue); - } - public void dropAnvil(Player player, Level level, BlockPos blockPos) { - if (player == null || level.isClientSide) return; + private void dropAnvil(Player player, Level level, BlockPos blockPos) { + if (player == null || level.isClientSide) return; if (System.currentTimeMillis() - lastDropAnvilTime <= 150) return; lastDropAnvilTime = System.currentTimeMillis(); AnvilFallOnLandEvent event = new AnvilFallOnLandEvent(level, blockPos.above(), new FallingBlockEntity(EntityType.FALLING_BLOCK, level), player.fallDistance); AnvilCraft.EVENT_BUS.post(event); - level.playSound (null, blockPos, SoundEvents.ANVIL_LAND, SoundSource.BLOCKS,1f,1f); + level.playSound(null, blockPos, SoundEvents.ANVIL_LAND, SoundSource.BLOCKS, 1f, 1f); ItemStack itemStack = player.getItemInHand(player.getUsedItemHand()); - if (itemStack.getItem() instanceof AnvilHammer){ + if (itemStack.getItem() instanceof AnvilHammerItem) { itemStack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(player.getUsedItemHand())); } } @Override - public @NotNull InteractionResult useOn(UseOnContext context) { - BlockPos blockPos = context.getClickedPos(); - Player player = context.getPlayer(); - Level level = context.getLevel(); - if (player == null) { - return InteractionResult.FAIL; - } - return InteractionResult.sidedSuccess(changeBlockState(player, blockPos, level, context.getItemInHand())); + public @NotNull InteractionResult useOn(@NotNull UseOnContext context) { + BlockPos blockPos = context.getClickedPos(); + Player player = context.getPlayer(); + Level level = context.getLevel(); + if (player == null) { + return InteractionResult.FAIL; + } + return InteractionResult.sidedSuccess(changeBlockState(player, blockPos, level, context.getItemInHand())); } + public void useAttackBlock(Player player, BlockPos blockPos, Level level) { if (player == null || level.isClientSide) return; if (player.isShiftKeyDown()) { @@ -129,8 +93,9 @@ public void useAttackBlock(Player player, BlockPos blockPos, Level level) { dropAnvil(player, level, blockPos); } } + @Override - public boolean canAttackBlock(@NotNull BlockState state, @NotNull Level level, @NotNull BlockPos pos, Player player) { + public boolean canAttackBlock(@NotNull BlockState state, @NotNull Level level, @NotNull BlockPos pos, @NotNull Player player) { return !player.isCreative(); } @@ -138,17 +103,19 @@ public boolean canAttackBlock(@NotNull BlockState state, @NotNull Level level, @ public float getDestroySpeed(@NotNull ItemStack stack, @NotNull BlockState state) { return 1.0f; } + @Override - public boolean mineBlock(@NotNull ItemStack stack, @NotNull Level level, BlockState state, @NotNull BlockPos pos, @NotNull LivingEntity miningEntity) { + public boolean mineBlock(@NotNull ItemStack stack, @NotNull Level level, @NotNull BlockState state, @NotNull BlockPos pos, @NotNull LivingEntity miningEntity) { if (state.getDestroySpeed(level, pos) != 0.0f) { stack.hurtAndBreak(2, miningEntity, e -> e.broadcastBreakEvent(EquipmentSlot.MAINHAND)); } return true; } + @Override - public boolean hurtEnemy(ItemStack stack, @NotNull LivingEntity target, @NotNull LivingEntity attacker) { - stack.hurtAndBreak(1, attacker, e -> e.broadcastBreakEvent(EquipmentSlot.MAINHAND)); - float damageBonus = attacker.fallDistance > 17 ? 34 : attacker.fallDistance*2; + public boolean hurtEnemy(@NotNull ItemStack stack, @NotNull LivingEntity target, @NotNull LivingEntity attacker) { + stack.hurtAndBreak(1, attacker, e -> e.broadcastBreakEvent(EquipmentSlot.MAINHAND)); + float damageBonus = attacker.fallDistance > 17 ? 34 : attacker.fallDistance * 2; target.hurt(target.level().damageSources().anvil(attacker), damageBonus); return true; } @@ -157,6 +124,7 @@ public boolean hurtEnemy(ItemStack stack, @NotNull LivingEntity target, @NotNull public boolean isCorrectToolForDrops(@NotNull BlockState block) { return false; } + @Override public @NotNull Multimap getDefaultAttributeModifiers(@NotNull EquipmentSlot slot) { if (slot == EquipmentSlot.MAINHAND) { diff --git a/fabric/src/generated/resources/data/anvilcraft/tags/blocks/hammer_changeable.json b/fabric/src/generated/resources/data/anvilcraft/tags/blocks/hammer_changeable.json new file mode 100644 index 000000000..f4ea87936 --- /dev/null +++ b/fabric/src/generated/resources/data/anvilcraft/tags/blocks/hammer_changeable.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "minecraft:piston" + ] +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/anvilcraft/tags/blocks/hammer_removable.json b/fabric/src/generated/resources/data/anvilcraft/tags/blocks/hammer_removable.json new file mode 100644 index 000000000..e5bb88043 --- /dev/null +++ b/fabric/src/generated/resources/data/anvilcraft/tags/blocks/hammer_removable.json @@ -0,0 +1,56 @@ +{ + "replace": false, + "values": [ + "minecraft:bell", + "minecraft:redstone_lamp", + "minecraft:iron_door", + "minecraft:rail", + "minecraft:activator_rail", + "minecraft:detector_rail", + "minecraft:powered_rail", + "minecraft:note_block", + "minecraft:observer", + "minecraft:hopper", + "minecraft:dropper", + "minecraft:dispenser", + "minecraft:honey_block", + "minecraft:slime_block", + "minecraft:piston", + "minecraft:sticky_piston", + "minecraft:lightning_rod", + "minecraft:daylight_detector", + "minecraft:lectern", + "minecraft:tripwire_hook", + "minecraft:sculk_shrieker", + "minecraft:lever", + "minecraft:stone_button", + "minecraft:oak_pressure_plate", + "minecraft:stone_pressure_plate", + "minecraft:light_weighted_pressure_plate", + "minecraft:heavy_weighted_pressure_plate", + "minecraft:sculk_sensor", + "minecraft:calibrated_sculk_sensor", + "minecraft:redstone_wire", + "minecraft:redstone_torch", + "minecraft:redstone_wall_torch", + "minecraft:redstone_block", + "minecraft:repeater", + "minecraft:comparator", + "minecraft:target", + "minecraft:iron_trapdoor", + "minecraft:cauldron", + "minecraft:lava_cauldron", + "minecraft:water_cauldron", + "minecraft:powder_snow_cauldron", + "minecraft:campfire", + "minecraft:anvil", + "minecraft:chipped_anvil", + "minecraft:damaged_anvil", + "anvilcraft:royal_smithing_table", + "anvilcraft:auto_crafter", + "anvilcraft:chute", + "anvilcraft:stamping_platform", + "anvilcraft:royal_anvil", + "anvilcraft:royal_grindstone" + ] +} \ No newline at end of file diff --git a/fabric/src/main/java/dev/dubhe/anvilcraft/listener/fabric/AnvilHammerListener.java b/fabric/src/main/java/dev/dubhe/anvilcraft/listener/fabric/AnvilHammerListener.java index 0340b716f..eb6e6eac4 100644 --- a/fabric/src/main/java/dev/dubhe/anvilcraft/listener/fabric/AnvilHammerListener.java +++ b/fabric/src/main/java/dev/dubhe/anvilcraft/listener/fabric/AnvilHammerListener.java @@ -1,6 +1,6 @@ package dev.dubhe.anvilcraft.listener.fabric; -import dev.dubhe.anvilcraft.item.AnvilHammer; +import dev.dubhe.anvilcraft.item.AnvilHammerItem; import net.fabricmc.fabric.api.event.player.AttackBlockCallback; import net.minecraft.core.BlockPos; import net.minecraft.world.InteractionHand; @@ -10,7 +10,7 @@ public class AnvilHammerListener { private static InteractionResult anvilHammer(Player player, Level level, InteractionHand hand, BlockPos blockPos) { - if (player.getItemInHand(hand).getItem() instanceof AnvilHammer anvilHammer ) { + if (player.getItemInHand(hand).getItem() instanceof AnvilHammerItem anvilHammer ) { anvilHammer.useAttackBlock(player, blockPos, level); } return InteractionResult.PASS; diff --git a/forge/src/generated/resources/assets/anvilcraft/lang/en_ud.json b/forge/src/generated/resources/assets/anvilcraft/lang/en_ud.json index de4dc2477..a7a5fa203 100644 --- a/forge/src/generated/resources/assets/anvilcraft/lang/en_ud.json +++ b/forge/src/generated/resources/assets/anvilcraft/lang/en_ud.json @@ -29,6 +29,7 @@ "item.anvilcraft.amethyst_pickaxe.tooltip": "¡spuoɯɐıp ʇou 'ǝɹo uoɹı ǝuıɯ uɐɔ 'ʎʇıןɐnb ǝxɐʞɔıd ǝuoʇS", "item.anvilcraft.amethyst_shovel": "ןǝʌoɥS ʇsʎɥʇǝɯⱯ", "item.anvilcraft.amethyst_sword": "pɹoʍS ʇsʎɥʇǝɯⱯ", + "item.anvilcraft.anvil_hammer": "ɹǝɯɯɐH ןıʌuⱯ", "item.anvilcraft.bark": "ʞɹɐᗺ", "item.anvilcraft.beef_mushroom_stew": "ʍǝʇS ɯooɹɥsnW ɟǝǝᗺ", "item.anvilcraft.beef_mushroom_stew_raw": "ʍɐᴚ ʍǝʇS ɯooɹɥsnW ɟǝǝᗺ", diff --git a/forge/src/generated/resources/assets/anvilcraft/lang/en_us.json b/forge/src/generated/resources/assets/anvilcraft/lang/en_us.json index 9a576d559..b0ced67d9 100644 --- a/forge/src/generated/resources/assets/anvilcraft/lang/en_us.json +++ b/forge/src/generated/resources/assets/anvilcraft/lang/en_us.json @@ -29,6 +29,7 @@ "item.anvilcraft.amethyst_pickaxe.tooltip": "Stone pickaxe quality, can mine iron ore, not diamonds!", "item.anvilcraft.amethyst_shovel": "Amethyst Shovel", "item.anvilcraft.amethyst_sword": "Amethyst Sword", + "item.anvilcraft.anvil_hammer": "Anvil Hammer", "item.anvilcraft.bark": "Bark", "item.anvilcraft.beef_mushroom_stew": "Beef Mushroom Stew", "item.anvilcraft.beef_mushroom_stew_raw": "Beef Mushroom Stew Raw", diff --git a/forge/src/generated/resources/data/anvilcraft/tags/blocks/hammer_changeable.json b/forge/src/generated/resources/data/anvilcraft/tags/blocks/hammer_changeable.json new file mode 100644 index 000000000..f4ea87936 --- /dev/null +++ b/forge/src/generated/resources/data/anvilcraft/tags/blocks/hammer_changeable.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "minecraft:piston" + ] +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/anvilcraft/tags/blocks/hammer_removable.json b/forge/src/generated/resources/data/anvilcraft/tags/blocks/hammer_removable.json new file mode 100644 index 000000000..e5bb88043 --- /dev/null +++ b/forge/src/generated/resources/data/anvilcraft/tags/blocks/hammer_removable.json @@ -0,0 +1,56 @@ +{ + "replace": false, + "values": [ + "minecraft:bell", + "minecraft:redstone_lamp", + "minecraft:iron_door", + "minecraft:rail", + "minecraft:activator_rail", + "minecraft:detector_rail", + "minecraft:powered_rail", + "minecraft:note_block", + "minecraft:observer", + "minecraft:hopper", + "minecraft:dropper", + "minecraft:dispenser", + "minecraft:honey_block", + "minecraft:slime_block", + "minecraft:piston", + "minecraft:sticky_piston", + "minecraft:lightning_rod", + "minecraft:daylight_detector", + "minecraft:lectern", + "minecraft:tripwire_hook", + "minecraft:sculk_shrieker", + "minecraft:lever", + "minecraft:stone_button", + "minecraft:oak_pressure_plate", + "minecraft:stone_pressure_plate", + "minecraft:light_weighted_pressure_plate", + "minecraft:heavy_weighted_pressure_plate", + "minecraft:sculk_sensor", + "minecraft:calibrated_sculk_sensor", + "minecraft:redstone_wire", + "minecraft:redstone_torch", + "minecraft:redstone_wall_torch", + "minecraft:redstone_block", + "minecraft:repeater", + "minecraft:comparator", + "minecraft:target", + "minecraft:iron_trapdoor", + "minecraft:cauldron", + "minecraft:lava_cauldron", + "minecraft:water_cauldron", + "minecraft:powder_snow_cauldron", + "minecraft:campfire", + "minecraft:anvil", + "minecraft:chipped_anvil", + "minecraft:damaged_anvil", + "anvilcraft:royal_smithing_table", + "anvilcraft:auto_crafter", + "anvilcraft:chute", + "anvilcraft:stamping_platform", + "anvilcraft:royal_anvil", + "anvilcraft:royal_grindstone" + ] +} \ No newline at end of file diff --git a/forge/src/main/java/dev/dubhe/anvilcraft/listener/AnvilHammerListener.java b/forge/src/main/java/dev/dubhe/anvilcraft/listener/AnvilHammerListener.java index 36e789a6f..92ff0a858 100644 --- a/forge/src/main/java/dev/dubhe/anvilcraft/listener/AnvilHammerListener.java +++ b/forge/src/main/java/dev/dubhe/anvilcraft/listener/AnvilHammerListener.java @@ -1,13 +1,13 @@ package dev.dubhe.anvilcraft.listener; -import dev.dubhe.anvilcraft.item.AnvilHammer; +import dev.dubhe.anvilcraft.item.AnvilHammerItem; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; public class AnvilHammerListener { @SubscribeEvent public void anvilHammer(PlayerInteractEvent.LeftClickBlock leftClickBlock) { - if (leftClickBlock.getEntity().getItemInHand(leftClickBlock.getEntity().getUsedItemHand()).getItem() instanceof AnvilHammer anvilHammer) { + if (leftClickBlock.getEntity().getItemInHand(leftClickBlock.getEntity().getUsedItemHand()).getItem() instanceof AnvilHammerItem anvilHammer) { anvilHammer.useAttackBlock(leftClickBlock.getEntity(), leftClickBlock.getPos(), leftClickBlock.getLevel()); } }