Touche personnalisée / Besoin de Packet?


  • Correcteurs

    Salut les gens,

    J'aimerais ajouter une touche personnalisée pour permettre à mon entité de décoller. J'ai cru comprendre que le keyBinding n'était que côté client, donc l'utiliser pour agir sur une autre entité, notamment son déplacement ne serait pas possible et nécessiterait un packet, c'est ça?

    Ou alors il faudrait que je puisse savoir si le joueur est en train d'appuyer sur la touche espace, mais ça j'ai pas trouvé.



  • Dans levent KeyInputEvent, tu regardes si la touche de jump est pressée si oui tu envoies ton packet au serveur



  • Sinon mets ça dans la méthode onLivingUpdate de ton entity
    if(Keyboard.isKeyDown(Keyboard.KEY_SPACE))

    Je pense que ça peut marcher, pas sûr…


  • Correcteurs

    Parfait!

    Je ne savais pas comment récupérer la touche enfoncée. Là ça marche, je peux me passer d'une touche personnalisée et du packet.
    Merci =D



  • Oui ça marche par contre si tu mets pas de packet, ton entité va décoller, mais que sur le client, pas sur le serveur.


  • Administrateurs

    @'Plaigon':

    Sinon mets ça dans la méthode onLivingUpdate de ton entity
    if(Keyboard.isKeyDown(Keyboard.KEY_SPACE))

    Je pense que ça peut marcher, pas sûr…

    Keyboard n'existe pas côté serveur, donc ça va faire crasher le serveur.


  • Correcteurs

    C'est prise de tête les packets niveau prise en main oO
    J'ai bien passer 3h1/2 sur les deux tutos vidéos mais y'a clairement qqch que je n'ai pas compris dans la façon dont les packets sont utilisés.

    Donc, je dois faire un packet pour une touche personnalisée, de ce que j'ai compris il me faudra donc deux packets, un du client vers le serveur et inversement.
    J'aimerais qu'appuyer sur la touche fasse passer une valeur booléenne d'une entité sur true aussi longtemps que la touche personnalisée est enfoncée,pour revenir à sa valeur initiale quand la touche est relâchée. Valeur enregistrée dans un tag.

    Du coup voici mes classes (à trou je pense):

    Dans la classe Proxy:

    public static KeyBinding flyMontureKey;
    @Override
        public void registerKeyBinding()
        {
            ClientRegistry.registerKeyBinding(flyMontureKey);
        }
    
    

    Dans la classe principale:

        public static SimpleNetworkWrapper network;
    […]
    @EventHandler
    public void preInit(FMLPreInitializationEvent event)
        {    
            network = NetworkRegistry.INSTANCE.newSimpleChannel("ModPgChannel");
            network.registerMessage(PacketRequestFlyMonture.Handler.class, PacketRequestFlyMonture.class, 0, Side.SERVER);
            network.registerMessage(PacketFlyMonture.Handler.class, PacketFlyMonture.class, 1, Side.CLIENT);
    […]
    
    @EventHandler
        public void init(FMLInitializationEvent event)
        {
    […]
            proxy.registerKeyBinding();
        }
    
    

    Dans la classe PacketRequestFlyMonture:

    package fr.powergame.modpg2.common;
    
    import cpw.mods.fml.common.network.simpleimpl.IMessage;
    import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
    import cpw.mods.fml.common.network.simpleimpl.MessageContext;
    import io.netty.buffer.ByteBuf;
    
    public class PacketRequestFlyMonture implements IMessage
    {
    
        public PacketRequestFlyMonture()
        {
    
        }
    
        @Override
        public void fromBytes(ByteBuf buf)
        {
    
        }
    
        @Override
        public void toBytes(ByteBuf buf)
        {
    
        }
    
        public static class Handler implements IMessageHandler <packetrequestflymonture, packetflymonture="">{
            @Override
            public PacketFlyMonture onMessage(PacketRequestFlyMonture message, MessageContext ctx)
            {
                return null;
    //            return new PacketFlyMonture(MinecraftServer.getServer().getAllUsernames());
            }
        }
    }
    

    Dans la classe PacketFlyMonture:

    
    package fr.powergame.modpg2.common;
    
    import cpw.mods.fml.common.network.ByteBufUtils;
    import cpw.mods.fml.common.network.simpleimpl.IMessage;
    import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
    import cpw.mods.fml.common.network.simpleimpl.MessageContext;
    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    import io.netty.buffer.ByteBuf;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.nbt.NBTTagCompound;
    
    public class PacketFlyMonture implements IMessage
    {
    //    boolean flyKeyPressed;
        NBTTagCompound flyKeyPressed;
    
        public PacketFlyMonture()
        {
    
        }
    
    //    PacketFlyMonture(boolean flyKeyPressed)
    //    {
    //        this.flyKeyPressed = flyKeyPressed;
    //    }
    
        PacketFlyMonture(NBTTagCompound flyKeyPressed)
        {
            this.flyKeyPressed = flyKeyPressed;
        }
    
        @Override
        public void fromBytes(ByteBuf buf)
        {
            buf.readBoolean();
        }
    
        @Override
        public void toBytes(ByteBuf buf)
        {
    //        buf.writeBoolean(this.flyKeyPressed);
            ByteBufUtils.writeTag(buf, this.flyKeyPressed);
        }
    
        public static class Handler implements IMessageHandler <packetflymonture, imessage="">{
            @Override
            @SideOnly(Side.CLIENT)
            public IMessage onMessage(PacketFlyMonture message, MessageContext ctx)
            {
                EntityPlayer player = ctx.getServerHandler().playerEntity;
                if(player.ridingEntity != null && player.ridingEntity instanceof EntitySpeeder)
                {
    //                ((EntitySpeeder)player.ridingEntity).setFlyKeyPressed(message.flyKeyPressed);
                    ((EntitySpeeder)player.ridingEntity).getEntityData().getBoolean(message.flyKeyPressed); //erreur sur le getBoolean
                }
                return null;
            }
        }
    }
    
    

    Dans la classe TickClientHandlerEvent:

    @SubscribeEvent
        @SideOnly(Side.CLIENT)
        public void onKeyInput (InputEvent.KeyInputEvent e)
        {
            EntityPlayer player = Minecraft.getMinecraft().thePlayer;
            if(ClientProxy.flyMontureKey.getIsKeyPressed() && player.ridingEntity != null && player.ridingEntity instanceof EntitySpeeder)
            {
                ModPg2.network.sendToServer(new PacketRequestFlyMonture((player.ridingEntity).getBoolean("flyKeyPressed")));  //erreur sur le getBoolean
            }
        }   
    
    

    Dans la classe de mon entité:

    
    public void onLivingUpdate()
        {
            boolean flyKeyPressed = this.getEntityData().getBoolean("flyKeyPressed");
            if(flyKeyPressed)
            {
                this.motionY += 0.15;
                this.motionX += -Math.sin((double)((float)Math.PI / 180.0F)) * 6 * (double)this.moveForward * 0.05000000074505806D;
                this.motionZ += Math.cos((double)((float)Math.PI / 180.0F)) * 6 * (double)this.moveForward * 0.05000000074505806D;
            }
    […]
        }
    
       public void writeEntityToNBT(NBTTagCompound nbt)
       {
            super.writeEntityToNBT(nbt);
            nbt.setBoolean("flyKeyPressed", false);
        }
    
        public void readEntityFromNBT(NBTTagCompound nbt)
        {
            super.readEntityFromNBT(nbt);
            nbt.getBoolean("flyKeyPressed");
        }
    
    

    Comme j'ai d'abord essayé avec une valeur booléenne simple (ne sachant pas si il fallait que je fasse avec les tag ou non), je me suis forcément embrouillé ici aussi je pense.</packetflymonture,></packetrequestflymonture,>



  • package fr.powergame.modpg2.common;
    
    import cpw.mods.fml.common.network.ByteBufUtils;
    import cpw.mods.fml.common.network.simpleimpl.IMessage;
    import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
    import cpw.mods.fml.common.network.simpleimpl.MessageContext;
    import cpw.mods.fml.relauncher.Side;
    import cpw.mods.fml.relauncher.SideOnly;
    import io.netty.buffer.ByteBuf;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.nbt.NBTTagCompound;
    
    public class PacketFlyMonture implements IMessage
    {
    // boolean flyKeyPressed;
    NBTTagCompound flyKeyPressed; // pourquoi nbt au lieu d'une booléen ?
    
    public PacketFlyMonture()
    {
    
    }
    
    // PacketFlyMonture(boolean flyKeyPressed)
    // {
    // this.flyKeyPressed = flyKeyPressed;
    // }
    
    PacketFlyMonture(NBTTagCompound flyKeyPressed) // il manque le public
    {
    this.flyKeyPressed = flyKeyPressed;
    }
    
    @Override
    public void fromBytes(ByteBuf buf) // Ici tu lis un booléen
    {
    buf.readBoolean();
    }
    
    @Override
    public void toBytes(ByteBuf buf) // Mais ici tu écris des nbt, ça risque pas de marcher
    {
    // buf.writeBoolean(this.flyKeyPressed);
    ByteBufUtils.writeTag(buf, this.flyKeyPressed);
    }
    
    public static class Handler implements IMessageHandler <packetflymonture, imessage="">{
    @Override
    @SideOnly(Side.CLIENT)
    public IMessage onMessage(PacketFlyMonture message, MessageContext ctx)
    {
    EntityPlayer player = ctx.getServerHandler().playerEntity;
    if(player.ridingEntity != null && player.ridingEntity instanceof EntitySpeeder)
    {
    // ((EntitySpeeder)player.ridingEntity).setFlyKeyPressed(message.flyKeyPressed);
    ((EntitySpeeder)player.ridingEntity).getEntityData().getBoolean(message.flyKeyPressed); // pourquoi getBoolean s'il faut le set ?
    }
    return null;
    }
    }
    }
    ```</packetflymonture,>

  • Correcteurs

    Ouki, le public manquant c'est corrigé, le read était un oubli, par contre quand je met setBoolean ça me demande de mettre get (qui me fait une erreur de toute façon)

    Edit: Pour le choix du Nbttag c'est un peu au pif, c'était soit l'un soit l'autre… J'ai pas su faire le choix



  • booléen c'est mieux. Pour le setBoolean, il faut normalement un String qui est la clé


  • Administrateurs

    Pourquoi deux paquets ?
    Il en faut que 1.

    Lorsque la touche est pressé, tu envoies un paquet au serveur avec comme valeur true. Dans l'action du paquet tu mets du-coup la variable du mob sur la même que celle du paquet donc true.
    Lorsque la touche est lâché, tu envoies un paquet au serveur avec comme valeur false. Dans l'action du paquet c'est la même chose, mais comme cette fois tu as envoyé false ça va mettre false.

    Il faut juste une valeur booléenne, pas de tag nbt.
    Le problème maintenant c'est détecté que la touche a été lâché 😕


  • Correcteurs

    Bah à la base j'avais suivi ce conseil:
    if(Keyboard.isKeyDown(Keyboard.KEY_SPACE))

    Mais qui n'est exécuté que côté client.

    Alors faudrait que je puisse en faire un packet. (Je vire mon paquet en trop du coup)


  • Administrateurs

    Oui, donc il faut un paquet pour envoyer l'info au serveur. Mais pas 2.