Jump to content

[1.7.10] get last attacker


knokko

Recommended Posts

hello guys,

I am trying to get the mob that has attacked a player the last time.

I have used player.getLastAttacker().

But that was the mob that was last attacked by the player.

Does anybody know how I can get the mob that has last attacked the player?

Link to comment
Share on other sites

I have tested it myself.

I have tested it on a zombie.

My mob froze the zombie when I hit it.

Not when the zombie attacked me.

 

Here is the code for it:

You only see this part because I don't think you need the whole code.

The method use mixed magic is called every tick if the mage is the right mage.

 public void useMixedMagic() {
	List partners = worldObj.getEntitiesWithinAABB(EntityUndeadMage.class, AxisAlignedBB.getBoundingBox(summoner.posX - 20, summoner.posY - 20, summoner.posZ - 20, summoner.posX + 20, summoner.posY + 20, summoner.posZ + 20));
	EntityLivingBase target;
	for (int j = 0; j < partners.size(); ++j){
		EntityUndeadMage partner = (EntityUndeadMage) partners.get(j);
		if(partner.getLastAttacker() != null && fightType == 0){
			target = partner.getLastAttacker();
			if(!target.isPotionActive(2) && mobMana >= 200){
				target.addPotionEffect(new PotionEffect(2, 100, 5));
				mobMana -= 200;
			}
		}
	}
	if(summoner.getLastAttacker() != null && fightType == 0){
		target = summoner.getLastAttacker();
		if(!target.isPotionActive(2) && mobMana >= 200){
			target.addPotionEffect(new PotionEffect(2, 100, 5));
			mobMana -= 200;
		}
	}
}

Link to comment
Share on other sites

Okay, I looked through the code and I think you are actually right, depending on how you made your custom mob.  What class did you extend?

 

Anyway, in EntityLivingBase the getLastAttacker() returns the lastAttacker field value and the lastAttacker field is set in the setAttacker() method which is called in the attackEntityAsMob() method.  So looking at this the other way around if the entity attacksAsMob() then it will set that entity as the lastAttacker. 

 

Actually, the code seems fairly inconsistent.  EntityMob has its own attackEntityAsMob() code that doesn't call super methods but also doesn't update lastAttacker.  There doesn't seem to be any update of lastAttacker anywhere in the class.

 

EntityPlayer also calls setLastAttacker() but you're right it is set to the entity the player attacks. 

 

Can someone else check this?  It is late at night, but it seems to me that the logic is backwards just like knokko says.

 

I think this is example where the naming of the methods is wrong.  There are several other logical naming errors in this attack code actually.  For example, the hitByEntity() method is actually a method to check if you can hit the entity and it returns false if you can.  It should really be named something like isEntityInvulnerable().

 

Anyway, in your custom mob you can create your own true variable to track the last attacker.  You could set it in the attackEntityFrom() method which is method called when your mob is attacked.

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

Link to comment
Share on other sites

The methods are pretty unintuitive and mixed up; what happens when an entity is attacked (i.e. attackEntityFrom is called, which happens almost always when an entity is damaged), the entity calls setRevengeTarget, which sets the field entityLivingToAttack which can be retrieved via getAITarget(); if the entity is a player, it also sets the attackingPlayer field, which does not have a specific getter, but you can use EntityLivingBase#func_94060_bK(), which returns either the combat tracker target, the attackingPlayer, or the entityLivingToAttack (i.e. AI target).

 

It's not a perfect solution, as your mob may have a target without being attacked, in which case it would apply the effect in error, so you could use getAITarget first then, if that returns null, call func_94060_bK and check if it is an EntityPlayer - this way may avoid some of the incorrect triggers, but it's difficult to say for sure how well it would work.

 

Depending on how your code is supposed to work, it may be better to use LivingHurtEvent and cause the effect to the hurt entity's attacker using event.source.getEntity(), or to put the code in your mob's attackEntityFrom method, but it looks like that may not be an option for you.

Link to comment
Share on other sites

I have seen the options you have said.

I am now going to test them.

Here is the whole class code in case of I could have made the problem.

 

But the class is really big for a mob...

public class EntityUndeadMage extends EntityAnimal{
/**
 * The summoner is the player that has summoned this mob.
 * This mob is programmed to help the summoner.
 */
public EntityPlayer summoner;
/**
 * The player name of the summoner.
 */
public String summonerName;
public UUID summonerUUID;
/**
 * The type of magic this mob uses.
 * 0 = healing
 * 1 = mixed
 * 2 = offensive
 */
public int mageType;
double movementSpeed = this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getBaseValue();
/**
 * The current mana the mob has
 */
public int mobMana;
/**
 * The time this mob can't cast spells.
 */
public int manaCooldown;
public String summonerId;

/**
 * returns true if the mob should follow the summoner.
 * returns false if the mob should keep on the place where it is.
 */

public boolean guardSummoner = true;

public int fightType;



/**
 * A required constructor for a mob.
 * 
 * Do not use this constructor to summon this mob.
 * Use the constructor world, summoner, mageType, x, y, z.
 * @param world
 */
    public EntityUndeadMage(World world)
    {
        super(world);
        this.setSize(0.9F, 1.8F);
    }

