(Cet article fait partie d'une série d'articles de commentaires)
Premier article: Introduction Article précédent: Ajouter un bloc Article suivant:
Jusqu'à présent, nous avons pris le corps des articles continus et supposé que les questions non spécifiées par ailleurs sont les mêmes que précédemment, mais soyez particulièrement prudent car nous avons modifié l'environnement à partir de cet article.
** Mise à jour de la version de Minecraft Forge. ** C'est parce que c'est une version en cours de développement et qu'il y a de nombreuses parties non développées. Veuillez également noter que la version est toujours en développement après la mise à jour et que des versions mises à jour sont publiées chaque jour.
version | |
---|---|
OS | Winsows 10 Home |
Oracle JDK | 8u212 |
Minecraft | 1.16.1 |
Minecraft Forge | 1.16.1 (32.0.108) -> 1.16.1 (33.0.22) |
InteliJ IDEA | 2020.1.3 (CE) |
Ajoutez des journaux, des feuilles et des blocs de semis en vous référant à Ajouter un bloc.
Blocks.java
package jp.koteko.liveinwater.block;
import jp.koteko.liveinwater.LiveInWater;
import jp.koteko.liveinwater.block.trees.WaterTree;
import net.minecraft.block.*;
import net.minecraft.block.material.Material;
import net.minecraft.block.material.MaterialColor;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup;
import net.minecraft.world.FoliageColors;
import net.minecraft.world.biome.BiomeColors;
import net.minecraftforge.client.event.ColorHandlerEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import java.util.ArrayList;
import java.util.List;
@Mod.EventBusSubscriber(modid = LiveInWater.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class Blocks {
public static List<Block> blockList = new ArrayList<Block>();
public static Block WATERTREE_ROOT_BLOCK = register("watertree_root_block", new Block(AbstractBlock.Properties.create(Material.WOOD).hardnessAndResistance(2.5F).sound(SoundType.WOOD)));
public static Block WATERTREE_LOG = register("watertree_log", new RotatedPillarBlock(AbstractBlock.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2.0F).sound(SoundType.WOOD)));
public static Block WATERTREE_LEAVES = register("watertree_leaves", new LeavesBlock(AbstractBlock.Properties.create(Material.LEAVES).hardnessAndResistance(0.2F).tickRandomly().sound(SoundType.PLANT).notSolid()));
public static Block WATERTREE_SAPLING = register("watertree_sapling", new SaplingBlock(new WaterTree(), AbstractBlock.Properties.create(Material.PLANTS).doesNotBlockMovement().tickRandomly().zeroHardnessAndResistance().sound(SoundType.PLANT)));
private static Block register(String key, Block blockIn){
blockList.add(blockIn);
return blockIn.setRegistryName(LiveInWater.MOD_ID, key);
}
@SubscribeEvent
public static void registerBlocks(RegistryEvent.Register<Block> event) {
for (Block block : blockList) {
event.getRegistry().register(block);
if (block instanceof SaplingBlock) {
RenderTypeLookup.setRenderLayer(block, RenderType.getCutout());
}
}
}
@SubscribeEvent
public static void registerBlockColors(ColorHandlerEvent.Block event) {
event.getBlockColors().register((p_210229_0_, p_210229_1_, p_210229_2_, p_210229_3_) -> {
return p_210229_1_ != null && p_210229_2_ != null ? BiomeColors.getFoliageColor(p_210229_1_, p_210229_2_) : FoliageColors.getDefault();
}, WATERTREE_LEAVES);
}
}
Les grumes sont fabriquées dans la classe Rotated Pillar Block
, les feuilles sont fabriquées dans la classe Leaves Block
et les semis sont fabriqués dans la classe Sapling Block
. Les paramètres détaillés sont communs à Block
(par exemple, définissez la dureté et la résistance avec .hardnessAndResistance ()
), donc modifiez-les si nécessaire. Les valeurs ci-dessus sont (devraient) être des valeurs standard pour chacun.
Le premier argument passé au constructeur SaplingBlock
est une instance de l'arbre généré par le semis. Je ne l'ai pas encore défini, mais je l'expliquerai plus tard.
De plus, une description a été ajoutée à la partie d'enregistrement de bloc. Cela définit le type de rendu afin d'afficher correctement la texture du bloc de semis. Si cela n'est pas fait, la partie qui doit être transparente sera peinte en noir. Référence
Enfin, la couleur du bloc de feuilles est réglée pour changer en fonction de la couleur du biome. Depuis que j'ai apporté la description de au 1.14.4 telle quelle, je n'ai pas regardé profondément à l'intérieur. Vous pouvez en voir plus en observant la classe BlockColors
. À propos de la couleur du biome [page de référence](https://minecraft-ja.gamepedia.com/%E3%83%90%E3%82%A4%E3%82%AA%E3%83%BC%E3%83% A0 # .E3.83.90.E3.82.A4.E3.82.AA.E3.83.BC.E3.83.A0.E3.82.AB.E3.83.A9.E3.83.BC.E3 .81.AE.E6.B1.BA.E5.AE.9A). Si ce n'est pas défini, la couleur de la texture sera utilisée telle quelle pour tous les biomes et peut être omise.
La couleur des feuilles change en fonction du biome (Puisque c'est après mise en œuvre jusqu'à la génération naturelle à la fin de l'article, aucun arbre n'est généré dans le monde à ce stade)
Items.java
package jp.koteko.liveinwater.item;
import jp.koteko.liveinwater.LiveInWater;
import jp.koteko.liveinwater.block.Blocks;
import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import java.util.ArrayList;
import java.util.List;
@Mod.EventBusSubscriber(modid = LiveInWater.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class Items {
public static List<Item> itemList = new ArrayList<Item>();
public static final Item WATERTREE_ROOT = register("watertree_root", new Item((new Item.Properties()).group(LiwItemGroup.DEFAULT)));
public static final Item WATERTREE_ROOT_BLOCK = register("watertree_root_block", Blocks.WATERTREE_ROOT_BLOCK, LiwItemGroup.DEFAULT);
public static final Item WATERTREE_LOG = register("watertree_log", Blocks.WATERTREE_LOG, LiwItemGroup.DEFAULT);
public static final Item WATERTREE_LEAVES = register("watertree_leaves", Blocks.WATERTREE_LEAVES, LiwItemGroup.DEFAULT);
public static final Item WATERTREE_SAPLING = register("watertree_sapling", Blocks.WATERTREE_SAPLING, LiwItemGroup.DEFAULT);
private static Item register(String key, Item itemIn) {
itemList.add(itemIn);
return itemIn.setRegistryName(LiveInWater.MOD_ID, key);
}
private static Item register(String key, Block blockIn, ItemGroup itemGroupIn) {
return register(key, new BlockItem(blockIn, (new Item.Properties()).group(itemGroupIn)));
}
@SubscribeEvent
public static void registerItems(RegistryEvent.Register<Item> event) {
for (Item item : itemList) {
event.getRegistry().register(item);
}
}
}
Déclarez et enregistrez BlockItem
. Voir également Ajouter un élément (https://qiita.com/koteko/items/578c3cfdfd7ef71df9c1).
Définissez resources
.
\src\main\resources
├ assets
│ └ example_mod
│ ├ blockstates
│ │ ├ watertree_leaves.json
│ │ ├ watertree_log.json
│ │ └ watertree_sapling.json
│ ├ lang
│ │ └ en_us.json
│ │ └ ja_jp.json
│ ├ models
│ │ ├ block
│ │ │ ├ watertree_leaves.json
│ │ │ ├ watertree_log.json
│ │ │ └ watertree_sapling.json
│ │ └ item
│ │ ├ example_leaves.json
│ │ ├ example_log.json
│ │ └ example_sapling.json
│ └ textures
│ ├ block
│ │ ├ watertree_leaves.json
│ │ ├ watertree_log.json
│ │ └ watertree_sapling.json
│ └ item
│ └ watertree_sapling.json
└ data
└ liveinwater
└ loot_tables
└ blocks
├ example_leaves.json
├ example_log.json
└ example_sapling.json
blockstates\watertree_leaves.json
{
"variants": {
"": { "model": "liveinwater:block/watertree_leaves" }
}
}
blockstates\watertree_log.json
{
"variants": {
"axis=y": { "model": "liveinwater:block/watertree_log" },
"axis=z": { "model": "liveinwater:block/watertree_log", "x": 90 },
"axis=x": { "model": "liveinwater:block/watertree_log", "x": 90, "y": 90 }
}
}
Faites pivoter le modèle en fonction du sens d'installation.
blockstates\watertree_sapling.json
{
"variants": {
"": { "model": "liveinwater:block/watertree_sapling" }
}
}
en_us.jp
{
"item.liveinwater.watertree_log": "WaterTree Log",
"item.liveinwater.watertree_leaves": "WaterTree Leaves",
"item.liveinwater.watertree_sapling": "WaterTree Sapling",
"block.liveinwater.watertree_log": "WaterTree Log",
"block.liveinwater.watertree_leaves": "WaterTree Leaves",
"block.liveinwater.watertree_sapling": "WaterTree Sapling"
}
ja_jp.json
{
"item.liveinwater.watertree_log": "Journal de l'arbre d'eau",
"item.liveinwater.watertree_leaves": "Feuilles d'arbre d'eau",
"item.liveinwater.watertree_sapling": "Arroser les plants d'arbres",
"block.liveinwater.watertree_log": "Journal de l'arbre d'eau",
"block.liveinwater.watertree_leaves": "Feuilles d'arbre d'eau",
"block.liveinwater.watertree_sapling": "Arroser les plants d'arbres"
}
models\block\watertree_leaves.json
{
"parent": "block/leaves",
"textures": {
"all": "liveinwater:block/watertree_leaves"
}
}
models\block\watertree_log.json
{
"parent": "block/cube_column",
"textures": {
"end": "liveinwater:block/watertree_log_top",
"side": "liveinwater:block/watertree_log"
}
}
Spécifiez block / cube_column
pour parent
, et appliquez une texture qui fait la distinction entre le haut et le bas et les côtés dans une forme cubique. Spécifions le chemin vers chaque fichier de texture.
models\block\watertree_sapling.json
{
"parent": "block/cross",
"textures": {
"cross": "liveinwater:block/watertree_sapling"
}
}
models\item\watertree_leaves.json
{
"parent": "liveinwater:block/watertree_leaves"
}
models\item\watertree_log.json
{
"parent": "liveinwater:block/watertree_log"
}
models\item\watertree_sapling.json
{
"parent": "item/generated",
"textures": {
"layer0": "liveinwater:item/watertree_sapling"
}
}
\loot_table\blocks\watertree_leaves.json
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:alternatives",
"children": [
{
"type": "minecraft:item",
"conditions": [
{
"condition": "minecraft:alternative",
"terms": [
{
"condition": "minecraft:match_tool",
"predicate": {
"item": "minecraft:shears"
}
},
{
"condition": "minecraft:match_tool",
"predicate": {
"enchantments": [
{
"enchantment": "minecraft:silk_touch",
"levels": {
"min": 1
}
}
]
}
}
]
}
],
"name": "liveinwater:watertree_leaves"
},
{
"type": "minecraft:item",
"conditions": [
{
"condition": "minecraft:survives_explosion"
},
{
"condition": "minecraft:table_bonus",
"enchantment": "minecraft:fortune",
"chances": [
0.05,
0.0625,
0.083333336,
0.1
]
}
],
"name": "liveinwater:watertree_sapling"
}
]
}
]
}
]
}
Pour plus de détails, voir [Page de référence](https://minecraft-ja.gamepedia.com/%E3%83%AB%E3%83%BC%E3%83%88%E3%83%86%E3%83%BC% E3% 83% 96% E3% 83% AB).
\loot_table\blocks\watertree_log.json
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "liveinwater:watertree_log"
}
]
}
]
}
\loot_table\blocks\watertree_sapling.json
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "liveinwater:watertree_sapling"
}
]
}
]
}
Ajoutez le bloc de journal ajouté à la balise minecraft: logs
. Ceci est utilisé pour déterminer la disparition des blocs feuilles (bien qu'il puisse être utilisé dans d'autres parties également), donc si cela n'est pas fait, les blocs feuilles générés commenceront à disparaître immédiatement.
\src\main\resources
├ assets
└ data
├ liveinwater
└ minecraft
└ tags
└ blocks
└ logs.json
** Créez un dossier ** \ src \ main \ resources \ data \ minecraft \ tags \ blocks
dans votre dossier de projet et placez-y logs.json
. Assurez-vous que ce nom est le même.
logs.json
{
"replace": false,
"values": [
"liveinwater:watertree_log"
]
}
En donnant «false» à «remplacer», la description dans ce fichier sera intégrée dans «minecraft: logs» du même nom. Spécifions le bloc dans values
.
De même, ajoutez des blocs de feuilles à la balise minecraft: feuilles
Ceci est nécessaire pour que le bloc de feuilles ne soit pas jugé comme un obstacle lorsque l'arbre se développe à partir du semis (s'il n'est pas dans l'étiquette de feuilles, il ne sera pas écrasé lors de la création de l'arbre).
\src\main\resources
├ assets
└ data
├ liveinwater
└ minecraft
└ tags
└ blocks
├ leaves.json
└ logs.json
leaves.json
{
"replace": false,
"values": [
"liveinwater:watertree_leaves"
]
}
Lorsque vous appuyez sur F3 dans le jeu pour afficher l'affichage de débogage et placer le curseur sur le bloc, vérifiez que la balise (par exemple, #mineraft: logs
) est affichée au centre à droite de l'écran.
Celles-ci sont difficiles à expliquer avec des mots, mais les deux sont des classes qui gèrent les arbres. La classe Tree
est une classe qui gère l'arbre lui-même et est requise en relation avec les plants qui seront ajoutés plus tard. D'autre part, la classe TreeFeature
gère les choses liées à la génération d'arbres, et vous pouvez également obtenir la TreeFeature
correspondante de la classe Tree
.
\src\main\java\jp\koteko\liveinwater\
├ block
│ └ trees
│ └ WaterTree.java
├ item
├ world
│ └ gen
│ └ feature
│ └ WaterTreeFeature.java
└ LiveInWater.java
WaterTree.java
package jp.koteko.liveinwater.block.trees;
import jp.koteko.liveinwater.world.gen.TreeGenerator;
import net.minecraft.block.trees.Tree;
import net.minecraft.world.gen.feature.BaseTreeFeatureConfig;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import javax.annotation.Nullable;
import java.util.Random;
public class WaterTree extends Tree {
@Nullable
protected ConfiguredFeature<BaseTreeFeatureConfig, ?> getTreeFeature(Random randomIn, boolean p_225546_2_) {
return TreeGenerator.WATERTREE.setConfiguration();
}
}
Étend la classe abstraite Tree
pour définir la classe. Définissons la méthode abstraite getTreeFeature
pour renvoyer une instance de la classe BaseTreeFeatureConfig
avec la configuration donnée au WaterTreeFeature
décrit ci-dessous (TreeGenerator
sera décrit dans une section ultérieure). Il est conçu pour recevoir des nombres aléatoires, mais cela est utilisé lorsque l'arbre devient une espèce énorme avec une probabilité, changez donc la valeur renvoyée en fonction du nombre aléatoire si nécessaire.
WaterTreeFeature.java
package jp.koteko.liveinwater.world.gen.feature;
import com.google.common.collect.ImmutableList;
import com.mojang.serialization.Codec;
import jp.koteko.liveinwater.block.Blocks;
import net.minecraft.world.gen.blockstateprovider.SimpleBlockStateProvider;
import net.minecraft.world.gen.feature.*;
import net.minecraft.world.gen.foliageplacer.BlobFoliagePlacer;
import net.minecraft.world.gen.placement.AtSurfaceWithExtraConfig;
import net.minecraft.world.gen.placement.Placement;
import net.minecraft.world.gen.treedecorator.BeehiveTreeDecorator;
import net.minecraft.world.gen.trunkplacer.StraightTrunkPlacer;
public class WaterTreeFeature extends TreeFeature {
public WaterTreeFeature(Codec<BaseTreeFeatureConfig> codec) {
super(codec);
}
public ConfiguredFeature<?, ?> configure() {
return this.setConfiguration().withPlacement(Placement.field_242902_f.configure(new AtSurfaceWithExtraConfig(10, 0.1F, 1)).func_242728_a());
}
public ConfiguredFeature<BaseTreeFeatureConfig, ?> setConfiguration() {
return this.withConfiguration(
new BaseTreeFeatureConfig.Builder(
new SimpleBlockStateProvider(Blocks.WATERTREE_LOG.getDefaultState()),
new SimpleBlockStateProvider(Blocks.WATERTREE_LEAVES.getDefaultState()),
new BlobFoliagePlacer(FeatureSpread.func_242252_a(2), FeatureSpread.func_242252_a(0), 3),
new StraightTrunkPlacer(5, 2, 0),
new TwoLayerFeature(1, 0, 1)
).func_236700_a_().func_236703_a_(ImmutableList.of(new BeehiveTreeDecorator(0.002F))).build());
}
}
Définissez la classe en étendant la classe TreeFeature
.
Deux méthodes sont définies pour gérer les restrictions imposées par les génériques (<BaseTreeFeatureConfig,?>
Part) lors de l'utilisation de Features d'autres classes.
Tout d'abord, le setConfiguration ()
ci-dessous définit la forme que cet arbre aura (withConfiguration ()
).
Un constructeur est préparé dans la configuration, et les arguments sont, dans l'ordre, le fournisseur du bloc qui devient le tronc, le fournisseur du bloc qui devient la feuille, la forme d'arrangement des feuilles, la forme d'arrangement du tronc, (argument d'utilisation inconnue ʻAbstractFeatureSizeType). Le nom est difficile à comprendre, mais
func_236700_a_ () donne une fonction qui rend ʻignore_vines
vraie, etfunc_236703_a_ ()
donne un argument (dans cet exemple, celui qui crée une ruche avec une probabilité de 0,002) comme décorateur. Chacun est défini dans le générateur en tant que fonction. Enfin, appelez build ()
pour créer un BaseTreeFeatureConfig
et passez-le à l'argument de withConfiguration ()
.
Ensuite, configure ()
donne à la fonctionnalité qui étaitsetConfiguration ()
plus de paramètres de l'emplacement du placement (withPlacement ()
).
On sait qu'il existe de nombreux types de "placement", et il est également possible d'utiliser plusieurs types dans les couches. Par conséquent, il sera nécessaire d'examiner en profondeur le contenu de "Placement" pour créer l'arrangement souhaité. Cette fois, j'ai vérifié et montré un seul exemple. Par exemple, Placement.field_242902_f
détermine le nombre de loteries,func_242728_a ()
applique enfinSquarePlacement
et la méthode getPosisions
renvoie une liste de coordonnées aléatoires dans le bloc. Semble faire. Si je comprends un peu plus ce domaine, je peux le résumer dans un autre article.
Enfin, faisons en sorte que l'arbre implémenté soit généré automatiquement lorsque le monde est généré.
\src\main\java\jp\koteko\liveinwater\
├ block
├ item
├ world
│ └ gen
│ ├ feture
│ └ TreeGenerator.java
└ LiveInWater.java
WorldGenOres.java
package jp.koteko.liveinwater.world.gen;
import com.google.common.collect.Lists;
import jp.koteko.liveinwater.world.gen.feature.WaterTreeFeature;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.WorldGenRegistries;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeGenerationSettings;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.feature.BaseTreeFeatureConfig;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
public class TreeGenerator {
public static WaterTreeFeature WATERTREE;
public static ConfiguredFeature<?, ?> CONFIGURED_WATERTREE;
public static void init() {
WATERTREE = Registry.register(Registry.FEATURE, "liveinwater:watertree", new WaterTreeFeature(BaseTreeFeatureConfig.field_236676_a_));
CONFIGURED_WATERTREE = Registry.register(WorldGenRegistries.field_243653_e, "liveinwater:watertree", WATERTREE.configure());
}
public static void setup() {
addTreeToOverworld(CONFIGURED_WATERTREE);
}
private static void addTreeToOverworld(ConfiguredFeature<?, ?> featureIn){
for(Map.Entry<RegistryKey<Biome>, Biome> biome : WorldGenRegistries.field_243657_i.func_239659_c_()) {
if(!biome.getValue().getCategory().equals(Biome.Category.NETHER) && !biome.getValue().getCategory().equals(Biome.Category.THEEND)) {
addFeatureToBiome(biome.getValue(), GenerationStage.Decoration.VEGETAL_DECORATION, featureIn);
}
}
}
public static void addFeatureToBiome(Biome biome, GenerationStage.Decoration decoration, ConfiguredFeature<?, ?> configuredFeature) {
List<List<Supplier<ConfiguredFeature<?, ?>>>> biomeFeatures = new ArrayList<>(biome.func_242440_e().func_242498_c());
while (biomeFeatures.size() <= decoration.ordinal()) {
biomeFeatures.add(Lists.newArrayList());
}
List<Supplier<ConfiguredFeature<?, ?>>> features = new ArrayList<>(biomeFeatures.get(decoration.ordinal()));
features.add(() -> configuredFeature);
biomeFeatures.set(decoration.ordinal(), features);
ObfuscationReflectionHelper.setPrivateValue(BiomeGenerationSettings.class, biome.func_242440_e(), biomeFeatures, "field_242484_f");
}
}
Il est difficile de tout comprendre, alors décidez quoi changer si nécessaire (parce que je l'ai fait). Dans la version 1.16.1, [de la même manière que précédemment](https://qiita.com/koteko/items/aebfc47cf73d7e49baa6#%E6%9C%A8%E3%81%AE%E7%94%9F%E6%88 Il n'a pas été possible d'enregistrer la fonctionnalité dans Biome à% 90). Par conséquent, recherchez un code de référence et reportez-vous au code de BluePower. J'étais autorisé à le faire.
En définissant ʻaddFeatureToBiomeen bas, il est possible d'enregistrer une caractéristique dans Biome de la même manière qu'auparavant. En bref, il semble que la variable membre
field_242484_f de la classe
BiomeGenerationSettings` a une liste de fonctionnalités, il semble donc que nous faisons le travail d'écrasement et d'ajout.
Une fois que addFeatureToBiome est défini, il peut être implémenté d'une manière similaire à la méthode précédente. Définition de la méthode ʻaddTreeToOverworld
qui s'enregistre auprès d'Overworld's Biome et l'appelle dans la méthode setup
. De plus, chaque fonctionnalité doit être déclarée à l'avance et enregistrée avec la méthode ʻinit`. Pour le moment, il semble que cela ne fonctionnera que si vous enregistrez la fonctionnalité et la fonctionnalité configurée comme décrit ci-dessus (même si c'était assez compact, je ne pouvais pas le comprendre complètement).
Enfin, appelez le TreeGenerator.init ()
TreeGenerator.setup ()
juste défini dans le fichier principal.
LiveInWater.java
package jp.koteko.liveinwater;
import jp.koteko.liveinwater.world.gen.TreeGenerator;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Mod(LiveInWater.MOD_ID)
public class LiveInWater
{
public static final String MOD_ID = "liveinwater";
private static final Logger LOGGER = LogManager.getLogger();
public LiveInWater() {
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff);
TreeGenerator.init();
MinecraftForge.EVENT_BUS.register(this);
}
private void setup(final FMLCommonSetupEvent event)
{
LOGGER.info("SETUP START");
TreeGenerator.setup();
LOGGER.info("SETUP END");
}
private void doClientStuff(final FMLClientSetupEvent event) {
// do something that can only be done on the client
}
private void enqueueIMC(final InterModEnqueueEvent event)
{
// some example code to dispatch IMC to another mod
}
private void processIMC(final InterModProcessEvent event)
{
// some example code to receive and process InterModComms from other mods
}
@SubscribeEvent
public void onServerStarting(FMLServerStartingEvent event) {
LOGGER.info("server starting");
}
}
Démarrez le jeu et créez un nouveau monde.
Un arbre est en cours de génération (comme décrit jusqu'à présent)
Une arborescence est en cours de génération (lorsque le placement et la configuration sont modifiés)
[Java] Créons un Minecraft Mod 1.14.4 [9. Ajouter et générer des arbres] --Qiita BluePower/BPWorldGen.java at master · Qmunity/BluePower · GitHub 1.14.3 Tags help - Modder Support - Forge Forums [Biome-Minecraft Wiki](https://minecraft-ja.gamepedia.com/%E3%83%90%E3%82%A4%E3%82%AA%E3%83%BC%E3%83%A0# .E3.83.90.E3.82.A4.E3.82.AA.E3.83.BC.E3.83.A0.E3.82.AB.E3.83.A9.E3.83.BC.E3.81 .AE.E6.B1.BA.E5.AE.9A) [Route Table - Minecraft Wiki](https://minecraft-ja.gamepedia.com/%E3%83%AB%E3%83%BC%E3%83%88%E3%83%86%E3%83%BC % E3% 83% 96% E3% 83% AB) [SOLVED] [1.15.2] A texture issue with cross models? - Modder Support - Forge Forums
Pour référence, je vais enregistrer un exemple de son implémentation à un niveau qui fonctionne pour le moment avant la mise à niveau de la version Forge.
<détails> Cela n'a pas de sens à ce stade, car ce n'est pas encore différent de la classe parente. Contrairement à environ 1.14, il semble qu'une interface appelée «Codec» ait été introduite. D'une manière ou d'une autre, quand je le regarde, il semble que ce soit pour la manipulation générale d'objets de différentes classes. C'est fondamentalement le même que dans 1.14, et il est généré en ajoutant la fonctionnalité de l'arbre au biome que vous voulez générer par
Recommended Posts
\src\main\java\jp\koteko\liveinwater\
├ block
├ item
├ world
│ └ gen
│ ├ feature
│ │ └ WaterTreeFeature.java
│ └ TreeGenerator.java
└ LiveInWater.java
WaterTreeFeature.java
package jp.koteko.liveinwater.world.gen.feature;
import com.mojang.serialization.Codec;
import net.minecraft.world.gen.feature.BaseTreeFeatureConfig;
import net.minecraft.world.gen.feature.TreeFeature;
public class WaterTreeFeature extends TreeFeature {
public WaterTreeFeature(Codec<BaseTreeFeatureConfig> codec) {
super(codec);
}
}
TreeGenerator.java
package jp.koteko.liveinwater.world.gen;
import com.google.common.collect.ImmutableList;
import jp.koteko.liveinwater.world.gen.feature.WaterTreeFeature;
import net.minecraft.block.Blocks;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.blockstateprovider.SimpleBlockStateProvider;
import net.minecraft.world.gen.feature.BaseTreeFeatureConfig;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.TwoLayerFeature;
import net.minecraft.world.gen.foliageplacer.BlobFoliagePlacer;
import net.minecraft.world.gen.placement.AtSurfaceWithExtraConfig;
import net.minecraft.world.gen.placement.Placement;
import net.minecraft.world.gen.treedecorator.BeehiveTreeDecorator;
import net.minecraft.world.gen.trunkplacer.StraightTrunkPlacer;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.OptionalInt;
public class TreeGenerator {
public static void setup() {
addTreeToOverworld(
new WaterTreeFeature(BaseTreeFeatureConfig.field_236676_a_)
.withConfiguration(
(new BaseTreeFeatureConfig.Builder(
new SimpleBlockStateProvider(Blocks.ACACIA_WOOD.getDefaultState()),
new SimpleBlockStateProvider(Blocks.BLUE_WOOL.getDefaultState()),
new BlobFoliagePlacer(2, 0, 0, 0, 3),
new StraightTrunkPlacer(5, 2, 0),
new TwoLayerFeature(0, 0, 0, OptionalInt.of(4)))
).func_236700_a_().func_236703_a_(ImmutableList.of(new BeehiveTreeDecorator(0.002F))).build())
.withPlacement(Placement.COUNT_EXTRA_HEIGHTMAP.configure(new AtSurfaceWithExtraConfig(10, 0.1F, 1)))
);
}
private static void addTreeToOverworld(ConfiguredFeature<?, ?> featureIn) {
for(Biome biome : ForgeRegistries.BIOMES) {
if (!biome.getCategory().equals(Biome.Category.NETHER) && !biome.getCategory().equals(Biome.Category.THEEND)) {
biome.addFeature(GenerationStage.Decoration.VEGETAL_DECORATION, featureIn);
}
}
}
}
Biome # addFeature
. Beaucoup de noms étaient difficiles à comprendre, et la gestion de «Feature» et «ConfiguredFeature» semblait changer, et «Biome # createDecoratedFeature» manquait également. Le code ci-dessus a été écrit en observant le code vanilla.
Pour ConfiguredFeature
(new WaterTreeFeature ()
), config (dans ce cas, le bloc ou la forme de l'arbre) et le placement (loterie au moment de la génération naturelle) avec withConfiguration () ʻet
withPlacement ()Emplacement) est défini. Un constructeur a été préparé pour la configuration, alors utilisez ceci. Dans l'ordre, le bloc de tronc (fournisseur), le bloc de feuille (fournisseur), la forme de la disposition des feuilles, la forme de la disposition du tronc et le type de taille minimale (détails inconnus). Les fournisseurs doivent passer une instance de la classe
SimpleBlockStateProvidersauf s'ils font quelque chose de spécial. Modifiez uniquement le type de bloc selon vos besoins. En ce qui concerne la forme de disposition des feuilles et du tronc, il existe plusieurs types utilisés dans la vanille, utilisez donc celui qui convient. Observez les sous-classes de
FoliagePlacer, ʻAbstractTrunkPlacer
. Spécifiez la hauteur, etc. avec l'argument. Le 5ème argument du constructeur semble être un objet de la classe ʻAbstractFeatureSizeType géré par le nom
taille_minimale, mais je ne savais pas comment cela fonctionnerait, donc je vais le faire correspondre avec un autre code. Renvoie une instance de la configuration en appelant
build ()au générateur.
func_236700_a_ ()spécifie qu'aucune tsuta n'est générée, et
func_236703_a_ ()spécifie qu'une ruche est générée en passant un argument comme celui-ci. Choisissez le type de placement approprié (voir la classe
Placement) et définissez-le avec
configure ()`.Article suivant