[JAVA] Minecraft Modding 1.12.2

Minecraft Modding 1.12.2

Die Mod-Entwicklung von Minecraft ist aufgrund kleiner Unterschiede nicht nur in der großen Version, sondern auch in der kleinen Version weiterhin schwer zu verstehen. Ich weiß also nicht, ob es den Benutzern helfen wird, die zu diesem Artikel gekommen sind, aber ich hoffe, es wird ein Hinweis sein.

Wenn Sie den Quellcode direkt überprüfen möchten, lesen Sie bitte Github.

Ich plane, die folgenden Inhalte jederzeit zu erstellen.

--Proxy-Funktion

Ich selbst lerne noch. Wenn Sie also Fehler in der Erklärung finden, kommentieren Sie diese bitte.

Umgebung

Bitte erstellen Sie die Entwicklungsumgebung unter hier.

Erstellen Sie ein Verzeichnis "jp / artan / tm" im Verzeichnis "src / main / java" und erstellen Sie eine "TutorialMod.java" in diesem Verzeichnis.

src/main/java/jp/artan/tm/TutorialMod.java


package jp.artan.tm;

import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLConstructionEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import org.apache.logging.log4j.Logger;

@Mod(modid = TutorialMod.MODID, name = TutorialMod.NAME, version = TutorialMod.VERSION)
public class TutorialMod
{
    public static final String MODID = "tm";
    public static final String NAME = "Tutorial Mod";
    public static final String VERSION = "1.0";

    public static Logger logger;

    @Mod.EventHandler
    public void construct(FMLConstructionEvent event) {
    }

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        logger = event.getModLog();
        logger.info("TutorialMod.preInit");
    }

    @Mod.EventHandler
    public void init(FMLInitializationEvent event) {
        logger.info("TutorialMod.init");
    }

    @Mod.EventHandler
    public void postInit(FMLPostInitializationEvent event) {
        logger.info("TutorialMod.postInit");
    }
}

Alle Java-Dateien, die von nun an erstellt werden sollen, werden anhand von "src / main / java / jp / artan / tm" erklärt. Zusätzlich werden PNG-Daten wie Texturen und JSON-Daten basierend auf "src / main / assets / tm" erläutert.

image.png

Proxy-Funktion

Proxy ist ein Mechanismus, mit dem ermittelt wird, ob der Client / Server den Mod aufgerufen und das entsprechende Ereignis automatisch aufgerufen hat. Der Grund, warum dieser Mechanismus erforderlich ist, besteht darin, dass die für die unten erläuterten Elemente erforderlichen Modellinformationen nicht auf dem Server ausgeführt werden sollten.

Erstellen Sie nun die folgende Datei.

proxy/CommonProxy.java


package jp.artan.tm.proxy;

import jp.artan.tm.TutorialMod;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

@Mod.EventBusSubscriber(modid = TutorialMod.MODID)
public abstract class CommonProxy {
    public void preInit(FMLPreInitializationEvent event) {
        TutorialMod.logger.info("CommonProxy.preInit");
    }

    public void init(FMLInitializationEvent event) {
        TutorialMod.logger.info("CommonProxy.init");
    }

    public void postInit(FMLPostInitializationEvent event) {
        TutorialMod.logger.info("CommonProxy.postInit");
    }
}

proxy/ClientProxy.java


package jp.artan.tm.proxy;

import jp.artan.tm.TutorialMod;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

public class ClientProxy extends CommonProxy {

    @Override
    public void preInit(FMLPreInitializationEvent event) {
        super.preInit(event);
        TutorialMod.logger.info("ClientProxy.preInit");
    }
}

proxy/ServerProxy.java


package jp.artan.tm.proxy;

public class ServerProxy extends CommonProxy {
 //Ich werde den Server diesmal nicht erklären, also werde ich nichts beschreiben
 //Erstellen und verwenden Sie Preinit usw. nach Bedarf.
}

Beschreiben Sie die allgemeine Verarbeitung für den Client / Server in "CommonProxy" und die Verarbeitung, die nur von jedem in "ClientProxy" und "ServerProxy" ausgeführt werden soll.