    /**
     * 
     * @param world - The world the mob has to spawn.
     * @param summoner - The player that summons this mob.
     * @param mageType - The type of magic this mob will use. 0 = positive 1 = mixed 2 = offensive
     * @param x - The X location the mob has to spawn.
     * @param y - The Y location the mob has to spawn.
     * @param z - The Z location the mob has to spawn.
     */
    public EntityUndeadMage(World world, EntityPlayer summoner, int mageType, double x, double y, double z){
    	super(world);
    	this.setSize(0.6F, 1.8F);
    	setPosition(x, y, z);
        prevPosX = x;
        prevPosY = y;
        prevPosZ = z;
        this.summoner = summoner;
        this.mageType = mageType;
    	
    }

    /**
     * Returns true if the newer Entity AI code should be run
     */
    public boolean isAIEnabled()
    {
        return true;
    }
    
    /**
     * The base attributes of this mob.
     */
    protected void applyEntityAttributes()
    {
        super.applyEntityAttributes();
        this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D);
        this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.35);
    }

    /**
     * Returns the sound this mob makes while it's alive.
     */
    protected String getLivingSound()
    {
        return null;
    }

    /**
     * Returns the sound this mob makes when it is hurt.
     */
    protected String getHurtSound()
    {
        return "mob.zombie.hurt";
    }

    /**
     * Returns the sound this mob makes on death.
     */
    protected String getDeathSound()
    {
        return "mob.zombie.hurt";
    }

    protected void func_145780_a(int x, int y, int z, Block block)
    {
        this.playSound("mob.zombie.step", 0.15F, 1.0F);
    }

    /**
     * Returns the volume for the sounds this mob makes.
     */
    protected float getSoundVolume()
    {
        return 0.4F;
    }

    protected Item getDropItem()
    {
        return Items.bone;
    }

    /**
     * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param
     * par2 - Level of Looting used to kill this mob.
     */
    protected void dropFewItems(boolean hitbyplayer, int lootinglevel)
    {
        int j = this.rand.nextInt(3) + this.rand.nextInt(1 + lootinglevel);
        int k;

        for (k = 0; k < j; ++k)
        {
            this.dropItem(Items.bone, 1);
        }

        j = this.rand.nextInt(3) + 1 + this.rand.nextInt(1 + lootinglevel);

        for (k = 0; k < j; ++k)
        {
            if (this.isBurning())
            {
                this.dropItem(Items.skull, 1);
            }
            else
            {
                this.dropItem(Items.skull, 1);
            }
        }
    }

    /**
     * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
     */
    


    public EntityUndeadMage createChild(EntityAgeable ageable)
    {
        return new EntityUndeadMage(this.worldObj);
    }
    public void onUpdate(){
    	super.onUpdate();
    	updateMana();
    	getSummoner();
    	if(summoner != null){
    	useMagic();
    	if(guardSummoner){
    		followSummoner();
    		}
    	}
    }
public void getSummoner() {
	if(summonerId != null && summonerUUID == null){
    		summonerUUID = UUID.fromString(summonerId);
    	}
    	if(summonerUUID != null && summoner == null){
    		summoner = worldObj.func_152378_a(summonerUUID);
    	}
    	if(summonerUUID != null){
        	summonerId = summonerUUID.toString();
        }
    	if(summoner != null && summonerUUID == null){
    		summonerUUID = summoner.getUniqueID();
    	}
}

public void useMagic() {
	if(mageType == 0){
		useHealingMagic();
	}
	if(mageType == 1){
		useMixedMagic();
	}
	if(mageType == 2){
		useOffensiveMagic();
	}
}

public void useOffensiveMagic() {

}

public void useMixedMagic() {
	List partners = worldObj.getEntitiesWithinAABB(EntityUndeadMage.class, AxisAlignedBB.getBoundingBox(summoner.posX - 20, summoner.posY - 20, summoner.posZ - 20, summoner.posX + 20, summoner.posY + 20, summoner.posZ + 20));
	EntityLivingBase target;
	for (int j = 0; j < partners.size(); ++j){
		EntityUndeadMage partner = (EntityUndeadMage) partners.get(j);
		if(partner.getLastAttacker() != null && fightType == 0){
			target = partner.getLastAttacker();
			if(!target.isPotionActive(2) && mobMana >= 200){
				target.addPotionEffect(new PotionEffect(2, 100, 5));
				mobMana -= 200;
			}
		}
	}
	if(summoner.getLastAttacker() != null && fightType == 0){
		target = summoner.getLastAttacker();
		if(!target.isPotionActive(2) && mobMana >= 200){
			target.addPotionEffect(new PotionEffect(2, 100, 5));
			mobMana -= 200;
		}
	}
}

