Un item mangeable !



  • Sommaire

    Introduction

    Bonjour tout le monde ! On se retrouve aujourd'hui dans ce tutoriel pour apprendre à créer son propre Item mangeable !
    Sans plus tarder, commençons

    Pré-Requis

    Code

    Comme d'habitude pour créer un nouvel item, on le déclare dans la classe au dessus de la méthode "preInit", je vais faire ici une orange.

    public static Item orange;
    

    Tout simplement 😉

    Dans la méthode preInit cette fois, nous allons renseigner notre objet, on a le choix de le faire en Programmation Orientée Objet (Avec une classe) ou directement depuis la classe principale, je vais faire ici les deux méthodes.

    1ère méthode, Programmation orientée objet (plus complète) :

    Dans la méthode preInit, mettez ce code :

    votreItemMangeable = new ItemMangeable(faimComblée, Saturation, NourritureDesLoups).setUnlocalizedName("itemmangeable").setTextureName("votremodid:item");
    

    Alors décortiquons ce code :

    • faimComblée (int) signifie le nombre de demis-gigots, je dit bien de demis-gigots, par exemple si vous mettez 2, quand vous mangerez l'item, vous aurez 1 gigot de plus
      PS : Elle se note en nombre entier.

    • Saturation (float) représente la saturation de l'item, cela signifie que plus vous mettrez de saturation, moins les gigots descendront vite
      PS : Elle se note "X.XF"

    • NourritureDesLoups (boolean) est un argument permettant que votre item soit une nourriture que vous donniez aux loups pour qu'ils soient apprivoisés.
      PS : Elle se note "false" si non et "true" si oui

    Voilà ! Pour moi cela donne :

    orange=new Orange(4,0.3F,false).setTextureName("tuto:orange").setUnlocalizedName("orange");
    

    Une fois cela fait, créez la classe de votre Item, et faite le hériter (extends) de la classe ItemFood que vous importerez, ajoutez ensuite le constructeur (choisissez la deuxième option (int, float, boolean)), vous devriez obtenir ceci :

    package votre.package;
    
    import net.minecraft.item.ItemFood;
    
    public class VotreItem extends ItemFood
    {
        public VotreItem(int p_i45339_1_, float p_i45339_2_, boolean p_i45339_3_) {
            super(p_i45339_1_, p_i45339_2_, p_i45339_3_);
            // TODO Auto-generated constructor stub
        }
    }
    

    Modifier les p_i4... etc par :

    • gigot pour le int
    • saturation pour le float
    • et wolf pour le boolean
      Ce qui doit donner :
    public VotreItem(int gigot, float saturation, boolean wolf) {
        super(gigot, saturation, wolf);
    }
    

    Voilà votre classe est crée, vous pouvez maintenant ajouter l'item dans un onglet créatif, pour que ce soit plus simple, je vous donne le code 😉 (Mettez le en dessous du constructeur super())

    this.setCreativeTab(CreativeTabs.tabFood);
    

    N'oubliez pas d'importer CreativeTabs 😉
    Voilà c'est fini pour cette méthode !

    2° Méthode : Directement depuis la classe principale (moins complète) :

    Dans la méthode preInit, mettez ce code :

    votreItem = new ItemFood(faimComblée, Saturation, NourritureDesLoups).setUnlocalizedName("itemmangeable").setTextureName("modid:item");
    

    Alors décortiquons ce code :

    • faimComblée (int) signifie le nombre de demis-gigots, je dit bien de demis-gigots, par exemple si vous mettez 2, quand vous mangerez l'item, vous aurez 1 gigot de plus
      PS : Elle se note en nombre entier.

    • Saturation (float) représente la saturation de l'item, cela signifie que plus vous mettrez de saturation, moins les gigots descendront vite
      PS : Elle se note "X.XF"

    • NourritureDesLoups (boolean) est un argument permettant que votre item soit une nourriture que vous donniez aux loups pour qu'ils soient apprivoisés.
      PS : Elle se note "false" si non et "true" si oui

    N'oubliez pas d'importer la classe ItemFood 😉

    Voilà ! Pour moi cela donne :

    orange=new ItemFood(4,0.3F,false).setTextureName("tuto:orange").setUnlocalizedName("orange");
    

    C'est fini pour cette méthode 😉 Elle est certes plus courte mais moins efficace que la méthode précédente 🙂

    Une fois une de ces deux méthodes faite, il ne manque plus qu'a enregistrer votre item 😉

    Encore une fois très très simple, placez vous dans la méthode preInit, après la définition des objets et mettez ce code :

    GameRegistry.registerItem(Item, "unlocalizedNameDeL'Item");
    

    Remplacez Item par la variable que vous avez définie au début (

    public static Item Item;
    

    )
    et "unlocalizedNameDeL'item" par la valeur du setUnlocalizedName()
    Pour moi, cela donne :

    GameRegistry.registerItem(orange, "orange");
    

    Ps : N'oubliez pas d'importer le GameRegistry si ce n'est pas déjà fait 😉

    Mettez une texture et un nom à votre item et lancez le jeu !
    Si vous ne savez pas comment faire celà, (re)regardez le tuto très bien expliqué de robin4002 😉 -> Créer un item basique

    Résultat

    Attention c'est beau ! _

    Image 1

    Image 2

    Bonus

    • Si vous voulez que l'item fasse un bruit de liquide :

    Cette fonction est disponible que si vous avez effectué la première méthode (POO)
    Vous voulez que votre item fasse le même bruit que quand on boit une potion ?

    Alors rajouter ce bout de code dans la classe (et non dans le constructeur)

        public EnumAction getItemUseAction(ItemStack par1ItemStack)
        {
            return EnumAction.drink;
        }
    

    N'oubliez pas d'importer les classes EnumAction et ItemStack

    • Ajouter un effet de potion :

    Vous voulez que quand on mange votre item, vous ayez un effet de potion ? Pas de souci, la fonction est disponible avec les 2 méthodes :
    Dans la définition de votre variable(

    orange = new ...
    

    ) dans le preInit, ajoutez

    .setPotionEffect(Potion.effet.id, 5, 2, 1.0F)
    

    avant le "setUnlocalizedName()"

    • Potion.effet.id correspond à l'id de l'effet de potion, pour voir les autres effets, effacez le ".effet.id" après potion et mettez un point, une liste va s'afficher
    • 30 correspond a la durée de l'effet
    • 2 correspond à l'intensité de l'éffet
    • 1.0F Chance d'obtenir l'effet (1.0F = 100%, 0.5F = 50% etc ...)

    Crédits

    Rédaction :

    Tutoriel basé sur l'ancien tutoriel de MrCupCakeMonster


  • Administrateurs

    Je déplace le tutoriel dans la section item.



  • Juste pour info, on peut utiliser ce code pour rendre n'importe quel item mangeable (merci robin 😉 ) :

    public EnumAction getItemUseAction(ItemStack stack)
    {
        return EnumAction.eat;
    }
    
    public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player)
    {
        if (player.canEat(false)) // Mettre true pour que le joueur puisse manger l'item même s'il n'a pas faim
        {
            player.setItemInUse(stack, this.getMaxItemUseDuration(stack));
        }
        return stack;
    }
    
    public int getMaxItemUseDuration(ItemStack stack)
    {
        return 32;
    }
    
    public ItemStack onEaten(ItemStack stack, World world, EntityPlayer player)
    {
        –stack.stackSize;
        player.getFoodStats().addStats(4, 2); // nombre de demi-gigots + saturation
        world.playSoundAtEntity(player, "random.burp", 0.5F, world.rand.nextFloat() * 0.1F + 0.9F);
        return stack;
    }
    


  • Je pense que le message de Squix (avec l'aide de robin4002) pourrait être mis dans les bonus du tutoriel 🙂



  • Personnellement sa me met une erreur sur potion.effet.id quand je change par potion.damageBoost je ne sais pas ce qui se passe



  • potion.effet.id = ID de la potion, tu peux le récupérer en mettant ceci :

    Potion.damageBoost.getId()
    

    Potion.damageBoost.getId() retourne l'ID du damageBoost 😉



  • Possibilité d'ajouter plusieurs effets ?


  • Administrateurs

    Oui, reprend la fonction onFoodEat et modifier les valeurs par ce que tu veux.



  • Je ne sais pas de fonction onFoodEat



  • essai ceci par exemple :

    public ItemStack onEaten(ItemStack stack, World world, EntityPlayer player)
    {
    –stack.stackSize;
    player.addPotionEffect(new PotionEffect(Potion.moveSlowdown.getId(), 200, 0, true));
    player.addPotionEffect(new PotionEffect(Potion.damageBoost.getId(), 200, 0, true));
    return stack;
    }
    

  • Administrateurs

    Il faut l'ajouter :

    protected void onFoodEaten(ItemStack stack, World world, EntityPlayer player)
    {
    if (!world.isRemote)
    {
    player.addPotionEffect(new PotionEffect(id de la potion, durée en seconde * 20, amplifier));
    player.addPotionEffect(new PotionEffect(deuxième id de la potion, durée en seconde * 20, amplifier));
    }
    }
    


  • Fonctionne très bien merci à vous !!!!


    Bizarre, je met la durée a 500 mais sa ne dure que 25s, il y a egalement le bruit qui ne s'active pas des le debut que l'on commence a manger.



  • Moi y a quand même quelque chose que je ne comprends pas avec forge (désolé du HS mais ca ne durera qu un message) pourquoi doit on mettre la condition du world. isRemote car là on dit si il n est pas en multi donc en solo alors il aura ses effets si il la mange mais quel intérêt quand on sera en multi ?



  • @'Julot10085':

    Moi y a quand même quelque chose que je ne comprends pas avec forge (désolé du HS mais ca ne durera qu un message) pourquoi doit on mettre la condition du world. isRemote car là on dit si il n est pas en multi donc en solo alors il aura ses effets si il la mange mais quel intérêt quand on sera en multi ?

    De toute facon mon mod est destinée a un serveur multijoueur …

    Sinon problème regler pour le son mais par pour le temps de l'effet.



  • @'Julot10085':

    Moi y a quand même quelque chose que je ne comprends pas avec forge (désolé du HS mais ca ne durera qu un message) pourquoi doit on mettre la condition du world. isRemote car là on dit si il n est pas en multi donc en solo alors il aura ses effets si il la mange mais quel intérêt quand on sera en multi ?

    Voici la réponse de robin sur l'explication de "if (!world.isRemote)" :
    @robin4002:

    world.isRemote -> monde client, il est sensé faire que le rendu, si tu fais des autres actions ça cause de problème de mauvaise valeur en client
    !world.isRemote -> monde serveur, tout le reste.


  • Administrateurs

    Je t'ai mit : durée en seconde * 20
    Car le temps est exprimé en tick, il faut le multiplier par 20 si tu veux des secondes.

    @'Julot10085':

    Moi y a quand même quelque chose que je ne comprends pas avec forge (désolé du HS mais ca ne durera qu un message) pourquoi doit on mettre la condition du world. isRemote car là on dit si il n est pas en multi donc en solo alors il aura ses effets si il la mange mais quel intérêt quand on sera en multi ?

    Quand tu joue, tu as toujours deux mondes. world.isRemote, le monde de rendu et !world.isRemote, le monde qui gère le reste.
    Quand tu joue sur un serveur, le serveur dédié s'occupe de !world.isRemote et ton client de world.isRemote. Quand tu joue en solo, ton jeu fait les deux (plus exactement le serveur intégré gère !world.isRemote). C'est pour ça que jouer sur un serveur demande moins de ressource.



  • D accord et juste une dernière question :
    -Est ce que cette condition est vraiment nécessaire le jeu ne détecte pas lui même que c est du code et non du rendu ? Je veux dire si on ignore cette ligne la nouvelle fonction OnFoodEaten marchera quand même ?

    Sinon quand on cree une nouvelle methode / fonction comme ci dessus par exemple on doit toujours mettre cette condition ou on peut s en passer ? Desolé pour ces questions que j aurais pu résoudre moi même mais etant donne que je n ai pas d ordinateur dispo chez moi ….


  • Administrateurs

    Si tu ne mets pas cette ligne ça va ajouter l'effet des deux côtés, dans ce cas là ce n'est pas très grave, par contre dans le cas d'un message de tchat par exemple, il s'affichera deux fois.

    @'Julot10085':

    Sinon quand on cree une nouvelle methode / fonction comme ci dessus par exemple on doit toujours mettre cette condition ou on peut s en passer ? Desolé pour ces questions que j aurais pu résoudre moi même mais etant donne que je n ai pas d ordinateur dispo chez moi ….

    Ça dépend de ce que tu veux faire. Si c'est des méthodes qui agissent sur le rendu, non.



  • Bonjour, j'ai voulu ajouté le bruit de liquide sauf que cela ne marche pas et je ne sais pas pourquoi:

    EDIT: problème résolu



  • Bonjour ! J'ai une erreur sur cette ligne sur .setPotionEffect :

    ​fish = new ItemFish(7, 0.7F, false).setUnlocalizedName("fish").setTextureName(HSMOD.MODID + ":fish").setCreativeTab(HSMOD.HSCreativeTabs).setPotionEffect(Potion.moveSpeed.getId(), 30, 2, 1.0F);
    

    Pourtant, j'ai fais comme dit dans les commentaires et le tuto …

    EDIT : L'erreur d'eclipse est :

    ​The method setPotionEffect(String) in the type Item is not applicable for the arguments (int, int, int, float)
    

    Merci d'avance !