[JAVA] Minecraft Modding 1.12.2

Minecraft Modding 1.12.2

Le développement de mod de Minecraft continue d'être difficile à comprendre en raison de petites différences non seulement dans la grande version mais aussi dans la petite version. Donc je ne sais pas si cela aidera les utilisateurs qui sont arrivés à cet article, mais j'espère que ce sera un indice.

Si vous voulez vérifier le code source directement, veuillez vous référer à Github.

Je prévois de créer les contenus suivants à tout moment.

J'étudie moi-même encore, donc si vous trouvez des erreurs dans l'explication, veuillez commenter.

environnement

Veuillez créer l'environnement de développement en vous référant à ici.

Créez un répertoire jp / artan / tm dans le répertoire src / main / java, et créez un `TutorialMod.java 'dans ce répertoire.

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");
    }
}

Tous les fichiers java à créer à partir de maintenant seront expliqués en fonction de src / main / java / jp / artan / tm. De plus, les données png telles que les textures et les données json seront expliquées en fonction de src / main / assets / tm.

image.png

Fonction proxy

Le proxy est un mécanisme pour déterminer si c'est le client / serveur qui a appelé le Mod et qui appelle automatiquement l'événement approprié. La raison pour laquelle ce mécanisme est nécessaire est que les informations de modèle requises pour les éléments expliqués ci-dessous ne doivent pas être exécutées sur le serveur.

Maintenant, créez le fichier suivant.

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 {
 //Je n'expliquerai pas le serveur cette fois, donc je ne décrirai rien
 //Créez et utilisez preinit etc. selon vos besoins.
}

Décrivez le traitement courant pour le client / serveur dans CommonProxy, et décrivez le traitement à effectuer uniquement par chacun dans ClientProxy et ServerProxy.

Ensuite, «ClientProxy» et «ServerProxy» sont automatiquement sélectionnés et le processus pour les appeler est décrit dans «TutorialMod.java». L'endroit où il est écrit comme note supplémentaire dans le commentaire est celui ajouté cette fois.

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"; //Postscript
    public static final String SERVER_PROXY = "jp.artan." + MODID + ".proxy.ServerProxy"; //Postscript

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

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

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

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

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

J'expliquerai en extrayant une partie.

.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;

L'annotation «SidedProxy» attachée à la variable «proxy» est importante. En spécifiant cette annotation, une instance est automatiquement générée en fonction des informations de répertoire de fichiers spécifiées de clientSide et serverSide et stockée dans une variable. ** * Le chemin spécifié à ce moment sera le chemin basé sur src / main / java **

Si vous démarrez le client et le serveur à ce stade, vous pouvez voir que chaque instance est préparée automatiquement.

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

Ajouter un item

Processus d'enregistrement des lots

Ensuite, je voudrais implémenter un élément qui n'a pas de fonction. Avant cela, nous allons créer un mécanisme pour enregistrer les éléments dans le registre gemé et le Model Loder à la fois.

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");
    }

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

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");
    }

//Ajouté ci-dessous
    @SubscribeEvent
    public void registerModels(ModelRegistryEvent event) { 
        TutorialMod.logger.info("ClientProxy.registerModels");

        ItemInit.ITEMS.forEach(f -> f.registerModel(event));
    }
//Ajouté ci-dessus
}

Les objets qui héritent de IItemRegisterEvent sont gérés collectivement par ITEMS et enregistrés un par un dans geméRegistry et ModelLoder. ** * L'événement registerModels ne doit être exécuté que sur le client. ** **

Implémentation d'article

Maintenant, je voudrais enregistrer l'élément pour le sujet principal.

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"));
    }
}

Après avoir créé TutorialItem, créez une instance avec 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"); //Postscript
}

Si vous l'exécutez avec ceci, les éléments seront enregistrés dans l'onglet «Autre» comme indiqué ci-dessous.

image.png

Paramètres de texture et de langue

En l'état, il est difficile à lire et la texture n'est pas définie, on ne peut donc pas dire qu'elle soit très utilisable. Alors, définissons la texture et la langue.

Cette fois, nous créons une instance comme new TutorialItem (" tutorial_item "), donc le nom de l'élément est tutorial_item.

models/item/tutorial_item.json


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

textures/items/tutorial_item.png [tutorial_item.png] ** * Veuillez noter que l'image ne sera pas lue correctement à moins qu'elle ne mesure 16 pixels x 16 pixels. ** **

lang/en_us.lang


# English Language File

# Items
item.tutorial_item.name=Tutorial Item

lang/ja_jp.lang


#Fichier de langue japonaise

# Items
item.tutorial_item.name=Élément du didacticiel

** * Selon la version de Forge, ʻen_us.lang, ja_jp.lang doit être spécifié comme ʻen_US.lang, ja_JP.lang. ** **

Il n'y a pas de problème s'il y a des données comme indiqué dans l'image suivante.

image.png

image.png

Ajouter un onglet de création

Les éléments et les blocs créés par moi-même constituent un certain groupe et je souhaite les enregistrer dans l'onglet Création. Cette fois, je voudrais créer un onglet tutoriel.

Je souhaite définir l'élément créé ci-dessus pour l'icône de l'onglet Création.

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);
    }

}

Assurez-vous de transmettre la chaîne transmise au constructeur CreativeTabs en minuscules. De plus, le nom spécifié ici sera la chaîne de caractères utilisée dans le paramètre de langue d'écriture.

lang/en_us.lang


# English Language File

# Tabs
itemGroup.tutorial_tab=Tutorial Tab

# Items
item.tutorial_item.name=Tutorial Item

lang/ja_jp.lang


#Fichier de langue japonaise

# Tabs
itemGroup.tutorial_tab=Onglet Tutoriel

# Items
item.tutorial_item.name=Élément du didacticiel

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(); //Postscript

    @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);
    }
}

Maintenant que vous avez créé l'onglet de création, remplacez la destination d'enregistrement de l'élément créé ci-dessus par l'onglet créé à partir de l'onglet «Autre».

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); //Changement

        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"));
    }
}

Si cela ressemble à l'image ci-dessous, c'est réussi.

image.png

Ajouter de la nourriture

J'avais l'habitude d'avoir une icône de banane, mais je ne pouvais pas la manger car celle que j'avais fabriquée plus tôt était un article non fonctionnel. Ensuite, je voudrais ajouter des articles comestibles. Aussi, pour la texture de cet article, j'utiliserai la texture de la pomme vanille.

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"));
    }
}

Les arguments du constructeur ItemFood sont les suivants. 1er argument montant Le montant de la récupération en mangeant 2ème argument saturation La quantité de récupération de satiété cachée en mangeant Le troisième argument estWolfFood: faire de la nourriture pour loup

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); //Postscript
}

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


#Fichier de langue japonaise

# Tabs
itemGroup.tutorial_tab=Onglet Tutoriel

# Items
item.tutorial_item.name=Élément du didacticiel
item.tutorial_food.name=Tutoriel alimentaire

models/item/tutorial_food.json


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

Si vous l'exécutez avec ceci, ce sera comme suit.

image.png

Ajouter une culture

Ensuite, je voudrais ajouter des cultures sur le terrain. Vous aurez besoin de trois éléments, un élément de départ, un élément de recadrage et un bloc de recadrage, pour créer un recadrage.

Processus d'enregistrement des lots

Commencez par configurer pour que les blocs puissent être enregistrés dans un lot de la même manière que le processus d'enregistrement du lot d'articles.

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) { //Postscript
        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)); //Postscript
    }
}

Création de blocs de culture et d'éléments de semence

Chaque bloc de culture et élément d'amorçage se trouve dans une instance et l'autre instance est utilisée. De plus, vous avez besoin d'une instance du bloc de recadrage lorsque vous instanciez un élément d'amorçage.

Tout d'abord, placez chaque instance dans BlockInit et ItemInit. Les noms de classe sont respectivement TutorialPlant et 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");
}

Maintenant que nous avons placé chaque instance, nous allons créer un TutorialPlant et un 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"));
    }
}

Spécifiez l'élément de départ à déposer lors de la destruction d'un bloc de culture avec getSeed Spécifiez l'élément de recadrage à déposer lors de la destruction d'un bloc de recadrage avec getCrop

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"));
    }
}

Paramètres de texture et de langue

Ensuite, définissez la langue et la texture.

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


#Fichier de langue japonaise

# Tabs
itemGroup.tutorial_tab=Onglet Tutoriel

# Items
item.tutorial_item.name=Élément du didacticiel
item.tutorial_food.name=Tutoriel alimentaire
item.tutorial_seed.name=Tutoriel espèces

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"
        }
    }
}

Dans le fichier ci-dessus, vous pouvez spécifier le fichier json qui stocke les informations de texture correspondant aux 7 étapes de croissance des cultures. Puisque seules les données de l'état initial qui n'ont pas augmenté sont décrites ci-dessous, créez 8 données json de 0 à 7.

models/block/tutorial_plant0.json


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

Les éléments de culture et les éléments de semence spécifiés dans l'installation du didacticiel doivent être abandonnés lorsqu'ils sont détruits après une croissance maximale.

image.png

À partir de la gauche, c'est un bloc lorsque la croissance est la 0ème étape, la croissance est la 3ème étape et la croissance est la 6ème étape. image.png

Recommended Posts

Minecraft Modding 1.12.2
Faire du gros pot avec le modding Minecraft
[Modding] Un concept Side important dans Minecraft
Résumé du site qui sera utile dans Minecraft Modding 1.12.2