Jump to content

[1.7.10] switching a mobs ai. [SOLVED] 100%


Recommended Posts

so im making an attackai for my mob, I want it so switch back and forth from ranged to melee. so I tried adding a distance method, but so far it hasn't gotten me any were accept a crash report.

so here is my code, im not asking for anything accept for why it doesn't work. thank you.

public void setCombatTask() {

	{
		if(this.getAttackTarget().getDistanceSqToEntity(this) > 121.0D){
		this.tasks.addTask(4, this.aiArrowAttack);
	}else{


		this.tasks.addTask(4, this.aiAttackOnCollide);
		}
	}
	}

Im serious don't look at it!!

Link to comment
Share on other sites

Please post the crash report as well.

 

However, you're also not really using the AI right. You're not supposed to keep adding tasks to the task list. Instead you should have all the tasks on the list already and you "switch" by changing the conditions that trigger in the shouldExecute() method.

 

It is important to note that the number (in your case "4") is NOT an index, but rather just a priority level. You can have multiple tasks with the same number. So when you're adding tasks in your code, your list is just getting longer and longer -- possibly that is the cause of your crash.

 

Anyway, the adding of the tasks should be something you just do once during initialization, not during every tick of the AI logic.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

well, I fixed the crash report but my bigger problem is, I don't want to make my own ai classes, and my I cant figure out how to make my entity attack on collide in the first place.

package com.OlympiansMod.entity;

import java.util.Iterator;
import java.util.List;

import com.OlympiansMod.Item.ModItems;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
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.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMoveTowardsTarget;
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.boss.BossStatus;
import net.minecraft.entity.boss.EntityDragon;
import net.minecraft.entity.boss.IBossDisplayData;
import net.minecraft.entity.monster.EntityGolem;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.monster.EntitySlime;
import net.minecraft.entity.monster.EntityWitch;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityPotion;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;

public class Zeus extends EntityGolem implements IBossDisplayData, 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 int attackTimer;
private int healthupdate;
private int attackMelee;;

public Zeus(World world) {
	super(world);
	{

		this.getNavigator().setAvoidsWater(true);
		this.isImmuneToFire = true;
		this.setHealth(this.getMaxHealth());
		this.setSize(1.1F, 2F);
		this.getNavigator().setAvoidsWater(true);
		this.tasks.addTask(1, new EntityAISwimming(this));
		this.tasks.addTask(2, new EntityAIWander(this, 0.5D));
		this.tasks.addTask(4, new EntityAIWatchClosest(this, EntityPlayer.class, 1.0F));
		this.tasks.addTask(5, new EntityAIWatchClosest(this, EntityUndead.class, 1.0F));
		this.tasks.addTask(6, new EntityAILookIdle(this));
		this.tasks.addTask(7, new EntityAIMoveTowardsTarget(this, 0.7D, 100.0F));
		this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
		this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));
		this.targetTasks.addTask(3, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, true, IMob.mobSelector));
            
		if (world != null && !world.isRemote) {
			this.setCombatTask();
		}
	}
}

public void onLivingUpdate() {
	super.onLivingUpdate();
	BossStatus.setBossStatus(this, true);

	if (this.getHealth() <= 1000) {
		--this.healthupdate;
	}

	if (this.attackTimer > 0) {

		--this.attackTimer;
	}
	if (this.attackTimer > 0)
        {
            --this.attackMelee;
        }

}

{
}

public boolean isAIEnabled() {

	return true;
}

@Override
protected void entityInit() {
	super.entityInit();
	dataWatcher.addObject(21, (byte) 0);
}

public void setAggressive(boolean par2) {
	this.getDataWatcher().updateObject(21,
			Byte.valueOf((byte) (par2 ? 1 : 0)));
}

public boolean getAggressive() {
	return this.getDataWatcher().getWatchableObjectByte(21) == 1;
}