public void useHealingMagic() {
	if(summoner.isBurning() && !summoner.isPotionActive(12) && mobMana >= 200){
		summoner.addPotionEffect(new PotionEffect(12, 40));
		mobMana -= 200;
		worldObj.spawnParticle("flame", posX, posY, posZ, 0D, 0D, 0D);
	}
	List partners = worldObj.getEntitiesWithinAABB(EntityUndeadMage.class, AxisAlignedBB.getBoundingBox(summoner.posX - 20, summoner.posY - 20, summoner.posZ - 20, summoner.posX + 20, summoner.posY + 20, summoner.posZ + 20));
	for (int j = 0; j < partners.size(); ++j){
		EntityUndeadMage partner = (EntityUndeadMage) partners.get(j);
		if(partner.summoner == summoner){
		if(partner.isBurning() && !partner.isPotionActive(12)){
			if(mobMana >= 200){
			partner.addPotionEffect(new PotionEffect(12, 40));
			mobMana -= 200;
			}
		}
		if(partner.getHealth() >= 11 && partner.getHealth() <= 19 && !partner.isPotionActive(10) && mobMana >= 20){
				partner.addPotionEffect(new PotionEffect(10, 100));
				mobMana -= 20;
		}
		if(partner.fallDistance >= 4 && mobMana >= 100){
				partner.fallDistance = 0;
				mobMana -= 100;
		}
		if(partner.getHealth() <= 10 && partner.getHealth() >= 6 && mobMana >= 100 && !partner.isPotionActive(10)){
			partner.addPotionEffect(new PotionEffect(10, 100, 1));
			mobMana -= 100;
		}
		if(partner.getHealth() <= 10 && partner.getHealth() >= 6 && partner.isPotionActive(10) && mobMana >= 100){
			partner.heal(1F);
			mobMana -= 100;
		}
		if(partner.getHealth() <= 5 && partner.getHealth() >= 1 && mobMana >= 500 && !partner.isPotionActive(10)){
			partner.addPotionEffect(new PotionEffect(10, 100, 2));
			mobMana -= 500;
		}
		if(partner.getHealth() <= 5 && partner.getHealth() >= 1 && mobMana >= 1000){
			mobMana -= 1000;
			partner.heal(5F);
		}
		}
	}
	if(summoner.getHealth() >= 11 && summoner.getHealth() <= 19 && !summoner.isPotionActive(10) && mobMana >= 20){
			summoner.addPotionEffect(new PotionEffect(10,100));
			mobMana -= 20;
	}
	if(summoner.fallDistance >= 4 && mobMana >= 100){
			summoner.fallDistance = 0;
			mobMana -= 100;
	}
	if(summoner.getHealth() <= 10 && summoner.getHealth() >= 6 && !summoner.isPotionActive(10) && mobMana >= 100){
			summoner.addPotionEffect(new PotionEffect(10, 10, 1));
			mobMana -= 100;
	}
	if(summoner.getHealth() <= 10 && summoner.getHealth() >= 6 && summoner.isPotionActive(10) && mobMana >= 100){
		summoner.heal(1F);
		mobMana -= 100;
	}
	if(summoner.getHealth() <= 5 && summoner.getHealth() >= 1 && !summoner.isPotionActive(10) && mobMana >= 500){
			summoner.addPotionEffect(new PotionEffect(10, 100, 2));
			mobMana -= 500;
	}
	if(summoner.getHealth() <= 5 && summoner.getHealth() >= 1 && mobMana >= 1000){
		mobMana -= 1000;
		summoner.heal(5F);
	}

}


public void updateMana() {
	if(mobMana <= 5000){
		mobMana += 1;
	}
	if(mobMana >= 5001){
		mobMana = 5000;
	}
	if(manaCooldown >= 1){
		manaCooldown -= 1;
	}
	if(manaCooldown <= 0){
		manaCooldown = 0;
	}
}

