Skip to content

Commit ab165d5

Browse files
让矿物涌泉使用配方系统
1 parent 91e591c commit ab165d5

File tree

12 files changed

+532
-32
lines changed

12 files changed

+532
-32
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"parent": "minecraft:recipes/root",
3+
"criteria": {
4+
"has_the_recipe": {
5+
"conditions": {
6+
"recipe": "anvilcraft:mineral_fountain/deepslate_iron_ore"
7+
},
8+
"trigger": "minecraft:recipe_unlocked"
9+
}
10+
},
11+
"requirements": [
12+
[
13+
"has_the_recipe"
14+
]
15+
],
16+
"rewards": {
17+
"recipes": [
18+
"anvilcraft:mineral_fountain/deepslate_iron_ore"
19+
]
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"parent": "minecraft:recipes/root",
3+
"criteria": {
4+
"has_the_recipe": {
5+
"conditions": {
6+
"recipe": "anvilcraft:mineral_fountain_chance/earth_core_shard_ore"
7+
},
8+
"trigger": "minecraft:recipe_unlocked"
9+
}
10+
},
11+
"requirements": [
12+
[
13+
"has_the_recipe"
14+
]
15+
],
16+
"rewards": {
17+
"recipes": [
18+
"anvilcraft:mineral_fountain_chance/earth_core_shard_ore"
19+
]
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"parent": "minecraft:recipes/root",
3+
"criteria": {
4+
"has_the_recipe": {
5+
"conditions": {
6+
"recipe": "anvilcraft:mineral_fountain_chance/void_stone"
7+
},
8+
"trigger": "minecraft:recipe_unlocked"
9+
}
10+
},
11+
"requirements": [
12+
[
13+
"has_the_recipe"
14+
]
15+
],
16+
"rewards": {
17+
"recipes": [
18+
"anvilcraft:mineral_fountain_chance/void_stone"
19+
]
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "anvilcraft:mineral_fountain",
3+
"from_block": "minecraft:deepslate",
4+
"need_block": "minecraft:deepslate_iron_ore",
5+
"to_block": "minecraft:deepslate_iron_ore"
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "anvilcraft:mineral_fountain_chance",
3+
"chance": 0.1,
4+
"dimension": "minecraft:overworld",
5+
"from_block": "minecraft:deepslate",
6+
"to_block": "anvilcraft:earth_core_shard_ore"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "anvilcraft:mineral_fountain_chance",
3+
"chance": 0.1,
4+
"dimension": "minecraft:overworld",
5+
"from_block": "minecraft:deepslate",
6+
"to_block": "anvilcraft:void_stone"
7+
}

src/main/java/dev/dubhe/anvilcraft/block/entity/MineralFountainBlockEntity.java

+59-32
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@
22

33
import dev.dubhe.anvilcraft.api.heatable.HeatableBlockManager;
44
import dev.dubhe.anvilcraft.init.ModBlockEntities;
5-
import dev.dubhe.anvilcraft.init.ModBlockTags;
65
import dev.dubhe.anvilcraft.init.ModBlocks;
6+
import dev.dubhe.anvilcraft.init.ModRecipeTypes;
7+
import dev.dubhe.anvilcraft.recipe.mineral.MineralFountainRecipe;
78

89
import net.minecraft.core.BlockPos;
910
import net.minecraft.core.Direction;
1011
import net.minecraft.resources.ResourceLocation;
1112
import net.minecraft.world.level.Level;
1213
import net.minecraft.world.level.block.Block;
1314
import net.minecraft.world.level.block.Blocks;
14-
import net.minecraft.world.level.block.LiquidBlock;
1515
import net.minecraft.world.level.block.entity.BlockEntity;
1616
import net.minecraft.world.level.block.entity.BlockEntityType;
1717
import net.minecraft.world.level.block.state.BlockState;
1818

1919
import org.jetbrains.annotations.NotNull;
2020

21+
import java.util.Arrays;
2122
import java.util.HashMap;
23+
import java.util.List;
2224

2325
public class MineralFountainBlockEntity extends BlockEntity {
2426
private static final HashMap<ResourceLocation, HashMap<Block, Float>> CHANGE_MAP = new HashMap<>() {
@@ -66,9 +68,9 @@ public void tick() {
6668
tickCount++;
6769
if (tickCount < 20) return;
6870
tickCount = 0;
69-
BlockState aroundBlock = getAroundBlock();
71+
BlockState aroundState = getAroundBlock();
7072
// 冷却检查
71-
if (aroundBlock.is(Blocks.BLUE_ICE)
73+
if (aroundState.is(Blocks.BLUE_ICE)
7274
|| aroundHas(Blocks.BEDROCK)
7375
|| aroundHas(ModBlocks.MINERAL_FOUNTAIN.get())) {
7476
level.destroyBlock(getBlockPos(), false);
@@ -84,49 +86,74 @@ public void tick() {
8486
checkPos = checkPos.below();
8587
if (!level.getBlockState(checkPos).is(Blocks.BEDROCK)) return;
8688
}
87-
BlockState aboveBlock = level.getBlockState(getBlockPos().above());
89+
BlockState aboveState = level.getBlockState(getBlockPos().above());
8890
// 岩浆处理
89-
if (aroundBlock.is(Blocks.LAVA)) {
90-
if (aboveBlock.is(Blocks.AIR)) {
91+
if (aroundState.is(Blocks.LAVA)) {
92+
if (aboveState.is(Blocks.AIR)) {
9193
level.setBlockAndUpdate(getBlockPos().above(), Blocks.LAVA.defaultBlockState());
9294
return;
9395
}
94-
Block hotBlock = HeatableBlockManager.getHotBlock(aboveBlock.getBlock());
96+
Block hotBlock = HeatableBlockManager.getHotBlock(aboveState.getBlock());
9597
if (hotBlock == null) return;
9698
level.setBlockAndUpdate(getBlockPos().above(), hotBlock.defaultBlockState());
97-
} else if (aroundBlock.is(ModBlockTags.DEEPSLATE_METAL) && aboveBlock.is(Blocks.DEEPSLATE)) {
98-
HashMap<Block, Float> changeMap =
99-
CHANGE_MAP.containsKey(level.dimension().location())
100-
? CHANGE_MAP.get(level.dimension().location())
101-
: CHANGE_MAP.get(Level.OVERWORLD.location());
102-
for (Block block : changeMap.keySet()) {
103-
if (level.getRandom().nextDouble() <= changeMap.get(block)) {
104-
level.setBlockAndUpdate(getBlockPos().above(), block.defaultBlockState());
105-
return;
106-
}
107-
}
108-
level.setBlockAndUpdate(getBlockPos().above(), aroundBlock);
99+
} else {
100+
MineralFountainRecipe.Input input =
101+
new MineralFountainRecipe.Input(aroundState.getBlock(), aboveState.getBlock());
102+
level.getRecipeManager()
103+
.getRecipeFor(ModRecipeTypes.MINERAL_FOUNTAIN.get(), input, level)
104+
.ifPresent(recipe -> {
105+
var chanceList = level
106+
.getRecipeManager()
107+
.getAllRecipesFor(ModRecipeTypes.MINERAL_FOUNTAIN_CHANCE.get())
108+
.stream()
109+
.filter(r -> r.value()
110+
.getDimension()
111+
.equals(level.dimension().location()))
112+
.filter(r -> r.value().getFromBlock() == aboveState.getBlock())
113+
.toList();
114+
for (var changeRecipe : chanceList) {
115+
if (level.getRandom().nextDouble()
116+
<= changeRecipe.value().getChance()) {
117+
level.setBlockAndUpdate(
118+
getBlockPos().above(),
119+
changeRecipe.value().getToBlock().defaultBlockState());
120+
return;
121+
}
122+
}
123+
level.setBlockAndUpdate(
124+
getBlockPos().above(),
125+
recipe.value().getToBlock().defaultBlockState());
126+
});
109127
}
110128
}
111129

130+
private static final Direction[] HORIZONTAL_DIRECTION = {
131+
Direction.NORTH, Direction.WEST, Direction.EAST, Direction.SOUTH
132+
};
133+
112134
private BlockState getAroundBlock() {
113-
if (level == null) return Blocks.AIR.defaultBlockState();
114-
BlockState blockState = level.getBlockState(getBlockPos().south());
115-
if (blockState.is(Blocks.LAVA) && blockState.getValue(LiquidBlock.LEVEL) > 0)
135+
if (level == null) {
116136
return Blocks.AIR.defaultBlockState();
117-
for (Direction direction : new Direction[] {Direction.NORTH, Direction.WEST, Direction.EAST}) {
118-
BlockState checkBlockState = level.getBlockState(getBlockPos().relative(direction));
119-
if (!checkBlockState.is(blockState.getBlock())) return Blocks.AIR.defaultBlockState();
120-
if (checkBlockState.is(Blocks.LAVA) && checkBlockState.getValue(LiquidBlock.LEVEL) > 0)
121-
return Blocks.AIR.defaultBlockState();
122137
}
123-
return blockState;
138+
List<BlockState> blockStates = Arrays.stream(HORIZONTAL_DIRECTION)
139+
.map(direction -> level.getBlockState(getBlockPos().relative(direction)))
140+
.toList();
141+
BlockState firstState = blockStates.getFirst();
142+
long count = blockStates.stream()
143+
.filter(s -> s.is(firstState.getBlock())
144+
&& (s.getFluidState().isEmpty() || s.getFluidState().isSource()))
145+
.count();
146+
return count == 4 ? firstState : Blocks.AIR.defaultBlockState();
124147
}
125148

126149
private boolean aroundHas(Block block) {
127-
if (level == null) return false;
128-
for (Direction direction : new Direction[] {Direction.SOUTH, Direction.NORTH, Direction.WEST, Direction.EAST}) {
129-
if (level.getBlockState(getBlockPos().relative(direction)).is(block)) return true;
150+
if (level == null) {
151+
return false;
152+
}
153+
for (Direction direction : HORIZONTAL_DIRECTION) {
154+
if (level.getBlockState(getBlockPos().relative(direction)).is(block)) {
155+
return true;
156+
}
130157
}
131158
return false;
132159
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package dev.dubhe.anvilcraft.data.recipe;
2+
3+
import dev.dubhe.anvilcraft.init.ModBlocks;
4+
import dev.dubhe.anvilcraft.recipe.mineral.MineralFountainChanceRecipe;
5+
import dev.dubhe.anvilcraft.recipe.mineral.MineralFountainRecipe;
6+
7+
import net.minecraft.world.level.Level;
8+
import net.minecraft.world.level.block.Blocks;
9+
10+
import com.tterrag.registrate.providers.RegistrateRecipeProvider;
11+
12+
public class MineralFountainRecipeLoader {
13+
public static void init(RegistrateRecipeProvider provider) {
14+
MineralFountainRecipe.builder()
15+
.needBlock(Blocks.DEEPSLATE_IRON_ORE)
16+
.fromBlock(Blocks.DEEPSLATE)
17+
.toBlock(Blocks.DEEPSLATE_IRON_ORE)
18+
.save(provider);
19+
20+
MineralFountainChanceRecipe.builder()
21+
.dimension(Level.OVERWORLD.location())
22+
.fromBlock(Blocks.DEEPSLATE)
23+
.toBlock(ModBlocks.VOID_STONE.get())
24+
.chance(0.1)
25+
.save(provider);
26+
27+
MineralFountainChanceRecipe.builder()
28+
.dimension(Level.OVERWORLD.location())
29+
.fromBlock(Blocks.DEEPSLATE)
30+
.toBlock(ModBlocks.EARTH_CORE_SHARD_ORE.get())
31+
.chance(0.1)
32+
.save(provider);
33+
}
34+
}

src/main/java/dev/dubhe/anvilcraft/data/recipe/RecipeHandler.java

+2
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,7 @@ public static void init(RegistrateRecipeProvider provider) {
1919
MultiBlockRecipeLoader.init(provider);
2020
MobTransformRecipeLoader.init(provider);
2121
ConcreteRecipeLoader.init(provider);
22+
23+
MineralFountainRecipeLoader.init(provider);
2224
}
2325
}

src/main/java/dev/dubhe/anvilcraft/init/ModRecipeTypes.java

+14
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import dev.dubhe.anvilcraft.recipe.anvil.StampingRecipe;
1616
import dev.dubhe.anvilcraft.recipe.anvil.SuperHeatingRecipe;
1717
import dev.dubhe.anvilcraft.recipe.anvil.TimeWarpRecipe;
18+
import dev.dubhe.anvilcraft.recipe.mineral.MineralFountainChanceRecipe;
19+
import dev.dubhe.anvilcraft.recipe.mineral.MineralFountainRecipe;
1820
import dev.dubhe.anvilcraft.recipe.multiblock.MultiblockRecipe;
1921
import dev.dubhe.anvilcraft.recipe.transform.MobTransformRecipe;
2022

@@ -109,6 +111,18 @@ public class ModRecipeTypes {
109111
public static final DeferredHolder<RecipeSerializer<?>, RecipeSerializer<MultiblockRecipe>> MULITBLOCK_SERIALIZER =
110112
RECIPE_SERIALIZERS.register("multiblock", MultiblockRecipe.Serializer::new);
111113

114+
public static final DeferredHolder<RecipeType<?>, RecipeType<MineralFountainRecipe>> MINERAL_FOUNTAIN =
115+
registerType("mineral_fountain");
116+
public static final DeferredHolder<RecipeSerializer<?>, RecipeSerializer<MineralFountainRecipe>>
117+
MINERAL_FOUNTAIN_SERIALIZER =
118+
RECIPE_SERIALIZERS.register("mineral_fountain", MineralFountainRecipe.Serializer::new);
119+
120+
public static final DeferredHolder<RecipeType<?>, RecipeType<MineralFountainChanceRecipe>> MINERAL_FOUNTAIN_CHANCE =
121+
registerType("mineral_fountain_chance");
122+
public static final DeferredHolder<RecipeSerializer<?>, RecipeSerializer<MineralFountainChanceRecipe>>
123+
MINERAL_FOUNTAIN_CHANCE_SERIALIZER =
124+
RECIPE_SERIALIZERS.register("mineral_fountain_chance", MineralFountainChanceRecipe.Serializer::new);
125+
112126
private static <T extends Recipe<?>> DeferredHolder<RecipeType<?>, RecipeType<T>> registerType(String name) {
113127
return RECIPE_TYPES.register(name, () -> new RecipeType<>() {
114128
@Override

0 commit comments

Comments
 (0)