(Dieser Artikel gehört zu einer Reihe von Kommentaren)
Erster Artikel: Einführung Vorheriger Artikel: Block hinzufügen Nächster Artikel:
Bis zu diesem Punkt haben wir den Bestand an fortlaufenden Artikeln übernommen und davon ausgegangen, dass die nicht anders genannten Punkte dieselben sind wie zuvor. Seien Sie jedoch besonders vorsichtig, da wir die Umgebung ** aus diesem Artikel heraus geändert haben.
** Die Version von Minecraft Forge wurde aktualisiert. ** Dies liegt daran, dass es sich um eine in Entwicklung befindliche Version handelt und es viele unentwickelte Teile gibt. Beachten Sie außerdem, dass sich die Version nach dem Update noch in der Entwicklung befindet und täglich aktualisierte Versionen veröffentlicht werden.
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) |
Fügen Sie Protokolle, Blätter und Sämlingsblöcke hinzu, indem Sie auf Block hinzufügen verweisen.
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);
}
}
Protokolle werden in der Klasse "Rotated Pillar Block" erstellt, Blätter in der Klasse "Leaves Block" und Sämlinge in der Klasse "Sapling Block". Detaillierte Einstellungen sind für "Block" üblich (z. B. Festlegen von Härte und Widerstand mit ".hardnessAndResistance ()"). Ändern Sie sie daher entsprechend. Jeder der oben genannten Werte ist (sollte) ein Standardwert. Das erste Argument, das an den Konstruktor "SaplingBlock" übergeben wird, ist eine Instanz des vom Sämling generierten Baums. Ich habe es noch nicht definiert, aber ich werde es später erklären. Zusätzlich wurde dem Blockregistrierungsteil eine Beschreibung hinzugefügt. Dadurch wird der Rendertyp festgelegt, um die Textur des Sämlingsblocks korrekt anzuzeigen. Andernfalls wird das Teil, das transparent sein soll, schwarz lackiert. Referenz Schließlich wird die Farbe des Blattblocks so eingestellt, dass sie sich entsprechend der Biomfarbe ändert. Ich habe die Beschreibung von um 1.14.4 so wie sie ist gebracht, also habe ich nicht tief hineingeschaut. Sie können mehr sehen, indem Sie die Klasse "BlockColors" beobachten. Informationen zur Biomfarbe [Referenzseite](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). Wenn dies nicht eingestellt ist, wird die Texturfarbe wie für alle Biome verwendet und kann weggelassen werden.
Die Farbe der Blätter ändert sich je nach Biom (da es nach der Implementierung bis zur natürlichen Erzeugung am Ende des Artikels noch keinen Baum auf der Welt gibt)
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);
}
}
}
Deklarieren und registrieren Sie BlockItem
. Siehe auch Element hinzufügen (https://qiita.com/koteko/items/578c3cfdfd7ef71df9c1).
Stellen Sie "Ressourcen" ein.
\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 }
}
}
Drehen Sie das Modell je nach Einbaurichtung.
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": "Protokoll des Wasserbaums",
"item.liveinwater.watertree_leaves": "Wasserbaumblätter",
"item.liveinwater.watertree_sapling": "Wasserbaumsetzlinge",
"block.liveinwater.watertree_log": "Protokoll des Wasserbaums",
"block.liveinwater.watertree_leaves": "Wasserbaumblätter",
"block.liveinwater.watertree_sapling": "Wasserbaumsetzlinge"
}
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"
}
}
Geben Sie "block / cube_column" für "parent" an und wenden Sie eine Textur an, die zwischen Ober- und Unterseite und Seiten in kubischer Form unterscheidet. Geben Sie den Pfad zu jeder Texturdatei an.
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"
}
]
}
]
}
]
}
Weitere Informationen finden Sie unter [Referenzseite](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"
}
]
}
]
}
Fügen Sie den hinzugefügten Protokollblock zum Tag "minecraft: logs" hinzu. Dies wird verwendet, um das Verschwinden von Blattblöcken zu bestimmen (obwohl es auch in anderen Teilen verwendet werden kann). Wenn dies nicht erfolgt, verschwinden die generierten Blattblöcke sofort.
\src\main\resources
├ assets
└ data
├ liveinwater
└ minecraft
└ tags
└ blocks
└ logs.json
** Erstellen Sie einen ** \ src \ main \ resources \ data \ minecraft \ tags \ blocks
-Ordner in Ihrem Projektordner und platzieren Sie logs.json
darin. Stellen Sie sicher, dass dieser Name identisch ist.
logs.json
{
"replace": false,
"values": [
"liveinwater:watertree_log"
]
}
Wenn Sie "false" für "replace" angeben, wird die Beschreibung in dieser Datei in "minecraft: logs" mit demselben Namen integriert. Geben wir den Block in values
an.
Fügen Sie in ähnlicher Weise Blattblöcke zum Tag "Minecraft: Blätter" hinzu. Dies ist erforderlich, damit der Blattblock nicht als Hindernis beurteilt wird, wenn der Baum aus dem Sämling wächst (wenn er nicht im Blatt-Tag enthalten ist, wird er beim Erstellen des Baums nicht überschrieben).
\src\main\resources
├ assets
└ data
├ liveinwater
└ minecraft
└ tags
└ blocks
├ leaves.json
└ logs.json
leaves.json
{
"replace": false,
"values": [
"liveinwater:watertree_leaves"
]
}
Wenn Sie im Spiel F3 drücken, um die Debug-Anzeige anzuzeigen und den Cursor auf den Block zu setzen, überprüfen Sie, ob das Tag (z. B. "#mineraft: logs") in der Mitte rechts auf dem Bildschirm angezeigt wird.
Diese sind schwer in Worten zu erklären, aber beide sind Klassen, die Bäume verwalten. Die Tree
-Klasse ist eine Klasse, die den Baum selbst verwaltet und in Verbindung mit den Sämlingen benötigt wird, die später hinzugefügt werden. Auf der anderen Seite verwaltet die "TreeFeature" -Klasse Dinge im Zusammenhang mit der Baumgenerierung, und Sie können das entsprechende "TreeFeature" auch aus der "Tree" -Klasse abrufen.
\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();
}
}
Erweitert die abstrakte Klasse "Tree", um die Klasse zu definieren. Definieren wir die abstrakte Methode "getTreeFeature", um eine Instanz der "BaseTreeFeatureConfig" -Klasse mit der Konfiguration zurückzugeben, die der unten beschriebenen "WaterTreeFeature" zugewiesen wurde ("TreeGenerator" wird in einem späteren Abschnitt beschrieben). Es ist so konzipiert, dass es Zufallszahlen empfängt. Dies wird jedoch verwendet, wenn der Baum mit einer Wahrscheinlichkeit zu einer riesigen Art heranwächst. Ändern Sie daher den zurückgegebenen Wert gegebenenfalls entsprechend der Zufallszahl.
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());
}
}
Definieren Sie die Klasse, indem Sie die TreeFeature-Klasse erweitern.
Es werden zwei Methoden definiert, um die von Generika auferlegten Einschränkungen zu erfüllen (<BaseTreeFeatureConfig,?>
Part), wenn Features aus anderen Klassen verwendet werden.
Zunächst legt die unten stehende setConfiguration ()
fest, welche Form dieser Baum haben wird (withConfiguration ()
).
In der Konfiguration wird ein Builder vorbereitet, und die Argumente sind in der Reihenfolge der Anbieter des Blocks, der zum Stamm wird, der Anbieter des Blocks, der zum Blatt wird, die Anordnungsform der Blätter, die Anordnungsform des Stamms (Argument unbekannter Verwendung AbstractFeatureSizeType
). Der Name ist schwer zu verstehen, aber func_236700_a_ ()
gibt eine Funktion an, die ignore_vines
wahr macht, und func_236703_a_ ()
gibt ein Argument (in diesem Beispiel eines, das einen Bienenstock mit einer Wahrscheinlichkeit von 0,002 erstellt) als Dekorateur an. Jedes wird im Builder als Funktion definiert. Rufen Sie abschließend "build ()" auf, um eine "BaseTreeFeatureConfig" zu erstellen und diese an das Argument "withConfiguration ()" zu übergeben.
Als nächstes gibt configure ()
dem Feature, dassetConfiguration ()
war, mehr Einstellungen für den Platzierungsort (withPlacement ()
).
Es ist bekannt, dass es viele Arten von "Platzierung" gibt, und es ist auch möglich, mehrere Arten in Schichten zu verwenden. Daher ist es notwendig, den Inhalt von "Platzierung" genau zu betrachten, um die gewünschte Anordnung zu erstellen. Diesmal habe ich nur ein Beispiel überprüft und gezeigt. Zum Beispiel bestimmt "Placement.field_242902_f" die Anzahl der Ziehungen, "func_242728_a ()" wendet schließlich "SquarePlacement" an und die "getPosisions" -Methode gibt eine Liste zufälliger Koordinaten im Block zurück. Scheint zu tun. Wenn ich diesen Bereich etwas tiefer verstehe, kann ich ihn in einem anderen Artikel zusammenfassen.
Lassen Sie uns abschließend den implementierten Baum automatisch generieren, wenn die Welt generiert wird.
\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");
}
}
Es ist schwer, alles zu verstehen, also entscheide, was du ändern musst, wenn du musst (weil ich es getan habe). In Version 1.16.1 [auf die gleiche Weise wie zuvor](https://qiita.com/koteko/items/aebfc47cf73d7e49baa6#%E6%9C%A8%E3%81%AE%E7%94%9F%E6%88 Es war nicht möglich, das Feature in Biome bei% 90 zu registrieren. Suchen Sie daher nach einem Referenzcode und beziehen Sie sich auf den Code von BluePower. Ich durfte.
Durch Definieren von "addFeatureToBiome" unten ist es möglich, ein Feature in Biome auf die gleiche Weise wie zuvor zu registrieren. Kurz gesagt, es scheint, dass die Mitgliedsvariable field_242484_f
der Klasse BiomeGenerationSettings
eine Liste von Funktionen enthält, sodass wir anscheinend die Arbeit des Überschreibens und Hinzufügens erledigen.
Sobald addFeatureToBiome
definiert ist, kann der Rest auf ähnliche Weise wie bei der vorherigen Methode implementiert werden. Definierte die "addTreeToOverworld" -Methode, die sich bei Overworlds Biome registriert und innerhalb der "setup" -Methode aufruft. Außerdem sollte jedes Feature im Voraus deklariert und mit der init
-Methode registriert werden. Derzeit scheint es nicht zu funktionieren, wenn Sie das Feature und das konfigurierte Feature nicht wie oben beschrieben registrieren (obwohl es ziemlich voll war, konnte ich es nicht vollständig verstehen).
Rufen Sie abschließend den gerade definierten "TreeGenerator.init ()" TreeGenerator.setup () "in der Hauptdatei auf.
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");
}
}
Starte das Spiel und erschaffe eine neue Welt.
Ein Baum wird generiert (wie bisher beschrieben)
Ein Baum wird generiert (wenn Platzierung und Konfiguration geändert werden)
[Java] Erstellen wir einen Minecraft Mod 1.14.4 [9. Bäume hinzufügen und generieren] --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) [Routentabelle - 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
Als Referenz werde ich ein Beispiel für die Implementierung auf ein Niveau aufzeichnen, das vor dem Upgrade der Forge-Version vorerst funktioniert.
\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);
}
}
Dies ist an dieser Stelle bedeutungslos, da es sich noch nicht von der übergeordneten Klasse unterscheidet. Anders als um 1.14 scheint eine Schnittstelle namens "Codec" eingeführt worden zu sein. Wenn ich es mir anschaue, scheint es irgendwie für den allgemeinen Umgang mit Objekten verschiedener Klassen zu sein.
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);
}
}
}
}
Es ist im Grunde dasselbe wie in 1.14 und wird durch Hinzufügen der Funktion des Baums zu dem Biom generiert, das Sie mit "Biome # addFeature" generieren möchten. Viele der Namen sind schwer zu verstehen, und es scheint, dass sich die Behandlung von "Feature" und "ConfiguredFeature" geändert hat und "Biome # createDecoratedFeature" ebenfalls verschwunden ist. Der obige Code wurde unter Beachtung des Vanille-Codes geschrieben.
Für ConfiguredFeature
(new WaterTreeFeature ()
) konfigurieren Sie (in diesem Fall den Block oder die Form des Baums) und platzieren Sie (Lotterie zum Zeitpunkt der natürlichen Erzeugung) mit withConfiguration ()
undwithPlacement ()
Ort) ist eingestellt.
Für die Konfiguration wurde ein Builder vorbereitet. Verwenden Sie diesen. In der Reihenfolge der Stammblock (Anbieter), der Blattblock (Anbieter), die Blattanordnungsform, die Stammanordnungsform und der Mindestgrößentyp (Details unbekannt). Anbieter sollten eine Instanz der Klasse "SimpleBlockStateProvider" übergeben, es sei denn, sie tun etwas Besonderes. Ändern Sie nur den Blocktyp entsprechend. Für die Anordnung der Blätter und des Stammes werden einige Arten in Vanille verwendet, verwenden Sie also die entsprechende. Beachten Sie die Unterklassen von "FoliagePlacer", "AbstractTrunkPlacer". Geben Sie die Höhe usw. mit dem Argument an. Das fünfte Argument des Builders scheint ein Objekt der Klasse "AbstractFeatureSizeType" zu sein, die unter dem Namen "minimal_size" verwaltet wird, aber ich war mir nicht sicher, wie es funktionieren würde, also werde ich es mit anderem Code abgleichen. Gibt eine Instanz der Konfiguration zurück, indem build ()
an den Builder aufgerufen wird. func_236700_a_ ()
gibt an, dass kein Tsuta generiert wird, und func_236703_a_ ()
gibt an, dass ein Bienenstock durch Übergeben eines solchen Arguments generiert wird.
Wählen Sie die entsprechende Art der Platzierung aus (siehe Klasse "Platzierung") und legen Sie sie mit "configure ()" fest.
Recommended Posts