protected void addRandomArmor() {
	super.addRandomArmor();
	this.setCurrentItemOrArmor(0, new ItemStack(ModItems.MasterBolt));
}

protected void applyEntityAttributes() {
	super.applyEntityAttributes();
	this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(70.0D);
	this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(5000.0D);
	this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.7D);

}

public void setCombatTask() {

	{

			this.tasks.addTask(4, this.aiArrowAttack);


			this.tasks.addTask(4, this.aiAttackOnCollide);
		}
	}




@Override
public boolean attackEntityAsMob(Entity entity) {
	this.attackTimer = 10;
	this.worldObj.setEntityState(this, (byte) 4);
     return entity.attackEntityFrom(DamageSource.causeMobDamage(this), (float) (7 + this.rand.nextInt(15)));
  
}
@Override
public void attackEntityWithRangedAttack(EntityLivingBase entity, float par1) {
	this.attackTimer = 10;
	this.worldObj.setEntityState(this, (byte) 4);


		this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "portal.portal", 10000.0F, 0.8F + this.rand.nextFloat() * 0.2F);
		EntityMasterBolt Bolt = new EntityMasterBolt(this.worldObj, this);
		Bolt.rotationPitch -= -20.0F;
		double d0 = entity.posX + entity.motionX - this.posX;
		double d1 = entity.posY + (double) entity.getEyeHeight() - 1.900000023841858D - this.posY;
		double d2 = entity.posZ + entity.motionZ - this.posZ;
		float f1 = MathHelper.sqrt_double(d0 * d0 + d2 * d2);

		Bolt.setThrowableHeading(d0, d1 + (double) (f1 * 0.2F), d2, 0.75F, 8.0F);
		this.worldObj.spawnEntityInWorld(Bolt);
		if (this.getHealth() <= 1500) {
			for (int i = 0; i < 10; i++) {
				this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "portal.portal", 10000.0F, 0.8F + this.rand.nextFloat() * 0.2F);
				EntityThunderBolt Bolt2 = new EntityThunderBolt(
						this.worldObj, this);
				Bolt.rotationPitch -= -20.0F;
				double d0l = entity.posX + entity.motionX - this.posX + 1;
				double d1l = entity.posY + (double) entity.getEyeHeight() - 0.900000023841858D - this.posY;
				double d2l = entity.posZ + entity.motionZ - this.posZ;
				float f1l = MathHelper.sqrt_double(d0 * d0 + d2 * d2);
				Bolt2.setThrowableHeading(d0l, d1l + (double) (f1l * 0.2F),	d2l, 0.75F, 8.0F);
				this.worldObj.spawnEntityInWorld(Bolt2);

			}

		}

	}



@SideOnly(Side.CLIENT)
public void handleHealthUpdate(byte p_70103_1_) {
	if (p_70103_1_ == 4) {
		this.attackTimer = 10;

	} else {
		super.handleHealthUpdate(p_70103_1_);
	}
}

@SideOnly(Side.CLIENT)
public int getattackTimer() {
	return this.attackTimer;

}

protected String getHurtSound() {
	return "mob.enderdragon.hit";
}


protected String getDeathSound() {
	return "mob.blaze.death";
}

protected void func_145780_a(int p_145780_1_, int p_145780_2_,
		int p_145780_3_, Block p_145780_4_) {
	this.playSound("step.cloth", 1.0F, 1.0F);
}

