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

Next revision
Previous revision
zh_cn:tutorial:ores [2020/01/08 11:56] – created lightcolourzh_cn:tutorial:ores [2023/12/18 01:03] (current) 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]]
-许多mod会添加自己的矿石,您需要一种将它们放置在现有生物群系中以便玩家寻的方法。 在本教程中我们将研究将矿石添加到现有生物群系及其他mod添加的生物群系。 将矿石添加生物群系需要执行2个步骤。 +
-   *遍历生物群系注册表以将您矿石添加到现生物群系中。 +
-   *使RegistryEntryAddedCallback以确保您矿石被添加到mod添加的任何生物群系中。+
  
-我们假设您此时已经创建了的矿石。 石英矿石将替代我们,我们的目标是在整个世界生物群系成它。 适当时用您的矿石替换对石英矿石的引用。+====== 生成定义的矿石 [1.19.3+] ====== 
 +许多模组会添加自己的矿石,您需要找到一种方法以其放置在现有生物群系中让玩家寻找。在本教程中,我们将研究将矿石添加到现有生物群系以及其他模组添加的生物群系。将矿石添加到物群系需要2个步骤 
 +  * 制作一个 ConfiguredFeature(已配置的地物),定义你的矿石方块如何生成。 
 +  * 使用 [[https://github.com/FabricMC/fabric/pull/1097|Fabric API 中的 Biome Modification API]]以将地物添加到生物群系
  
-==== 群系中添加矿石 ====+为了简化,我们使用原版的末地烛作为矿石,因为末地烛可以轻易地在地下发现,旁观模式下很容易看到。 
 + 
 +==== 添加到主世界生物群系 ==== 
 +在这个章节中,我们会在主世界生成矿石。 
 + 
 +首先,在你的模组的目录创建两个 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 java [enable_line_numbers="true"]> 
-private void handleBiome(Biome biome) { 
- if(biome.getCategory() != Biome.Category.NETHER && biome.getCategory() != Biome.Category.THEEND) { 
- biome.addFeature( 
-            GenerationStep.Feature.UNDERGROUND_ORES, 
-            Biome.configureFeature( 
-                Feature.ORE, 
-        new OreFeatureConfig( 
-        OreFeatureConfig.Target.NATURAL_STONE, 
-        Blocks.NETHER_QUARTZ_ORE.getDefaultState(), 
-                8 //Ore vein size 
-        ), 
-                Decorator.COUNT_RANGE, 
-        new RangeDecoratorConfig( 
-        8, //Number of veins per chunk 
-        0, //Bottom Offset 
-        0, //Min y level 
-        64 //Max y level 
-        ))); 
  }  }
 } }
 </code> </code>
  
-此方法通过提供生成设将您矿石添加到整个世界。 随意更改值以适合您mod+注意两件事: 
 +  * ''RegistryKey'' 是泛型,其顾炎武为 PlacedFeature。 
 +  * 我们的 id 使用的名字 ore_custom 中由已放置的地物的 JSON 文件指定的我们不需要给予已配置的地物,因为放置的地物存储了对应的配置的地物名字
  
-==== 迭代生物群系注册表 ====+现在将地物添加到生物群系中:
  
-接下来,我们需要处理已注册的所有生物群系以及将来将要注册的所有生物群落(由其他模块添加)。 我们首先遍历当前注册表,然后注册一个侦听器,以供将来添加。+<code Java src/main/java/net/fabricmc/example/ExampleMod.java>
  
-<code java [enable_line_numbers="true"]> 
 @Override @Override
-public void onInitialize() { + public void onInitialize() { 
- //Loop over existing biomes +  
- Registry.BIOME.forEach(this::handleBiome);+ //Your other code here... 
 + BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Feature.UNDERGROUND_ORES, CUSTOM_ORE_PLACED_KEY); 
 + }
  
