User Tools

Site Tools


zh_cn:tutorial:ores

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
zh_cn:tutorial:ores [2021/09/23 00:19] – [结论] solidblockzh_cn:tutorial:ores [2023/12/18 01:03] solidblock
Line 1: Line 1:
-====== 在世界中添加矿石 ======+如果你在找 1.19.3,矿石应该完全使用 json 完成。你可以了解到的有用的工具:[[https://misode.github.io/worldgen/feature/|Configured Features]] 和 [[https://misode.github.io/worldgen/placed-feature/|Placed Features]] 
 + 
 +====== 生成自定义的矿石 [1.19.3+] ======
 许多模组会添加自己的矿石,您需要找到一种方法以将其放置在现有生物群系中让玩家寻找。在本教程中,我们将研究将矿石添加到现有生物群系以及其他模组添加的生物群系。将矿石添加到生物群系需要2个步骤。 许多模组会添加自己的矿石,您需要找到一种方法以将其放置在现有生物群系中让玩家寻找。在本教程中,我们将研究将矿石添加到现有生物群系以及其他模组添加的生物群系。将矿石添加到生物群系需要2个步骤。
-  * 制作一个 ConfiguredFeature,定义你的矿石方块如何生成。+  * 制作一个 ConfiguredFeature(已配置的地物),定义你的矿石方块如何生成。
   * 使用 [[https://github.com/FabricMC/fabric/pull/1097|Fabric API 中的 Biome Modification API]]以将地物添加到生物群系。   * 使用 [[https://github.com/FabricMC/fabric/pull/1097|Fabric API 中的 Biome Modification API]]以将地物添加到生物群系。
  
-注意 Biome Modification API 实验性的。如果 API 不起作用考虑 [[?rev=1599388827|mixin 本]]。+为了简化,我们使用原版的末地烛作为矿石,因为末地烛可以轻易地在地下发现,旁观模式下很容易看到。 
 + 
 +==== 添加到主世界生物群系 ==== 
 +在这个章节中,我们会在主世界生成矿石。 
 + 
 +首先,在你的模组的目录创建两个 JSON 文件: 
 + 
 +<code JavaScript src\main\resources\data\tutorial\worldgen\configured_feature\ore_custom.json> 
 +
 +  "type": "minecraft:ore", 
 +  "config":
 +    "discard_chance_on_air_exposure": 0.0, 
 +    "size": 12, 
 +    "targets":
 +      { 
 +        "state":
 +          "Name": "minecraft:end_rod" 
 +        }, 
 +        "target":
 +          "predicate_type": "minecraft:tag_match", 
 +          "tag": "minecraft:stone_ore_replaceables" 
 +        } 
 +      }, 
 +      { 
 +        "state":
 +          "Name": "minecraft:end_rod" 
 +        }, 
 +        "target":
 +          "predicate_type": "minecraft:tag_match", 
 +          "tag": "minecraft:deepslate_ore_replaceables" 
 +        } 
 +      } 
 +    ] 
 +  } 
 +
 +</code> 
 + 
 +这个已配置的地物(configured feature)会告诉游戏矿脉的大小、哪些矿石方块会因为空气暴露而被移除,以及,最重要的还有这个矿石能够替换哪些方块。注意我们的 ''target'' 数组中有两个 ''target'' 对象:一个是生成在石头中的矿石,还有一个是深板岩中的矿石。为了简化,我们都用末地烛。 
 + 
 +<code JavaScript src\main\resources\data\tutorial\worldgen\placed_feature\ore_custom.json> 
 +
 +  "feature": "tutorial:ore_custom", 
 +  "placement":
 +    { 
 +      "type": "minecraft:count", 
 +      "count": 20 
 +    }, 
 +    { 
 +      "type": "minecraft:in_square" 
 +    }, 
 +    { 
 +      "type": "minecraft:height_range", 
 +      "height":
 +        "type": "minecraft:trapezoid", 
 +        "max_inclusive":
 +          "absolute": 70 
 +        }, 
 +        "min_inclusive":
 +          "absolute": -24 
 +        } 
 +      } 
 +    }, 
 +    { 
 +      "type": "minecraft:biome" 
 +    } 
 +  ] 
 +
 +</code> 
 + 
 +已放置的地物(placed feature)告诉游戏,一个区块内应该放置多少的矿脉,矿脉应该以什么形状放置,以及放置在哪些 y 轴级别上。注意,放置的地物的第一行引用了我们刚刚创建的配置的地物。 
 +  
 +手写 JSON 文件可能会有些麻烦。注意这些工作可以借助像 [[https://misode.github.io/worldgen/feature/|Configured Features generator]] 或者 [[https://misode.github.io/worldgen/placed-feature/|Placed Features generator]] 来完成。你也可以打开原版的 Minecraft 的 ''.jar'' 文件,将原版的文件作为参考。 
 + 
 +现在我们的数据已经创建好了,是时候编写代码了!好在 Minecraft 1.19.3 以来的更改,在世界中添加矿石需要的 Java 代码非常少。我们所需要做的,就只是注册这个地物,然后使用 Fabric Biome Modification API 来告诉 Minecraft,在哪些地方生成这些矿石,以及在哪些阶段生成这些矿石。 
 + 
 +在这个类中,我们创建新的 ''RegistryKey''。 
 + 
 +<code Java src/main/java/net/fabricmc/example/ExampleMod.java> 
 +public class ExampleMod implements ModInitializer { 
 +  
 + public static final RegistryKey<PlacedFeature> CUSTOM_ORE_PLACED_KEY = RegistryKey.of(RegistryKeys.PLACED_FEATURE, new Identifier("tutorial","ore_custom")); 
 + 
 + @Override 
 + public void onInitialize() { 
 + 
 + //Your other code here... 
 + 
 +
 +
 +</code> 
 + 
 +注意两件事: 
 +  * ''RegistryKey'' 泛型,其顾炎武为 PlacedFeature。 
 +  * 我们的 id 使用的名字 ore_custom 中由已放置的地物的 JSON 文件指定的。我们不需要给予已配置的地物,因为放置的地物存储了对应的配置的地物的名字。 
 + 
 +现在将地物添加到生物群系中: 
 + 
 +<code Java src/main/java/net/fabricmc/example/ExampleMod.java> 
 + 
 +@Override 
 + public void onInitialize() { 
 +  
 + //Your other code here... 
 + BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Feature.UNDERGROUND_ORES, CUSTOM_ORE_PLACED_KEY); 
 +
 + 
 +</code> 
 + 
 +==== 测试==== 
 + 
 +要测试你的新矿石,生成一个新世界。你也可以打开已存在的世界,但需要走到新的区块。在这个末地烛的示例中,矿石可以直接在地下在旁观模式下看到。 
 + 
 +==== 添加到下界或末地 ==== 
 + 
 +将矿石添加到其他维度的过程和添加到主世界的过程很类似。 
 + 
 +就像在主世界中一样,我们创建 JSON 文件。如果以原版的下界金矿石为例我们的已放置的地物看起来应该会像这样: 
 + 
 +<code JavaScript src/main/resources/data/tutorial/worldgen/placed_feature/ore_custom_nether.json> 
 +
 +  "feature": "tutorial:ore_nether_custom", 
 +  "placement": [ 
 +    { 
 +      "type": "minecraft:count", 
 +      "count": 20 
 +    }, 
 +    { 
 +      "type": "minecraft:in_square" 
 +    }, 
 +    { 
 +      "type": "minecraft:height_range", 
 +      "height":
 +        "type": "minecraft:uniform", 
 +        "max_inclusive":
 +          "below_top": 10 
 +        }, 
 +        "min_inclusive":
 +          "above_bottom": 10 
 +        } 
 +      } 
 +    }, 
 +    { 
 +      "type": "minecraft:biome" 
 +    } 
 +  ] 
 +
 +</code> 
 + 
 +注意区别在于,其高度范围是以不同的方式描述的,高度类型是 ''uniform'' 而不是 ''trapezoid''。trapezoid 的形状和绝对的高度范围在下界仍是有效的,但我们只是遵循原版 Minecraft 的游戏设计。 
 + 
 +和之前一样,添加配置的地物。 
 + 
 +<code JavaScript src/main/resources/data/tutorial/worldgen/configured_feature/ore_nether_custom.json> 
 +
 +  "type": "minecraft:ore", 
 +  "config":
 +    "discard_chance_on_air_exposure": 0.0, 
 +    "size": 20, 
 +    "targets":
 +      { 
 +        "state":
 +          "Name": "minecraft:end_rod" 
 +        }, 
 +        "target":
 +          "block": "minecraft:netherrack", 
 +          "predicate_type": "minecraft:block_match" 
 +        } 
 +      } 
 +    ] 
 +  } 
 +
 +</code> 
 + 
 +在配置的地物中,记住 ''Name'' 是你的矿石方块的名字,而不是放置的地物的名字 
 + 
 +最后,回到 Java 代码,再添加一行 BiomdModifaction 的内容: 
 + 
 +<code Java src/main/java/net/fabricmc/example/ExampleMod.java> 
 + BiomeModifications.addFeature(BiomeSelectors.foundInNether(), GenerationStep.Feature.UNDERGROUND_ORES, CUSTOM_ORE_PLACED_KEY); 
 +</code> 
 + 
 +====== 生成自定义的矿石 [1.18.2 / 1.19.2] ======
  
 我们假设您此时已经创建了自己的矿石。本教程中,我们使用羊毛方块进行替换。你可以适时将羊毛改成你自己的矿石。 我们假设您此时已经创建了自己的矿石。本教程中,我们使用羊毛方块进行替换。你可以适时将羊毛改成你自己的矿石。