public void followSummoner() {
	if(summoner != null){
		if(summoner.posX >= posX + 5){

			moveEntity(movementSpeed , 0, 0);
		}
		else if(summoner.posX <= posX - 5){
			moveEntity(-1 * movementSpeed, 0, 0);
		}
		if(summoner.posZ >= posZ + 5){
			moveEntity(0, 0, movementSpeed);
		}
		else if(summoner.posZ <= posZ - 5){
			moveEntity(0, 0, -1 * movementSpeed);
		}
		if(this.onGround && summoner.posY >= posY + 2){
			moveEntity(0, 3.0, 0);
		}
		if(summoner.posX >= posX + 16 || summoner.posX <= posX - 16 ||summoner.posY >= posY + 16 || summoner.posY <= posY - 16 || summoner.posZ >= posZ  + 16|| summoner.posZ <= posZ - 16){
			if(summoner.onGround || summoner.handleWaterMovement()){
			setPosition(summoner.posX, summoner.posY, summoner.posZ);
			}
		}
		if(summoner.posX >= posX + 100 || summoner.posX <= posX - 100 || summoner.posZ >= posZ + 100 || summoner.posZ <= posZ - 100){
			setPosition(summoner.posX, summoner.posY, summoner.posZ);
		}
	}
}
public void writeEntityToNBT(NBTTagCompound nbt){
	super.writeEntityToNBT(nbt);
	if(summoner != null){
		nbt.setString("summonerUUID", summonerId);
	}
	nbt.setInteger("mobMana", mobMana);
	nbt.setBoolean("guardSummoner", guardSummoner);
}
public void readEntityFromNBT(NBTTagCompound nbt){
	super.readEntityFromNBT(nbt);
	mobMana = nbt.getInteger("mobMana");
	summonerId = nbt.getString("summonerUUID");
	guardSummoner = nbt.getBoolean("guardSummoner");
}
public boolean interact(EntityPlayer player){
	if(!worldObj.isRemote){
		if(player == summoner){
	System.out.println(summoner);
	System.out.println(summonerUUID);
	System.out.println(summonerId);
	ItemStack currentItem = player.inventory.getCurrentItem();
	if(currentItem != null){
	if(currentItem.getItem() == EnderpowerItems.positiveSpellBook && mageType != 0){
		mageType = 0;
		player.addChatMessage(new ChatComponentTranslation("I am now a healing mage."));
	}
	if(currentItem.getItem() == EnderpowerItems.mixedSpellBook && mageType != 1){
		mageType = 1;
		player.addChatMessage(new ChatComponentTranslation("I am now a mixed mage."));
	}
	if(currentItem.getItem() == EnderpowerItems.offensiveSpellBook && mageType != 2){
		mageType = 2;
		player.addChatMessage(new ChatComponentTranslation("I am now an offensive mage."));
	}
	if(currentItem.getItem() == Items.wooden_sword || currentItem.getItem() == Items.stone_sword || currentItem.getItem() == Items.iron_sword || currentItem.getItem() == Items.golden_sword || currentItem.getItem() == Items.diamond_sword){
		if(fightType == 0 && mageType != 0){
			fightType = 1;
			player.addChatMessage(new ChatComponentTranslation("I will attack every mob that attacks you or you attack."));
		}
	}
	}
	if(currentItem == null && guardSummoner == true && !worldObj.isRemote){
		guardSummoner = false;
		player.addChatMessage(new ChatComponentTranslation("I will guard it here."));
	}
	else if(currentItem == null && guardSummoner == false && !worldObj.isRemote){
		guardSummoner = true;
		player.addChatMessage(new ChatComponentTranslation("I will follow you now."));
	}
	}
		}
	return super.interact(player);
}
}

Link to comment
Share on other sites

I actually think, that for your own custom mobs, that keeping track of your own lastAttacker type field is easiest thing to do.  You can simply update it in the attackEntityFrom() method.

 

I really think that various Entity lastAttacker fields are unreliable because some classes are implemented that override the entire attackEntityFrom() and attackEntityAsMob() or the various attack AI classes and therefore I suspect that there are least a couple entity classes that don't keep that field properly up to date.

 

Anyway, I think if you have custom entities that extend various entity classes you should carefully inspect the behavior of lastAttacker.

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

Link to comment
Share on other sites