Dann werden "ClientProxy" und "ServerProxy" automatisch ausgewählt, und der Vorgang zum Aufrufen wird in "TutorialMod.java" beschrieben. Der Ort, an dem es als zusätzliche Anmerkung im Kommentar geschrieben wird, ist derjenige, der dieses Mal hinzugefügt wurde.

TutorialMod.java


package jp.artan.tm;

import jp.artan.tm.proxy.CommonProxy;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLConstructionEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import org.apache.logging.log4j.Logger;

@Mod(modid = TutorialMod.MODID, name = TutorialMod.NAME, version = TutorialMod.VERSION)
public class TutorialMod
{
    public static final String MODID = "tm";
    public static final String NAME = "Tutorial Mod";
    public static final String VERSION = "1.0";

    public static Logger logger;

    public static final String CLIENT_PROXY = "jp.artan." + MODID + ".proxy.ClientProxy"; //Nachtrag
    public static final String SERVER_PROXY = "jp.artan." + MODID + ".proxy.ServerProxy"; //Nachtrag

    @SidedProxy(clientSide = CLIENT_PROXY, serverSide = SERVER_PROXY) //Nachtrag
    public static CommonProxy proxy; //Nachtrag

    @Mod.EventHandler
    public void construct(FMLConstructionEvent event) {
        MinecraftForge.EVENT_BUS.register(proxy); //Nachtrag
    }

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        logger = event.getModLog();
        logger.info("TutorialMod.preInit");
        proxy.preInit(event); //Nachtrag
    }

    @Mod.EventHandler
    public void init(FMLInitializationEvent event) {
        logger.info("TutorialMod.init");
        proxy.init(event); //Nachtrag
    }

    @Mod.EventHandler
    public void postInit(FMLPostInitializationEvent event) {
        logger.info("TutorialMod.postInit");
        proxy.postInit(event); //Nachtrag
    }
}

Ich werde es durch einen Auszug aus einem Teil erklären.

.java


public static final String CLIENT_PROXY = "jp.artan." + MODID + ".proxy.ClientProxy";
public static final String SERVER_PROXY = "jp.artan." + MODID + ".proxy.ServerProxy";

@SidedProxy(clientSide = CLIENT_PROXY, serverSide = SERVER_PROXY)
public static CommonProxy proxy;

Die Annotation "SidedProxy", die an die Variable "Proxy" angehängt ist, ist wichtig. Durch Angabe dieser Anmerkung wird automatisch eine Instanz basierend auf den angegebenen Dateiverzeichnisinformationen von "clientSide" und "serverSide" generiert und in einer Variablen gespeichert. ** * Der zu diesem Zeitpunkt angegebene Pfad ist der Pfad, der auf src / main / java basiert **

Wenn Sie den Client und den Server zu diesem Zeitpunkt starten, können Sie sehen, dass jede Instanz automatisch vorbereitet wird.

runClient.log


[17:25:39] [Client thread/INFO] [tm]: TutorialMod.preInit
[17:25:39] [Client thread/INFO] [tm]: CommonProxy.preInit
[17:25:39] [Client thread/INFO] [tm]: ClientProxy.preInit
[17:25:44] [Client thread/INFO] [tm]: TutorialMod.init
[17:25:44] [Client thread/INFO] [tm]: CommonProxy.init
[17:25:44] [Client thread/INFO] [tm]: TutorialMod.postInit
[17:25:44] [Client thread/INFO] [tm]: CommonProxy.postInit

runServer.log


[17:33:43] [Server thread/INFO] [tm]: TutorialMod.preInit
[17:33:43] [Server thread/INFO] [tm]: CommonProxy.preInit
[17:33:43] [Server thread/INFO] [tm]: TutorialMod.init
[17:33:43] [Server thread/INFO] [tm]: CommonProxy.init
[17:33:44] [Server thread/INFO] [tm]: TutorialMod.postInit
[17:33:44] [Server thread/INFO] [tm]: CommonProxy.postInit

Artikel hinzufügen

Batch-Registrierungsprozess

Als nächstes möchte ich ein Element implementieren, das keine Funktion hat. Zuvor werden wir einen Mechanismus zum gleichzeitigen Registrieren von Elementen in der gemé-Registrierung und im Model Loder erstellen.