Line 10: Line 193:
 本段落将会在主世界生成矿石。 本段落将会在主世界生成矿石。
  
-我们需要创建一个 ConfiguredFeature,确保在 ''onInitialize'' 中注册你的 ConfiguredFeature,你可以自由地改变一些值以适应你的模组。+我们需要创建一个已配置的地物,确保在 ''onInitialize'' 中注册你的已配置的地物,你可以自由地改变一些值以适应你的模组。
  
 <code java> <code java>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
-  private static ConfiguredFeature<?, ?> ORE_WOOL_OVERWORLD = Feature.ORE +  private static ConfiguredFeature<?, ?> OVERWORLD_WOOL_ORE_CONFIGURED_FEATURE new ConfiguredFeature 
-    .configure(new OreFeatureConfig( +      (Feature.OREnew OreFeatureConfig( 
-      OreFeatureConfig.Rules.BASE_STONE_OVERWORLD+          OreConfiguredFeatures.STONE_ORE_REPLACEABLES
-      Blocks.WHITE_WOOL.getDefaultState(), +          Blocks.WHITE_WOOL.getDefaultState(), 
-      9)) // Vein size +          9))// 矿脉大小 
-    .range(new RangeDecoratorConfig+ 
-      // You can also use one of the other height providers if you don't want a uniform distribution +  public static PlacedFeature OVERWORLD_WOOL_ORE_PLACED_FEATURE = new PlacedFeature
-      UniformHeightProvider.create(YOffset.aboveBottom(0), YOffset.fixed(64)))) // Inclusive min and max height +      RegistryEntry.of(OVERWORLD_WOOL_ORE_CONFIGURED_FEATURE), 
-    .spreadHorizontally() +      Arrays.asList( 
-    .repeat(20); // Number of veins per chunk+          CountPlacementModifier.of(20), // 每个区块的矿脉数量 
 +          SquarePlacementModifier.of()// 水平传播 
 +          HeightRangePlacementModifier.uniform(YOffset.getBottom(), YOffset.fixed(64)) 
 +      )); // 高度
  
   @Override   @Override
   public void onInitialize() {   public void onInitialize() {
-    RegistryKey<ConfiguredFeature<?, ?>> oreWoolOverworld = RegistryKey.of(Registry.CONFIGURED_FEATURE_KEY+    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE
-      new Identifier("tutorial", "ore_wool_overworld")); +        new Identifier("tutorial", "overworld_wool_ore"), OVERWORLD_WOOL_ORE_CONFIGURED_FEATURE); 
-    Registry.register(BuiltinRegistries.CONFIGURED_FEATUREoreWoolOverworld.getValue(), ORE_WOOL_OVERWORLD); +    Registry.register(BuiltinRegistries.PLACED_FEATUREnew Identifier("tutorial", "overworld_wool_ore"), 
-    BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Feature.UNDERGROUND_ORES, oreWoolOverworld);+        OVERWORLD_WOOL_ORE_PLACED_FEATURE); 
 +    BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Feature.UNDERGROUND_ORES, 
 +        RegistryKey.of(Registry.PLACED_FEATURE_KEY, 
 +            new Identifier("tutorial", "overworld_wool_ore")));
   }   }
 } }
