• Register
    • Login
    • Search
    • Recent
    • Tags
    • Popular
    • Users
    • Groups

    Solved Entité Agressive type Archer // Mauvaise précision du tir

    1.7.x
    1.7.10
    3
    10
    1351
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Folgansky
      Folgansky Correcteurs last edited by

      Bonjour les gens,

      J’ai un petit mob munis d’un fusil qui est normalement capable de canarder les gens qui passent à portée.
      Il suit bien le joueur, il tire mais là je ne dirais pas qu’il tire bien…

      Il tire surtout un peu trop haut, alors je ne sais pas si c’est l’IA des archers qui voudrait qu’ils tirent plus haut pour compenser la gravité des flèches, mais les entités qui servent de balles n’y sont pas soumises.

      Du coup le mob ne tire “passablement” bien que si on s’approche de lui.
      Voici la classe du monstre:

      package fr.powergame.modpg2.common;
      
      import net.minecraft.entity.EntityLivingBase;
      import net.minecraft.entity.IRangedAttackMob;
      import net.minecraft.entity.SharedMonsterAttributes;
      import net.minecraft.entity.ai.EntityAIArrowAttack;
      import net.minecraft.entity.ai.EntityAIAttackOnCollide;
      import net.minecraft.entity.ai.EntityAIHurtByTarget;
      import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
      import net.minecraft.entity.monster.EntityMob;
      import net.minecraft.entity.player.EntityPlayer;
      import net.minecraft.item.ItemStack;
      import net.minecraft.nbt.NBTTagCompound;
      import net.minecraft.world.World;
      
      public class EntityMobGangster3 extends EntityMob implements IRangedAttackMob
      {
           private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F);
           private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
           private static final ItemStack defaultHeldItem;
      
          public EntityMobGangster3(World world)
          {
              super(world);
              this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
              this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));
              if (world != null && !world.isRemote)
              {
                  this.setCombatTask();
              }
          }
      
          protected int getExperiencePoints(EntityPlayer p_70693_1_)
          {
              return this.experienceValue = 0;
          }
      
          public void applyEntityAttributes()
          {
              super.applyEntityAttributes();
              this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(60D);
              this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(18D);
              this.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).setBaseValue(0.5D);
              this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.3D);
          }
      
          protected void entityInit()
          {
              super.entityInit();
              this.dataWatcher.addObject(13, new Byte((byte)0));
          }
      
          public ItemStack getHeldItem()
          {
              return defaultHeldItem;
          }
      
          public boolean isAIEnabled()
          {
              return true;
          }
      
      //    protected String getHurtSound()
      //    {
      //        return "mob.skeleton.hurt";
      //    }
      //    
      //    protected String getDeathSound()
      //    {
      //        return "mob.skeleton.death";
      //    }
      
          public void setCombatTask()
          {
              this.tasks.removeTask(this.aiAttackOnCollide);
              this.tasks.removeTask(this.aiArrowAttack);
              ItemStack itemstack = this.getHeldItem();
      
              if (itemstack != null && itemstack.getItem() == ModPg2.itemSPR)
              {
                  this.tasks.addTask(4, this.aiArrowAttack);
              }
              else
              {
                  this.tasks.addTask(4, this.aiAttackOnCollide);
              }
          }
      
          @Override
          public void attackEntityWithRangedAttack(EntityLivingBase entity, float f)
          {
              EntityBulletSPR entityBulletSPR = new EntityBulletSPR(this.worldObj, this, entity, 2.0F, (float)(14 - this.worldObj.difficultySetting.getDifficultyId() * 4));
              this.worldObj.playSoundAtEntity(entity, "modPg2:thomson", 0.8F, 0.5F);
              this.worldObj.spawnEntityInWorld(entityBulletSPR);
              entityBulletSPR.setDamage((double)(f * 20.0F) + this.rand.nextGaussian() * 0.25D + (double)((float)this.worldObj.difficultySetting.getDifficultyId() * 0.11F));
          }
      
          static
          {
              defaultHeldItem = new ItemStack(ModPg2.itemSPR, 1);
          }
      
          public void readEntityFromNBT(NBTTagCompound nbt)
          {
              super.readEntityFromNBT(nbt);
              this.setCombatTask();
          }
      
          public void writeEntityToNBT(NBTTagCompound nbt)
          {
              super.writeEntityToNBT(nbt);
          }
      }
      
      1 Reply Last reply Reply Quote 0
      • SCAREX
        SCAREX last edited by

        Il faut voir ça dans la classe de l’entité car ici tout ce que l’entité fait c’est tiré la flèche mais il n’y a aucun calcul de trajectoire.

        Site web contenant mes scripts : http://SCAREXgaming.github.io

        Pas de demandes de support par MP ni par skype SVP.
        Je n'accepte sur skype que l…

        1 Reply Last reply Reply Quote 0
        • Folgansky
          Folgansky Correcteurs last edited by

          Oh, je pensais que la trajectoire était avant tout fonction de l’action du mob.

          Voici la classe de l’entité, tirée avec l’arme en main du joueur, ça tire bien droit, là où on vise quoi.

          package fr.powergame.modpg2.common;
          
          import net.minecraft.entity.Entity;
          import net.minecraft.entity.EntityLivingBase;
          import net.minecraft.entity.projectile.EntityThrowable;
          import net.minecraft.util.DamageSource;
          import net.minecraft.util.EntityDamageSourceIndirect;
          import net.minecraft.util.MathHelper;
          import net.minecraft.util.MovingObjectPosition;
          import net.minecraft.world.World;
          
          public class EntityBulletSPR extends EntityThrowable
          {
              public float strength;
              public int ticksAlive;
              private EntityLivingBase thrower;
              public Entity shootingEntity;
              private double damage = 20.0D;
          
              public EntityBulletSPR(World worldIn)
              {
                  super(worldIn);
                  strength = 20F;
                  this.setSize(0.3F, 0.3F);
                  this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, this.func_70182_d(), 1.0F);
              }
          
              public EntityBulletSPR(World worldIn, EntityLivingBase throwerIn)
              {
                  super(worldIn, throwerIn);
                  this.thrower = throwerIn;
                  strength = 20F;
                  this.setSize(0.3F, 0.3F);
                  this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, this.func_70182_d(), 1.0F);
              }
          
              public EntityBulletSPR(World worldIn, double x, double y, double p_i1778_6_)
              {
                  super(worldIn, x, y, p_i1778_6_);
                  strength = 20F;
                  this.setSize(0.3F, 0.3F);
                  this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, this.func_70182_d(), 1.0F);
              }
          
              public EntityBulletSPR(World world, EntityLivingBase shooter, EntityLivingBase target, float f0, float f1)
              {
                  super(world);
                  this.renderDistanceWeight = 10.0D;
                  this.shootingEntity = shooter;
          
                  this.posY = shooter.posY + (double)shooter.getEyeHeight() - 0.25D;
                  double d0 = target.posX - shooter.posX;
                  double d1 = target.boundingBox.minY + (double)(target.height / 3.0F) - this.posY;
                  double d2 = target.posZ - shooter.posZ;
                  double d3 = (double)MathHelper.sqrt_double(d0 * d0 + d2 * d2);
          
                  if (d3 >= 1.0E-7D)
                  {
                      float f2 = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
                      float f3 = (float)(-(Math.atan2(d1, d3) * 180.0D / Math.PI));
                      double d4 = d0 / d3;
                      double d5 = d2 / d3;
                      this.setLocationAndAngles(shooter.posX + d4, this.posY, shooter.posZ + d5, f2, f3);
                      this.yOffset = 0.0F;
                      float f4 = (float)d3 * 0.2F;
                      this.setThrowableHeading(d0, d1 + (double)f4, d2, f0, f1);
                  }
              }
          
              public void setArrowHeading(double d, double d1, double d2, float spread, float speed)
              {
                  spread /= 2F;
                  float f2 = MathHelper.sqrt_double(d * d + d1 * d1 + d2 * d2);
                  d /= f2;
                  d1 /= f2;
                  d2 /= f2;
                  d *= speed;
                  d1 *= speed;
                  d2 *= speed;
                  d += rand.nextGaussian() * spread * speed * 0.005D ;
                  d1 += rand.nextGaussian() * spread * speed * 0.005D ;
                  d2 += rand.nextGaussian() * spread * speed * 0.005D ;
                  this.motionX *= d;
                  this.motionY *= d1;
                  this.motionZ *= d2;
                  float f3 = MathHelper.sqrt_double(d * d + d2 * d2);
                  prevRotationYaw = rotationYaw = (float) ((Math.atan2(d, d2) * 180D) / 3.1415927410125732D);
                  prevRotationPitch = rotationPitch = (float) ((Math.atan2(d1, f3) * 180D) / 3.1415927410125732D);    
              }
          
              public void setDamage(double p_70239_1_)
              {
                  this.damage = p_70239_1_;
              }
          
              public double getDamage()
              {
                  return this.damage;
              }
          
              @Override
              protected void onImpact(MovingObjectPosition mop)
              {
                  DamageSource spr = new EntityDamageSourceIndirect("SPR", this, this.thrower).setProjectile();
                  if(mop.entityHit != null)
                  {
                      mop.entityHit.attackEntityFrom(spr, (float) (mop.entityHit instanceof EntityLivingBase ? this.damage : this.damage));
                      setDead();
                  }
                  else
                  {
                      setDead();
                  }
              }
          
              public void onUpdate()
              {
                  if(ticksAlive++>200)
                  {
                      setDead();
                  }
                  super.onUpdate();
              }
          
              protected float getGravityVelocity()
              {
                  return 0.0F;
              }
          }
          
          1 Reply Last reply Reply Quote 0
          • SCAREX
            SCAREX last edited by

            Normal car tu utilises surement un autre constructeur que celui de ton mob.

            Si ta balle n’est pas soumise à la gravité ce sera plus facile, dans le dernier constructeur il faudra modifier tout ce qui est trigonométrie et le refaire, je te conseille pour cela de bien identifier chaque variable pour ensuite retirer tout ce dont tu n’as pas besoin (petite aide : vu que tu n’as pas de gravité, les calculs sur l’axe Y seront allégés)

            Site web contenant mes scripts : http://SCAREXgaming.github.io

            Pas de demandes de support par MP ni par skype SVP.
            Je n'accepte sur skype que l…

            1 Reply Last reply Reply Quote 0
            • AymericRed
              AymericRed last edited by

              Il serait plus propre de tout refaire comme SCRAREX l’a dit. Mais si tu veux directement le truc en faute, c’est le 2.0F que tu mets quand tu appelles ton constructeur, argument f0 de celui ci et spread de setThrowableHeading, sachant que spread veut dire envergure selon Google traduction.

              Envoyé de mon RAINBOW LITE 4G en utilisant Tapatalk

              Si je vous ai aidé, n'oubliez pas d’être heureux, j'aiderai encore +

              AymericRed, moddeur expérimenté qui aide sur ce forum et qui peut accepter de faire un mod Forge rémunéré de temps en temps.

              Mes tutos : Table de craft, plugin NEI, plugin JEI, modifier l'overlay
              Je suis un membre apprécié et joueur, j'ai déjà obtenu 6 points de réputation.

              1 Reply Last reply Reply Quote 0
              • Folgansky
                Folgansky Correcteurs last edited by

                Le 2.0F (dans la classe du mob) je l’ai fais varier, il gère la vitesse du projectile simplement

                1 Reply Last reply Reply Quote 0
                • AymericRed
                  AymericRed last edited by

                  Ah OK autant pour moi, mais si tu montes la vitesse, il ira plus “droit” non ?

                  Envoyé de mon RAINBOW LITE 4G en utilisant Tapatalk

                  Si je vous ai aidé, n'oubliez pas d’être heureux, j'aiderai encore +

                  AymericRed, moddeur expérimenté qui aide sur ce forum et qui peut accepter de faire un mod Forge rémunéré de temps en temps.

                  Mes tutos : Table de craft, plugin NEI, plugin JEI, modifier l'overlay
                  Je suis un membre apprécié et joueur, j'ai déjà obtenu 6 points de réputation.

                  1 Reply Last reply Reply Quote 0
                  • Folgansky
                    Folgansky Correcteurs last edited by

                    C’est possible. Je sais déjà quel paramètre modifier dans la classe du projectile pour régler la précision.

                    Mon problème est plus simple que ça je pense, c’est que mon entité vise trop haut.

                    1 Reply Last reply Reply Quote 0
                    • SCAREX
                      SCAREX last edited by

                      public EntityBulletSPR(World world, EntityLivingBase shooter, EntityLivingBase target, float f0, float f1)
                      {
                      super(world);
                      this.renderDistanceWeight = 10.0D;
                      this.shootingEntity = shooter;
                      
                      this.posY = shooter.posY + (double)shooter.getEyeHeight() - 0.25D; // On positionne la flèche pour qu'elle parte de la tête du tireur
                      double d0 = target.posX - shooter.posX; // Différence sur l'axe X
                      double d1 = target.boundingBox.minY + (double)(target.height / 3.0F) - this.posY; // Différence sur l'axe Y (je suppose que le code supplémentaire permet de viser au 1/3 de la cible)
                      double d2 = target.posZ - shooter.posZ; // Différence sur l'axe Z
                      double d3 = (double)MathHelper.sqrt_double(d0 * d0 + d2 * d2); // Distance séparant les 2 entités sur l'axe X et Z (la hauteur n'est pas prise en compte)
                      
                      if (d3 >= 1.0E-7D) // Si la cible n'est pas collée au tireur
                      {
                      float f2 = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F; // Calcul de la direction sur le plan X,Z
                      float f3 = (float)(-(Math.atan2(d1, d3) * 180.0D / Math.PI)); // Calcul de la direction sur le plan X,Y
                      double d4 = d0 / d3; // distance sur l'axe X au lancement
                      double d5 = d2 / d3; // distance sur l'axe Z au lancement
                      this.setLocationAndAngles(shooter.posX + d4, this.posY, shooter.posZ + d5, f2, f3); // On place l'entité et on lui donne la direction
                      this.yOffset = 0.0F;
                      float f4 = (float)d3 * 0.2F; // Calcul de la hauteur (compensation de la gravité)
                      this.setThrowableHeading(d0, d1 + (double)f4, d2, f0, f1); // On lui donne la direction
                      }
                      }
                      

                      J’ai commenté le code, je ne suis pas sûr que tout soit juste mais ça devrait t’aider

                      Site web contenant mes scripts : http://SCAREXgaming.github.io

                      Pas de demandes de support par MP ni par skype SVP.
                      Je n'accepte sur skype que l…

                      1 Reply Last reply Reply Quote 0
                      • Folgansky
                        Folgansky Correcteurs last edited by

                        Parfait, un grand merci pour toutes ces annotations, cela m’a grandement aidé.

                        J’ai réduis le coeff du f4 et j’ai indiqué un f1 de 0.5F (la précision jouait quand même au final)

                        Du coup, ce mob est un redoutable sniper  maintenant 😃 Merci

                        1 Reply Last reply Reply Quote 0
                        • 1 / 1
                        • First post
                          Last post
                        Design by Woryk
                        Contact / Mentions Légales

                        MINECRAFT FORGE FRANCE © 2018

                        Powered by NodeBB