- //Listen for other biomes being registered +</code> 
- RegistryEntryAddedCallback.event(Registry.BIOME).register((iidentifier, biome) -> handleBiome(biome));+ 
 +==== 测试==== 
 + 
 +要测试你的新矿石,生成一个新世界。你也可以打开已存在的世界,但需要走到新的区块。在这个末地烛的示例中,矿石可以直接在地下在旁观模式下看到。 
 + 
 +==== 添加到下界或末地 ==== 
 + 
 +将矿石添加到其他维度的过程和添加到主世界的过程很类似。 
 + 
 +就像在主世界中一样,我们创建 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> </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] ====== 
 + 
 +我们假设此时已经创建了自己的矿石。本教程中,我们使用羊毛方块进行替换。你可以适时将羊毛改成你自己的矿石。 
 +==== 添加到主世界生物群系 ==== 
 +本段落将会在世界生成矿石。 
 + 
 +我们需要创建一个已配置的地物,确保在 ''onInitialize'' 注册你的已配置的地物,你可以自由地改变一些值以适应你的模组。 
 + 
 +<code java> 
 +public class ExampleMod implements ModInitializer { 
 +  private static ConfiguredFeature<?, ?> OVERWORLD_WOOL_ORE_CONFIGURED_FEATURE = new ConfiguredFeature 
 +      (Feature.ORE, new OreFeatureConfig( 
 +          OreConfiguredFeatures.STONE_ORE_REPLACEABLES, 
 +          Blocks.WHITE_WOOL.getDefaultState(), 
 +          9)); // 矿脉大小 
 + 
 +  public static PlacedFeature OVERWORLD_WOOL_ORE_PLACED_FEATURE = new PlacedFeature( 
 +      RegistryEntry.of(OVERWORLD_WOOL_ORE_CONFIGURED_FEATURE), 
 +      Arrays.asList( 
 +          CountPlacementModifier.of(20), // 每个区块的矿脉数量 
 +          SquarePlacementModifier.of(), // 水平传播 
 +          HeightRangePlacementModifier.uniform(YOffset.getBottom(), YOffset.fixed(64)) 
 +      )); // 高度 
 + 
 +  @Override 
 +  public void onInitialize() { 
 +    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, 
 +        new Identifier("tutorial", "overworld_wool_ore"), OVERWORLD_WOOL_ORE_CONFIGURED_FEATURE); 
 +    Registry.register(BuiltinRegistries.PLACED_FEATURE, new Identifier("tutorial", "overworld_wool_ore"), 
 +        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"))); 
 +  } 
 +
 +</code> 
 + 
 +=== 结果 === 
 +检查你的世界生成结果时,记得要创建新世界。你应该见羊毛在主世界生成了。你可以使用下面的命令移除周围的头方块。 
 +<code> 
 +/fill ~-8 0 ~-8 ~8 ~ ~8 minecraft:air replace minecraft:stone 
 +</code> 
 + 
 +{{tutorial:ores.png?800}} 
 + 
 +==== 添加到下界生物群系 ==== 
 +本段落将会基于前面的段落添加矿石到下界生物群系。 
 + 
 +在下界,需要替换方块和主世界地不同,所以需要把 ''OreConfiguredFeatures.STONE_ORE_REPLACEABLES'' 替换成 ''OreConfiguredFeatures.NETHERRACK''。 
 + 
 +<code java> 
 +public class ExampleMod implements ModInitializer { 
 +  private static ConfiguredFeature<?, ?> NETHER_WOOL_ORE_CONFIGURED_FEATURE = new ConfiguredFeature 
 +      (Feature.ORE, new OreFeatureConfig( 
 +          OreConfiguredFeatures.NETHERRACK, // 我们这里使用 OreConfiguredFeatures.NETHERRACK 
 +          Blocks.WHITE_WOOL.getDefaultState(), 
 +          9)); 
 + 
 +  public static PlacedFeature NETHER_WOOL_ORE_PLACED_FEATURE = new PlacedFeature( 
 +      RegistryEntry.of(NETHER_WOOL_ORE_CONFIGURED_FEATURE), 
 +      Arrays.asList( 
 +          CountPlacementModifier.of(20), 
 +          SquarePlacementModifier.of(), 
 +          HeightRangePlacementModifier.uniform(YOffset.getBottom(), YOffset.fixed(64)))); 
 + 
 +  @Override 
 +  public void onInitialize() { 
 +    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, 
 +        new Identifier("tutorial", "nether_wool_ore"), NETHER_WOOL_ORE_CONFIGURED_FEATURE); 
 +    Registry.register(BuiltinRegistries.PLACED_FEATURE, new Identifier("tutorial", "nether_wool_ore"), 
 +        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"))); 
 +  } 
 +
 +</code> 
 + 
 +==== 添加到末地物群系 ==== 
 +本段落将会基于主世界的代码添加矿石到末地生物群系。 
 + 
 +在末地,基础方块是末地石,所以需要把 ''OreConfiguredFeatures.STONE_ORE_REPLACEABLES'' 替换成 ''new BlockMatchRuleTest(Blocks.END_STONE)''。 
 + 
 +<code java> 
 +public class ExampleMod implements ModInitializer { 
 +  private static ConfiguredFeature<?, ?> END_WOOL_ORE_CONFIGURED_FEATURE = new ConfiguredFeature 
 +      (Feature.ORE, new OreFeatureConfig( 
 +          new BlockMatchRuleTest(Blocks.END_STONE), // 我们这里使用 new BlockMatchRuleTest(Blocks.END_STONE) 
 +          Blocks.WHITE_WOOL.getDefaultState(), 
 +          9)); 
 + 
 +  public static PlacedFeature END_WOOL_ORE_PLACED_FEATURE = new PlacedFeature( 
 +      RegistryEntry.of(END_WOOL_ORE_CONFIGURED_FEATURE), 
 +      Arrays.asList( 
 +          CountPlacementModifier.of(20), 
 +          SquarePlacementModifier.of(), 
 +          HeightRangePlacementModifier.uniform(YOffset.getBottom(), YOffset.fixed(64)))); 
 + 
 +  @Override 
 +  public void onInitialize() { 
 +    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, 
 +        new Identifier("tutorial", "end_wool_ore"), END_WOOL_ORE_CONFIGURED_FEATURE); 
 +    Registry.register(BuiltinRegistries.PLACED_FEATURE, new Identifier("tutorial", "end_wool_ore"), 
 +        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"))); 
 +  } 
 +
 +</code>
  
-{{https://i.imgur.com/UemsMaI.png|Quartz Ores}} 
  
  
zh_cn/tutorial/ores.1578484569.txt.gz · Last modified: 2020/01/08 11:56 by lightcolour