Line 46: Line 235:
 本段落将会基于前面的段落添加矿石到下界生物群系。 本段落将会基于前面的段落添加矿石到下界生物群系。
  
-在下界,需要替换的方块和主世界地不同,所以需要把 ''OreFeatureConfig.Rules.BASE_STONE_OVERWORLD'' 替换成 ''OreFeatureConfig.Rules.BASE_STONE_NETHER''+在下界,需要替换的方块和主世界地不同,所以需要把 ''OreConfiguredFeatures.STONE_ORE_REPLACEABLES'' 替换成 ''OreConfiguredFeatures.NETHERRACK''
  
 <code java> <code java>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
-  private static ConfiguredFeature<?, ?> ORE_WOOL_NETHER = Feature.ORE +  private static ConfiguredFeature<?, ?> NETHER_WOOL_ORE_CONFIGURED_FEATURE new ConfiguredFeature 
-    .configure(new OreFeatureConfig( +      (Feature.OREnew OreFeatureConfig( 
-      OreFeatureConfig.Rules.BASE_STONE_NETHER, // 对于下界,我们使用 OreFeatureConfig.Rules.BASE_STONE_NETHER +          OreConfiguredFeatures.NETHERRACK, // 我们这里使用 OreConfiguredFeatures.NETHERRACK 
-      Blocks.WHITE_WOOL.getDefaultState(), +          Blocks.WHITE_WOOL.getDefaultState(), 
-      9)) +          9)); 
-    .range(new RangeDecoratorConfig+ 
-      UniformHeightProvider.create(YOffset.fixed(0), YOffset.fixed(64)))+  public static PlacedFeature NETHER_WOOL_ORE_PLACED_FEATURE = new PlacedFeature
-    .spreadHorizontally() +      RegistryEntry.of(NETHER_WOOL_ORE_CONFIGURED_FEATURE), 
-    .repeat(20);+      Arrays.asList( 
 +          CountPlacementModifier.of(20), 
 +          SquarePlacementModifier.of(), 
 +          HeightRangePlacementModifier.uniform(YOffset.getBottom(), YOffset.fixed(64))));
  
   @Override   @Override
   public void onInitialize() {   public void onInitialize() {
-    RegistryKey<ConfiguredFeature<?, ?>> oreWoolNether = RegistryKey.of(Registry.CONFIGURED_FEATURE_WORLDGEN+    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE
-        new Identifier("tutorial", "ore_wool_nether")); +        new Identifier("tutorial", "nether_wool_ore"), NETHER_WOOL_ORE_CONFIGURED_FEATURE); 
-    Registry.register(BuiltinRegistries.CONFIGURED_FEATUREoreWoolNether.getValue(), ORE_WOOL_NETHER); +    Registry.register(BuiltinRegistries.PLACED_FEATUREnew Identifier("tutorial", "nether_wool_ore"), 
-    BiomeModifications.addFeature(BiomeSelectors.foundInTheNether(), GenerationStep.Feature.UNDERGROUND_ORES, oreWoolNether);+        NETHER_WOOL_ORE_PLACED_FEATURE); 
 +    BiomeModifications.addFeature(BiomeSelectors.foundInTheNether(), GenerationStep.Feature.UNDERGROUND_ORES, 
 +        RegistryKey.of(Registry.PLACED_FEATURE_KEY, 
 +            new Identifier("tutorial", "nether_wool_ore")));
   }   }
 } }