event/IItemRegisterEvent.java


package jp.artan.tm.event;

import net.minecraft.item.Item;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.event.RegistryEvent;

public interface IItemRegisterEvent {

    /**
     * Register Item
     *
     * @param event
     */
    void registerItem(RegistryEvent.Register<Item> event);

    /**
     * Register Model
     *
     * @param event
     */
    void registerModel(ModelRegistryEvent event);
}

init/ItemInit.java


package jp.artan.tm.init;

import jp.artan.tm.event.IItemRegisterEvent;

import java.util.ArrayList;
import java.util.List;

public class ItemInit {
    public static final List<IItemRegisterEvent> ITEMS = new ArrayList<IItemRegisterEvent>();
}

proxy/CommonProxy.java


package jp.artan.tm.proxy;

import jp.artan.tm.TutorialMod;
import jp.artan.tm.init.ItemInit;
import net.minecraft.item.Item;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

@Mod.EventBusSubscriber(modid = TutorialMod.MODID)
public abstract class CommonProxy {
    public void preInit(FMLPreInitializationEvent event) {
        TutorialMod.logger.info("CommonProxy.preInit");
    }

    public void init(FMLInitializationEvent event) {
        TutorialMod.logger.info("CommonProxy.init");
    }

    public void postInit(FMLPostInitializationEvent event) {
        TutorialMod.logger.info("CommonProxy.postInit");
    }

//Unten hinzugefügt
    @SubscribeEvent
    public void registerItems(RegistryEvent.Register<Item> event) {
        TutorialMod.logger.info("CommonProxy.registerItems");
        ItemInit.ITEMS.forEach(f -> f.registerItem(event));
    }
//Ergänzung oben
}

proxy/ClientProxy.java


package jp.artan.tm.proxy;

import jp.artan.tm.TutorialMod;
import jp.artan.tm.init.ItemInit;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

public class ClientProxy extends CommonProxy {

    @Override
    public void preInit(FMLPreInitializationEvent event) {
        super.preInit(event);
        TutorialMod.logger.info("ClientProxy.preInit");
    }

//Unten hinzugefügt
    @SubscribeEvent
    public void registerModels(ModelRegistryEvent event) { 
        TutorialMod.logger.info("ClientProxy.registerModels");

        ItemInit.ITEMS.forEach(f -> f.registerModel(event));
    }
//Ergänzung oben
}

Objekte, die IItemRegisterEvent erben, werden gemeinsam von ITEMS verwaltet und einzeln in geméRegistry und ModelLoder registriert. ** * Das registerModels-Ereignis sollte nur auf dem Client ausgeführt werden. ** ** **

Artikelimplementierung

Jetzt möchte ich den Artikel für das Hauptthema registrieren.

item/TutorialItem.java


package jp.artan.tm.item;

import jp.artan.tm.TutorialMod;
import jp.artan.tm.event.IItemRegisterEvent;
import jp.artan.tm.init.ItemInit;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.event.RegistryEvent;

public class TutorialItem extends Item implements IItemRegisterEvent {

    private final String name;

    public TutorialItem(String name) {
        super();
        this.name = name;
        this.setUnlocalizedName(this.name);
        this.setRegistryName(TutorialMod.MODID, this.name);
        this.setCreativeTab(CreativeTabs.MISC);

        ItemInit.ITEMS.add(this);
    }

    @Override
    public void registerItem(RegistryEvent.Register<Item> event) {
        event.getRegistry().register(this);
    }

    public void registerModel(ModelRegistryEvent event) {
        ModelLoader.setCustomModelResourceLocation(this, 0,
                new ModelResourceLocation(new ResourceLocation(TutorialMod.MODID, this.name), "inventory"));
    }
}

Erstellen Sie nach dem Erstellen des TutorialItem eine Instanz mit ItemInit.

init/ItemInit.java


package jp.artan.tm.init;

import jp.artan.tm.event.IItemRegisterEvent;
import jp.artan.tm.item.TutorialItem;
import net.minecraft.item.Item;

import java.util.ArrayList;
import java.util.List;