public void setDead() {

	for (int i = 0; i < 2; ++i) {
		worldObj.spawnParticle("lava", this.posX, this.posY, this.posZ,
				0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX, this.posY + 1, this.posZ,
				0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX, this.posY + 2, this.posZ,
				0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX, this.posY + 3, this.posZ,
				0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX, this.posY + 4, this.posZ,
				0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX, this.posY + 5, this.posZ,
				0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX, this.posY + 6, this.posZ,
				0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX + 1, this.posY + 1,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX + 1, this.posY + 2,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX + 1, this.posY + 3,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX + 1, this.posY + 4,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX + 1, this.posY + 5,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("lava", this.posX + 1, this.posY + 6,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX, this.posY, this.posZ,
				0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX, this.posY + 1,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX, this.posY + 2,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX, this.posY + 3,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX, this.posY + 4,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX, this.posY + 5,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX, this.posY + 6,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX + 1, this.posY + 1,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX + 1, this.posY + 2,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX + 1, this.posY + 3,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX + 1, this.posY + 4,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX + 1, this.posY + 5,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("explode", this.posX + 1, this.posY + 6,
				this.posZ, 50.0F, 50.0F, 50.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX, this.posY,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX, this.posY + 1,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX, this.posY + 2,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX, this.posY + 3,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX, this.posY + 4,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX, this.posY + 5,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX, this.posY + 6,
				this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX + 1,
				this.posY + 1, this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX + 1,
				this.posY + 2, this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX + 1,
				this.posY + 3, this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX + 1,
				this.posY + 4, this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX + 1,
				this.posY + 5, this.posZ, 0.0F, 0.0F, 0.0F);
		worldObj.spawnParticle("hugeexplosion", this.posX + 1,
				this.posY + 6, this.posZ, 0.0F, 0.0F, 0.0F);
	}
	if (!this.worldObj.isRemote) {
		ZeusExtended zeus = new ZeusExtended(worldObj);
		zeus.setPosition(this.posX, this.posY, this.posZ);
		this.worldObj.spawnEntityInWorld(zeus);
		this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ,
				"ambient.weather.thunder", 10000.0F,
				0.8F + this.rand.nextFloat() * 0.2F);

	}
	super.setDead();
}
}

 

after I know why it wont even attempt to attack on collide I think I will be able to fix the problem on my own.

 

thanks for the quick response.

Im serious don't look at it!!

Link to comment
Share on other sites

ok so, ive attempted to make an ai class, that requires the entity to attack on collide if the entity is collided. im sort of struggling here though, for I lack understanding of this specific concept, or in other words I would like someone to walk me through it, thanks.

 

public void updateTask()
    {
    	EntityLivingBase entitylivingbase = this.attacker.getAttackTarget();
        double d0 = this.entityHost.getDistanceSq(this.attackTarget.posX, this.attackTarget.boundingBox.minY, this.attackTarget.posZ);
        boolean flag = this.entityHost.getEntitySenses().canSee(this.attackTarget);
        if(this.attackTarget.isCollided){
        	this.attacker.attackEntityAsMob(entitylivingbase);
        	
        }
        if (flag)
        {
            ++this.field_75318_f;
        }
        else
        {
            this.field_75318_f = 0;
        }

        if (d0 <= (double)this.field_82642_h && this.field_75318_f >= 20)
        {
            this.entityHost.getNavigator().clearPathEntity();
            
        }
        else
        {
            this.entityHost.getNavigator().tryMoveToEntityLiving(this.attackTarget, this.entityMoveSpeed);
        }

        this.entityHost.getLookHelper().setLookPositionWithEntity(this.attackTarget, 30.0F, 30.0F);
        float f;

        if (--this.rangedAttackTime == 0)
        {
            if (d0 > (double)this.field_82642_h || !flag)
            {
                return;
            }

            f = MathHelper.sqrt_double(d0) / this.field_96562_i;
            float f1 = f;

            if (f < 0.1F)
            {
                f1 = 0.1F;
            }

            if (f1 > 1.0F)
            {
                f1 = 1.0F;
            }

            this.rangedAttackEntityHost.attackEntityWithRangedAttack(this.attackTarget, f1);
            this.rangedAttackTime = MathHelper.floor_float(f * (float)(this.maxRangedAttackTime - this.field_96561_g) + (float)this.field_96561_g);
        }
        else if (this.rangedAttackTime < 0)
        {
            f = MathHelper.sqrt_double(d0) / this.field_96562_i;
            this.rangedAttackTime = MathHelper.floor_float(f * (float)(this.maxRangedAttackTime - this.field_96561_g) + (float)this.field_96561_g);
        }
    }
}

 

