diff --git a/src/generated/resources/assets/anvilcraft/blockstates/exp_fluid.json b/src/generated/resources/assets/anvilcraft/blockstates/exp_fluid.json new file mode 100644 index 0000000000..0c6b101f18 --- /dev/null +++ b/src/generated/resources/assets/anvilcraft/blockstates/exp_fluid.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "anvilcraft:block/exp_fluid" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/anvilcraft/blockstates/exp_gem_block.json b/src/generated/resources/assets/anvilcraft/blockstates/exp_gem_block.json new file mode 100644 index 0000000000..bcd3974c66 --- /dev/null +++ b/src/generated/resources/assets/anvilcraft/blockstates/exp_gem_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "anvilcraft:block/exp_gem_block" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/anvilcraft/lang/en_ud.json b/src/generated/resources/assets/anvilcraft/lang/en_ud.json index f8f6f95069..9f083e793e 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_ud.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_ud.json @@ -307,6 +307,9 @@ "block.anvilcraft.ember_metal_block": "ןɐʇǝW ɹǝqɯƎ ɟo ʞɔoןᗺ", "block.anvilcraft.ember_smithing_table": "ǝןqɐ⟘ buıɥʇıɯS ɹǝqɯƎ", "block.anvilcraft.end_dust": "ʇsnᗡ puƎ", + "block.anvilcraft.exp_cauldron": "uoɹpןnɐƆ dxƎ", + "block.anvilcraft.exp_fluid": "pınןℲ dxƎ", + "block.anvilcraft.exp_gem_block": "ɯǝ⅁ ǝɔuǝıɹǝdxƎ ɟo ʞɔoןᗺ", "block.anvilcraft.exposed_copper_pressure_plate": "ǝʇɐןԀ ǝɹnssǝɹԀ ɹǝddoƆ pǝsodxƎ", "block.anvilcraft.ferrite_core_magnet_block": "ʇǝubɐW ɟo ʞɔoןᗺ pǝɹoƆ-ǝʇıɹɹǝℲ", "block.anvilcraft.fire_cauldron": "uoɹpןnɐƆ ǝɹıℲ", @@ -755,6 +758,8 @@ "item.anvilcraft.ember_metal_sword": "pɹoʍS ןɐʇǝW ɹǝqɯƎ", "item.anvilcraft.ember_metal_upgrade_smithing_template": "ǝʇɐןdɯǝ⟘ buıɥʇıɯS", "item.anvilcraft.emerald_amulet": "ʇǝןnɯⱯ pןɐɹǝɯƎ", + "item.anvilcraft.exp_bucket": "ʇǝʞɔnᗺ dxƎ", + "item.anvilcraft.exp_gem": "ɯǝ⅁ dxƎ", "item.anvilcraft.feather_amulet": "ʇǝןnɯⱯ ɹǝɥʇɐǝℲ", "item.anvilcraft.filter": "ɹǝʇןıℲ", "item.anvilcraft.flour": "ɹnoןℲ", diff --git a/src/generated/resources/assets/anvilcraft/lang/en_us.json b/src/generated/resources/assets/anvilcraft/lang/en_us.json index 298caeae67..37047d82b5 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_us.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_us.json @@ -307,6 +307,9 @@ "block.anvilcraft.ember_metal_block": "Block of Ember Metal", "block.anvilcraft.ember_smithing_table": "Ember Smithing Table", "block.anvilcraft.end_dust": "End Dust", + "block.anvilcraft.exp_cauldron": "Exp Cauldron", + "block.anvilcraft.exp_fluid": "Exp Fluid", + "block.anvilcraft.exp_gem_block": "Block of Experience Gem", "block.anvilcraft.exposed_copper_pressure_plate": "Exposed Copper Pressure Plate", "block.anvilcraft.ferrite_core_magnet_block": "Ferrite-Cored Block of Magnet", "block.anvilcraft.fire_cauldron": "Fire Cauldron", @@ -755,6 +758,8 @@ "item.anvilcraft.ember_metal_sword": "Ember Metal Sword", "item.anvilcraft.ember_metal_upgrade_smithing_template": "Smithing Template", "item.anvilcraft.emerald_amulet": "Emerald Amulet", + "item.anvilcraft.exp_bucket": "Exp Bucket", + "item.anvilcraft.exp_gem": "Exp Gem", "item.anvilcraft.feather_amulet": "Feather Amulet", "item.anvilcraft.filter": "Filter", "item.anvilcraft.flour": "Flour", diff --git a/src/generated/resources/assets/anvilcraft/models/block/exp_fluid.json b/src/generated/resources/assets/anvilcraft/models/block/exp_fluid.json new file mode 100644 index 0000000000..fb292bcb10 --- /dev/null +++ b/src/generated/resources/assets/anvilcraft/models/block/exp_fluid.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "anvilcraft:block/exp_fluid" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/anvilcraft/models/block/exp_gem_block.json b/src/generated/resources/assets/anvilcraft/models/block/exp_gem_block.json new file mode 100644 index 0000000000..3ab27deed3 --- /dev/null +++ b/src/generated/resources/assets/anvilcraft/models/block/exp_gem_block.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "anvilcraft:block/exp_gem_block" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/anvilcraft/models/item/exp_bucket.json b/src/generated/resources/assets/anvilcraft/models/item/exp_bucket.json new file mode 100644 index 0000000000..a05a9b196d --- /dev/null +++ b/src/generated/resources/assets/anvilcraft/models/item/exp_bucket.json @@ -0,0 +1,5 @@ +{ + "parent": "neoforge:item/bucket_drip", + "fluid": "anvilcraft:exp_fluid", + "loader": "neoforge:fluid_container" +} \ No newline at end of file diff --git a/src/generated/resources/assets/anvilcraft/models/item/exp_gem.json b/src/generated/resources/assets/anvilcraft/models/item/exp_gem.json new file mode 100644 index 0000000000..a26075f36f --- /dev/null +++ b/src/generated/resources/assets/anvilcraft/models/item/exp_gem.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "anvilcraft:item/exp_gem" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/anvilcraft/models/item/exp_gem_block.json b/src/generated/resources/assets/anvilcraft/models/item/exp_gem_block.json new file mode 100644 index 0000000000..7669cba68b --- /dev/null +++ b/src/generated/resources/assets/anvilcraft/models/item/exp_gem_block.json @@ -0,0 +1,3 @@ +{ + "parent": "anvilcraft:block/exp_gem_block" +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/recipes/building_blocks/exp_gem_block.json b/src/generated/resources/data/anvilcraft/advancement/recipes/building_blocks/exp_gem_block.json new file mode 100644 index 0000000000..0a10f3a744 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/recipes/building_blocks/exp_gem_block.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_exp_gem": { + "conditions": { + "items": [ + { + "items": "anvilcraft:exp_gem" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "anvilcraft:exp_gem_block" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_exp_gem" + ] + ], + "rewards": { + "recipes": [ + "anvilcraft:exp_gem_block" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/recipes/bulging/exp_cauldron.json b/src/generated/resources/data/anvilcraft/advancement/recipes/bulging/exp_cauldron.json new file mode 100644 index 0000000000..3d51ed2fe4 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/recipes/bulging/exp_cauldron.json @@ -0,0 +1,21 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": { + "recipe": "anvilcraft:bulging/exp_cauldron" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "anvilcraft:bulging/exp_cauldron" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/recipes/bulging/exp_gem.json b/src/generated/resources/data/anvilcraft/advancement/recipes/bulging/exp_gem.json new file mode 100644 index 0000000000..bdd6ba598c --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/recipes/bulging/exp_gem.json @@ -0,0 +1,21 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": { + "recipe": "anvilcraft:bulging/exp_gem" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "anvilcraft:bulging/exp_gem" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/recipes/misc/exp_gem.json b/src/generated/resources/data/anvilcraft/advancement/recipes/misc/exp_gem.json new file mode 100644 index 0000000000..9aa929cfaa --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/recipes/misc/exp_gem.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": { + "recipe": "anvilcraft:exp_gem" + }, + "trigger": "minecraft:recipe_unlocked" + }, + "hasitem": { + "conditions": { + "items": [ + { + "items": "anvilcraft:exp_gem_block" + } + ] + }, + "trigger": "minecraft:inventory_changed" + } + }, + "requirements": [ + [ + "has_the_recipe", + "hasitem" + ] + ], + "rewards": { + "recipes": [ + "anvilcraft:exp_gem" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/loot_table/blocks/exp_cauldron.json b/src/generated/resources/data/anvilcraft/loot_table/blocks/exp_cauldron.json new file mode 100644 index 0000000000..b02998cb1d --- /dev/null +++ b/src/generated/resources/data/anvilcraft/loot_table/blocks/exp_cauldron.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:cauldron" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "anvilcraft:blocks/exp_cauldron" +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/loot_table/blocks/exp_gem_block.json b/src/generated/resources/data/anvilcraft/loot_table/blocks/exp_gem_block.json new file mode 100644 index 0000000000..f83cc06989 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/loot_table/blocks/exp_gem_block.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "anvilcraft:exp_gem_block" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "anvilcraft:blocks/exp_gem_block" +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/recipe/bulging/exp_cauldron.json b/src/generated/resources/data/anvilcraft/recipe/bulging/exp_cauldron.json new file mode 100644 index 0000000000..64b2b71f86 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/recipe/bulging/exp_cauldron.json @@ -0,0 +1,11 @@ +{ + "type": "anvilcraft:bulging", + "fluid": "minecraft:water", + "ingredients": [ + { + "items": "anvilcraft:exp_gem" + } + ], + "results": [], + "transform": "anvilcraft:exp" +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/recipe/bulging/exp_gem.json b/src/generated/resources/data/anvilcraft/recipe/bulging/exp_gem.json new file mode 100644 index 0000000000..0a75326234 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/recipe/bulging/exp_gem.json @@ -0,0 +1,11 @@ +{ + "type": "anvilcraft:bulging", + "consume": 1000, + "fluid": "anvilcraft:exp_fluid", + "ingredients": [], + "results": [ + { + "id": "anvilcraft:exp_gem" + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/recipe/exp_gem.json b/src/generated/resources/data/anvilcraft/recipe/exp_gem.json new file mode 100644 index 0000000000..8f11c8cc13 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/recipe/exp_gem.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { + "item": "anvilcraft:exp_gem_block" + } + ], + "result": { + "count": 9, + "id": "anvilcraft:exp_gem" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/recipe/exp_gem_block.json b/src/generated/resources/data/anvilcraft/recipe/exp_gem_block.json new file mode 100644 index 0000000000..332a172bfb --- /dev/null +++ b/src/generated/resources/data/anvilcraft/recipe/exp_gem_block.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "A": { + "item": "anvilcraft:exp_gem" + } + }, + "pattern": [ + "AAA", + "AAA", + "AAA" + ], + "result": { + "count": 1, + "id": "anvilcraft:exp_gem_block" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/storage_blocks.json b/src/generated/resources/data/c/tags/block/storage_blocks.json index 42a9aa17a2..b0ce68317c 100644 --- a/src/generated/resources/data/c/tags/block/storage_blocks.json +++ b/src/generated/resources/data/c/tags/block/storage_blocks.json @@ -18,6 +18,7 @@ "anvilcraft:topaz_block", "anvilcraft:ruby_block", "anvilcraft:sapphire_block", + "anvilcraft:exp_gem_block", "anvilcraft:resin_block", "anvilcraft:amber_block", "anvilcraft:chocolate_block", diff --git a/src/generated/resources/data/c/tags/block/storage_blocks/exp_gem.json b/src/generated/resources/data/c/tags/block/storage_blocks/exp_gem.json new file mode 100644 index 0000000000..eb92f6015e --- /dev/null +++ b/src/generated/resources/data/c/tags/block/storage_blocks/exp_gem.json @@ -0,0 +1,5 @@ +{ + "values": [ + "anvilcraft:exp_gem_block" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/fluid/experience.json b/src/generated/resources/data/c/tags/fluid/experience.json new file mode 100644 index 0000000000..759ad225a5 --- /dev/null +++ b/src/generated/resources/data/c/tags/fluid/experience.json @@ -0,0 +1,6 @@ +{ + "values": [ + "anvilcraft:exp_fluid", + "anvilcraft:flowing_exp_fluid" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/buckets.json b/src/generated/resources/data/c/tags/item/buckets.json index 29ae2ecd3e..6e504011e9 100644 --- a/src/generated/resources/data/c/tags/item/buckets.json +++ b/src/generated/resources/data/c/tags/item/buckets.json @@ -1,5 +1,6 @@ { "values": [ + "anvilcraft:exp_bucket", "anvilcraft:oil_bucket", "anvilcraft:white_cement_bucket", "anvilcraft:light_gray_cement_bucket", diff --git a/src/generated/resources/data/c/tags/item/buckets/exp_fluid.json b/src/generated/resources/data/c/tags/item/buckets/exp_fluid.json new file mode 100644 index 0000000000..e05bc7d780 --- /dev/null +++ b/src/generated/resources/data/c/tags/item/buckets/exp_fluid.json @@ -0,0 +1,5 @@ +{ + "values": [ + "anvilcraft:exp_bucket" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/storage_blocks.json b/src/generated/resources/data/c/tags/item/storage_blocks.json index 1b61a18bdc..5eae1caa7f 100644 --- a/src/generated/resources/data/c/tags/item/storage_blocks.json +++ b/src/generated/resources/data/c/tags/item/storage_blocks.json @@ -19,6 +19,7 @@ "anvilcraft:topaz_block", "anvilcraft:ruby_block", "anvilcraft:sapphire_block", + "anvilcraft:exp_gem_block", "anvilcraft:resin_block", "anvilcraft:amber_block", "anvilcraft:chocolate_block", diff --git a/src/generated/resources/data/c/tags/item/storage_blocks/exp_gem.json b/src/generated/resources/data/c/tags/item/storage_blocks/exp_gem.json new file mode 100644 index 0000000000..eb92f6015e --- /dev/null +++ b/src/generated/resources/data/c/tags/item/storage_blocks/exp_gem.json @@ -0,0 +1,5 @@ +{ + "values": [ + "anvilcraft:exp_gem_block" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/beacon_base_blocks.json b/src/generated/resources/data/minecraft/tags/block/beacon_base_blocks.json index aef2fe5940..6858324eb7 100644 --- a/src/generated/resources/data/minecraft/tags/block/beacon_base_blocks.json +++ b/src/generated/resources/data/minecraft/tags/block/beacon_base_blocks.json @@ -17,6 +17,7 @@ "anvilcraft:brass_block", "anvilcraft:topaz_block", "anvilcraft:ruby_block", - "anvilcraft:sapphire_block" + "anvilcraft:sapphire_block", + "anvilcraft:exp_gem_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/cauldrons.json b/src/generated/resources/data/minecraft/tags/block/cauldrons.json index f17fbfb916..82d13a849d 100644 --- a/src/generated/resources/data/minecraft/tags/block/cauldrons.json +++ b/src/generated/resources/data/minecraft/tags/block/cauldrons.json @@ -4,6 +4,7 @@ "anvilcraft:melt_gem_cauldron", "anvilcraft:honey_cauldron", "anvilcraft:obsidian_cauldron", + "anvilcraft:exp_cauldron", "anvilcraft:oil_cauldron", "anvilcraft:fire_cauldron", "anvilcraft:white_cement_cauldron", 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 b73573c8e9..3c1e0d18b2 100644 --- a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json +++ b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json @@ -106,6 +106,7 @@ "anvilcraft:ruby_block", "anvilcraft:sapphire_block", "anvilcraft:chromatic_stone", + "anvilcraft:exp_gem_block", "anvilcraft:amber_block", "anvilcraft:mob_amber_block", "anvilcraft:resentful_amber_block", @@ -215,6 +216,7 @@ "anvilcraft:melt_gem_cauldron", "anvilcraft:honey_cauldron", "anvilcraft:obsidian_cauldron", + "anvilcraft:exp_cauldron", "anvilcraft:oil_cauldron", "anvilcraft:fire_cauldron", "anvilcraft:white_cement_cauldron", diff --git a/src/generated/resources/data/minecraft/tags/block/needs_iron_tool.json b/src/generated/resources/data/minecraft/tags/block/needs_iron_tool.json index 1b2abd6d04..95e6bf82eb 100644 --- a/src/generated/resources/data/minecraft/tags/block/needs_iron_tool.json +++ b/src/generated/resources/data/minecraft/tags/block/needs_iron_tool.json @@ -31,6 +31,7 @@ "anvilcraft:topaz_block", "anvilcraft:ruby_block", "anvilcraft:sapphire_block", - "anvilcraft:chromatic_stone" + "anvilcraft:chromatic_stone", + "anvilcraft:exp_gem_block" ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/item/beacon_payment_items.json b/src/generated/resources/data/minecraft/tags/item/beacon_payment_items.json index f34985df6c..1166282cf1 100644 --- a/src/generated/resources/data/minecraft/tags/item/beacon_payment_items.json +++ b/src/generated/resources/data/minecraft/tags/item/beacon_payment_items.json @@ -9,6 +9,7 @@ "anvilcraft:topaz", "anvilcraft:ruby", "anvilcraft:sapphire", + "anvilcraft:exp_gem", "anvilcraft:tungsten_ingot", "anvilcraft:titanium_ingot", "anvilcraft:zinc_ingot", diff --git a/src/main/java/dev/dubhe/anvilcraft/block/ExpFluidBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/ExpFluidBlock.java new file mode 100644 index 0000000000..35cf2bdcb0 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/block/ExpFluidBlock.java @@ -0,0 +1,28 @@ +package dev.dubhe.anvilcraft.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.LiquidBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FlowingFluid; + +public class ExpFluidBlock extends LiquidBlock { + public static final int XP_POINTS = 50; + + public ExpFluidBlock(FlowingFluid fluid, Properties properties) { + super(fluid, properties); + } + + @Override + public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { + // 这个不触发,我没招了... + if (level.isClientSide) return; + if (entity instanceof Player player) { + player.giveExperiencePoints(XP_POINTS); + level.setBlock(pos, Blocks.AIR.defaultBlockState(), 3); + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/block/ExpFluidCauldronBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/ExpFluidCauldronBlock.java new file mode 100644 index 0000000000..6c96f1f912 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/block/ExpFluidCauldronBlock.java @@ -0,0 +1,49 @@ +package dev.dubhe.anvilcraft.block; + +import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; +import dev.dubhe.anvilcraft.util.ModInteractionMap; +import net.minecraft.core.BlockPos; +import net.minecraft.core.cauldron.CauldronInteraction; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.entity.Entity; +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.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; + +public class ExpFluidCauldronBlock extends Layered4LevelCauldronBlock implements IHammerRemovable { + public ExpFluidCauldronBlock(Properties properties) { + super(properties, ModInteractionMap.EXP_FLUID); + } + + @Override + public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { + if (level.isClientSide) return; + if (!this.isEntityInsideContent(state, pos, entity)) return; + if (entity instanceof Player player) { + if (!this.isFull(state)) return; + player.giveExperiencePoints(ExpFluidBlock.XP_POINTS); + level.setBlock(pos, Blocks.CAULDRON.defaultBlockState(), 3); + } + } + + @Override + public ItemInteractionResult useItemOn( + ItemStack stack, + BlockState state, + Level level, + BlockPos pos, + Player player, + InteractionHand hand, + BlockHitResult hitResult + ) { + CauldronInteraction interaction = this.interactions.map().get(stack.getItem()); + if (interaction == null) { + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + return interaction.interact(state, level, pos, player, hand, stack); + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/JewelCraftingScreen.java b/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/JewelCraftingScreen.java index 8313b11599..63f2be11e3 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/JewelCraftingScreen.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/JewelCraftingScreen.java @@ -13,6 +13,7 @@ import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; +import org.lwjgl.glfw.GLFW; public class JewelCraftingScreen extends AbstractContainerScreen { private static final ResourceLocation CONTAINER_LOCATION = AnvilCraft.of("textures/gui/container/jewelcrafting/background.png"); @@ -108,4 +109,14 @@ protected void renderSlotContents(GuiGraphics guiGraphics, ItemStack itemstack, } super.renderSlotContents(guiGraphics, itemstack, slot, countString); } + + @Override + public boolean keyPressed(int key, int scanCode, int modifiers) { + if (key == GLFW.GLFW_KEY_SPACE) { + // 处理空格键快速填充配方逻辑 + this.menu.autoFill(); + return true; + } + return super.keyPressed(key, scanCode, modifiers); + } } diff --git a/src/main/java/dev/dubhe/anvilcraft/data/recipe/BulgingRecipeLoader.java b/src/main/java/dev/dubhe/anvilcraft/data/recipe/BulgingRecipeLoader.java index 7b66bbfd98..3a2a888484 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/recipe/BulgingRecipeLoader.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/recipe/BulgingRecipeLoader.java @@ -4,6 +4,7 @@ import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.block.state.Color; import dev.dubhe.anvilcraft.init.block.ModBlocks; +import dev.dubhe.anvilcraft.init.block.ModFluids; import dev.dubhe.anvilcraft.init.item.ModFoodItems; import dev.dubhe.anvilcraft.init.item.ModItemTags; import dev.dubhe.anvilcraft.init.item.ModItems; @@ -54,13 +55,23 @@ public static void init(RegistrateRecipeProvider provider) { .result(Blocks.RED_MUSHROOM_BLOCK) .result(Blocks.MUSHROOM_STEM, 0.1f) .save(provider); - BulgingRecipe.builder() .cauldron(Blocks.WATER_CAULDRON) .requires(Items.BROWN_MUSHROOM) .result(Blocks.BROWN_MUSHROOM_BLOCK) .result(Blocks.MUSHROOM_STEM, 0.1f) .save(provider); + + BulgingRecipe.builder() + .cauldron(ModFluids.EXP_FLUID.getId()) + .consume(1000) + .result(ModItems.EXP_GEM) + .save(provider); + BulgingRecipe.builder() + .cauldron(Blocks.WATER_CAULDRON) + .transform(ModBlocks.EXP_CAULDRON.get()) + .requires(ModItems.EXP_GEM) + .save(provider, AnvilCraft.of("bulging/exp_cauldron")); } private static void bulging(RegistrateRecipeProvider provider, ItemLike input, ItemLike result, int consume) { diff --git a/src/main/java/dev/dubhe/anvilcraft/data/tags/FluidTagLoader.java b/src/main/java/dev/dubhe/anvilcraft/data/tags/FluidTagLoader.java index bb2725b59d..11a644c654 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/tags/FluidTagLoader.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/tags/FluidTagLoader.java @@ -35,6 +35,9 @@ public static void init(RegistrateTagsProvider provider) { provider.addTag(ModFluidTags.OIL) .add(findResourceKey(ModFluids.OIL.get())) .add(findResourceKey(ModFluids.FLOWING_OIL.get())); + provider.addTag(ModFluidTags.EXPERIENCE) + .add(findResourceKey(ModFluids.EXP_FLUID.get())) + .add(findResourceKey(ModFluids.FLOWING_EXP_FLUID.get())); TagsProvider.TagAppender appender = provider.addTag(ModFluidTags.CEMENT); ModFluids.SOURCE_CEMENTS.forEach((color, cement) -> { appender.add(findResourceKey(cement.get())); diff --git a/src/main/java/dev/dubhe/anvilcraft/event/PlayerEventListener.java b/src/main/java/dev/dubhe/anvilcraft/event/PlayerEventListener.java index fc0b93e60b..fabc9c5575 100644 --- a/src/main/java/dev/dubhe/anvilcraft/event/PlayerEventListener.java +++ b/src/main/java/dev/dubhe/anvilcraft/event/PlayerEventListener.java @@ -11,6 +11,7 @@ import dev.dubhe.anvilcraft.init.item.ModItems; import dev.dubhe.anvilcraft.item.AnvilHammerItem; import dev.dubhe.anvilcraft.item.DragonRodItem; +import dev.dubhe.anvilcraft.item.ExpGemItem; import dev.dubhe.anvilcraft.item.MultitoolItem; import dev.dubhe.anvilcraft.item.property.component.BoxContents; import dev.dubhe.anvilcraft.network.DragonRodDevourPacket; @@ -55,6 +56,13 @@ public static void useEntity(PlayerInteractEvent.EntityInteract event) { event.setCanceled(true); } } + if (item.is(ModItems.EXP_GEM)) { + InteractionResult result = ExpGemItem.useEntity(player, target, item); + if (result != InteractionResult.PASS) { + event.setCancellationResult(result); + event.setCanceled(true); + } + } } @SubscribeEvent diff --git a/src/main/java/dev/dubhe/anvilcraft/init/ModNetworks.java b/src/main/java/dev/dubhe/anvilcraft/init/ModNetworks.java index 10cc33428e..7d02f3c922 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/ModNetworks.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/ModNetworks.java @@ -18,6 +18,7 @@ import dev.dubhe.anvilcraft.network.HeliostatsIrradiationPacket; import dev.dubhe.anvilcraft.network.InspectionStateChangedPacket; import dev.dubhe.anvilcraft.network.ItemDetectorChangeRangePacket; +import dev.dubhe.anvilcraft.network.JewelCraftingAutoFillPacket; import dev.dubhe.anvilcraft.network.LaserEmitPacket; import dev.dubhe.anvilcraft.network.MachineCycleFilterModePacket; import dev.dubhe.anvilcraft.network.MachineEnableFilterPacket; @@ -286,5 +287,10 @@ public static void init(PayloadRegistrar registrar) { FrostGrindstoneSyncPacket.HANDLER ); FrostSmithingPackets.register(registrar); + registrar.playToServer( + JewelCraftingAutoFillPacket.TYPE, + JewelCraftingAutoFillPacket.STREAM_CODEC, + JewelCraftingAutoFillPacket.HANDLER + ); } } \ No newline at end of file diff --git a/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlockTags.java b/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlockTags.java index a9e0cb73d1..21b4f00551 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlockTags.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlockTags.java @@ -81,6 +81,7 @@ public class ModBlockTags { public static final TagKey STORAGE_BLOCKS_TOPAZ = bindC("storage_blocks/topaz"); public static final TagKey STORAGE_BLOCKS_SAPPHIRE = bindC("storage_blocks/sapphire"); public static final TagKey STORAGE_BLOCKS_RUBY = bindC("storage_blocks/ruby"); + public static final TagKey STORAGE_BLOCKS_EXP_GEM = bindC("storage_blocks/exp_gem"); public static final TagKey STORAGE_BLOCKS_AMBER = bindC("storage_blocks/amber"); public static final TagKey STORAGE_BLOCKS_RESIN = bindC("storage_blocks/resin"); public static final TagKey STORAGE_BLOCKS_TRANSCENDIUM = bindC("storage_blocks/transcendium"); 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 b78d583a00..cc74adb801 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/block/ModBlocks.java @@ -42,6 +42,8 @@ import dev.dubhe.anvilcraft.block.EmberMetalStairBlock; import dev.dubhe.anvilcraft.block.EmberSmithingTableBlock; import dev.dubhe.anvilcraft.block.EndDustBlock; +import dev.dubhe.anvilcraft.block.ExpFluidBlock; +import dev.dubhe.anvilcraft.block.ExpFluidCauldronBlock; import dev.dubhe.anvilcraft.block.FerriteCoreMagnetBlock; import dev.dubhe.anvilcraft.block.FireCauldronBlock; import dev.dubhe.anvilcraft.block.FlintBlock; @@ -240,10 +242,7 @@ import static dev.dubhe.anvilcraft.api.power.IPowerComponent.OVERLOAD; import static dev.dubhe.anvilcraft.api.power.IPowerComponent.SWITCH; -@SuppressWarnings({ - "unused", - "CodeBlock2Expr" -}) +@SuppressWarnings({"unused", "CodeBlock2Expr"}) public class ModBlocks { static { REGISTRATE.defaultCreativeTab(ModItemGroups.ANVILCRAFT_FUNCTION_BLOCK.getKey()); @@ -2962,6 +2961,31 @@ public class ModBlocks { .simpleItem() .register(); + public static final BlockEntry EXP_GEM_BLOCK = REGISTRATE.block("exp_gem_block", Block::new) + .lang("Block of Experience Gem") + .initialProperties(() -> Blocks.EMERALD_BLOCK) + .item() + .tag(Tags.Items.STORAGE_BLOCKS, ModItemTags.STORAGE_BLOCKS_EXP_GEM) + .build() + .tag( + BlockTags.MINEABLE_WITH_PICKAXE, + BlockTags.NEEDS_IRON_TOOL, + BlockTags.BEACON_BASE_BLOCKS, + Tags.Blocks.STORAGE_BLOCKS, + ModBlockTags.STORAGE_BLOCKS_EXP_GEM + ) + .recipe((ctx, provider) -> { + ShapedRecipeBuilder.shaped(RecipeCategory.BUILDING_BLOCKS, ctx.get()) + .pattern("AAA") + .pattern("AAA") + .pattern("AAA") + .define('A', ModItems.EXP_GEM) + .unlockedBy(AnvilCraftDatagen.hasItem(ModItems.EXP_GEM), AnvilCraftDatagen.has(ModItems.EXP_GEM)) + .save(provider); + }) + .register(); + + public static final BlockEntry RESIN_BLOCK = REGISTRATE.block("resin_block", ResinBlock::new) .lang("Block of Resin") .initialProperties(() -> Blocks.SLIME_BLOCK) @@ -3989,6 +4013,14 @@ public class ModBlocks { .onRegister(block -> Item.BY_BLOCK.put(block, Items.CAULDRON)) .register(); + public static final BlockEntry EXP_CAULDRON = REGISTRATE.block("exp_cauldron", ExpFluidCauldronBlock::new) + .initialProperties(() -> Blocks.CAULDRON) + .blockstate(DataGenUtil::noExtraModelOrState) + .loot((tables, block) -> tables.dropOther(block, Items.CAULDRON)) + .tag(BlockTags.MINEABLE_WITH_PICKAXE, BlockTags.CAULDRONS) + .onRegister(block -> Item.BY_BLOCK.put(block, Items.CAULDRON)) + .register(); + public static final BlockEntry OIL_CAULDRON = REGISTRATE.block("oil_cauldron", OilCauldronBlock::new) .initialProperties(() -> Blocks.CAULDRON) .blockstate(DataGenUtil::noExtraModelOrState) @@ -4347,7 +4379,22 @@ private static BlockEntry registerPressu }) .register(); - public static final BlockEntry OIL = REGISTRATE.block("oil", p -> new LiquidBlock(ModFluids.OIL.get(), p)) + public static final BlockEntry EXP_FLUID = REGISTRATE.block( + "exp_fluid", + p -> new LiquidBlock(ModFluids.EXP_FLUID.get(), p) + ) + .properties(it -> it.mapColor(MapColor.COLOR_GREEN) + .replaceable() + .noCollission() + .pushReaction(PushReaction.DESTROY) + .noLootTable() + .liquid() + .sound(SoundType.EMPTY) + .strength(100.0F)) + .blockstate(ModelProviderUtil::liquid) + .register(); + + public static final BlockEntry OIL = REGISTRATE.block("oil", p -> new ExpFluidBlock(ModFluids.OIL.get(), p)) .properties(it -> it.mapColor(MapColor.TERRACOTTA_BLACK) .replaceable() .noCollission() diff --git a/src/main/java/dev/dubhe/anvilcraft/init/block/ModFluidTags.java b/src/main/java/dev/dubhe/anvilcraft/init/block/ModFluidTags.java index 070fe4a3f2..8659ac565d 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/block/ModFluidTags.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/block/ModFluidTags.java @@ -10,6 +10,7 @@ public class ModFluidTags { public static final TagKey OIL = bindC("oil"); public static final TagKey CEMENT = bindC("cement"); + public static final TagKey EXPERIENCE = bindC("experience"); public static final TagKey MENGER_SPONGE_CAN_ABSORB = bind("menger_sponge_can_absorb"); diff --git a/src/main/java/dev/dubhe/anvilcraft/init/block/ModFluids.java b/src/main/java/dev/dubhe/anvilcraft/init/block/ModFluids.java index 9d2b1925ff..d1b03f6b99 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/block/ModFluids.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/block/ModFluids.java @@ -35,6 +35,42 @@ public class ModFluids { ); public static final DeferredRegister FLUIDS = DeferredRegister.create(Registries.FLUID, AnvilCraft.MOD_ID); + public static final DeferredHolder EXP_FLUID_TYPE = FLUID_TYPES.register( + "exp_fluid", + () -> new FluidType(FluidType.Properties.create() + .descriptionId("block.anvilcraft.exp_fluid") + .density(1000) + .viscosity(500) + .fallDistanceModifier(0) + .motionScale(0.01) + .supportsBoating(true) + .sound(SoundActions.BUCKET_FILL, SoundEvents.BUCKET_FILL) + .sound(SoundActions.BUCKET_EMPTY, SoundEvents.BUCKET_EMPTY) + ) + ); + + public static final DeferredHolder EXP_FLUID = FLUIDS.register( + "exp_fluid", + () -> new BaseFlowingFluid.Source(ModFluids.EXP_FLUID_PROPERTIES) + ); + + public static final DeferredHolder FLOWING_EXP_FLUID = FLUIDS.register( + "flowing_exp_fluid", + () -> new BaseFlowingFluid.Flowing(ModFluids.EXP_FLUID_PROPERTIES) + ); + + public static final BaseFlowingFluid.Properties EXP_FLUID_PROPERTIES = new BaseFlowingFluid.Properties( + EXP_FLUID_TYPE, + EXP_FLUID, + FLOWING_EXP_FLUID + ) + .bucket(ModItems.EXP_BUCKET) + .block(ModBlocks.EXP_FLUID) + .tickRate(60) + .slopeFindDistance(2) + .levelDecreasePerBlock(3) + .explosionResistance(100); + public static final DeferredHolder OIL_TYPE = FLUID_TYPES.register( "oil", () -> new FluidType(FluidType.Properties.create() @@ -42,7 +78,6 @@ public class ModFluids { .density(2000) .viscosity(4000) .fallDistanceModifier(0) - .motionScale(0.007) .supportsBoating(true) .sound(SoundActions.BUCKET_FILL, SoundEvents.BUCKET_FILL) .sound(SoundActions.BUCKET_EMPTY, SoundEvents.BUCKET_EMPTY) @@ -208,6 +243,14 @@ public static void registerFluidInteractions(FMLCommonSetupEvent event) { } public static void onRegisterFluidType(RegisterClientExtensionsEvent e) { + e.registerFluidType( + new ModClientFluidTypeExtensionImpl( + AnvilCraft.of("block/exp_fluid"), + AnvilCraft.of("block/exp_fluid_flow"), + 0xC1E8A9, + 1.0f + ), EXP_FLUID_TYPE + ); e.registerFluidType( new ModClientFluidTypeExtensionImpl( AnvilCraft.of("block/oil"), diff --git a/src/main/java/dev/dubhe/anvilcraft/init/item/ModItemTags.java b/src/main/java/dev/dubhe/anvilcraft/init/item/ModItemTags.java index 28d7e8d17a..255fdc8e2c 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/item/ModItemTags.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/item/ModItemTags.java @@ -54,6 +54,7 @@ public class ModItemTags { public static final TagKey STORAGE_BLOCKS_TOPAZ = bindC("storage_blocks/topaz"); public static final TagKey STORAGE_BLOCKS_SAPPHIRE = bindC("storage_blocks/sapphire"); public static final TagKey STORAGE_BLOCKS_RUBY = bindC("storage_blocks/ruby"); + public static final TagKey STORAGE_BLOCKS_EXP_GEM = bindC("storage_blocks/exp_gem"); public static final TagKey STORAGE_BLOCKS_AMBER = bindC("storage_blocks/amber"); public static final TagKey STORAGE_BLOCKS_RESIN = bindC("storage_blocks/resin"); public static final TagKey STORAGE_BLOCKS_TRANSCENDIUM = bindC("storage_blocks/transcendium"); @@ -124,6 +125,7 @@ public class ModItemTags { public static final TagKey RAW_SILVER = bindC("raw_materials/silver"); public static final TagKey RAW_URANIUM = bindC("raw_materials/uranium"); + public static final TagKey EXP_BUCKETS = bindC("buckets/exp_fluid"); public static final TagKey OIL_BUCKETS = bindC("buckets/oil"); public static final TagKey CEMENT_BUCKETS = bindC("buckets/cement"); diff --git a/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java b/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java index be3164fd9d..50054f82d0 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/item/ModItems.java @@ -37,6 +37,7 @@ import dev.dubhe.anvilcraft.item.EmberMetalSwordItem; import dev.dubhe.anvilcraft.item.EmptyCapacitorItem; import dev.dubhe.anvilcraft.item.EmptySuperCapacitorItem; +import dev.dubhe.anvilcraft.item.ExpGemItem; import dev.dubhe.anvilcraft.item.FilterItem; import dev.dubhe.anvilcraft.item.FrostMetalAxeItem; import dev.dubhe.anvilcraft.item.FrostMetalHeavyHalberdItem; @@ -1369,6 +1370,15 @@ public Holder getType() { .save(provider); }) .register(); + public static final ItemEntry EXP_GEM = REGISTRATE.item("exp_gem", ExpGemItem::new) + .tag(ItemTags.BEACON_PAYMENT_ITEMS) + .recipe((ctx, provider) -> { + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ctx.get(), 9) + .requires(ModBlocks.EXP_GEM_BLOCK) + .unlockedBy("hasitem", RegistrateRecipeProvider.has(ModBlocks.EXP_GEM_BLOCK)) + .save(provider); + }) + .register(); public static final ItemEntry RESIN = REGISTRATE.item("resin", Item::new).tag(ModItemTags.RESIN).recipe((ctx, provider) -> { ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ctx.get(), 9) .requires(ModBlocks.RESIN_BLOCK) @@ -2059,6 +2069,15 @@ public Holder getType() { .properties((properties) -> properties.stacksTo(1)) .register(); + public static final ItemEntry EXP_BUCKET = REGISTRATE.item( + "exp_bucket", + p -> new BucketItem(ModFluids.EXP_FLUID.get(), p) + ) + .tag(ModItemTags.EXP_BUCKETS, Tags.Items.BUCKETS) + .initialProperties(() -> new Item.Properties().stacksTo(1).craftRemainder(Items.BUCKET)) + .model(ModelProviderUtil::bucket) + .register(); + public static final ItemEntry OIL_BUCKET = REGISTRATE.item("oil_bucket", p -> new BucketItem(ModFluids.OIL.get(), p)) .tag(ModItemTags.OIL_BUCKETS, Tags.Items.BUCKETS) .initialProperties(() -> new Item.Properties().stacksTo(1).craftRemainder(Items.BUCKET)) diff --git a/src/main/java/dev/dubhe/anvilcraft/inventory/JewelCraftingMenu.java b/src/main/java/dev/dubhe/anvilcraft/inventory/JewelCraftingMenu.java index 6f4faf4ef7..b50ed7ee7a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/inventory/JewelCraftingMenu.java +++ b/src/main/java/dev/dubhe/anvilcraft/inventory/JewelCraftingMenu.java @@ -4,8 +4,10 @@ import dev.dubhe.anvilcraft.inventory.component.jewel.JewelInputSlot; import dev.dubhe.anvilcraft.inventory.component.jewel.JewelResultSlot; import dev.dubhe.anvilcraft.inventory.container.JewelSourceContainer; +import dev.dubhe.anvilcraft.network.JewelCraftingAutoFillPacket; import dev.dubhe.anvilcraft.recipe.JewelCraftingRecipe; import dev.dubhe.anvilcraft.recipe.anvil.cache.RecipeCaches; +import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.core.component.DataComponents; import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; import net.minecraft.server.level.ServerPlayer; @@ -19,13 +21,19 @@ import net.minecraft.world.inventory.ResultContainer; import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.TransientCraftingContainer; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.item.enchantment.ItemEnchantments; import net.minecraft.world.level.Level; +import net.neoforged.neoforge.network.PacketDistributor; import org.jetbrains.annotations.Nullable; +import java.util.List; + + public class JewelCraftingMenu extends AbstractContainerMenu { public static final int RESULT_SLOT = 0; public static final int SOURCE_SLOT = 1; @@ -98,52 +106,50 @@ public ItemStack quickMoveStack(Player player, int index) { ItemStack copyOfSourceStack = sourceStack.copy(); // noinspection ConstantValue - if (sourceSlot != null && sourceSlot.hasItem()) { - if (index >= RESULT_SLOT && index < CRAFT_SLOT_END) { - if (!moveItemStackTo(copyOfSourceStack, INV_SLOT_START, USE_ROW_SLOT_END, true)) { - return ItemStack.EMPTY; - } - } else if (index >= INV_SLOT_START && index < USE_ROW_SLOT_END) { - if (!moveItemStackTo(copyOfSourceStack, SOURCE_SLOT, SOURCE_SLOT + 1, false)) { - if (!moveItemStackTo(copyOfSourceStack, CRAFT_SLOT_START, CRAFT_SLOT_END, false)) { - // 在背包里 - if (index < INV_SLOT_END) { - // 移到快捷栏 - if (!moveItemStackTo(copyOfSourceStack, USE_ROW_SLOT_START, USE_ROW_SLOT_END, false)) { - return ItemStack.EMPTY; - } - } else { - // 移动到背包 - if (!moveItemStackTo(copyOfSourceStack, INV_SLOT_START, INV_SLOT_END, false)) { - return ItemStack.EMPTY; - } - } - } else { - this.slotsChanged(craftingContainer); - } - } else { - this.slotsChanged(sourceContainer); - } - } - if (copyOfSourceStack.isEmpty()) { - sourceSlot.setByPlayer(ItemStack.EMPTY); - } else { - sourceSlot.setChanged(); - } + if (sourceSlot == null || !sourceSlot.hasItem()) return sourceStack; - if (copyOfSourceStack.getCount() == sourceStack.getCount()) { + if (index >= RESULT_SLOT && index < CRAFT_SLOT_END) { + if (!moveItemStackTo(copyOfSourceStack, INV_SLOT_START, USE_ROW_SLOT_END, true)) { return ItemStack.EMPTY; } + } else if (index >= INV_SLOT_START && index < USE_ROW_SLOT_END) { + ItemStack empty = quickMoveInvStack(index, copyOfSourceStack); + if (empty != null) return empty; + } - sourceStack.setCount(copyOfSourceStack.getCount()); - sourceSlot.onTake(player, copyOfSourceStack); - if (index == RESULT_SLOT) { - player.drop(copyOfSourceStack, false); - } + if (copyOfSourceStack.isEmpty()) { + sourceSlot.setByPlayer(ItemStack.EMPTY); + } else { + sourceSlot.setChanged(); + } + if (copyOfSourceStack.getCount() == sourceStack.getCount()) { + return ItemStack.EMPTY; + } + + sourceStack.setCount(copyOfSourceStack.getCount()); + sourceSlot.onTake(player, copyOfSourceStack); + if (index == RESULT_SLOT) { + player.drop(copyOfSourceStack, false); } return sourceStack; } + protected @Nullable ItemStack quickMoveInvStack(int index, ItemStack copyOfSourceStack) { + // 从背包里转移物品 + if (moveItemStackTo(copyOfSourceStack, SOURCE_SLOT, SOURCE_SLOT + 1, false)) { + this.slotsChanged(sourceContainer); + } else if (moveItemStackTo(copyOfSourceStack, CRAFT_SLOT_START, CRAFT_SLOT_END, false)) { + this.slotsChanged(craftingContainer); + } else if (index < INV_SLOT_END && !moveItemStackTo(copyOfSourceStack, USE_ROW_SLOT_START, USE_ROW_SLOT_END, false)) { + // 移到快捷栏 + return ItemStack.EMPTY; + } else if (index >= INV_SLOT_END && !moveItemStackTo(copyOfSourceStack, INV_SLOT_START, INV_SLOT_END, false)) { + // 移动到背包 + return ItemStack.EMPTY; + } + return null; + } + @Override public boolean stillValid(Player player) { return stillValid(access, player, ModBlocks.JEWEL_CRAFTING_TABLE.get()); @@ -198,6 +204,40 @@ private static void changedCraftingSlots( } } + /** + * 自动填充配方所需物品 + * 当玩家按下空格键时调用此方法 + */ + public void autoFill() { + if (player.level().isClientSide()) { + PacketDistributor.sendToServer(new JewelCraftingAutoFillPacket()); + return; + } + + RecipeHolder recipe = sourceContainer.getRecipe(); + if (recipe == null) return; + + List> mergedIngredients = recipe.value().mergedIngredients; + for (int i = 0; i < Math.min(mergedIngredients.size(), 4); i++) { + Object2IntMap.Entry entry = mergedIngredients.get(i); + Ingredient ingredient = entry.getKey(); + Item item = ingredient.getItems()[0].getItem(); + quickMoveStack(player, CRAFT_SLOT_START + i); + moveInvItemTo(item, CRAFT_SLOT_START + i); + } + } + + protected void moveInvItemTo(Item needItem, int targetIndex) { + for (int i = INV_SLOT_START; i < USE_ROW_SLOT_END; i++) { + Slot slot = slots.get(i); + if (slot.getItem().getItem() == needItem) { + if (!moveItemStackTo(slot.getItem(), targetIndex, targetIndex + 1, false)) { + return; + } + } + } + } + @Override public void removed(Player player) { super.removed(player); diff --git a/src/main/java/dev/dubhe/anvilcraft/item/ExpGemItem.java b/src/main/java/dev/dubhe/anvilcraft/item/ExpGemItem.java new file mode 100644 index 0000000000..bdb82692ee --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/item/ExpGemItem.java @@ -0,0 +1,113 @@ +package dev.dubhe.anvilcraft.item; + +import com.google.common.collect.Lists; +import dev.dubhe.anvilcraft.block.ExpFluidBlock; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.npc.Villager; +import net.minecraft.world.entity.npc.VillagerData; +import net.minecraft.world.entity.npc.VillagerProfession; +import net.minecraft.world.entity.npc.VillagerTrades; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.flag.FeatureFlags; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.trading.MerchantOffer; +import net.minecraft.world.item.trading.MerchantOffers; +import net.minecraft.world.level.Level; + +import java.util.ArrayList; + +public class ExpGemItem extends Item { + public static final int VILLAGER_XP = 20; + public static final int AGE_ADDITION = 2 * 60; + + public ExpGemItem(Properties properties) { + super(properties); + } + + @Override + public InteractionResultHolder use( + Level level, + Player player, + InteractionHand usedHand + ) { + ItemStack itemStack = player.getItemInHand(usedHand); + int count = player.isShiftKeyDown() ? itemStack.getCount() : 1; + player.giveExperiencePoints(ExpFluidBlock.XP_POINTS * count); + itemStack.shrink(count); + player.getCooldowns().addCooldown(this, 5); + return InteractionResultHolder.sidedSuccess(itemStack, level.isClientSide()); + } + + /** + * 右键实体 + */ + public static InteractionResult useEntity(Player player, Entity target, ItemStack stack) { + if (!(target instanceof Villager villager)) return InteractionResult.PASS; + if (villager.level().isClientSide()) return InteractionResult.PASS; + if (villager.getAge() >= 0) { + // 只对有职业且不满级的村民生效 + VillagerData villagerData = villager.getVillagerData(); + int villagerLevel = villagerData.getLevel(); + if (villagerData.getProfession() == VillagerProfession.NONE) return InteractionResult.PASS; + if (!VillagerData.canLevelUp(villagerLevel)) return InteractionResult.PASS; + + updateVillager(villager); + stack.shrink(1); + return InteractionResult.SUCCESS; + } else { + villager.ageUp(AGE_ADDITION, true); + stack.shrink(1); + return InteractionResult.SUCCESS; + } + } + + public static void updateVillager(Villager villager) { + VillagerData villagerData = villager.getVillagerData(); + int villagerLevel = villagerData.getLevel(); + int villagerXp = villager.getVillagerXp() + VILLAGER_XP; + villager.setVillagerXp(villagerXp); + // 检测经验值是否足够,足够则升级(我好想直接用Villager::increaseMerchantCareer啊,可惜protect) + if (villagerXp >= VillagerData.getMaxXpPerLevel(villagerLevel)) { + villager.setVillagerXp(villagerXp); + ++villagerLevel; + villagerData = villagerData.setLevel(villagerLevel); + villager.setVillagerData(villagerData); + + villager.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 200, 0)); + villager.playSound(SoundEvents.PLAYER_LEVELUP, 1.0F, 0.9f + 0.2f * villager.getRandom().nextFloat()); + + // 获取对应职业的交易列表 + Int2ObjectMap trades = VillagerTrades.TRADES.get(villagerData.getProfession()); + if (villager.level().enabledFeatures().contains(FeatureFlags.TRADE_REBALANCE)) { + Int2ObjectMap rebalanceTrades = + VillagerTrades.EXPERIMENTAL_TRADES.get(villagerData.getProfession()); + if (rebalanceTrades != null) { + trades = rebalanceTrades; + } + } + if (trades == null || trades.isEmpty()) return; + VillagerTrades.ItemListing[] itemlisting = trades.get(villagerLevel); + if (itemlisting == null) return; + ArrayList arraylist = Lists.newArrayList(itemlisting); + + // 更新村民当前的交易列表(MerchantOffers) + MerchantOffers merchantoffers = villager.getOffers(); + for (int i = 0; i < itemlisting.length; i++) { + if (arraylist.isEmpty() || i >= 2) break; + MerchantOffer merchantoffer = arraylist.remove(villager.getRandom().nextInt(arraylist.size())) + .getOffer(villager, villager.getRandom()); + if (merchantoffer != null) { + merchantoffers.add(merchantoffer); + } + } + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/network/JewelCraftingAutoFillPacket.java b/src/main/java/dev/dubhe/anvilcraft/network/JewelCraftingAutoFillPacket.java new file mode 100644 index 0000000000..5853db3ed0 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/network/JewelCraftingAutoFillPacket.java @@ -0,0 +1,39 @@ +package dev.dubhe.anvilcraft.network; + +import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.inventory.JewelCraftingMenu; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import net.neoforged.neoforge.network.handling.IPayloadHandler; + +/** + * 宝石工艺台自动填充网络包 + * 用于将客户端的自动填充请求发送到服务端执行 + */ +public record JewelCraftingAutoFillPacket() implements CustomPacketPayload { + + public static final Type TYPE = + new Type<>(AnvilCraft.of("jewel_crafting_auto_fill")); + + public static final StreamCodec STREAM_CODEC = + StreamCodec.unit(new JewelCraftingAutoFillPacket()); + + public static final IPayloadHandler HANDLER = + JewelCraftingAutoFillPacket::serverHandler; + + private static void serverHandler(JewelCraftingAutoFillPacket packet, IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player().containerMenu instanceof JewelCraftingMenu menu) { + menu.autoFill(); + } + }); + } + + @Override + public Type type() { + return TYPE; + } + +} \ No newline at end of file diff --git a/src/main/java/dev/dubhe/anvilcraft/util/ModInteractionMap.java b/src/main/java/dev/dubhe/anvilcraft/util/ModInteractionMap.java index 14b0fc0a73..4db2d00083 100644 --- a/src/main/java/dev/dubhe/anvilcraft/util/ModInteractionMap.java +++ b/src/main/java/dev/dubhe/anvilcraft/util/ModInteractionMap.java @@ -24,12 +24,64 @@ public class ModInteractionMap { public static final CauldronInteraction.InteractionMap LAYERED_LAVA = CauldronInteraction.newInteractionMap("layered_lava"); + public static final CauldronInteraction.InteractionMap EXP_FLUID = CauldronInteraction.newInteractionMap("exp_fluid"); public static final CauldronInteraction.InteractionMap OIL = CauldronInteraction.newInteractionMap("oil"); public static final CauldronInteraction.InteractionMap CEMENT = CauldronInteraction.newInteractionMap("cement"); public static final CauldronInteraction.InteractionMap HONEY = CauldronInteraction.newInteractionMap("honey"); public static final CauldronInteraction.InteractionMap MELT_GEM = CauldronInteraction.newInteractionMap("melt_gem"); public static void initInteractionMap() { + var expFluidInteractionMap = EXP_FLUID.map(); + expFluidInteractionMap.put( + Items.BUCKET, + (state, level, pos, player, hand, stack) -> CauldronInteraction.fillBucket( + state, + level, + pos, + player, + hand, + stack, + ModItems.EXP_BUCKET.asStack(), + (s) -> ModBlocks.EXP_CAULDRON.get().isFull(state), + SoundEvents.BUCKET_FILL + ) + ); + expFluidInteractionMap.put( + Items.GLASS_BOTTLE, + (state, level, pos, player, hand, stack) -> { + if (!level.isClientSide()) { + Item item = stack.getItem(); + player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, Items.EXPERIENCE_BOTTLE.getDefaultInstance())); + player.awardStat(Stats.USE_CAULDRON); + player.awardStat(Stats.ITEM_USED.get(item)); + Layered4LevelCauldronBlock.lowerFillLevel(state, level, pos); + level.playSound(null, pos, SoundEvents.BOTTLE_FILL, SoundSource.BLOCKS); + level.gameEvent(null, GameEvent.FLUID_PICKUP, pos); + } + return ItemInteractionResult.sidedSuccess(level.isClientSide()); + } + ); + expFluidInteractionMap.put( + Items.EXPERIENCE_BOTTLE, + (state, level, pos, player, hand, stack) -> { + if (ModBlocks.HONEY_CAULDRON.get().isFull(state)) { + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + if (!level.isClientSide()) { + player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, new ItemStack(Items.GLASS_BOTTLE))); + player.awardStat(Stats.FILL_CAULDRON); + player.awardStat(Stats.ITEM_USED.get(stack.getItem())); + // 50%概率 + if (level.random.nextBoolean()) { + level.setBlockAndUpdate(pos, state.cycle(HoneyCauldronBlock.LEVEL)); + } + level.playSound(null, pos, SoundEvents.BOTTLE_EMPTY, SoundSource.BLOCKS); + level.gameEvent(null, GameEvent.FLUID_PLACE, pos); + } + return ItemInteractionResult.sidedSuccess(level.isClientSide()); + } + ); + var oilInteractionMap = OIL.map(); oilInteractionMap.put( Items.BUCKET, @@ -178,6 +230,34 @@ public static void initInteractionMap() { ) ) ); + emptyInteractionMap.put( + ModItems.EXP_BUCKET.get(), + (state, level, pos, player, hand, stack) -> CauldronInteraction.emptyBucket( + level, + pos, + player, + hand, + stack, + ModBlocks.EXP_CAULDRON.get().fullFilled(), + SoundEvents.BUCKET_EMPTY + ) + ); + emptyInteractionMap.put( + Items.EXPERIENCE_BOTTLE, + (state, level, pos, player, hand, stack) -> { + if (!level.isClientSide()) { + player.setItemInHand(hand, ItemUtils.createFilledResult(stack, player, new ItemStack(Items.GLASS_BOTTLE))); + player.awardStat(Stats.USE_CAULDRON); + player.awardStat(Stats.ITEM_USED.get(stack.getItem())); + if (level.random.nextBoolean()) { + level.setBlockAndUpdate(pos, ModBlocks.EXP_CAULDRON.getDefaultState()); + } + level.playSound(null, pos, SoundEvents.BOTTLE_EMPTY, SoundSource.BLOCKS); + level.gameEvent(null, GameEvent.FLUID_PLACE, pos); + } + return ItemInteractionResult.sidedSuccess(level.isClientSide()); + } + ); emptyInteractionMap.put( ModItems.OIL_BUCKET.get(), (state, level, pos, player, hand, stack) -> switch (state) { diff --git a/src/main/java/dev/dubhe/anvilcraft/util/registrater/ModelProviderUtil.java b/src/main/java/dev/dubhe/anvilcraft/util/registrater/ModelProviderUtil.java index 0b29eeacf0..872bcdda21 100644 --- a/src/main/java/dev/dubhe/anvilcraft/util/registrater/ModelProviderUtil.java +++ b/src/main/java/dev/dubhe/anvilcraft/util/registrater/ModelProviderUtil.java @@ -17,7 +17,7 @@ public class ModelProviderUtil { /** * 用于流体的BlockState生成器 */ - public static void liquid(DataGenContext ctx, RegistrateBlockstateProvider provider) { + public static void liquid(DataGenContext ctx, RegistrateBlockstateProvider provider) { provider.simpleBlock( ctx.get(), provider.models().getBuilder(ctx.getName()).texture("particle", provider.modLoc("block/" + ctx.getName())) diff --git a/src/main/resources/assets/anvilcraft/blockstates/exp_cauldron.json b/src/main/resources/assets/anvilcraft/blockstates/exp_cauldron.json new file mode 100644 index 0000000000..11846c6f47 --- /dev/null +++ b/src/main/resources/assets/anvilcraft/blockstates/exp_cauldron.json @@ -0,0 +1,16 @@ +{ + "variants": { + "level=1": { + "model": "anvilcraft:block/exp_cauldron_level1" + }, + "level=2": { + "model": "anvilcraft:block/exp_cauldron_level2" + }, + "level=3": { + "model": "anvilcraft:block/exp_cauldron_level3" + }, + "level=4": { + "model": "anvilcraft:block/exp_cauldron_full" + } + } +} \ No newline at end of file