public class ItemInit {
    public static final List<IItemRegisterEvent> ITEMS = new ArrayList<IItemRegisterEvent>();

    public static final Item TUTORIAL_ITEM = new TutorialItem("tutorial_item"); //Nachtrag
}

Wenn Sie dies damit ausführen, werden die Elemente auf der Registerkarte "Andere" registriert (siehe unten).

image.png

Textur- und Spracheinstellungen

Da es so ist, ist es schwer zu lesen und die Textur ist nicht festgelegt, so dass nicht gesagt werden kann, dass es sehr brauchbar ist. Stellen wir also die Textur und Sprache ein.

Dieses Mal erstellen wir eine Instanz wie "new TutorialItem (" tutorial_item ")", daher lautet der Name des Elements "tutorial_item".

models/item/tutorial_item.json


{
  "parent": "item/generated",
  "textures": {
    "layer0": "tm:items/tutorial_item"
  }
}

textures/items/tutorial_item.png [tutorial_item.png] ** * Bitte beachten Sie, dass das Bild nur dann korrekt gelesen wird, wenn es 16 x 16 Pixel groß ist. ** ** **

lang/en_us.lang


# English Language File

# Items
item.tutorial_item.name=Tutorial Item

lang/ja_jp.lang


#Japanische Sprachdatei

# Items
item.tutorial_item.name=Tutorial-Artikel

** * Abhängig von der Version von Forge muss "en_us.lang", "ja_jp.lang" als "en_US.lang", "ja_JP.lang" angegeben werden. ** ** **

Es gibt kein Problem, wenn Daten vorhanden sind, wie in der folgenden Abbildung dargestellt.

image.png

image.png

Registerkarte "Creative" hinzufügen

Von mir selbst erstellte Elemente und Blöcke sind eine bestimmte Gruppe, und ich möchte sie auf der Registerkarte "Creative" registrieren. Dieses Mal möchte ich einen Tutorial-Tab erstellen.

Ich möchte das oben erstellte Element für das Symbol auf der Registerkarte "Creative" festlegen.

tab/TutorialTab.java


package jp.artan.tm.tab;

import jp.artan.tm.init.ItemInit;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemStack;

public class TutorialTab extends CreativeTabs {

    public TutorialTab() {
        super("tutorial_tab");
    }

    @Override
    public ItemStack getTabIconItem() {
        return new ItemStack(ItemInit.TUTORIAL_ITEM);
    }

}

Stellen Sie sicher, dass Sie die an den CreativeTabs-Konstruktor übergebene Zeichenfolge in Kleinbuchstaben übergeben. Der hier angegebene Name ist auch die Zeichenfolge, die in der Schreibspracheneinstellung verwendet wird.

lang/en_us.lang


# English Language File

# Tabs
itemGroup.tutorial_tab=Tutorial Tab

# Items
item.tutorial_item.name=Tutorial Item

lang/ja_jp.lang


#Japanische Sprachdatei

# Tabs
itemGroup.tutorial_tab=Registerkarte Tutorial

# Items
item.tutorial_item.name=Tutorial-Artikel

TutorialMod.java


package jp.artan.tm;

import jp.artan.tm.proxy.CommonProxy;
import jp.artan.tm.tab.TutorialTab;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLConstructionEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import org.apache.logging.log4j.Logger;

@Mod(modid = TutorialMod.MODID, name = TutorialMod.NAME, version = TutorialMod.VERSION)
public class TutorialMod
{
    public static final String MODID = "tm";
    public static final String NAME = "Tutorial Mod";
    public static final String VERSION = "1.0";

    public static Logger logger;

    public static final String CLIENT_PROXY = "jp.artan." + MODID + ".proxy.ClientProxy";
    public static final String SERVER_PROXY = "jp.artan." + MODID + ".proxy.ServerProxy";

    @SidedProxy(clientSide = CLIENT_PROXY, serverSide = SERVER_PROXY)
    public static CommonProxy proxy;

    public static CreativeTabs creativeTabs = new TutorialTab(); //Nachtrag