so this is a snippet of my code, what ive done is copy and pasted the entityaiarrow attack, and added a

    if(this.attackTarget.isCollided){
        	this.attacker.attackEntityAsMob(entitylivingbase);(

im really not sure how to make it work at this point.

Im serious don't look at it!!

Link to comment
Share on other sites

Did you read my tutorial on AI that I linked above. It explains how the AI works in detail.

 

Briefly, there are two types of AI. The original AI which called a couple methods to update the state of the entity, and all the code for the AI ran there. But the newer AI is much more complex and is enabled if the isAIEnabled() method of your entity returns true. In that case, it cycles through a number of AI class instances (that you add to a list in your entity constructor) based on a priority you set. It checks if the AI should start executing, or if it is already executing it checks to see if it should continue executing. So there are methods for each of those that you override and put in the condition you want.

 

So in your case, if you want to switch between ranged and melee, your entity just needs a field to "remember" what it used in the last attack. Then you can have both types of attack in your AI list, but in the shouldExecute() method of each you would check what the last attack was and only return true if the last attack was the opposite type. The rest of the AI would just be copied from the melee and ranged attack AI.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

actually I have another question, why doesn't this work?

	public void onUpdateTasks() {
	if (this.getAttackTarget().getDistanceSqToEntity(this) > 16.0D) {
		this.tasks.addTask(4, aiArrowAttack);
		this.tasks.removeTask(aiAttackOnCollide);
	} else if (this.getAttackTarget().getDistanceSqToEntity(this) < 16.0D) {
		this.tasks.removeTask(aiArrowAttack);
		this.tasks.addTask(4, aiAttackOnCollide);

	}
}

 

it doesn't work how I want it to, and if u read the code, you can see that im trying to get the mob to remove ai tasks as soon as its a certain distance close/away from the player. thanks for your help.

Im serious don't look at it!!

Link to comment
Share on other sites

nevermind about that last idea, my game crashes from doing this to the combat tasks, and my life would be ten times easier if this would work.

 

why doesn't it work?

    public void setCombatTask()
    {
       

        if (this.getAttackTarget().getDistanceSqToEntity(this) > 16.0D)
        {
            this.tasks.addTask(4, this.aiArrowAttack);
        }
        else
        {
            this.tasks.addTask(4, this.aiAttackOnCollide);
        }
    }

 

crash report:

A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Stacktrace:
at com.OlympiansMod.entity.Zeus.setCombatTask(Zeus.java:150)
at com.OlympiansMod.entity.Zeus.<init>(Zeus.java:76)
at com.OlympiansMod.Item.ZeusSpawn.onItemRightClick(ZeusSpawn.java:18)
at net.minecraft.item.ItemStack.useItemRightClick(ItemStack.java:164)
at net.minecraft.server.management.ItemInWorldManager.tryUseItem(ItemInWorldManager.java:345)
at net.minecraft.network.NetHandlerPlayServer.processPlayerBlockPlacement(NetHandlerPlayServer.java:576)
at net.minecraft.network.play.client.C08PacketPlayerBlockPlacement.processPacket(C08PacketPlayerBlockPlacement.java:74)
at net.minecraft.network.play.client.C08PacketPlayerBlockPlacement.processPacket(C08PacketPlayerBlockPlacement.java:122)
at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:241)

-- Ticking connection --
Details:
Connection: net.minecraft.network.NetworkManager@447b1252
Stacktrace:
at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:182)
at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:726)
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:614)
at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:485)
at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:752)

