Jump to content

How to make custom mob shoot fireballs?


MikeDark

Recommended Posts

I'm creating a mage that shoots balls of fire, however I can not do it and  need your help, please help me ...

 

My Entity Class:

 


package mike.bathicraft.mob;

import mike.bathicraft.items.GerenciadorDeItems;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
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.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityLargeFireball;
import net.minecraft.entity.projectile.EntitySmallFireball;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;

public class EntityMage extends EntityMob{

    public EntityMage(World world) {
	super(world);
	 isImmuneToFire = true;
	this.setSize(0.9F, 1.9F);
	this.tasks.addTask(0, new EntityAISwimming(this));
	this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false));
        this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
        this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 12.0F));
        this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
        this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));
}

  @Override
    protected void applyEntityAttributes()
    {
        
        super.applyEntityAttributes();
        this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(3.0D);
        this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(20.0D);
        this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.4D);
        this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(120.0D);
        
    }
  
	protected boolean isAIEnabled()
    {
        return true;
    }

	@Override
	protected boolean isValidLightLevel()
	{
		 return true;
	}

	 @Override
	 public boolean getCanSpawnHere()
	 {
		 return true;		 
	 }

	 public ItemStack getHeldItem()
	 {
	 return heldItem;
	 }

	 private static final ItemStack heldItem = new ItemStack(GerenciadorDeItems.CetroDeFogo, 1);
	 		 		  
	 protected Item getDropItem(){
			return Items.blaze_powder;
		}

		protected void dropRareDrop(int par1){
			switch (this.rand.nextInt(3)){

			case 0:
				this.dropItem(GerenciadorDeItems.CetroDeFogo, 1);
			}
		}

	    protected void playStepSound(int par1, int par2, int par3, int par4)
	        {
	           this.worldObj.playSoundAtEntity(this, null, 0.15F,  1.0F);
	        }
	}

Link to comment
Share on other sites

Show what you have tried.

 

I tried to adapt this code:

 


pprotected void attackEntity(Entity entity, float f)
    {
        if (f < 10F)
        {
            double d = entity.posX - posX;
            double d1 = entity.posZ - posZ;
            if (attackTime == 0)
            {
                EntitySnowball entitysnowball = new EntitySnowball(worldObj, this);
                double d2 = (entity.posY + (double)entity.getEyeHeight()) - 1.1000000238418579D - entitysnowball.posY;
                float f1 = MathHelper.sqrt_double(d * d + d1 * d1) * 0.2F;
                worldObj.playSoundAtEntity(this, "random.bow", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F));
                worldObj.spawnEntityInWorld(entitysnowball);
                entitysnowball.setThrowableHeading(d, d2 + (double)f1, d1, 1.6F, 12F);
                attackTime = 10;
            }
            rotationYaw = (float)((Math.atan2(d1, d) * 180D) / 3.1415927410125732D) - 90F;
            hasAttacked = true;
        }
    }

Link to comment
Share on other sites

You need an AI task to make your Entity actually do something. The snow golem for example uses EntityAIArrowAttack.

 

I used the following code, and it worked almost perfectly, the only problem is, the fireballs instead of being out of the mob are coming out of my player

 

@Override
		public void attackEntityWithRangedAttack(EntityLivingBase entity, float arg1) {

			Vec3 look = entity.getLookVec();
			EntityLargeFireball fireball2 = new EntityLargeFireball(worldObj);
			fireball2.setPosition(entity.posX + look.xCoord * 5, entity.posY + look.yCoord * 5, entity.posZ + look.zCoord * 5);
			fireball2.accelerationX = look.xCoord * 0.4;
			fireball2.accelerationY = look.yCoord * 0.4;
			fireball2.accelerationZ = look.zCoord * 0.4;
			this.worldObj.spawnEntityInWorld(fireball2);
		}

Link to comment
Share on other sites

You are using the entity being passed in as the "source" of the projectiles. But the entity you get as the parameter is the entity being attacked, not the entity that is doing the attack.

 

and how I could change to the entity that will make the attack, i tried to change some parts,however at the end, just did not work

Link to comment
Share on other sites

It is a method in your Entity. Thus

this

refers to your Entity.

 

I fix and now my body is firing fireballs, but after he started shooting for a part he did not "upgrade" and is always there to shoot, but if I get away and return back, he start shoot for one only direction, it returns with bug

 

@Override
		public void attackEntityWithRangedAttack(EntityLivingBase entity, float arg1) {

			Vec3 look = this.getLookVec();
			EntityLargeFireball var3 = new EntityLargeFireball(this.worldObj, this, 1, 1, 1);
			var3.setPosition(this.posX + look.xCoord * 1, this.posY + look.yCoord * 1, this.posZ + look.zCoord * 1);
			var3.accelerationX = look.xCoord * 0.3;
			var3.accelerationY = look.yCoord * 0.3;
			var3.accelerationZ = look.zCoord * 0.3;
	        this.worldObj.spawnEntityInWorld(var3);
		}

 

 

