Avoir un item tenu comme un arc en train de charger



  • Le nom du tutoriel était assez dur a trouver …

    Vous connaissez peut-être le mod Portal Gun ?
    En 3eme personne, le Portal Gun est tenu avec les deux bras tendus en avant, et non pas baissé.

    J'ai trouvé comment faire ça de manière permanente, et non juste lors du click droit.

    Commençons !

    Sommaire

    Prérequis :

    Savoir faire un item.

    Recommandation :

    Avoir un item avec une apparence 3D, pour un meilleur rendu en main
    /!\ Cette technique ralentit le joueur, si vous ne voulez pas de ralentissements, référez vous à la fin du tutoriel et zappez celle technique!

    • Les modifications apportées a l'Item
    • Le TickHandlerClient
    • Les modifications apportées a la classe du mod

    Les modifications apportées a l'Item

    Note : Dans ce tutoriel, je prend en compte le fait que vous avez DÉJÀ votre item.

    Méthodes a ajouter dans votre item :

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

    Cette méthode retournera l’animation quand l'Item est "inUse".
    Exemple : Avec la nourriture ou les boissons, il y a l'animation, ou l'arc lorsqu'on charge la flèche.

    C'est tout pour l'Item !

    Le TickHandlerClient

    Si vous n'avez pas de TickHandlerClient, créez une classe, puis implémentez ITickHandler

    public class TickHandlerClient implements ITickHandler {
    
    }
    

    Ensuite, importez les méthodes pré-requises par l'interface, et modifiez les comme ceci :.

    @Override
    public void tickStart(EnumSet<TickType> type, Object… tickData) {
    
    }
    
    @Override
    public void tickEnd(EnumSet<TickType> type, Object... tickData) {
    
    }
    
    @Override
    public EnumSet<TickType> ticks() {
        return EnumSet.of(TickType.PLAYER);
    }
    
    @Override
    public String getLabel() {
        return "TickHandlerClient";
    }
    

    Ensuite, ajoutez cette méthode qui sera exécutée a chaque tick de joueur :

    public void playerTick(World world, EntityPlayer player) {
    
    }
    

    Ensuite, faites en sorte qu'elle soit appelée lors du tickEnd :

    if (type.equals(EnumSet.of(TickType.PLAYER))) {
        playerTick(((EntityPlayer)tickData[0]).worldObj ,(EntityPlayer) tickData[0]);
    }
    

    Ajoutez ce code a l'intérieur de la méthode playerTick :

    ItemStack is = player.getCurrentEquippedItem();
    if ((is != null) && ((is.getItem() instanceof ItemMONITEM))) {
        if (((player != Minecraft.getMinecraft().renderViewEntity) || (Minecraft
        .getMinecraft().gameSettings.thirdPersonView != 0))) {
            if (player.getItemInUseCount() <= 0) {
                player.clearItemInUse();
                player.setItemInUse(is, Integer.MAX_VALUE);
            }
        }
    }
    

    Remplacez ceci : ItemMONITEM comme vous le voulez.

    C'est tout pour le TickHandler !

    Les modifications apportées à la classe du mod

    Enregistrez votre TickHandler de cette manière :

    Dans les variables, ajoutez cette ligne :

    public TickHandlerClient tickHandlerClient;
    

    Dans la méthode init, ajoutez ces lignes :

    this.tickHandlerClient = new TickHandlerClient();
    TickRegistry.registerTickHandler(this.tickHandlerClient, Side.CLIENT);
    

    #Sans ralentissements du joueur(Sans ralentissements du joueur)
    Dans votre classe principale, ajoutez dans une méthode du "type init" ou "type load"
    cette ligne si vous ne l'avez pas déjà:

    MinecraftForge.EVENT_BUS.register(this);
    

    Elle permet d'enregistrer votre mod en tant qu'écouteur ("Listener" en Anglais :D) des events. Pour plus d'infos, allez voir le tutoriel de robin sur l'event drop
    Ensuite, vous devez faire en sorte que la classe principale gère cet event: RenderPlayerEvent.Pre
    Pour cela, ajoutez cette méthode:

    @ForgeSubscribe
    public void preRenderPlayer(RenderPlayerEvent.Pre event)
    {
        EntityPlayer player = event.entityPlayer;
        ItemStack is = player.getCurrentEquippedItem();
        if ((is != null) && ((is.getItem() instanceof ItemYourItem)))
        {
        ModelBiped modelMain = ObfuscationReflectionHelper.getPrivateValue(RenderPlayer.class, event.renderer, 1);
        ModelBiped modelArmorChestplate = ObfuscationReflectionHelper.getPrivateValue(RenderPlayer.class, event.renderer, 2);
        ModelBiped modelArmor = ObfuscationReflectionHelper.getPrivateValue(RenderPlayer.class, event.renderer, 3);
        modelMain.aimedBow = modelArmorChestplate.aimedBow = modelArmor.aimedBow = true;
        }
    }
    

    (Changez ItemYourItem par la classe de votre objet)
    Cette méthode consiste à recevoir l'event RenderPlayerEvent.Pre qui est envoyé par RenderPlayer.class juste avant de dessiner le joueur et à "lever les bras".

    **ObfuscationReflectionHelper.getPrivateValue(RenderPlayer.class, event.renderer, nbr); **Cette méthode permet de récupérer n'importe quelle variable d'une classe même si cette dernière est brouillée. RenderPlayer.class est la classe dans laquelle il faut chercher, event.renderer est l'instance de RenderPlayer utilisée et nbr est le numéro de la variable (sa place dans le code en partant du 0 et du haut du fichier)

    Après avoir récupéré les trois ModelBiped de RenderPlayer, on leur dit de se mettre en position "d'arc chargé".
    Et c'est tout, 12 lignes pour un résultat bien sympathique 😉

    C'est fini !

    Allez in game, et admirez votre item ( En troisième personne uniquement ) !



  • trop cool, les premiers tuto que tu fait sont génial !!



  • Merci 🙂

    Je compte faire des tutos plutôt recherchés, ou assez compliqués, plutôt que des tuto assez simple / des choses que tout les mods ont :^)



  • moi je suis en train de faire un arbre mais j'ai ue un problème avec le src(toutes les modifications faitent n'aparaisse pas en jeu. Ex: je crée un bloc et il n'est pas jeu)puis ma conexion bug donc je télécharge le mcp manuellement et il ne veut pas s'installer :@
    Je RAGE !!!___
    il faut que j'arrête de raconter ma vie, moi 😐



  • 0nit, as tu oublié le GameRegistry.registerBlock(monBlock, "unlocalizedName); ?



  • Salut !
    Est-ce que cela fonctionne aussi avec un bloc ?
    Merci d'avance !



  • Non, uniquement avec les items !


  • Modérateurs

    Ajout d'une partie pour ne pas ralentir le joueur.
    Attention! Cette partie nécessite de ne pas suivre le reste du tuto!



  • Merci pour le tuto mais… J'ai un nombre astronomique d'erreurs dans mes class je n'y comprend rien j'espere que vous pourrez m'aider


  • Administrateurs

    Sachant que le tutoriel est pour la 1.6.4 et que cette partie a complétement changé en 1.7.x, c'est normal.



  • Utilise la méthode courte, elle est plus efficace, et ne contient pas d'erreurs ( Celle notée comme sans ralentissements )



  • il serait possible d'avoir une mise a jour 1.7.x ou 1.8.x


  • Administrateurs

    La partie sans ralentissement du joueur devrait fonctionner en 1.7 et surement en 1.8


  • Administrateurs

    Si quelqu'un a la solution pour la 1.8, qu'il n'hésite pas à en faire part ! Cela pourrait aider un bon grand nombre d'entre nous. 🙂



  • J'ai la solution mais que pour la 1.7



  • Bah go faire un tuto x)


  • Administrateurs

    @'SCAREX':

    J'ai la solution mais que pour la 1.7

    Moi aussi haha, mais pour la 1.8 on dirait que l'ASM est la seule solution. Robin et moi avions check le fonctionnement en 1.8 et on a pas réussi à faire bouger le boolean aimedBow


  • Correcteurs

    Coucou les gens, est-il possible de ré-expliquer pas à pas pour la 1.7(.10 pour moi) svp?

    Vu que le TickHandler est totalement différent voire n'existe plus à ce qu'on m'a dit.



  • Euh si il existe toujours


  • Administrateurs

    Non, l'interface ITickHandler n'existe plus, maintenant c'est un even.