    @Mod.EventHandler
    public void construct(FMLConstructionEvent event) {
        MinecraftForge.EVENT_BUS.register(proxy);
    }

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        logger = event.getModLog();
        logger.info("TutorialMod.preInit");
        proxy.preInit(event);
    }

    @Mod.EventHandler
    public void init(FMLInitializationEvent event) {
        logger.info("TutorialMod.init");
        proxy.init(event);
    }

    @Mod.EventHandler
    public void postInit(FMLPostInitializationEvent event) {
        logger.info("TutorialMod.postInit");
        proxy.postInit(event);
    }
}

Nachdem die Registerkarte "Creative" erstellt wurde, ändern Sie das Registrierungsziel des oben erstellten Elements in die Registerkarte, die auf der Registerkarte "Andere" erstellt wurde.

item/TutorialItem.java


package jp.artan.tm.item;

import jp.artan.tm.TutorialMod;
import jp.artan.tm.event.IItemRegisterEvent;
import jp.artan.tm.init.ItemInit;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.event.RegistryEvent;

public class TutorialItem extends Item implements IItemRegisterEvent {

    private final String name;

    public TutorialItem(String name) {
        super();
        this.name = name;
        this.setUnlocalizedName(this.name);
        this.setRegistryName(TutorialMod.MODID, this.name);
        this.setCreativeTab(TutorialMod.creativeTabs); //Veränderung

        ItemInit.ITEMS.add(this);
    }

    @Override
    public void registerItem(RegistryEvent.Register<Item> event) {
        event.getRegistry().register(this);
    }

    public void registerModel(ModelRegistryEvent event) {
        ModelLoader.setCustomModelResourceLocation(this, 0,
                new ModelResourceLocation(new ResourceLocation(TutorialMod.MODID, this.name), "inventory"));
    }
}

Wenn es wie im Bild unten aussieht, ist es erfolgreich.

image.png

Essen hinzufügen

Früher hatte ich ein Bananensymbol, aber ich konnte es nicht essen, weil das, das ich zuvor gemacht hatte, ein nicht funktionierendes Produkt war. Als nächstes möchte ich essbare Gegenstände hinzufügen. Auch für die Textur dieses Artikels werde ich die Textur des Vanilleapfels verwenden.

imte/TutorialFood.java


package jp.artan.tm.item;

import jp.artan.tm.TutorialMod;
import jp.artan.tm.event.IItemRegisterEvent;
import jp.artan.tm.init.ItemInit;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.event.RegistryEvent;

public class TutorialFood extends ItemFood implements IItemRegisterEvent {

    private final String name;

    public TutorialFood(String name, int amount, float saturation) {
        super(amount, saturation, false);
        this.name = name;
        this.setUnlocalizedName(this.name);
        this.setRegistryName(TutorialMod.MODID, this.name);
        this.setCreativeTab(TutorialMod.creativeTabs);

        ItemInit.ITEMS.add(this);
    }

    @Override
    public void registerItem(RegistryEvent.Register<Item> event) {
        event.getRegistry().register(this);
    }

    @Override
    public void registerModel(ModelRegistryEvent event) {
        ModelLoader.setCustomModelResourceLocation(this, 0,
                new ModelResourceLocation(new ResourceLocation(TutorialMod.MODID, this.name), "inventory"));
    }
}

Die Argumente des ItemFood-Konstruktors lauten wie folgt.

  1. Argument Menge Die Menge der Erholung beim Essen
  2. Argument Sättigung Das Ausmaß der Wiederherstellung des verborgenen Sättigungsgefühls beim Essen Das dritte Argument ist WolfFood, ob es ein Wolfsfutter sein soll

init/ItemInit.java


package jp.artan.tm.init;

import jp.artan.tm.event.IItemRegisterEvent;
import jp.artan.tm.item.TutorialFood;
import jp.artan.tm.item.TutorialItem;
import net.minecraft.item.Item;

import java.util.ArrayList;
import java.util.List;

public class ItemInit {
    public static final List<IItemRegisterEvent> ITEMS = new ArrayList<IItemRegisterEvent>();

    public static final Item TUTORIAL_ITEM = new TutorialItem("tutorial_item");

    public static final Item TUTORIAL_FOOD = new TutorialFood("tutorial_food", 1, 1.0F); //Nachtrag
}