Link to comment
Share on other sites

Post your entire Entity class again please.

 

Entity Class:

 

package mike.bathicraft.mob;

import mike.bathicraft.items.GerenciadorDeItems;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
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.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityLargeFireball;
import net.minecraft.entity.projectile.EntitySmallFireball;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;

public class EntityMage extends EntityMob implements IRangedAttackMob{

private int explosionStrength = 1;
  private Entity targetedEntity = null;

    public EntityMage(World world) {
	super(world);
	 isImmuneToFire = true;
	this.setSize(0.9F, 1.9F);
	this.tasks.addTask(0, new EntityAISwimming(this));
	this.tasks.addTask(1, new EntityAIArrowAttack(this, 0.25F, 20, 10.0F));
        this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
        this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 12.0F));
        this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
        this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));
}
    
  @Override
    protected void applyEntityAttributes()
    {
        
        super.applyEntityAttributes();
        this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(3.0D);
        this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(20.0D);
        this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.4D);
        this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(120.0D);
        
    }
  
	protected boolean isAIEnabled()
    {
        return true;
    }

	@Override
	protected boolean isValidLightLevel()
	{
		 return true;
	}

	 @Override
	 public boolean getCanSpawnHere()
	 {
		 return true;		 
	 }

	 public ItemStack getHeldItem()
	 {
	 return heldItem;
	 }

	 private static final ItemStack heldItem = new ItemStack(GerenciadorDeItems.CetroDeFogo, 1);
	 		 		  
	 protected Item getDropItem(){
			return Items.blaze_powder;
		}

		protected void dropRareDrop(int par1){
			switch (this.rand.nextInt(3)){

			case 0:
				this.dropItem(GerenciadorDeItems.CetroDeFogo, 1);
			}
		}

	    protected void playStepSound(int par1, int par2, int par3, int par4)
	        {
	           this.worldObj.playSoundAtEntity(this, null, 0.15F,  1.0F);
	        }
	    
		@Override
		public void attackEntityWithRangedAttack(EntityLivingBase entity, float arg1) {

			Vec3 look = this.getLookVec();
			EntityLargeFireball var3 = new EntityLargeFireball(this.worldObj, this, 1, 1, 1);
			var3.setPosition(this.posX + look.xCoord * 1, this.posY + look.yCoord * 1, this.posZ + look.zCoord * 1);
			var3.accelerationX = look.xCoord * 0.3;
			var3.accelerationY = look.yCoord * 0.3;
			var3.accelerationZ = look.zCoord * 0.3;
	        this.worldObj.spawnEntityInWorld(var3);

		}
}

Link to comment
Share on other sites

This is the code from EntityBlaze I put into my own mob. It works perfectly, as I will explain below. (Hopefully accurately.)

 

    @Override
    public void attackEntityWithRangedAttack(EntityLivingBase entity, float distance) {

        double d0 = entity.posX - this.posX;
        double d1 = entity.boundingBox.minY + (double)(entity.height / 2.0F) - (this.posY + (double)(this.height / 2.0F));
        double d2 = entity.posZ - this.posZ;

 

This calculates the x,y,z DISTANCE between the projectile and the target. getLook() only gives the DIRECTION.

 

        float f1 = MathHelper.sqrt_float(distance) * 0.5F;

 

This is calculating the accuracy (randomness) of the projectile. (The square root of the total distance divided by half. So, larger distances are more accurately fired.)

 

        this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1009, (int)this.posX, (int)this.posY, (int)this.posZ, 0);
        for (int i = 0; i < 1; ++i)
        {

 

This part has a for loop because the Blaze can fire three fireballs at a time, but it's not needed in this case.

 

            EntitySmallFireball entitysmallfireball = new EntitySmallFireball(this.worldObj, this, d0 + this.rand.nextGaussian() * (double)f1, d1, d2 + this.rand.nextGaussian() * (double)f1);

 

This is the important part. This sets the x,y,z vector of the projectile, it uses the distance numbers calculated above, times a random number. (Because the Blaze fires randomly), you can take out "this.rand.nextGaussian() * (double)f1" and the projectile will always hit you dead on.

 

            entitysmallfireball.posY = this.posY + (double)(this.height / 2.0F) + 0.5D;

 

This is where the projectile starts, the 0.5 is added to half the height to place it near the mobs mouth area.

 

            this.worldObj.spawnEntityInWorld(entitysmallfireball);
        }
    }

 

Done. My class extends EntitySkeleton and nothing but this method is in it. I spawned it in, and now I have a skelington that shoots (Inaccurate) fireballs instead of arrows.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.