• Récent
  • Mots-clés
  • Populaire
  • Utilisateurs
  • Groupes
  • S'inscrire
  • Se connecter
  • S'inscrire
  • Se connecter
  • Recherche
  • Récent
  • Mots-clés
  • Populaire
  • Utilisateurs
  • Groupes

Utiliser les événements

Les events
1.7.x 1.8.x
11
39
20.9k
Charger plus de messages
  • Du plus ancien au plus récent
  • Du plus récent au plus ancien
  • Les plus votés
Répondre
  • Répondre à l'aide d'un nouveau sujet
Se connecter pour répondre
Ce sujet a été supprimé. Seuls les utilisateurs avec les droits d'administration peuvent le voir.
  • robin4002
    robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par robin4002 29 nov. 2021, 00:43 21 mars 2014, 12:44

    youtubeCe tutoriel est également disponible en vidéo.

    Sommaire

    • Introduction
    • Pré-requis
    • Code
      • Enregistrer une classe avec des événement
      • La fonction pour l’événement
      • Quelques exemples d’utilisations
    • Résultat
    • Crédits

    Introduction

    Lors du développement de la version 2.0 de buildcraft, SpaceToad a voulu ajouter du pétrole. Le problème, c’est que pour ajouter un fluide il faut modifier la classe du seau de minecraft, ce qui aurait causé une incompatibilité avec les autres mods voulant ajouter un fluide. Pour corriger ce problème, SpaceToad a eu l’idée de créer une api qui modifie les classes de minecraft, et permettrait aux mods utilisant cette api d’ajouter des fluides sans modifier les classes de minecraft. Et c’est ainsi que forge à été créé, en effet la fonctionnalité pour les seaux était la première de forge ( le 4ème commit sur github)
    Depuis, avec l’ASM un système d’événement a été mit en place, plus optimisé. Tout ça pour dire que les événements font partis des fonctionnalités les plus importe de forge, puis qu’ils permettent de faire des choses qui serait normalement impossible sans modifier les classes de minecraft.

    En revanche, les événements sont très varier, vous comprendrez qu’il n’est pas possible de tous les présenter. D’ailleurs, les possibilités des événements sont aussi très varier, on peut faire des choses vraiment très différentes avec le même événement. Dans ce tutoriel nous allons donc voir comment utiliser les événements, puis voir quelques exemples d’utilisations. Pour faire ce que vous souhaitez avec les événements, vous allez donc avoir besoin de compétence en java (ce qui est plutôt logique vu que les mods minecraft sont codés en java). Si vous avez besoin d’aide, vous pouvez toujours expliquer votre problème dans la section support pour les moddeurs. Nous verrons plus en détails certains événements dans d’autres tutoriels quand ils sont nécessaire (exemple, nous verrons l’event bone meal dans le tutoriel sur les plantes ou les arbres, l’event bucket dans le tutoriel sur les fluides, etc …).

    Pré-requis

    • Créer la base de votre mod

    Code

    Enregistrer une classe avec des événement :

    Tout d’abord il faut savoir que depuis la 1.7 les événements se distingue en deux catégories : les événements de FML (package cpw.mods.fml.common.gameevent) et les événements de Forge (package net.minecraftforge.client.event.* et net.minecraftforge.event.*).
    Il y a donc deux méthodes pour enregistrer une classe d’événements.

            FMLCommonHandler.instance().bus().register(new ClasseAvecTousVosEvent());
    

    Pour enregistrer une classe avec des événements FML et :

            MinecraftForge.EVENT_BUS.register(new ClasseAvecTousVosEvent());
    

    Pour enregistrer une classe avec des événements Forge.
    Le nom de la classe importe peu, mais pour une question d’organisation, si vous avez peu d’événement dans votre mod, faite simplement une classe EventHandler. Si vous avez beaucoup d’événement, il est sûrement de créer une classe par une catégorie (il faut donc enregistrer toutes les classes où il y a des événements avec la fonction s’y dessus). Par exemple, une classe LivingEventHandler pour tous les événements qui concerne le entité vivante, PlayerEventHandler pour tous les événements du joueur, etc …

    Le code se place dans votre classe principale, dans la fonction init. D’ailleurs il est possible d’avoir des événements Forge et FML dans la même classe, simplement en enregistrant la classe avec les deux événements.

    FMLCommonHandler.instance().bus().register(new ClasseCommunAuEventForgeEtFML());
    MinecraftForge.EVENT_BUS.register(new ClasseCommunAuEventForgeEtFML());

    Voila, il ne vous reste plu qu’à créer la classe.

    Petite astuce, les événements de Forge qui sont dans le package net.minecraftforge.client.event.* ne sont que utilisable en client, pour enregistrer la classe passé donc par les proxy ou alors utilisez :

    if(event.getSide().isClient())
    {
    MinecraftForge.EVENT_BUS.register(new EventEnSoloUniquement());
    }

    La fonction pour l’événement :

    Maintenant la classe créé et enregistré, il faut y placer les événements. Le principe est vraiment simple, il suffit de créer une fonction void, avec en argument que vous souhaitez utiliser. Sans oublier d’ajouter l’annotation @SubscribeEvent au dessus de la fonction puisque c’est elle qui permet à FML ou Forge de détecter que le void est un événement.
    Un petit exemple :

    package fr.minecraftforgefrance.tutoriel.common;
    import net.minecraftforge.event.entity.EntityJoinWorldEvent;
    import cpw.mods.fml.common.eventhandler.SubscribeEvent;
    public class EntityEventHandler
    {
    @SubscribeEvent
    public void onEntityJoin(EntityJoinWorldEvent event)
    {
    }
    }

    J’ai ici ma classe EntityEventHandler où je place tout mes événements qui concerne les entités. Comme il s’agit d’un événement de Forge, je l’ai enregistré dans la fonction init de ma classe principale avec la fonction de forge.
    Dedans, j’ai bien une fonction du type void, avec l’annotation @SubscribeEvent juste au dessus, et en argument j’ai la classe de l’événement. Le nom de la fonction n’affecte absolument pas l’effet obtenu.

    @SubscribeEvent
    public void eventDemoParMinecraftForgeFrance(EntityJoinWorldEvent event)
    {
    }

    Ce code fonctionne tout aussi bien. Mais par principe, on met comme nom de fonction quelque chose qui correspond à son effet.
    Avec un minimum d’anglais, on devine que EntityJoinWorldEvent est déclenché lorsqu’une entité rejoint le monde. Pour l’instant le code ne fait rien, puisque je n’ai rien mit dedans. Mais si j’ajoute :

            System.out.println("une entité a rejoint le monde");
    

    Dans les logs, ce message apparaîtra dès qu’une entité rejoindra le monde. Un peu plus poussé :

            System.out.println("une entité (" + event.entity.getCommandSenderName() + ") a rejoint le monde");
    

    Maintenant dans les logs, ce message apparaîtra dès qu’une entité rejoindra le monde, mais en plus son nom sera indiqué entre parenthèse.
    Vous allez dire que ça n’a aucun intérêt, puisque afficher quelque chose dans la console ne sert à rien. Et en effet, ça ne sert à rien en soit, ce code est juste là pour vous expliquez le principe. Mais vous avez sûrement remarquez que dans le deuxième code j’ai utilisé event.entity. En effet, en fonction de l’événement que vous utilisez, vous allez avoir un certains nombres d’arguments. Tapez event. et appuyez sur la touche espace, vous allez voir tous les arguments disponibles. Dans cette événement, il y a deux arguments, entity et world. Et avec ces arguments, on peut faire des choses plus poussé. Par exemple :

    @SubscribeEvent
    public void onEntityJoin(EntityJoinWorldEvent event)
    {
    if(event.entity instanceof EntityZombie)
    {
    event.setCanceled(true);
    }
    }

    Avec ce code, si l’entité qui vient de rejoindre le monde est d’instance EntityZombie (donc les zombies et tous les mobs extends EntityZombie), j’annule l’événement. Annuler un événement sert à bloquer l’action. Dans le cas de cette exemple, les zombies (et autres mobs extends EntityZombie) ne pourrons plus spawner.
    /!\ Tous les événements ne peuvent pas être annulé. Pour savoir si l’événement que vous utilisez peut être annulé ou pas, faite un ctrl + clic sur la nom de la classe pour l’ouvrir, si vous voyez l’annotation @Cancelable, il peut être annulé. Dans le cas contraire, il ne peut pas être annulé. Sinon tester juste, si vous essayer d’annuler un événement qui ne peut pas être annulé, le jeu va crasher. /!\

    Certains événement on aussi l’annotation @HasResult, qui dans certains cas à le même effet que @Cancelable, par exemple pour la plupart des événements lié à la génération, si vous faite un

                event.setResult(Event.Result.DENY);
    

    (importez la classe Event de FML), la génération va se stoper.
    Dans d’autres cas, il sert pour appliquer l’effet, par exemple pour l’événement de la houe ou de la poudre d’os, mettre :

                event.setResult(Event.Result.ALLOW);
    

    sert à user la houe / réduire la quantité de poudre d’os et à faire l’animation du clic droit.
    Pour voir si un événement à un résultat, tout comme pour savoir si il peut être annulé, faite un ctrl + clic sur la classe et regardez les annotations que l’événement a.

    Quelques conseils :
    En général le nom des variables (c’est ce qui s’affiche quand vous faite event. + ctrl + espace) est toujours claire, si vous n’arrivez pas à déterminer à quoi sert une variable dans un événement, lisez la java doc, elle est assez remplit pour les événements.
    Le nom des événements est aussi toujours très claire, mais si vous souhaitez remontez à l’endroit où est déclenché l’événement, voici une petite astuce :

    • Sélectionnez le nom de la classe de l’événement
    • Ouvrez le menu Search d’eclipse, puis cliquez sur Java…
    • Comme vous avez sélectionnez le nom de la classe avant, la case de recherche devrait être déjà pleine, lancez la recherche
    • Il y a maintenant deux possibilités, soit vous tombez sur la classe ou l’événement est déclenché, soit vous tombez dans une classe du type ForgeHook ou FMLCommonHandler
    • Dans le premier cas, vous êtes là ou l’événement est déclenché, dans le second cas il faut simplement faire une second recherche de la fonction sur laquelle vous êtes tombé.
      Remonter à l’endroit où l’événement est déclenché peut parfois aider à comprendre à quoi sert l’événement.
      Lorsque vous cherchez un événement, ouvrez bien les classes, souvent il y a plusieurs événement dans une classe.

    Voila, vous savez maintenant tout ce qu’il y a à savoir sur les événements, je peux vraiment expliquer plus puisque sinon ça va être du cas par cas. Seule vos connaissances en java et votre imagination vont permettre d’utiliser les événements. Pour ceux qui ont du mal, place aux exemples !

    Quelques exemples d’utilisations :

    Je vais montrer ici les codes que j’utilise pour mes mods et les expliquer. Au moins cela vous donnes un exemple concret, utile, contrairement à mon exemple au dessus qui ne sert qu’à désactiver le spawn d’un mob.

    Dans un de mes mods actuellement en dévelopement, j’utilise BreakEvent pour rendre mon bloc destructible que par le propriétaire du bloc :

    package fr.mcnanotech.privatizer.common;
    import net.minecraft.tileentity.TileEntity;
    import net.minecraft.util.ChatComponentText;
    import net.minecraftforge.event.world.BlockEvent;
    import cpw.mods.fml.common.eventhandler.SubscribeEvent;
    public class PrivatizerEventHandler
    {
    @SubscribeEvent
    public void onBlockDestroyed(BlockEvent.BreakEvent event)
    {
    if(event.block instanceof BlockPrivate) // Vérifie si le bloc détruit est un bloc privé
    {
    TileEntity te = event.world.getTileEntity(event.x, event.y, event.z); // Obtient le tile entité du bloc
    if(te != null && te instanceof TileEntityPrivate) // Si il n'est pas null est qu'il est d'instance TileEntityPrivate
    {
    TileEntityPrivate tePrivate = (TileEntityPrivate)te; // Je cast TileEntityPrivate à l'objet pour accéder au fonction de mon tile entity
    if(!PrivatizerHelper.canBreak(event.getPlayer().getCommandSenderName(), tePrivate.getOwner())) // (Petite fonction pour vérifie que le joueur peut détruire le bloc passant par une autre classe) dans le cas où il ne peut pas détruire le bloc, alors
    {
    event.getPlayer().addChatMessage(new ChatComponentText("You can't remove this block, the owner is : " + tePrivate.getOwner())); // envoie un message au joueur
    event.setCanceled(true); // annule l'événement, le bloc ne se casse pas.
    }
    }
    }
    }
    }

    Il s’agit d’un événement de forge, dans ma classe principale il est donc enregistré avec MinecraftForge.EVENT_BUS.register(new PrivatizerEventHandler());
    Pour les intéressé, lien du projet github : https://github.com/FFMT/Privatizer

    Un autre code qui m’a souvent été demandé :

    @SubscribeEvent
    public void onTickClient(TickEvent.ClientTickEvent event)
    {
    if(event.phase == Phase.START)
    {
    Minecraft mc = Minecraft.getMinecraft();
    GuiScreen currentScreen = mc.currentScreen;
    GuiCustomMainMenu customMenu = new GuiCustomMainMenu();
    if(currentScreen instanceof GuiMainMenu && !currentScreen.equals(customMenu))
    {
    mc.displayGuiScreen(customMenu);
    }
    }
    }
    }

    Il permet de remplacer le menu principale par son propre menu. Attention, à faire côté client seulement ! Et il s’agit d’un événement de FML, donc à enregistrer avec :

    if(event.getSide().isClient())
    {
    FMLCommonHandler.instance().bus().register(new LaClasseOuSeTrouveVotreEvent());
    }

    À propos des événements fait en client seulement, il est aussi possible d’utiliser @SideOnly :

    @SubscribeEvent
    @SideOnly(Side.CLIENT)
    public void onTooltip(ItemTooltipEvent event)
    {
    if(event.itemStack.getItem() == Items.dye && event.itemStack.getItemDamage() == 15)
    {
    event.toolTip.add("clic droit sur les plantes pour les faire pousser");
    }
    else if(event.itemStack.getItem() == Item.getItemFromBlock(Blocks.obsidian))
    {
    if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))
    {
    event.toolTip.add("Bloc très résistant aux exposions");
    event.toolTip.add("Résistance : 2000");
    }
    else
    {
    event.toolTip.add("Maintenir shift gauche pour plus d'information");
    }
    }
    }

    Même si je mets cette fonction dans un, événement enregistré en client et en serveur, le jeu ne crachera pas avec un NoClassDefFound : org.lwjgl.input.Keyboard puisqu’en serveur il ne lira pas ce code. Ce code permet d’afficher du texte en dessous de d’un item / bloc lorsqu’on passe la souris dessus. L’astuce du “Maintenir shift gauche pour plus d’information” peut être très utile si vous beaucoup de ligne d’information.
    Item.getItemFromBlock(objet du bloc) est un fonction très importante qui sert à chaque fois que avez besoin de comparer un bloc avec un item.

    Résultat

    Voir le commit sur github
    Le commit sur github montre clairement où ont été placés les fichiers, ainsi que ce qui a été ajouté et retiré dans le fichier.

    Crédits

    Rédaction :

    • robin4002

    Correction :

    • FireDreft

    Creative Commons
    Ce tutoriel de Minecraft Forge France est mis à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International

    retourRetour vers le sommaire des tutoriels

    1 réponse Dernière réponse Répondre Citer 0
    • Ama
      Ama dernière édition par 18 avr. 2014, 23:00

      Une petite question, comment faire ceci:

      :::

      @SubscribeEvent
      @SideOnly(Side.CLIENT)
      public void onTooltip(ItemTooltipEvent event)
      {
      if(event.itemStack.getItem() == Items.dye && event.itemStack.getItemDamage() == 15)
      {
      event.toolTip.add("clic droit sur les plantes pour les faire pousser");
      }
      else if(event.itemStack.getItem() == Item.getItemFromBlock(Blocks.obsidian))
      {
      if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))
      {
      event.toolTip.add("Bloc très résistant aux exposions");
      event.toolTip.add("Résistance : 2000");
      }
      else
      {
      event.toolTip.add("Maintenir shift gauche pour plus d'information");
      }
      }
      }

      :::

      En 1.6.4 ?

      Si je t'ai filé un coup de main n'oublie pas le + / -
      Par contre évite les demandes d'aides en MP, tu sera sympa'

      La JavaDoc c'est comme le PQ, ça sert à ce démerder tous seul. -Victor Hugo- 2017

      Une superbe API pour animer vos super modèles CraftStudio dans Minecraft !

      1 réponse Dernière réponse Répondre Citer 0
      • robin4002
        robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par 18 avr. 2014, 23:06

        Même chose, sauf qu’il faut comparer les id.

        if(event.itemStack.itemID == Item.dye.itemID && event.itemStack.getItemDamage() == 15)
        
        1 réponse Dernière réponse Répondre Citer 0
        • Ama
          Ama dernière édition par 19 avr. 2014, 10:07

          Merci c’est bon !

          Si je t'ai filé un coup de main n'oublie pas le + / -
          Par contre évite les demandes d'aides en MP, tu sera sympa'

          La JavaDoc c'est comme le PQ, ça sert à ce démerder tous seul. -Victor Hugo- 2017

          Une superbe API pour animer vos super modèles CraftStudio dans Minecraft !

          1 réponse Dernière réponse Répondre Citer 0
          • valentinp72
            valentinp72 dernière édition par robin4002 23 juin 2018, 10:40 17 juin 2014, 19:41

            C’est possible de rendre “plus rapide” les évents ?

            Car je viens de créer un GuiMainMenu perso (et un Ingame), j’ai utilisé la méthode citée dans ton poste, mais ça donne moyen, on voit tout de même apparaître le menu “par défaut” :

            0_1529750411039_175051menu.gif

            1 réponse Dernière réponse Répondre Citer 0
            • robin4002
              robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par 17 juin 2014, 19:48

              Non, pas possible.

              1 réponse Dernière réponse Répondre Citer 0
              • utybo
                utybo dernière édition par 17 juin 2014, 21:22

                @‘robin4002’:

                Non, pas possible.

                Oh mon dieu, Robin a trouvé quelque chose d’impossible à faire avec Forge 😮

                Moddeur à la retraite et développeur de trucs en Java.

                J'aide les gens comme je peux, alors si mon message v…

                1 réponse Dernière réponse Répondre Citer 0
                • geekuko
                  geekuko dernière édition par 30 août 2014, 13:56

                  pour ma part sa marche pas ! il pige pas @SubscribeEvent donc j’ai mi à la place @SubscribeEvent ce qui enleve l’erreure mais sa marche pas jai pas l’effet

                  1 réponse Dernière réponse Répondre Citer 0
                  • robin4002
                    robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par 30 août 2014, 14:39

                    Heu ? Pas tout compris, envoie ton code. Tu code en quelle version ?

                    1 réponse Dernière réponse Répondre Citer 0
                    • sosoh
                      sosoh dernière édition par 27 nov. 2014, 19:20

                      Salut, oui c’est encore moi ^^ Je ne trouves pas d’event pour quand on drop, j’ai pour quand on pickup mais pas drop…

                      Et je voulais savoir, si cet event existe serait-il possible de faire que si c’est dropper sur un block, ici pour moi un chaudron, beh ca “l’avale” et ca ajoute une valeur a une variable, et que quand cette variable est égal a un nombre, alors ca give un item et ca reset la variable, comme ca je pourrais faire un systeme pour créer des potions! 🙂 ^^ Merci de votre aide!

                      Cordialement Sosoh

                      Developpeur d'Hogsmod, un mod implémentant le Monde d'Harry Potter dans Minecraft!

                      1 réponse Dernière réponse Répondre Citer 0
                      • Superloup10
                        Superloup10 Modérateurs dernière édition par 27 nov. 2014, 19:27

                        Regarde le code du Hopper

                        Si vous souhaitez me faire un don, il vous suffit de cliquer sur le bouton situé en dessous.

                        Je suis un membre apprécié et joueur, j'ai déjà obtenu 17 points de réputation.

                        1 réponse Dernière réponse Répondre Citer 0
                        • sosoh
                          sosoh dernière édition par 27 nov. 2014, 19:29

                          Oh, mais je crois que je suis débile! Je peux faire un GUI, mais je vais regarder quand même du coté hopper, merci.

                          Edit: Ils use des NBT tag, mais je sais pas trop comment donc je penses que je vais faire un GUI, mais si quelqu’un sait comment faire je suis ok!

                          Developpeur d'Hogsmod, un mod implémentant le Monde d'Harry Potter dans Minecraft!

                          1 réponse Dernière réponse Répondre Citer 0
                          • robin4002
                            robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par 27 nov. 2014, 19:32

                            Et sinon tu as PlayerTossItem event il me semble pour quand le joueur lâche un item (ou un truc du genre).

                            1 réponse Dernière réponse Répondre Citer 0
                            • sosoh
                              sosoh dernière édition par 27 nov. 2014, 19:33

                              Toss en anglais ça veut dire tirage au sort, donc je ne sais pas…

                              Developpeur d'Hogsmod, un mod implémentant le Monde d'Harry Potter dans Minecraft!

                              1 réponse Dernière réponse Répondre Citer 0
                              • robin4002
                                robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par robin4002 23 juin 2018, 10:35 27 nov. 2014, 20:10

                                Faut pas s’arrêter à la première traduction :

                                net.minecraftforge.event.entity.item.ItemTossEvent

                                1 réponse Dernière réponse Répondre Citer 0
                                • sosoh
                                  sosoh dernière édition par 27 nov. 2014, 20:11

                                  Ah oui, je me suis lancer dans le gui donc je verrais apres… ^^

                                  Developpeur d'Hogsmod, un mod implémentant le Monde d'Harry Potter dans Minecraft!

                                  1 réponse Dernière réponse Répondre Citer 0
                                  • mathmatboy
                                    mathmatboy dernière édition par robin4002 23 juin 2018, 10:34 8 déc. 2014, 01:08

                                    Il existe tu un event qui permet de modifier une class de minecraft, par exemple comme avec les GuiMenu

                                    @SubscribeEvent
                                    public void onTickClient(TickEvent.ClientTickEvent event)
                                    {
                                    if(event.phase == Phase.START)
                                    {
                                    Minecraft mc = Minecraft.getMinecraft();
                                    GuiScreen currentScreen = mc.currentScreen;
                                    GuiCustomMainMenu customMenu = new GuiCustomMainMenu();
                                    if(currentScreen instanceof GuiMainMenu && !currentScreen.equals(customMenu))
                                    {
                                    mc.displayGuiScreen(customMenu);
                                    }
                                    }
                                    }

                                    C’est pour modifier ma class ItemArmor afin de réduire tout les armures par Default de minecraft et aussi pour autre chose.

                                    1 réponse Dernière réponse Répondre Citer 0
                                    • robin4002
                                      robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par 8 déc. 2014, 11:44

                                      Non, il n’existe pas d’event pour ça.

                                      1 réponse Dernière réponse Répondre Citer 0
                                      • mathmatboy
                                        mathmatboy dernière édition par 8 déc. 2014, 12:49

                                        Merci ta réponse mais il existe surement un moyen chargé les armures de résistance par Default ? 
                                        Car quand je rajoute plusieurs armures et que je montre leurs résistance les armures se détruit a moitié de leurs capacité.

                                        1 réponse Dernière réponse Répondre Citer 0
                                        • robin4002
                                          robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par 8 déc. 2014, 15:52

                                          heu comment ça ?

                                          1 réponse Dernière réponse Répondre Citer 0
                                          • 1
                                          • 2
                                          • 1 / 2
                                          1 sur 39
                                          • Premier message
                                            1/39
                                            Dernier message
                                          Design by Woryk
                                          Contact / Mentions Légales

                                          MINECRAFT FORGE FRANCE © 2018

                                          Powered by NodeBB