In the LivingHurtEvent just check it was the player that was hit last, and if the damage source was caused by something extending EntityLivingBase (so you don't get stuff like fall damage, fire, etc.), and if so, map it somewhere. Maybe a map with the Player's UUID > Entity which attacked, or something like that.

BEFORE ASKING FOR HELP READ THE EAQ!

 

I'll help if I can. Apologies if I do something obviously stupid. :D

 

If you don't know basic Java yet, go and follow these tutorials.

Link to comment
Share on other sites

I have put the livinghurtevent in my mob class.

But now it is a little bit crazy.

If my livinghurtevent asks what the target is, it gets the last one who attacked me.

But if I ask it in another method, it says there is no target.

 

here is the new part of the code:

    @SubscribeEvent
public void hurtEvent(LivingHurtEvent event){
	if(event.entityLiving == summoner && event.source.getEntity() != null){
		if(event.source.getEntity() instanceof EntityLivingBase){
			this.target = (EntityLivingBase) event.source.getEntity();
			System.out.println(this.target);
		}
	}
}

 

 

Here is the updated version of the whole class:

import java.util.List;
import java.util.UUID;

import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import enderpower.items.EnderpowerItems;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.passive.EntityAnimal;
import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.DamageSource;
import net.minecraft.util.IChatComponent;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.living.LivingHurtEvent;

public class EntityUndeadMage extends EntityAnimal{
/**
 * The summoner is the player that has summoned this mob.
 * This mob is programmed to help the summoner.
 */
public EntityPlayer summoner;
/**
 * The player name of the summoner.
 */
public String summonerName;
public UUID summonerUUID;
/**
 * The type of magic this mob uses.
 * 0 = healing
 * 1 = mixed
 * 2 = offensive
 */
public int mageType;
double movementSpeed = this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getBaseValue();
/**
 * The current mana the mob has
 */
public int mobMana;
/**
 * The time this mob can't cast spells.
 */
public int manaCooldown;
public String summonerId;

/**
 * returns true if the mob should follow the summoner.
 * returns false if the mob should keep on the place where it is.
 */

public boolean guardSummoner = true;

public int fightType;

public Entity lastAttacker;

public EntityLivingBase target;



/**
 * A required constructor for a mob.
 * 
 * Do not use this constructor to summon this mob.
 * Use the constructor world, summoner, mageType, x, y, z.
 * @param world
 */
    public EntityUndeadMage(World world)
    {
        super(world);
        this.setSize(0.9F, 1.8F);
    }

    /**
     * 
     * @param world - The world the mob has to spawn.
     * @param summoner - The player that summons this mob.
     * @param mageType - The type of magic this mob will use. 0 = positive 1 = mixed 2 = offensive
     * @param x - The X location the mob has to spawn.
     * @param y - The Y location the mob has to spawn.
     * @param z - The Z location the mob has to spawn.
     */
    public EntityUndeadMage(World world, EntityPlayer summoner, int mageType, double x, double y, double z){
    	super(world);
    	this.setSize(0.6F, 1.8F);
    	setPosition(x, y, z);
        prevPosX = x;
        prevPosY = y;
        prevPosZ = z;
        this.summoner = summoner;
        this.mageType = mageType;
    	
    }
    @SubscribeEvent
public void hurtEvent(LivingHurtEvent event){
	if(event.entityLiving == summoner && event.source.getEntity() != null){
		if(event.source.getEntity() instanceof EntityLivingBase){
			this.target = (EntityLivingBase) event.source.getEntity();
			System.out.println(this.target);
		}
	}
}

    /**
     * Returns true if the newer Entity AI code should be run
     */
    public boolean isAIEnabled()
    {
        return true;
    }
    
    /**
     * The base attributes of this mob.
     */
    protected void applyEntityAttributes()
    {
        super.applyEntityAttributes();
        this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D);
        this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.35);
    }

    /**
     * Returns the sound this mob makes while it's alive.
     */
    protected String getLivingSound()
    {
        return null;
    }

    /**
     * Returns the sound this mob makes when it is hurt.
     */
    protected String getHurtSound()
    {
        return "mob.zombie.hurt";
    }

    /**
     * Returns the sound this mob makes on death.
     */
    protected String getDeathSound()
    {
        return "mob.zombie.hurt";
    }

    protected void func_145780_a(int x, int y, int z, Block block)
    {
        this.playSound("mob.zombie.step", 0.15F, 1.0F);
    }

    /**
     * Returns the volume for the sounds this mob makes.
     */
    protected float getSoundVolume()
    {
        return 0.4F;
    }

    protected Item getDropItem()
    {
        return Items.bone;
    }

    /**
     * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param
     * par2 - Level of Looting used to kill this mob.
     */
    protected void dropFewItems(boolean hitbyplayer, int lootinglevel)
    {
        int j = this.rand.nextInt(3) + this.rand.nextInt(1 + lootinglevel);
        int k;

        for (k = 0; k < j; ++k)
        {
            this.dropItem(Items.bone, 1);
        }

        j = this.rand.nextInt(3) + 1 + this.rand.nextInt(1 + lootinglevel);

        for (k = 0; k < j; ++k)
        {
            if (this.isBurning())
            {
                this.dropItem(Items.skull, 1);
            }
            else
            {
                this.dropItem(Items.skull, 1);
            }
        }
    }

    /**
     * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
     */
    


    public EntityUndeadMage createChild(EntityAgeable ageable)
    {
        return new EntityUndeadMage(this.worldObj);
    }
    public void onUpdate(){
    	super.onUpdate();
    	updateMana();
    	getSummoner();
    	if(summoner != null){
    	useMagic();
    	if(guardSummoner){
    		followSummoner();
    		}
    	}
    }
public void getSummoner() {
	if(summonerId != null && summonerUUID == null){
    		summonerUUID = UUID.fromString(summonerId);
    	}
    	if(summonerUUID != null && summoner == null){
    		summoner = worldObj.func_152378_a(summonerUUID);
    	}
    	if(summonerUUID != null){
        	summonerId = summonerUUID.toString();
        }
    	if(summoner != null && summonerUUID == null){
    		summonerUUID = summoner.getUniqueID();
    	}
}

public void useMagic() {
	if(mageType == 0){
		useHealingMagic();
	}
	if(mageType == 1){
		useMixedMagic();
	}
	if(mageType == 2){
		useOffensiveMagic();
	}
}

public void useOffensiveMagic() {

}