-- System Details --
Details:
Minecraft Version: 1.7.10
Operating System: Windows 8.1 (amd64) version 6.3
Java Version: 1.8.0_45, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 679592152 bytes (648 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 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: 0, tcache: 0, allocated: 0, tallocated: 0
FML: MCP v9.05 FML v7.10.85.1230 Minecraft Forge 10.13.2.1230 4 mods loaded, 4 mods active
mcp{9.05} [Minecraft Coder Pack] (minecraft.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available
FML{7.10.85.1230} [Forge Mod Loader] (forgeSrc-1.7.10-10.13.2.1230.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available
Forge{10.13.2.1230} [Minecraft Forge] (forgeSrc-1.7.10-10.13.2.1230.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available
theolympiansmod{0.1} [The Olympians Mod] (bin) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available
Profiler Position: N/A (disabled)
Vec3 Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
Player Count: 1 / 8; [EntityPlayerMP['Player959'/1478, l='New World', x=1139.40, y=241.78, z=1095.47]]
Type: Integrated Server (map_client.txt)
Is Modded: Definitely; Client brand changed to 'fml,forge'
[18:48:26] [Client thread/INFO] [sTDOUT]: [net.minecraft.client.Minecraft:displayCrashReport:393]: #@!@# Game crashed! Crash report saved to: #@!@# .\crash-reports\crash-2015-07-13_18.48.26-server.txt
[18:48:26] [Client thread/INFO] [FML]: Waiting for the server to terminate/save.
[18:48:28] [server thread/INFO] [FML]: Unloading dimension 0
[18:48:28] [server thread/INFO] [FML]: Unloading dimension -1
[18:48:28] [server thread/INFO] [FML]: Unloading dimension 1
[18:48:28] [server thread/INFO] [FML]: Applying holder lookups
[18:48:28] [server thread/INFO] [FML]: Holder lookups applied
[18:48:28] [server thread/INFO] [FML]: The state engine was in incorrect state SERVER_STOPPING and forced into state SERVER_STOPPED. Errors may have been discarded.
[18:48:28] [Client thread/INFO] [FML]: Server terminated.
AL lib: (EE) alc_cleanup: 1 device not closed
Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release

 

this line of code is erroring it btw,

 if (this.getAttackTarget().getDistanceSqToEntity(this) > 16.0D)

Im serious don't look at it!!

Link to comment
Share on other sites

That doesn't look like the full crash log, but based on the line you say it's pointing to, it's a NullPointerException: the attack target can be NULL.

 

As to your other issue, you should be able to remove tasks from the list, though the best way to do that is with an Iterator to avoid potential ConcurrentModificationExceptions.

 

Another option is to add both tasks, but in the respective attack methods add some extra checks to make sure it can't attack using both within a certain time of the other.

Link to comment
Share on other sites

im not sure if that will make a difference, but ill try it, the problem is, is that even when the code is not erred depending on which ever task is first in the line of code, that's the attack that it uses, I just want to make it remove the aiArrowattack whenever its in a certain range, like this..

	@Override
public boolean attackEntityAsMob(Entity entity) {

	if (this.getAttackTarget().getDistanceSqToEntity(this) < 16.0D) {
		this.tasks.removeTask(aiArrowAttack);
		this.attackTimer = 10;
		this.worldObj.setEntityState(this, (byte) 4);
		entity.attackEntityFrom(DamageSource.causeMobDamage(this),
				(float) (7 + this.rand.nextInt(15)));

		return true;
	} else {

	}

	this.tasks.addTask(3, aiArrowAttack);
	return true;

}

 

but it doesn't work at all, also what do you mean by "making sure that the attacks doesn't happen at the same time"

 

like if the attack timer equals something different on each attack.

Im serious don't look at it!!

Link to comment
Share on other sites

also you said before that I was getting the crash report because the game thinks this.getattacktarget cant equal null? how can I let the game know that it can be null?

No, I said it CAN be null, but you are treating it like it could never possibly be null, which is not true:

Object o = null;
if (o.someMethod()) { // crashes because object is null

You can't call methods or access fields on null.

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.

×
×
  • Create New...

Important Information

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