Line 73: Line 268:
 本段落将会基于主世界的代码添加矿石到末地生物群系。 本段落将会基于主世界的代码添加矿石到末地生物群系。
  
-在末地,基础方块是末地石,所以需要把 ''OreFeatureConfig.Rules.BASE_STONE_OVERWORLD'' 替换成 ''new BlockMatchRuleTest(Blocks.END_STONE)''+在末地,基础方块是末地石,所以需要把 ''OreConfiguredFeatures.STONE_ORE_REPLACEABLES'' 替换成 ''new BlockMatchRuleTest(Blocks.END_STONE)''
  
 <code java> <code java>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
-  private static ConfiguredFeature<?, ?> ORE_WOOL_END = Feature.ORE +  private static ConfiguredFeature<?, ?> END_WOOL_ORE_CONFIGURED_FEATURE new ConfiguredFeature 
-    .configure(new OreFeatureConfig( +      (Feature.OREnew OreFeatureConfig( 
-      new BlockMatchRuleTest(Blocks.END_STONE), // 在末地生物群系,基础方块是末地石 +          new BlockMatchRuleTest(Blocks.END_STONE), // 我们这里使用 new BlockMatchRuleTest(Blocks.END_STONE) 
-      Blocks.WHITE_WOOL.getDefaultState(), +          Blocks.WHITE_WOOL.getDefaultState(), 
-      9)) +          9)); 
-    .range(new RangeDecoratorConfig+ 
-      UniformHeightProvider.create(YOffset.fixed(0), YOffset.fixed(64)))+  public static PlacedFeature END_WOOL_ORE_PLACED_FEATURE = new PlacedFeature
-    .spreadHorizontally() +      RegistryEntry.of(END_WOOL_ORE_CONFIGURED_FEATURE), 
-    .repeat(20);+      Arrays.asList( 
 +          CountPlacementModifier.of(20), 
 +          SquarePlacementModifier.of(), 
 +          HeightRangePlacementModifier.uniform(YOffset.getBottom(), YOffset.fixed(64))));
  
   @Override   @Override
   public void onInitialize() {   public void onInitialize() {
-    RegistryKey<ConfiguredFeature<?, ?>> oreWoolEnd = RegistryKey.of(Registry.CONFIGURED_FEATURE_KEY+    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE
-        new Identifier("tutorial", "ore_wool_end")); +        new Identifier("tutorial", "end_wool_ore"), END_WOOL_ORE_CONFIGURED_FEATURE); 
-    Registry.register(BuiltinRegistries.CONFIGURED_FEATUREoreWoolEnd.getValue(), ORE_WOOL_END); +    Registry.register(BuiltinRegistries.PLACED_FEATUREnew Identifier("tutorial", "end_wool_ore"), 
-    BiomeModifications.addFeature(BiomeSelectors.foundInTheEnd(), GenerationStep.Feature.UNDERGROUND_ORES, oreWoolEnd);+        END_WOOL_ORE_PLACED_FEATURE); 
 +    BiomeModifications.addFeature(BiomeSelectors.foundInTheEnd(), GenerationStep.Feature.UNDERGROUND_ORES, 
 +        RegistryKey.of(Registry.PLACED_FEATURE_KEY, 
 +            new Identifier("tutorial", "end_wool_ore")));
   }   }
 } }
zh_cn/tutorial/ores.txt · Last modified: 2024/05/21 10:00 by sjk1949