public void useMixedMagic() {
	System.out.println(this.target);
	List partners = worldObj.getEntitiesWithinAABB(EntityUndeadMage.class, AxisAlignedBB.getBoundingBox(summoner.posX - 20, summoner.posY - 20, summoner.posZ - 20, summoner.posX + 20, summoner.posY + 20, summoner.posZ + 20));
	for (int j = 0; j < partners.size(); ++j){
		EntityUndeadMage partner = (EntityUndeadMage) partners.get(j);
		if(partner.getLastAttacker() != null && fightType == 0){
			this.target = partner.getLastAttacker();
			if(!this.target.isPotionActive(2) && mobMana >= 200){
				this.target.addPotionEffect(new PotionEffect(2, 100, 5));
				mobMana -= 200;
			}
		}
	}
	if(this.target != null && fightType == 0){
		if(!this.target.isPotionActive(2) && mobMana >= 200){
			this.target.addPotionEffect(new PotionEffect(2, 100, 5));
			mobMana -= 200;
		}
	}
}

public void useHealingMagic() {
	if(summoner.isBurning() && !summoner.isPotionActive(12) && mobMana >= 200){
		summoner.addPotionEffect(new PotionEffect(12, 40));
		mobMana -= 200;
		worldObj.spawnParticle("flame", posX, posY, posZ, 0D, 0D, 0D);
	}
	List partners = worldObj.getEntitiesWithinAABB(EntityUndeadMage.class, AxisAlignedBB.getBoundingBox(summoner.posX - 20, summoner.posY - 20, summoner.posZ - 20, summoner.posX + 20, summoner.posY + 20, summoner.posZ + 20));
	for (int j = 0; j < partners.size(); ++j){
		EntityUndeadMage partner = (EntityUndeadMage) partners.get(j);
		if(partner.summoner == summoner){
		if(partner.isBurning() && !partner.isPotionActive(12)){
			if(mobMana >= 200){
			partner.addPotionEffect(new PotionEffect(12, 40));
			mobMana -= 200;
			}
		}
		if(partner.getHealth() >= 11 && partner.getHealth() <= 19 && !partner.isPotionActive(10) && mobMana >= 20){
				partner.addPotionEffect(new PotionEffect(10, 100));
				mobMana -= 20;
		}
		if(partner.fallDistance >= 4 && mobMana >= 100){
				partner.fallDistance = 0;
				mobMana -= 100;
		}
		if(partner.getHealth() <= 10 && partner.getHealth() >= 6 && mobMana >= 100 && !partner.isPotionActive(10)){
			partner.addPotionEffect(new PotionEffect(10, 100, 1));
			mobMana -= 100;
		}
		if(partner.getHealth() <= 10 && partner.getHealth() >= 6 && partner.isPotionActive(10) && mobMana >= 100){
			partner.heal(1F);
			mobMana -= 100;
		}
		if(partner.getHealth() <= 5 && partner.getHealth() >= 1 && mobMana >= 500 && !partner.isPotionActive(10)){
			partner.addPotionEffect(new PotionEffect(10, 100, 2));
			mobMana -= 500;
		}
		if(partner.getHealth() <= 5 && partner.getHealth() >= 1 && mobMana >= 1000){
			mobMana -= 1000;
			partner.heal(5F);
		}
		}
	}
	if(summoner.getHealth() >= 11 && summoner.getHealth() <= 19 && !summoner.isPotionActive(10) && mobMana >= 20){
			summoner.addPotionEffect(new PotionEffect(10,100));
			mobMana -= 20;
	}
	if(summoner.fallDistance >= 4 && mobMana >= 100){
			summoner.fallDistance = 0;
			mobMana -= 100;
	}
	if(summoner.getHealth() <= 10 && summoner.getHealth() >= 6 && !summoner.isPotionActive(10) && mobMana >= 100){
			summoner.addPotionEffect(new PotionEffect(10, 10, 1));
			mobMana -= 100;
	}
	if(summoner.getHealth() <= 10 && summoner.getHealth() >= 6 && summoner.isPotionActive(10) && mobMana >= 100){
		summoner.heal(1F);
		mobMana -= 100;
	}
	if(summoner.getHealth() <= 5 && summoner.getHealth() >= 1 && !summoner.isPotionActive(10) && mobMana >= 500){
			summoner.addPotionEffect(new PotionEffect(10, 100, 2));
			mobMana -= 500;
	}
	if(summoner.getHealth() <= 5 && summoner.getHealth() >= 1 && mobMana >= 1000){
		mobMana -= 1000;
		summoner.heal(5F);
	}

}


public void updateMana() {
	if(mobMana <= 5000){
		mobMana += 1;
	}
	if(mobMana >= 5001){
		mobMana = 5000;
	}
	if(manaCooldown >= 1){
		manaCooldown -= 1;
	}
	if(manaCooldown <= 0){
		manaCooldown = 0;
	}
}