lang/en_us.lang


# English Language File

# Tabs
itemGroup.tutorial_tab=Tutorial Tab

# Items
item.tutorial_item.name=Tutorial Item
item.tutorial_food.name=Tutorial Food

lang/ja_jp.lang


#Japanische Sprachdatei

# Tabs
itemGroup.tutorial_tab=Registerkarte Tutorial

# Items
item.tutorial_item.name=Tutorial-Artikel
item.tutorial_food.name=Tutorial Essen

models/item/tutorial_food.json


{
  "parent": "item/generated",
  "textures": {
    "layer0": "minecraft:items/apple"
  }
}

Wenn Sie es damit ausführen, wird es wie folgt sein.

image.png

Ernte hinzufügen

Als nächstes möchte ich Feldfrüchte hinzufügen. Sie benötigen drei Elemente, ein Saatgutelement, ein Erntegutelement und einen Ernteblock, um eine Ernte zu erstellen.

Batch-Registrierungsprozess

Richten Sie zunächst so ein, dass Blöcke auf dieselbe Weise wie bei der Stapelregistrierung von Artikeln in einem Stapel registriert werden können.

event/IBlockRegisterEvent.java


package jp.artan.tm.event;

import net.minecraft.block.Block;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.event.RegistryEvent;

public interface IBlockRegisterEvent {

    /**
     * Register Block
     *
     * @param event
     */
    void registerBlock(RegistryEvent.Register<Block> event);

    /**
     * Register Model
     *
     * @param event
     */
    void registerModel(ModelRegistryEvent event);
}

init/BlockInit.java


package jp.artan.tm.init;

import jp.artan.tm.block.TutorialPlant;
import jp.artan.tm.event.IBlockRegisterEvent;
import net.minecraft.block.BlockCrops;

import java.util.ArrayList;
import java.util.List;

public class BlockInit {
    public static final List<IBlockRegisterEvent> BLOCKS = new ArrayList<IBlockRegisterEvent>();
}

proxy/CommonProxy.java


package jp.artan.tm.proxy;

import jp.artan.tm.TutorialMod;
import jp.artan.tm.init.BlockInit;
import jp.artan.tm.init.ItemInit;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

@Mod.EventBusSubscriber(modid = TutorialMod.MODID)
public abstract class CommonProxy {
    public void preInit(FMLPreInitializationEvent event) {
        TutorialMod.logger.info("CommonProxy.preInit");
    }

    public void init(FMLInitializationEvent event) {
        TutorialMod.logger.info("CommonProxy.init");
    }

    public void postInit(FMLPostInitializationEvent event) {
        TutorialMod.logger.info("CommonProxy.postInit");
    }

    @SubscribeEvent
    public void registerItems(RegistryEvent.Register<Item> event) {
        TutorialMod.logger.info("CommonProxy.registerItems");
        ItemInit.ITEMS.forEach(f -> f.registerItem(event));
    }

    @SubscribeEvent
    public void registerBlocks(RegistryEvent.Register<Block> event) { //Nachtrag
        TutorialMod.logger.info("CommonProxy.registerBlocks");
        BlockInit.BLOCKS.forEach(f -> f.registerBlock(event));
    }
}

proxy/ClientProxy.java


package jp.artan.tm.proxy;

import jp.artan.tm.TutorialMod;
import jp.artan.tm.init.BlockInit;
import jp.artan.tm.init.ItemInit;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

public class ClientProxy extends CommonProxy {

    @Override
    public void preInit(FMLPreInitializationEvent event) {
        super.preInit(event);
        TutorialMod.logger.info("ClientProxy.preInit");
    }

    @SubscribeEvent
    public void registerModels(ModelRegistryEvent event) {
        TutorialMod.logger.info("ClientProxy.registerModels");

        ItemInit.ITEMS.forEach(f -> f.registerModel(event));
        BlockInit.BLOCKS.forEach(f -> f.registerModel(event)); //Nachtrag
    }
}

Erstellen von Ernteblöcken und Saatgutelementen

Jeder Ernteblock und jedes Startelement befindet sich in einer Instanz, und die andere Instanz wird verwendet. Außerdem benötigen Sie eine Instanz des Zuschneideblocks, wenn Sie einen Startwert instanziieren.

