Mob chevauchable



  • Bonjour bonjour (enfin re).

    Alors voila, je suis toujours sur l'avancée du code et j'aimerais faire un mob "sellable" et montable, et après des recherches sur le forum je n'ai trouver qu'un sujet datant de un an qui n'a pas été résolu.

    Comme je ne demande pas un travail tout fait j'ai d'abord fait beaucoup de recherches de mon coté, sur les sites anglophones et sur les classes de bases, j'arrive déjà à monter et descendre du mob simplement mais impossible de poser une selle pour pouvoir le monter (comme un cochon).

    Je vous expose ce que j'ai compris du code et ce que j'aimerais avant celui-ci :

    • il faut se servir de "NBTTagCompound" pour stocker les différents noms de la selle (si elle est renommée à l'enclume par exemple)
    • "dataWatcher" pour la syncronisation entre le client et le serveur, mises à jour entre les deux (voir si le mob est sellé ou pas)
      - je ne veux pas créer un "extends entity horse", ni un "extends entity pig" car j'utilise un mob personnalisé et ça me posera un problème de dimension et de textures

    Dans un premier temps je cherche juste a mettre un selle simple et monter simplement comme sur un cochon, ensuite je recommencerais mes recherches quand j'aurais déjà résolu ce problème.

    Merci d'avance pour vos réponse et voici mon code :

    package fr.minecraftforgefrance.tutoriel.common;
    
    import net.minecraft.entity.EntityAgeable;
    import net.minecraft.entity.EntityLiving;
    import net.minecraft.entity.SharedMonsterAttributes;
    import net.minecraft.entity.monster.EntityMob;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.init.Items;
    import net.minecraft.item.ItemStack;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.world.World;
    
    public class EntityMobDragon extends EntityLiving{
    
    private static final String NBT_SADDLED = "Saddle";
    private static final int INDEX_SADDLED = 20;
    
    public EntityMobDragon(World world) {
    super(world);
    
    }
    
    public void applyEntityAttributes()
    {
    super.applyEntityAttributes();
    this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20D);
    this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.699999988079071D);
    }
    
    protected void entityInit()
        {
            super.entityInit();
            dataWatcher.addObject(INDEX_SADDLED, (byte) 0);
        }
    
    @Override
      public void writeEntityToNBT(NBTTagCompound nbt) {
       super.writeEntityToNBT(nbt);
       nbt.setBoolean(NBT_SADDLED, isSaddled());
    }
    
           @Override
        public void readEntityFromNBT(NBTTagCompound nbt) {
        super.readEntityFromNBT(nbt);
        setSaddled(nbt.getBoolean(NBT_SADDLED));
    }
    
    public boolean interact (EntityPlayer entityPlayer){
    ItemStack PlayerItem = entityPlayer.inventory.getCurrentItem();
    
    if (super.interact(entityPlayer)){
    if (PlayerItem.getItem() == Items.saddle) {
                        setSaddled(true);
    
                        }
    return false;
    
    }
    
    return false;
    }
    
    public boolean isSaddled() {
            return getBooleanData(INDEX_SADDLED);
        }
    
    public void setSaddled(boolean saddled) {
            setBooleanData(INDEX_SADDLED, saddled);
        }
    
    public boolean getBooleanData(int index) {
            return (dataWatcher.getWatchableObjectByte(index) & 1) != 0;
        }
    
    public void setBooleanData(int index, boolean value) {
            dataWatcher.updateObject(index, Byte.valueOf(value ? (byte) 1 : (byte) 0));
        }
    
    }
    
    

  • Correcteurs

    peut-être que je me trompe mais ton index est un int est tu lui set un boolean?



  • Eh ben écoute, j'ai essayer avec le code de la classe Entitypig en vain, alors j'ai essayer de prendre un bout de code du mod "dragon mounts" (Je précise que j'utilise et modifie ce code légalement selon les termes définis par son créateur "Barracuda") et de la modifier selon mes classes en recherchant au goutte à goutte pour ne pas écrire des choses que je ne comprenais pas, mais pour le coup le int/boolean je n'avais même pas remarquer mais il fonctionne très bien et quand je le change en int j'ai des erreurs.



  • Envoi les erreurs données



  • Ah mais c'est pas des erreurs de log c'est juste qu'on me dit : convertir ceci en int ou en boolean,  les suggestions de éclipse basiques



  • Oui, envoi les avec les lignes concernées



  • Bon ben enfait Scarex après avoir chercher encore et encore j'ai modifier mon code comme ceci
    (voici juste les lignes changées) :

    public boolean interact (EntityPlayer entityPlayer){
    ItemStack PlayerItem = entityPlayer.inventory.getCurrentItem();
    
    if (super.interact(entityPlayer))
            {
                return true;
            }
    else if (!isChild() && riddenByEntity == null && PlayerItem.getItem() == Items.saddle) {
                        setSaddled(true);
                        return true;
                    }
    
            else if (isSaddled()){
                entityPlayer.mountEntity(this);
                return true;
                }
    
            else
    return false;
    
    }
    

    Et la ça fonctionne presque !

    En fait, quand je met la selle et que je clic dessus avec un autre item, surprise : ça MARCHE… ou presque..

    Je peux mettre une selle (invisible car pas encore de texture), je peux monter dessus en tenant un autre item, mais si je clic droit sur le mob sans item dans la main, qu'il soit séllé ou pas, le jeux crash... voici le rapport d'erreur (attention ça fait mal aux yeux)

    ---- Minecraft Crash Report ----
    // Shall we play a game?
    
    Time: 14/09/15 19:24
    Description: Unexpected error
    
    java.lang.NullPointerException: Unexpected error
    at fr.minecraftforgefrance.tutoriel.common.EntityMobDragon.interact(EntityMobDragon.java:61)
    at net.minecraft.entity.EntityLiving.interactFirst(EntityLiving.java:1158)
    at net.minecraft.entity.player.EntityPlayer.interactWith(EntityPlayer.java:1267)
    at net.minecraft.client.multiplayer.PlayerControllerMP.interactWithEntitySendPacket(PlayerControllerMP.java:472)
    at net.minecraft.client.Minecraft.func_147121_ag(Minecraft.java:1514)
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:2045)
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1040)
    at net.minecraft.client.Minecraft.run(Minecraft.java:962)
    at net.minecraft.client.main.Main.main(Main.java:164)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source)
    at GradleStart.main(Unknown Source)
    
    A detailed walkthrough of the error, its code path and all known details is as follows:
    ---------------------------------------------------------------------------------------
    
    -- Head --
    Stacktrace:
    at fr.minecraftforgefrance.tutoriel.common.EntityMobDragon.interact(EntityMobDragon.java:61)
    at net.minecraft.entity.EntityLiving.interactFirst(EntityLiving.java:1158)
    at net.minecraft.entity.player.EntityPlayer.interactWith(EntityPlayer.java:1267)
    at net.minecraft.client.multiplayer.PlayerControllerMP.interactWithEntitySendPacket(PlayerControllerMP.java:472)
    at net.minecraft.client.Minecraft.func_147121_ag(Minecraft.java:1514)
    
    -- Affected level --
    Details:
    Level name: MpServer
    All players: 1 total; [EntityClientPlayerMP['Player690'/190, l='MpServer', x=-68,89, y=64,62, z=-83,42]]
    Chunk stats: MultiplayerChunkCache: 556, 556
    Level seed: 0
    Level generator: ID 00 - default, ver 1\. Features enabled: false
    Level generator options:
    Level spawn location: World: (-59,64,-100), Chunk: (at 5,4,12 in -4,-7; contains blocks -64,0,-112 to -49,255,-97), Region: (-1,-1; contains chunks -32,-32 to -1,-1, blocks -512,0,-512 to -1,255,-1)
    Level time: 676 game time, 676 day time
    Level dimension: 0
    Level storage version: 0x00000 - Unknown?
    Level weather: Rain time: 0 (now: false), thunder time: 0 (now: false)
    Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: false
    Forced entities: 61 total; [EntityItem['item.tile.gravel'/5151, l='MpServer', x=-37,19, y=39,13, z=-57,25], EntityItem['item.tile.gravel'/5152, l='MpServer', x=-36,72, y=39,13, z=-56,22], EntityCow['Cow'/57, l='MpServer', x=-139,50, y=67,00, z=-126,50], EntityCow['Cow'/58, l='MpServer', x=-140,13, y=68,00, z=-130,81], EntityCow['Cow'/60, l='MpServer', x=-140,50, y=65,00, z=-135,50], EntityCow['Cow'/61, l='MpServer', x=-146,50, y=64,00, z=-35,56], EntityCow['Cow'/62, l='MpServer', x=-145,47, y=64,00, z=-39,47], EntityCow['Cow'/63, l='MpServer', x=-145,47, y=64,00, z=-36,81], EntityCow['Cow'/64, l='MpServer', x=-143,09, y=63,00, z=-35,97], EntityCow['Cow'/70, l='MpServer', x=-146,53, y=64,00, z=-39,59], EntityCow['Cow'/72, l='MpServer', x=-144,34, y=63,00, z=-35,47], EntityCow['Cow'/73, l='MpServer', x=-146,44, y=64,00, z=-29,38], EntityPig['Pig'/74, l='MpServer', x=-122,50, y=64,00, z=-12,50], EntityPig['Pig'/75, l='MpServer', x=-123,50, y=64,00, z=-14,50], EntityPig['Pig'/76, l='MpServer', x=-126,22, y=64,00, z=-16,09], EntityPig['Pig'/77, l='MpServer', x=-129,69, y=65,00, z=-13,50], EntityPig['Pig'/94, l='MpServer', x=-77,56, y=63,00, z=-40,78], EntityPig['Pig'/95, l='MpServer', x=-79,50, y=63,00, z=-39,50], EntityPig['Pig'/96, l='MpServer', x=-83,28, y=63,00, z=-36,78], EntityPig['Pig'/97, l='MpServer', x=-84,50, y=63,00, z=-34,50], EntitySheep['Sheep'/115, l='MpServer', x=-25,53, y=68,00, z=-129,22], EntitySheep['Sheep'/116, l='MpServer', x=-27,50, y=66,00, z=-132,16], EntitySheep['Sheep'/117, l='MpServer', x=-29,50, y=66,00, z=-132,50], EntitySheep['Sheep'/118, l='MpServer', x=-30,50, y=66,00, z=-129,50], EntityPig['Pig'/127, l='MpServer', x=-22,06, y=64,00, z=-27,84], EntityPig['Pig'/128, l='MpServer', x=-19,50, y=66,00, z=-18,19], EntityPig['Pig'/129, l='MpServer', x=-17,50, y=66,00, z=-18,50], EntityPig['Pig'/130, l='MpServer', x=-13,50, y=66,00, z=-18,50], EntitySkeleton['Skeleton'/2221, l='MpServer', x=-106,72, y=42,59, z=-92,84], EntityCreeper['Creeper'/2241, l='MpServer', x=-16,50, y=15,00, z=-73,50], EntityClientPlayerMP['Player690'/190, l='MpServer', x=-68,89, y=64,62, z=-83,42], EntityBat['Bat'/263, l='MpServer', x=-8,75, y=14,10, z=-32,25], EntityBat['Bat'/265, l='MpServer', x=-15,75, y=18,10, z=-34,75], EntityMobTutoriel['Tutorial Mob'/283, l='MpServer', x=-39,38, y=34,00, z=-79,28], EntitySkeleton['Skeleton'/284, l='MpServer', x=-38,44, y=33,00, z=-81,06], EntityCreeper['Creeper'/294, l='MpServer', x=-16,50, y=13,00, z=-65,50], EntityMobDragon['entity.mobDragon.name'/5416, l='MpServer', x=-70,07, y=63,00, z=-85,18], EntityItem['item.tile.mushroom'/5422, l='MpServer', x=-76,06, y=65,13, z=-119,53], EntityItem['item.tile.gravel'/2432, l='MpServer', x=-37,22, y=39,13, z=-57,78], EntityCreeper['Creeper'/418, l='MpServer', x=-57,91, y=50,00, z=-34,50], EntityCreeper['Creeper'/419, l='MpServer', x=-59,50, y=50,00, z=-27,50], EntityZombie['Zombie'/488, l='MpServer', x=0,50, y=27,00, z=-104,50], EntityZombie['Zombie'/5615, l='MpServer', x=-14,50, y=19,00, z=-57,50], EntityZombie['Zombie'/5629, l='MpServer', x=-132,50, y=21,00, z=-48,50], EntityZombie['Zombie'/516, l='MpServer', x=-29,50, y=30,00, z=-45,03], EntityBat['Bat'/555, l='MpServer', x=3,90, y=18,87, z=-50,66], EntityBat['Bat'/556, l='MpServer', x=-5,59, y=16,10, z=-38,75], EntityBat['Bat'/558, l='MpServer', x=1,16, y=18,00, z=-47,40], EntityBat['Bat'/559, l='MpServer', x=-1,70, y=11,00, z=-32,63], EntityBat['Bat'/560, l='MpServer', x=-3,52, y=12,17, z=-31,30], EntityBat['Bat'/646, l='MpServer', x=-11,63, y=14,51, z=-24,53], EntityCreeper['Creeper'/662, l='MpServer', x=-42,47, y=50,00, z=-38,66], EntityCreeper['Creeper'/663, l='MpServer', x=-43,09, y=51,00, z=-42,53], EntityZombie['Zombie'/665, l='MpServer', x=-42,25, y=51,00, z=-42,50], EntitySkeleton['Skeleton'/5825, l='MpServer', x=-57,50, y=52,00, z=-15,50], EntitySkeleton['Skeleton'/5826, l='MpServer', x=-56,50, y=52,00, z=-16,50], EntityBat['Bat'/724, l='MpServer', x=-141,78, y=34,29, z=-145,75], EntityBat['Bat'/726, l='MpServer', x=-139,25, y=35,10, z=-143,25], EntityBat['Bat'/780, l='MpServer', x=0,65, y=14,30, z=-20,86], EntityCreeper['Creeper'/5953, l='MpServer', x=-48,50, y=52,00, z=-40,50], EntityCreeper['Creeper'/5954, l='MpServer', x=-50,50, y=52,00, z=-39,50]]
    Retry entities: 0 total; []
    Server brand: fml,forge
    Server type: Integrated singleplayer server
    Stacktrace:
    at net.minecraft.client.multiplayer.WorldClient.addWorldInfoToCrashReport(WorldClient.java:415)
    at net.minecraft.client.Minecraft.addGraphicsAndWorldToCrashReport(Minecraft.java:2567)
    at net.minecraft.client.Minecraft.run(Minecraft.java:991)
    at net.minecraft.client.main.Main.main(Main.java:164)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source)
    at GradleStart.main(Unknown Source)
    
    – System Details --
    Details:
    Minecraft Version: 1.7.10
    Operating System: Windows 7 (amd64) version 6.1
    Java Version: 1.8.0_60, Oracle Corporation
    Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
    Memory: 662957872 bytes (632 MB) / 1037959168 bytes (989 MB) up to 1037959168 bytes (989 MB)
    JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
    AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
    IntCache: cache: 1, tcache: 1, allocated: 12, tallocated: 94
    FML: MCP v9.05 FML v7.10.99.99 Minecraft Forge 10.13.4.1448 4 mods loaded, 4 mods active
    States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
    UCHIJAAAA mcp{9.05} [Minecraft Coder Pack] (minecraft.jar)
    UCHIJAAAA FML{7.10.99.99} [Forge Mod Loader] (forgeSrc-1.7.10-10.13.4.1448-1.7.10.jar)
    UCHIJAAAA Forge{10.13.4.1448} [Minecraft Forge] (forgeSrc-1.7.10-10.13.4.1448-1.7.10.jar)
    UCHIJAAAA modtutoriel{1.0.0} [Mod Tutoriel] (bin)
    GL info: ' Vendor: 'NVIDIA Corporation' Version: '4.5.0 NVIDIA 347.52' Renderer: 'GeForce 840M/PCIe/SSE2'
    Launched Version: 1.7.10
    LWJGL: 2.9.1
    OpenGL: GeForce 840M/PCIe/SSE2 GL version 4.5.0 NVIDIA 347.52, NVIDIA Corporation
    GL Caps: Using GL 1.3 multitexturing.
    Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported.
    Anisotropic filtering is supported and maximum anisotropy is 16.
    Shaders are available because OpenGL 2.1 is supported.
    
    Is Modded: Definitely; Client brand changed to 'fml,forge'
    Type: Client (map_client.txt)
    Resource Packs: []
    Current Language: English (US)
    Profiler Position: N/A (disabled)
    Vec3 Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
    Anisotropic Filtering: Off (1)
    


  • Ok c'est très normal car tu n'as pas mis de null-check dans ton code avant d'initialiser ta variable de type ItemStack. Il faut déjà vérifier si getCurrentItem() n'est pas null avant de regarder si le joueur tient une selle. Comme ceci alors :

    
    public boolean interact (EntityPlayer entityPlayer){
    
    if (super.interact(entityPlayer))
           {
               return true;
           }
    else if (entityPlayer.inventory.getCurrentItem() != null)
    {
    ItemStack PlayerItem = entityPlayer.inventory.getCurrentItem();
    if(!isChild() && riddenByEntity == null && PlayerItem.getItem() == Items.saddle)
    {
                       setSaddled(true);
                       return true;
    }
                   }
    
           else if (isSaddled()){
               entityPlayer.mountEntity(this);
               return true;
               }
    
           else
    return false;
    
    }
    
    


  • Merci Julot, bon je ne peux toujours pas monter dessus quand j'ai rien dans la main mais déjà le jeu a cesser de crash et je pense qu'en fouillant un peu je réglerais ce problème, le plus gros étant déjà régler.

    Je passe en résolu 🙂

    PS : Quand tout les problèmes auront été résolus et que j'aurais le résultat attendu je pense soumettre un tuto pour créer un mob "chevauchable" parce que j'ai chercher par petits morceaux et c'est moins évident qu'il n'y paraît en regardant les autres classes de ce type 😕



  • Essaie ça pour pouvoir monter dessus même avec rien en main

    public boolean interact (EntityPlayer entityPlayer){
    
    if (super.interact(entityPlayer))
    {
    return true;
    }
    else if (entityPlayer.inventory.getCurrentItem() != null)
    {
    ItemStack PlayerItem = entityPlayer.inventory.getCurrentItem();
    if(!isChild() && riddenByEntity == null)
    {
    if(PlayerItem.getItem() == Items.saddle)
    {
    setSaddled(true);
    return true;
    }
    else
    {
    setSaddled(true);
    return true;
    }
    }
    }
    
    else if (isSaddled()){
    entityPlayer.mountEntity(this);
    return true;
    }
    
    else
    return false;
    
    }
    
    


  • Merci Julot, mais ensuite je ne pouvais plus monter avec un item dans la main alors je donne juste le code final au cas ou quelqu'un d'autre cherche la solution, mais c'est grâce a toi que j'ai trouver la fin 😉

    public boolean interact (EntityPlayer entityPlayer){
    
    if (super.interact(entityPlayer))
            {
                return true;
            }
    else if (entityPlayer.inventory.getCurrentItem() != null){
    ItemStack PlayerItem = entityPlayer.inventory.getCurrentItem();
    
    if (!isChild() && riddenByEntity == null && PlayerItem.getItem() == Items.saddle) {
                        setSaddled(true);
                        return true;
                    } 
    else if (isSaddled()){
    entityPlayer.mountEntity(this);
            return true;
                    }
    else{
    setSaddled(true);
    return true;
    }
    }
    
            else if (isSaddled()){
                entityPlayer.mountEntity(this);
                return true;
                }
    
    return false; }
    

    Merci à tous 🙂

    edit : en fait maintenant je peux monter sans selle si j'ai un objet en main ahah



  • Ton code est mal organisé. .. En plus c est pas du tout optimisé,  si tu t étais relu, t aurais vu que t as deux fois le même else if..
    Et ton problème vient de ta condition else a la fin
    Tu sais au moins a quoi elle sert ?! Si oui tu ne l aurais pas mis …



  • Ben si je ne me trompe pas le else en gros : si non, pas d'interaction

    Sauf si je me trompe?

    Et pour le double else if, c'est pas que je ne me suis pas relu, à la base c'était un pour la condition si l'item dans la main est nul et l'autre s'il item est différent de null, je sais que c'est pas du tout optimisé mais pour le moment c'est plus un apprentissage que la volonté de créer un mod fonctionnel et de le partager.

    Edit : voici mon code finalement fonctionnel même si pas vraiment optimisé

    
    public boolean interact (EntityPlayer entityPlayer){
    
    if (super.interact(entityPlayer))
            {
                return true;
            }
    
    else if (isSaddled()){
            entityPlayer.mountEntity(this);
            return true;}
    
    else if (entityPlayer.inventory.getCurrentItem() != null){
    ItemStack PlayerItem = entityPlayer.inventory.getCurrentItem();
    
    if (!isChild() && (this.riddenByEntity == null || this.riddenByEntity == entityPlayer)&& PlayerItem.getItem() == Items.saddle) {
                        setSaddled(true);
                        return true;
                    }
    }
    
    return false; 
    }
    
    

    PS : Si tu as des critique constructives, par exemple l'optimisation de ce code Julot10085, je suis preneur car je suis encore un débutant en modding