public void followSummoner() {
	if(summoner != null){
		if(summoner.posX >= posX + 5){

			moveEntity(movementSpeed , 0, 0);
		}
		else if(summoner.posX <= posX - 5){
			moveEntity(-1 * movementSpeed, 0, 0);
		}
		if(summoner.posZ >= posZ + 5){
			moveEntity(0, 0, movementSpeed);
		}
		else if(summoner.posZ <= posZ - 5){
			moveEntity(0, 0, -1 * movementSpeed);
		}
		if(this.onGround && summoner.posY >= posY + 2){
			moveEntity(0, 3.0, 0);
		}
		if(summoner.posX >= posX + 16 || summoner.posX <= posX - 16 ||summoner.posY >= posY + 16 || summoner.posY <= posY - 16 || summoner.posZ >= posZ  + 16|| summoner.posZ <= posZ - 16){
			if(summoner.onGround || summoner.handleWaterMovement()){
			setPosition(summoner.posX, summoner.posY, summoner.posZ);
			}
		}
		if(summoner.posX >= posX + 100 || summoner.posX <= posX - 100 || summoner.posZ >= posZ + 100 || summoner.posZ <= posZ - 100){
			setPosition(summoner.posX, summoner.posY, summoner.posZ);
		}
	}
}
public void writeEntityToNBT(NBTTagCompound nbt){
	super.writeEntityToNBT(nbt);
	if(summoner != null){
		nbt.setString("summonerUUID", summonerId);
	}
	nbt.setInteger("mobMana", mobMana);
	nbt.setBoolean("guardSummoner", guardSummoner);
}
public void readEntityFromNBT(NBTTagCompound nbt){
	super.readEntityFromNBT(nbt);
	mobMana = nbt.getInteger("mobMana");
	summonerId = nbt.getString("summonerUUID");
	guardSummoner = nbt.getBoolean("guardSummoner");
}
public boolean interact(EntityPlayer player){
	if(!worldObj.isRemote){
		if(player == summoner){
	System.out.println(summoner);
	System.out.println(summonerUUID);
	System.out.println(summonerId);
	ItemStack currentItem = player.inventory.getCurrentItem();
	if(currentItem != null){
	if(currentItem.getItem() == EnderpowerItems.positiveSpellBook && mageType != 0){
		mageType = 0;
		player.addChatMessage(new ChatComponentTranslation("I am now a healing mage."));
	}
	if(currentItem.getItem() == EnderpowerItems.mixedSpellBook && mageType != 1){
		mageType = 1;
		player.addChatMessage(new ChatComponentTranslation("I am now a mixed mage."));
	}
	if(currentItem.getItem() == EnderpowerItems.offensiveSpellBook && mageType != 2){
		mageType = 2;
		player.addChatMessage(new ChatComponentTranslation("I am now an offensive mage."));
	}
	if(currentItem.getItem() == Items.wooden_sword || currentItem.getItem() == Items.stone_sword || currentItem.getItem() == Items.iron_sword || currentItem.getItem() == Items.golden_sword || currentItem.getItem() == Items.diamond_sword){
		if(fightType == 0 && mageType != 0){
			fightType = 1;
			player.addChatMessage(new ChatComponentTranslation("I will attack every mob that attacks you or you attack."));
		}
	}
	}
	if(currentItem == null && guardSummoner == true && !worldObj.isRemote){
		guardSummoner = false;
		player.addChatMessage(new ChatComponentTranslation("I will guard it here."));
	}
	else if(currentItem == null && guardSummoner == false && !worldObj.isRemote){
		guardSummoner = true;
		player.addChatMessage(new ChatComponentTranslation("I will follow you now."));
	}
	}
		}
	return super.interact(player);
}
public boolean attackEntityFrom(DamageSource damage, float f){
	lastAttacker = damage.getEntity();
	return super.attackEntityFrom(damage, f);

}


}

Link to comment
Share on other sites

I think I have found the solution.

I have used a trick on LivingHurtEvent.

Here is the code of the event, it is in the initializationEvent.

 

please say it if I am doing something stupid.