Platzieren Sie zunächst jede Instanz in BlockInit und ItemInit. Die Klassennamen sind TutorialPlant bzw. TutorialSeed.

init/BlockInit.java


package jp.artan.tm.init;

import jp.artan.tm.block.TutorialPlant;
import jp.artan.tm.event.IBlockRegisterEvent;
import net.minecraft.block.BlockCrops;

import java.util.ArrayList;
import java.util.List;

public class BlockInit {
    public static final List<IBlockRegisterEvent> BLOCKS = new ArrayList<IBlockRegisterEvent>();

    public static final BlockCrops TUTORIAL_PLANT = new TutorialPlant("tutorial_plant");
}

init/ItemInit.java


package jp.artan.tm.init;

import jp.artan.tm.event.IItemRegisterEvent;
import jp.artan.tm.item.TutorialFood;
import jp.artan.tm.item.TutorialItem;
import jp.artan.tm.item.TutorialSeed;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemSeeds;

import java.util.ArrayList;
import java.util.List;

public class ItemInit {
    public static final List<IItemRegisterEvent> ITEMS = new ArrayList<IItemRegisterEvent>();

    public static final Item TUTORIAL_ITEM = new TutorialItem("tutorial_item");

    public static final ItemFood TUTORIAL_FOOD = new TutorialFood("tutorial_food", 1, 1.0F);

    public static final ItemSeeds TUTORIAL_SEED = new TutorialSeed("tutorial_seed");
}

Nachdem wir jede Instanz platziert haben, erstellen wir eine TutorialPlant und eine TutorialSeed.

block/TutorialPlant.java


package jp.artan.tm.block;

import jp.artan.tm.TutorialMod;
import jp.artan.tm.event.IBlockRegisterEvent;
import jp.artan.tm.init.BlockInit;
import jp.artan.tm.init.ItemInit;
import net.minecraft.block.Block;
import net.minecraft.block.BlockCrops;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.event.RegistryEvent;

public class TutorialPlant extends BlockCrops implements IBlockRegisterEvent {
    protected final String Name;

    public TutorialPlant(String name) {
        super();
        this.Name = name;
        this.setUnlocalizedName(this.Name);
        this.setRegistryName(TutorialMod.MODID, this.Name);

        BlockInit.BLOCKS.add(this);
    }

    @Override
    public Item getSeed() {
        return ItemInit.TUTORIAL_SEED;
    }

    @Override
    public Item getCrop() {
        return ItemInit.TUTORIAL_FOOD;
    }

    @Override
    public void registerBlock(RegistryEvent.Register<Block> event) {
        event.getRegistry().register(this);
    }

    @Override
    public void registerModel(ModelRegistryEvent event) {
        ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0,
                new ModelResourceLocation(new ResourceLocation(TutorialMod.MODID, this.Name), "inventory"));
    }
}

Geben Sie den Samengegenstand an, der fallen gelassen werden soll, wenn Sie einen Ernteblock mit "getSeed" zerstören Geben Sie das Erntegut an, das fallen gelassen werden soll, wenn Sie einen Erntegutblock mit "getCrop" zerstören

item/TutorialSeed.java


package jp.artan.tm.item;

import jp.artan.tm.TutorialMod;
import jp.artan.tm.event.IItemRegisterEvent;
import jp.artan.tm.init.BlockInit;
import jp.artan.tm.init.ItemInit;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemSeeds;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.common.EnumPlantType;
import net.minecraftforge.event.RegistryEvent;

public class TutorialSeed extends ItemSeeds implements IItemRegisterEvent {

    private final String name;

    public TutorialSeed(String name) {
        super(BlockInit.TUTORIAL_PLANT, Blocks.FARMLAND);
        this.name = name;
        this.setUnlocalizedName(this.name);
        this.setRegistryName(TutorialMod.MODID, this.name);
        this.setCreativeTab(TutorialMod.creativeTabs);

        ItemInit.ITEMS.add(this);
    }