@SubscribeEvent
public void hurtEvent(LivingHurtEvent event){
	if(event.entityLiving instanceof EntityPlayer){
		EntityPlayer player = (EntityPlayer) event.entityLiving;
		World world = event.entityLiving.worldObj;
		List UndeadMages = world.getEntitiesWithinAABB(EntityUndeadMage.class, AxisAlignedBB.getBoundingBox(player.posX - 20, 0, player.posZ - 20, player.posX + 20, 260, player.posZ + 20));
		for(int u = 0; u < UndeadMages.size(); ++u){
			EntityUndeadMage mage = (EntityUndeadMage) UndeadMages.get(u);
			if(player == mage.summoner && event.source.getEntity() != null){
				mage.target = (EntityLivingBase) event.source.getEntity();
			}
		}
	}
}

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.



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Minecraft opened, but when I went to create a new world I got another error. https://pastebin.com/mmdNztmW
    • java.lang.RuntimeException: Could not execute entrypoint stage 'main' due to errors, provided by 'terrablender'!     at net.fabricmc.loader.impl.FabricLoaderImpl.lambda$invokeEntrypoints$2(FabricLoaderImpl.java:388) ~[fabric-loader-0.15.11.jar:?]     at net.fabricmc.loader.impl.util.ExceptionUtil.gatherExceptions(ExceptionUtil.java:33) ~[fabric-loader-0.15.11.jar:?]     at net.fabricmc.loader.impl.FabricLoaderImpl.invokeEntrypoints(FabricLoaderImpl.java:386) ~[fabric-loader-0.15.11.jar:?]     at net.fabricmc.loader.impl.game.minecraft.Hooks.startServer(Hooks.java:63) ~[fabric-loader-0.15.11.jar:?]     at net.minecraft.server.Main.main(Main.java:112) ~[server-intermediary.jar:?]     at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:470) ~[fabric-loader-0.15.11.jar:?]     at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74) ~[fabric-loader-0.15.11.jar:?]     at net.fabricmc.loader.impl.launch.knot.KnotServer.main(KnotServer.java:23) ~[fabric-loader-0.15.11.jar:?]     at net.fabricmc.loader.impl.launch.server.FabricServerLauncher.main(FabricServerLauncher.java:69) ~[fabric-loader-0.15.11.jar:?] Caused by: java.lang.NoSuchFieldError: Class me.lortseam.completeconfig.data.BooleanEntry does not have member field 'boolean checkbox'     at me.lortseam.completeconfig.data.BooleanEntry.<init>(BooleanEntry.java:25) ~[completeconfig-base-2.5.0-cd5950f26b406f27.jar:?]     at me.lortseam.completeconfig.data.Entry.create(Entry.java:42) ~[completeconfig-base-2.5.0-cd5950f26b406f27.jar:?]     at me.lortseam.completeconfig.data.EntrySet.lambda$resolve$1(EntrySet.java:31) ~[completeconfig-base-2.5.0-cd5950f26b406f27.jar:?]     at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:212) ~[?:?]     at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:194) ~[?:?]     at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024) ~[?:?]     at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:556) ~[?:?]     at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:546) ~[?:?]     at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) ~[?:?]     at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) ~[?:?]     at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265) ~[?:?]     at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:611) ~[?:?]     at me.lortseam.completeconfig.data.EntrySet.resolve(EntrySet.java:32) ~[completeconfig-base-2.5.0-cd5950f26b406f27.jar:?]     at me.lortseam.completeconfig.data.Parent.resolveContainer(Parent.java:58) ~[completeconfig-base-2.5.0-cd5950f26b406f27.jar:?]     at me.lortseam.completeconfig.data.Parent.resolve(Parent.java:110) ~[completeconfig-base-2.5.0-cd5950f26b406f27.jar:?]     at me.lortseam.completeconfig.data.Config.lambda$new$0(Config.java:51) ~[completeconfig-base-2.5.0-cd5950f26b406f27.jar:?]     at me.lortseam.completeconfig.data.Config.deserialize(Config.java:94) ~[completeconfig-base-2.5.0-cd5950f26b406f27.jar:?]     at me.lortseam.completeconfig.data.Config.load(Config.java:121) ~[completeconfig-base-2.5.0-cd5950f26b406f27.jar:?]     at io.github.uhq_games.regions_unexplored.RegionsUnexplored.onTerraBlenderInitialized(RegionsUnexplored.java:70) ~[RegionsUnexploredFabric-0.5.31.20.1.jar:?]     at terrablender.core.TerraBlenderFabric.lambda$onInitialize$0(TerraBlenderFabric.java:40) ~[TerraBlender-fabric-1.20.1-3.0.1.7.jar:?]     at java.util.ArrayList.forEach(ArrayList.java:1597) ~[?:?]     at terrablender.core.TerraBlenderFabric.onInitialize(TerraBlenderFabric.java:38) ~[TerraBlender-fabric-1.20.1-3.0.1.7.jar:?]     at net.fabricmc.loader.impl.FabricLoaderImpl.invokeEntrypoints(FabricLoaderImpl.java:384) ~[fabric-loader-0.15.11.jar:?]  
    • Hi, I have the oficial launcher using the version 1.21, and forge 51.0.13, as soon as I start the installation the games crashes and gives me "exit code: 1", I haven't put any mods yet in the folder. Its the second time that uninstall and install everything and nothing works, checket my graphics and they are updated. https://pastebin.com/STPgEiVs   thanks!
    • Ty very much it worked
    • no clue what is going on, you guys seem more knowledgeable than I am. So here's my log as well as my mod list. Error Folder On Google Drive  
  • Topics

  • Who's Online (See full list)

    • There are no registered users currently online
×
×
  • Create New...

Important Information

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