    @Override
    public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand,
                                      EnumFacing facing, float hitX, float hitY, float hitZ) {
        ItemStack stack = player.getHeldItem(hand);
        IBlockState state = worldIn.getBlockState(pos);

        if (facing == EnumFacing.UP && player.canPlayerEdit(pos.offset(facing), facing, stack)
                && state.getBlock().canSustainPlant(state, worldIn, pos, EnumFacing.UP, this)
                && worldIn.isAirBlock(pos.up())) {
            worldIn.setBlockState(pos.up(), BlockInit.TUTORIAL_PLANT.getDefaultState());
            if (player.capabilities.isCreativeMode || !worldIn.isRemote) {
                stack.shrink(1);
            }
            return EnumActionResult.SUCCESS;
        }
        return EnumActionResult.FAIL;
    }

    @Override
    public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos) {
        return EnumPlantType.Crop;
    }

    @Override
    public IBlockState getPlant(IBlockAccess world, BlockPos pos) {
        return BlockInit.TUTORIAL_PLANT.getDefaultState();
    }

    @Override
    public void registerItem(RegistryEvent.Register<Item> event) {
        event.getRegistry().register(this);
    }

    @Override
    public void registerModel(ModelRegistryEvent event) {
        ModelLoader.setCustomModelResourceLocation(this, 0,
                new ModelResourceLocation(new ResourceLocation(TutorialMod.MODID, this.name), "inventory"));
    }
}

Textur- und Spracheinstellungen

Als nächstes stellen Sie die Sprache und Textur ein.

lang/en_us.lang


# English Language File

# Tabs
itemGroup.tutorial_tab=Tutorial Tab

# Items
item.tutorial_item.name=Tutorial Item
item.tutorial_food.name=Tutorial Food
item.tutorial_seed.name=Tutorial Seed

lang/ja_jp.lang


#Japanische Sprachdatei

# Tabs
itemGroup.tutorial_tab=Registerkarte Tutorial

# Items
item.tutorial_item.name=Tutorial-Artikel
item.tutorial_food.name=Tutorial Essen
item.tutorial_seed.name=Tutorial-Arten

models/item/tutorial_seed.json


{
  "parent": "item/generated",
  "textures": {
    "layer0": "tm:items/tutorial_seed"
  }
}

models/item/tutorial_plant.json


{
  "parent": "block/cube_all",
  "textures": {
    "all": "tm:blocks/tutorial_plant"
  }
}

blockstates/tutorial_plant.json


{
    "variants": {
        "age=0": {
            "model": "tm:tutorial_plant0"
        },
        "age=1": {
            "model": "tm:tutorial_plant1"
        },
        "age=2": {
            "model": "tm:tutorial_plant2"
        },
        "age=3": {
            "model": "tm:tutorial_plant3"
        },
        "age=4": {
            "model": "tm:tutorial_plant4"
        },
        "age=5": {
            "model": "tm:tutorial_plant5"
        },
        "age=6": {
            "model": "tm:tutorial_plant6"
        },
        "age=7": {
            "model": "tm:tutorial_plant7"
        }
    }
}

In der obigen Datei können Sie die JSON-Datei angeben, in der die Texturinformationen gespeichert sind, die den 7 Phasen des Pflanzenwachstums entsprechen. Da im Folgenden nur die Daten des Anfangszustands beschrieben werden, die nicht gewachsen sind, erstellen Sie 8 JSON-Daten von 0 bis 7.

models/block/tutorial_plant0.json


{
  "parent": "block/crop",
  "textures": {
    "crop": "tm:blocks/tutorial_plant0"
  }
}

Die in der Lernpflanze angegebenen Erntegut- und Saatgutgegenstände sollten fallen gelassen werden, wenn sie nach maximalem Wachstum zerstört werden.

image.png

Von links ist es ein Block, wenn das Wachstum die 0. Stufe ist, das Wachstum die 3. Stufe ist und das Wachstum die 6. Stufe ist. image.png

Recommended Posts

Minecraft Modding 1.12.2
Mache fettes Glas mit Minecraft Modding
[Modding] Ein wichtiges Nebenkonzept in Minecraft
Site-Zusammenfassung, die beim Minecraft-Modding 1.12.2 hilfreich sein wird