initial commit

This commit is contained in:
Sen 2025-03-11 00:23:54 +01:00 committed by Sen
parent 3c9ee26b06
commit 22186c33b9
1458 changed files with 282792 additions and 0 deletions

View file

@ -0,0 +1,96 @@
package game.ai;
import game.entity.npc.EntityNPC;
import game.entity.projectile.EntityFireball;
import game.entity.types.EntityLiving;
import game.init.Items;
import game.item.ItemStack;
import game.world.BlockPos;
import game.world.Vec3;
import game.world.World;
public class AIFireballAttack extends EntityAIBase
{
public final int power;
public final int delay;
public final double distance;
public final double velocity;
private final EntityNPC parentEntity;
public int attackTimer;
public AIFireballAttack(EntityNPC entity, int power, int delay, double distance, double velocity)
{
this.parentEntity = entity;
this.power = power;
this.delay = delay;
this.distance = distance;
this.velocity = velocity;
// this.setMutexBits(3);
}
public boolean shouldExecute()
{
return this.parentEntity.getAttackTarget() != null;
}
public void startExecuting()
{
this.attackTimer = 0;
}
public void resetTask()
{
this.parentEntity.setItemNoUpdate(0, null);
}
public void updateTask()
{
EntityLiving target = this.parentEntity.getAttackTarget();
// double d0 = 64.0D;
if (target.getDistanceSqToEntity(this.parentEntity) < this.distance * this.distance && this.parentEntity.canEntityBeSeen(target))
{
World world = this.parentEntity.worldObj;
++this.attackTimer;
if (this.attackTimer == this.delay)
{
world.playAuxSFX(1007, new BlockPos(this.parentEntity), 0);
this.parentEntity.setItemNoUpdate(0, new ItemStack(Items.orb));
}
if (this.attackTimer == this.delay * 2)
{
this.parentEntity.swingItem();
this.parentEntity.setItemNoUpdate(0, null);
double d1 = 1.0D;
Vec3 vec3 = this.parentEntity.getLook(1.0F);
double d2 = target.posX - (this.parentEntity.posX + vec3.xCoord * d1);
double d3 = target.getEntityBoundingBox().minY + (double)(target.height / 2.0F) - (this.parentEntity.posY + (double)this.parentEntity.getEyeHeight());
double d4 = target.posZ - (this.parentEntity.posZ + vec3.zCoord * d1);
world.playAuxSFX(1008, new BlockPos(this.parentEntity), 0);
EntityFireball fireball = new EntityFireball(world, this.parentEntity, d2, d3, d4, this.velocity);
// 0.0, 0.0, 0.0);
// fireball.setAcceleration(d2 + this.parentEntity.getRNG().gaussian() * 0.1D,
// d3 + this.parentEntity.getRNG().gaussian() * 0.1D,
// d4 + this.parentEntity.getRNG().gaussian() * 0.1D);
// fireball.accelerationX *= this.velocity;
// fireball.accelerationY *= this.velocity;
// fireball.accelerationZ *= this.velocity;
fireball.explosionPower = this.power;
fireball.posX = this.parentEntity.posX + vec3.xCoord * d1;
fireball.posY = this.parentEntity.posY + (double)this.parentEntity.getEyeHeight();
fireball.posZ = this.parentEntity.posZ + vec3.zCoord * d1;
world.spawnEntityInWorld(fireball);
this.attackTimer = -this.delay * this.parentEntity.getRNG().range(1, 4);
}
this.parentEntity.getLookHelper().setLookPositionWithEntity(target, 30.0f, 30.0f);
}
else if (this.attackTimer > 0)
{
--this.attackTimer;
}
this.parentEntity.setItemNoUpdate(0, this.attackTimer > this.delay ? new ItemStack(Items.orb) : null);
}
}

View file

@ -0,0 +1,91 @@
package game.ai;
import game.entity.npc.EntityNPC;
import game.entity.projectile.EntityBox;
import game.entity.types.EntityLiving;
import game.world.BlockPos;
public class AIFlyingBoxAttack extends EntityAIBase
{
private EntityNPC entity;
private int delay;
private int charge;
public AIFlyingBoxAttack(EntityNPC entity)
{
this.entity = entity;
// this.setMutexBits(3);
}
public boolean shouldExecute()
{
EntityLiving tgt = this.entity.getAttackTarget();
return tgt != null && tgt.isEntityAlive();
}
public void startExecuting()
{
this.delay = 0;
this.charge = 0;
}
public void updateTask()
{
if (this.delay <= 0)
{
this.delay = this.entity.getRNG().excl(10, 20);
int k3 = this.charge;
++this.charge;
if (k3 > 15)
{
float f = 10.0F;
float f1 = 5.0F;
double d0 = this.entity.getRNG().drange(this.entity.posX - (double)f, this.entity.posX + (double)f);
double d1 = this.entity.getRNG().drange(this.entity.posY - (double)f1, this.entity.posY + (double)f1);
double d2 = this.entity.getRNG().drange(this.entity.posZ - (double)f, this.entity.posZ + (double)f);
this.launchBoxToCoords(d0, d1, d2, true);
this.charge = 0;
}
EntityLiving entity = this.entity.getAttackTarget();
if (entity != null && entity.isEntityAlive() && this.entity.getDistanceSqToEntity(entity) <= 900.0D && this.entity.canEntityBeSeen(entity))
{
this.launchBoxToEntity(entity);
this.delay = this.entity.getRNG().excl(5, 10);
this.charge = 0;
this.entity.getLookHelper().setLookPositionWithEntity(entity, 30.0F, 30.0F);
}
}
else {
--this.delay;
}
super.updateTask();
}
private void launchBoxToEntity(EntityLiving p_82216_2_)
{
this.launchBoxToCoords(p_82216_2_.posX, p_82216_2_.posY + (double)p_82216_2_.getEyeHeight() * 0.5D, p_82216_2_.posZ,
this.entity.getRNG().chance(100));
}
private void launchBoxToCoords(double x, double y, double z, boolean invulnerable)
{
this.entity.swingItem();
this.entity.worldObj.playAuxSFX(1014, new BlockPos(this.entity), 0);
double d0 = this.entity.posX;
double d1 = this.entity.posY + this.entity.height + 0.8;
double d2 = this.entity.posZ;
double d3 = x - d0;
double d4 = y - d1;
double d5 = z - d2;
EntityBox skull = new EntityBox(this.entity.worldObj, this.entity, d3, d4, d5, invulnerable);
skull.posY = d1;
skull.posX = d0;
skull.posZ = d2;
this.entity.worldObj.spawnEntityInWorld(skull);
}
}

View file

@ -0,0 +1,122 @@
package game.ai;
import game.ExtMath;
import game.entity.npc.EntityNPC;
import game.entity.types.EntityLiving;
public class AIRangedAttack extends EntityAIBase
{
private final EntityNPC entity;
private EntityLiving target;
private int delay;
private double speed;
private int timeout;
private int minDelay;
private int maxDelay;
private float distance;
private float distanceSq;
public AIRangedAttack(EntityNPC attacker, double movespeed, int minDelay, int maxDelay, float maxAttackDistanceIn)
{
this.delay = -1;
this.entity = attacker;
this.speed = movespeed;
this.minDelay = minDelay;
this.maxDelay = maxDelay;
this.distance = maxAttackDistanceIn;
this.distanceSq = maxAttackDistanceIn * maxAttackDistanceIn;
this.setMutexBits(3);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if(this.entity.isFleeing())
return false;
EntityLiving entitylivingbase = this.entity.getAttackTarget();
if (entitylivingbase == null || entitylivingbase.dead)
{
this.target = null;
return false;
}
else
{
this.target = entitylivingbase;
return true;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return this.shouldExecute() || (!this.entity.isFleeing() && !this.entity.getNavigator().noPath() && this.target != null && !this.target.dead);
}
public void startExecuting()
{
this.entity.setUsingItem(true);
}
/**
* Resets the task
*/
public void resetTask()
{
this.target = null;
this.timeout = 0;
this.delay = -1;
this.entity.setUsingItem(false);
}
/**
* Updates the task
*/
public void updateTask()
{
double d0 = this.entity.getDistanceSq(this.target.posX, this.target.getEntityBoundingBox().minY, this.target.posZ);
boolean flag = this.entity.getEntitySenses().canSee(this.target);
if (flag)
{
++this.timeout;
}
else
{
this.timeout = 0;
}
if (d0 <= (double)this.distanceSq && this.timeout >= 20)
{
this.entity.getNavigator().clearPathEntity();
}
else
{
this.entity.getNavigator().tryMoveToEntityLiving(this.target, this.speed);
}
this.entity.getLookHelper().setLookPositionWithEntity(this.target, 30.0F, 30.0F);
if (--this.delay == 0)
{
if (d0 > (double)this.distanceSq || !flag)
{
return;
}
float f = ExtMath.sqrtd(d0) / this.distance;
float lvt_5_1_ = ExtMath.clampf(f, 0.1F, 1.0F);
this.entity.attackEntityWithRangedAttack(this.target, lvt_5_1_);
this.delay = ExtMath.floorf(f * (float)(this.maxDelay - this.minDelay) + (float)this.minDelay);
}
else if (this.delay < 0)
{
float f2 = ExtMath.sqrtd(d0) / this.distance;
this.delay = ExtMath.floorf(f2 * (float)(this.maxDelay - this.minDelay) + (float)this.minDelay);
}
}
}

View file

@ -0,0 +1,105 @@
package game.ai;
import game.entity.npc.EntityNPC;
import game.entity.projectile.EntityFireCharge;
import game.entity.types.EntityLiving;
import game.world.BlockPos;
public class AISmallFireballAttack extends EntityAIBase
{
private EntityNPC entity;
private int timer;
private int charge;
private int amount;
public AISmallFireballAttack(EntityNPC entity)
{
this.entity = entity;
this.setMutexBits(3);
}
public boolean shouldExecute()
{
EntityLiving tgt = this.entity.getAttackTarget();
return tgt != null && tgt.isEntityAlive();
}
public void startExecuting()
{
this.timer = 0;
}
public void resetTask()
{
this.entity.setAttacking(false);
}
public void updateTask()
{
--this.charge;
EntityLiving target = this.entity.getAttackTarget();
double d0 = this.entity.getDistanceSqToEntity(target);
if (d0 < 4.0D)
{
if (this.charge <= 0)
{
this.charge = this.entity.getRNG().range(8, 20);
this.entity.attackEntityAsMob(target);
}
this.entity.getMoveHelper().setMoveTo(target.posX, target.posY, target.posZ, 1.0D);
}
else if (d0 < 256.0D)
{
double d1 = target.posX - this.entity.posX;
double d2 = target.getEntityBoundingBox().minY + (double)(target.height / 2.0F) - (this.entity.posY + (double)(this.entity.height / 2.0F));
double d3 = target.posZ - this.entity.posZ;
if (this.charge <= 0)
{
++this.timer;
if (this.timer == 1)
{
this.charge = this.entity.getRNG().range(10, 20); // 60
this.entity.setAttacking(true);
this.amount = this.entity.getRNG().range(5, 25);
}
else if (this.timer <= this.amount)
{
this.charge = this.entity.getRNG().range(2, 6); // 6
}
else
{
this.charge = this.entity.getRNG().range(2, 6); // 100
this.timer = 0;
this.entity.setAttacking(false);
}
if (this.timer > 1)
{
this.entity.swingItem();
// float f = MathHelper.sqrt_float(MathHelper.sqrt_double(d0)) * 0.5F;
this.entity.worldObj.playAuxSFX(1009, new BlockPos((int)this.entity.posX, (int)this.entity.posY, (int)this.entity.posZ), 0);
for (int i = 0; i < 1; ++i)
{
EntityFireCharge entitysmallfireball = new EntityFireCharge(this.entity.worldObj, this.entity, d1 /* + this.entity.getRNG().gaussian() * (double)f */, d2, d3 /* + this.entity.getRNG().gaussian() * (double)f */);
entitysmallfireball.posY = this.entity.posY + (double)(this.entity.height / 2.0F) + 0.5D;
this.entity.worldObj.spawnEntityInWorld(entitysmallfireball);
}
}
}
this.entity.getLookHelper().setLookPositionWithEntity(target, 30.0F, 30.0F);
}
else
{
this.entity.getNavigator().clearPathEntity();
this.entity.getMoveHelper().setMoveTo(target.posX, target.posY, target.posZ, 1.0D);
}
super.updateTask();
}
}

View file

@ -0,0 +1,167 @@
package game.ai;
import game.entity.Entity;
import game.entity.types.EntityLiving;
import game.pathfinding.PathEntity;
import game.world.BlockPos;
import game.world.World;
public class EntityAIAttackOnCollide extends EntityAIBase
{
World worldObj;
protected EntityLiving attacker;
/**
* An amount of decrementing ticks that allows the entity to attack once the tick reaches 0.
*/
int attackTick;
/** The speed with which the mob will approach the target */
double speedTowardsTarget;
/**
* When true, the mob will continue chasing its target, even if it can't find a path to them right now.
*/
boolean longMemory;
private final boolean swing;
/** The PathEntity of our entity. */
PathEntity entityPathEntity;
Class <? extends Entity > classTarget;
private int delayCounter;
private double targetX;
private double targetY;
private double targetZ;
public EntityAIAttackOnCollide(EntityLiving creature, Class <? extends Entity > targetClass, double speedIn, boolean useLongMemory, boolean swingItem)
{
this(creature, speedIn, useLongMemory, swingItem);
this.classTarget = targetClass;
}
public EntityAIAttackOnCollide(EntityLiving creature, double speedIn, boolean useLongMemory, boolean swingItem)
{
this.attacker = creature;
this.worldObj = creature.worldObj;
this.speedTowardsTarget = speedIn;
this.longMemory = useLongMemory;
this.swing = swingItem;
this.setMutexBits(3);
}
public EntityAIAttackOnCollide(EntityLiving creature, Class <? extends Entity > targetClass, double speedIn, boolean useLongMemory)
{
this(creature, speedIn, useLongMemory);
this.classTarget = targetClass;
}
public EntityAIAttackOnCollide(EntityLiving creature, double speedIn, boolean useLongMemory)
{
this(creature, speedIn, useLongMemory, false);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
EntityLiving entitylivingbase = this.attacker.getAttackTarget();
if (entitylivingbase == null)
{
return false;
}
else if (!entitylivingbase.isEntityAlive())
{
return false;
}
else if (this.classTarget != null && !this.classTarget.isAssignableFrom(entitylivingbase.getClass()))
{
return false;
}
else
{
this.entityPathEntity = this.attacker.getNavigator().getPathToEntityLiving(entitylivingbase);
return this.entityPathEntity != null;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
EntityLiving entitylivingbase = this.attacker.getAttackTarget();
return entitylivingbase == null ? false : (!entitylivingbase.isEntityAlive() ? false : (!this.longMemory ? !this.attacker.getNavigator().noPath() : this.attacker.isWithinHomeDistanceFromPosition(new BlockPos(entitylivingbase))));
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.attacker.getNavigator().setPath(this.entityPathEntity, this.speedTowardsTarget);
this.delayCounter = 0;
}
/**
* Resets the task
*/
public void resetTask()
{
this.attacker.getNavigator().clearPathEntity();
}
/**
* Updates the task
*/
public void updateTask()
{
EntityLiving entitylivingbase = this.attacker.getAttackTarget();
this.attacker.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F);
double d0 = this.attacker.getDistanceSq(entitylivingbase.posX, entitylivingbase.getEntityBoundingBox().minY, entitylivingbase.posZ);
double d1 = this.getAttackRange(entitylivingbase);
--this.delayCounter;
if ((this.longMemory || this.attacker.getEntitySenses().canSee(entitylivingbase)) && this.delayCounter <= 0 && (this.targetX == 0.0D && this.targetY == 0.0D && this.targetZ == 0.0D || entitylivingbase.getDistanceSq(this.targetX, this.targetY, this.targetZ) >= 1.0D || this.attacker.getRNG().floatv() < 0.05F))
{
this.targetX = entitylivingbase.posX;
this.targetY = entitylivingbase.getEntityBoundingBox().minY;
this.targetZ = entitylivingbase.posZ;
this.delayCounter = 4 + this.attacker.getRNG().zrange(7);
if (d0 > 1024.0D)
{
this.delayCounter += 10;
}
else if (d0 > 256.0D)
{
this.delayCounter += 5;
}
if (!this.attacker.getNavigator().tryMoveToEntityLiving(entitylivingbase, this.speedTowardsTarget))
{
this.delayCounter += 15;
}
}
this.attackTick = Math.max(this.attackTick - 1, 0);
if (d0 <= d1 && this.attackTick <= 0)
{
this.attackTick = 20;
// if (this.attacker.getHeldItem() != null)
// {
this.attacker.swingItem();
// }
this.attacker.attackEntityAsMob(entitylivingbase);
}
}
protected double getAttackRange(EntityLiving attackTarget)
{
return (double)(this.attacker.width * 2.0F * this.attacker.width * 2.0F + attackTarget.width);
}
}

View file

@ -0,0 +1,126 @@
package game.ai;
import java.util.List;
import java.util.function.Predicate;
import game.Predicates;
import game.entity.Entity;
import game.entity.types.EntityLiving;
import game.pathfinding.PathEntity;
import game.pathfinding.PathNavigate;
import game.world.Vec3;
public class EntityAIAvoidEntity<T extends Entity> extends EntityAIBase
{
private final Predicate<Entity> canBeSeenSelector;
/** The entity we are attached to */
protected EntityLiving theEntity;
private double farSpeed;
private double nearSpeed;
protected T closestLivingEntity;
private float avoidDistance;
/** The PathEntity of our entity */
private PathEntity entityPathEntity;
/** The PathNavigate of our entity */
private PathNavigate entityPathNavigate;
private Class<T> classToAvoid;
private Predicate <? super T > avoidTargetSelector;
public EntityAIAvoidEntity(EntityLiving theEntityIn, Class<T> classToAvoidIn, float avoidDistanceIn, double farSpeedIn, double nearSpeedIn)
{
this(theEntityIn, classToAvoidIn, Predicates.<T>alwaysTrue(), avoidDistanceIn, farSpeedIn, nearSpeedIn);
}
public EntityAIAvoidEntity(EntityLiving theEntityIn, Class<T> classToAvoidIn, Predicate <? super T > avoidTargetSelectorIn, float avoidDistanceIn, double farSpeedIn, double nearSpeedIn)
{
this.canBeSeenSelector = new Predicate<Entity>()
{
public boolean test(Entity p_apply_1_)
{
return p_apply_1_.isEntityAlive() && EntityAIAvoidEntity.this.theEntity.getEntitySenses().canSee(p_apply_1_);
}
};
this.theEntity = theEntityIn;
this.classToAvoid = classToAvoidIn;
this.avoidTargetSelector = avoidTargetSelectorIn;
this.avoidDistance = avoidDistanceIn;
this.farSpeed = farSpeedIn;
this.nearSpeed = nearSpeedIn;
this.entityPathNavigate = theEntityIn.getNavigator();
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
List<T> list = this.theEntity.worldObj.<T>getEntitiesWithinAABB(this.classToAvoid, this.theEntity.getEntityBoundingBox().expand((double)this.avoidDistance, 3.0D, (double)this.avoidDistance), Predicates.and(new Predicate[] {this.canBeSeenSelector, this.avoidTargetSelector}));
if (list.isEmpty())
{
return false;
}
else
{
this.closestLivingEntity = list.get(0);
Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockAwayFrom(this.theEntity, 16, 7, new Vec3(this.closestLivingEntity.posX, this.closestLivingEntity.posY, this.closestLivingEntity.posZ));
if (vec3 == null)
{
return false;
}
else if (this.closestLivingEntity.getDistanceSq(vec3.xCoord, vec3.yCoord, vec3.zCoord) < this.closestLivingEntity.getDistanceSqToEntity(this.theEntity))
{
return false;
}
else
{
this.entityPathEntity = this.entityPathNavigate.getPathToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord);
return this.entityPathEntity == null ? false : this.entityPathEntity.isDestinationSame(vec3);
}
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.entityPathNavigate.noPath();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.entityPathNavigate.setPath(this.entityPathEntity, this.farSpeed);
}
/**
* Resets the task
*/
public void resetTask()
{
this.closestLivingEntity = null;
}
/**
* Updates the task
*/
public void updateTask()
{
if (this.theEntity.getDistanceSqToEntity(this.closestLivingEntity) < 49.0D)
{
this.theEntity.getNavigator().setSpeed(this.nearSpeed);
}
else
{
this.theEntity.getNavigator().setSpeed(this.farSpeed);
}
}
}

View file

@ -0,0 +1,71 @@
package game.ai;
public abstract class EntityAIBase
{
/**
* A bitmask telling which other tasks may not run concurrently. The test is a simple bitwise AND - if it yields
* zero, the two tasks may run concurrently, if not - they must run exclusively from each other.
*/
private int mutexBits;
/**
* Returns whether the EntityAIBase should begin execution.
*/
public abstract boolean shouldExecute();
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return this.shouldExecute();
}
/**
* Determine if this AI Task is interruptible by a higher (= lower value) priority task. All vanilla AITask have
* this value set to true.
*/
public boolean isInterruptible()
{
return true;
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
}
/**
* Resets the task
*/
public void resetTask()
{
}
/**
* Updates the task
*/
public void updateTask()
{
}
/**
* Sets a bitmask telling which other tasks may not run concurrently. The test is a simple bitwise AND - if it
* yields zero, the two tasks may run concurrently, if not - they must run exclusively from each other.
*/
public void setMutexBits(int mutexBitsIn)
{
this.mutexBits = mutexBitsIn;
}
/**
* Get a bitmask telling which other tasks may not run concurrently. The test is a simple bitwise AND - if it yields
* zero, the two tasks may run concurrently, if not - they must run exclusively from each other.
*/
public int getMutexBits()
{
return this.mutexBits;
}
}

View file

@ -0,0 +1,77 @@
package game.ai;
import game.entity.animal.EntityWolf;
import game.entity.npc.EntityNPC;
import game.init.Items;
import game.item.ItemStack;
import game.world.World;
public class EntityAIBeg extends EntityAIBase
{
private EntityWolf theWolf;
private EntityNPC thePlayer;
private World worldObject;
private float minPlayerDistance;
private int timeoutCounter;
public EntityAIBeg(EntityWolf wolf, float minDistance)
{
this.theWolf = wolf;
this.worldObject = wolf.worldObj;
this.minPlayerDistance = minDistance;
this.setMutexBits(2);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
this.thePlayer = this.worldObject.getClosestPlayerToEntity(this.theWolf, (double)this.minPlayerDistance);
return this.thePlayer == null ? false : this.hasPlayerGotBoneInHand(this.thePlayer);
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.thePlayer.isEntityAlive() ? false : (this.theWolf.getDistanceSqToEntity(this.thePlayer) > (double)(this.minPlayerDistance * this.minPlayerDistance) ? false : this.timeoutCounter > 0 && this.hasPlayerGotBoneInHand(this.thePlayer));
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.theWolf.setBegging(true);
this.timeoutCounter = 40 + this.theWolf.getRNG().zrange(40);
}
/**
* Resets the task
*/
public void resetTask()
{
this.theWolf.setBegging(false);
this.thePlayer = null;
}
/**
* Updates the task
*/
public void updateTask()
{
this.theWolf.getLookHelper().setLookPosition(this.thePlayer.posX, this.thePlayer.posY + (double)this.thePlayer.getEyeHeight(), this.thePlayer.posZ, 10.0F, (float)this.theWolf.getVerticalFaceSpeed());
--this.timeoutCounter;
}
/**
* Gets if the Player has the Bone in the hand.
*/
private boolean hasPlayerGotBoneInHand(EntityNPC player)
{
ItemStack itemstack = player.inventory.getCurrentItem();
return itemstack == null ? false : (!this.theWolf.isTamed() && itemstack.getItem() == Items.bone ? true : this.theWolf.isBreedingItem(itemstack));
}
}

View file

@ -0,0 +1,226 @@
package game.ai;
import game.ExtMath;
import game.block.Block;
import game.block.BlockSlab;
import game.block.BlockStairs;
import game.entity.npc.EntityNPC;
import game.entity.types.EntityLiving;
import game.init.Items;
import game.item.ItemStack;
import game.material.Material;
import game.pathfinding.WalkNodeProcessor;
import game.world.BlockPos;
public class EntityAIControlledByPlayer extends EntityAIBase
{
private final EntityLiving thisEntity;
private final float maxSpeed;
private float currentSpeed;
/** Whether the entity's speed is boosted. */
private boolean speedBoosted;
/**
* Counter for speed boosting, upon reaching maxSpeedBoostTime the speed boost will be disabled
*/
private int speedBoostTime;
/** Maximum time the entity's speed should be boosted for. */
private int maxSpeedBoostTime;
public EntityAIControlledByPlayer(EntityLiving entitylivingIn, float maxspeed)
{
this.thisEntity = entitylivingIn;
this.maxSpeed = maxspeed;
this.setMutexBits(7);
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.currentSpeed = 0.0F;
}
/**
* Resets the task
*/
public void resetTask()
{
this.speedBoosted = false;
this.currentSpeed = 0.0F;
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
return this.thisEntity.isEntityAlive() && this.thisEntity.passenger != null && this.thisEntity.passenger.isPlayer() && (this.speedBoosted || this.thisEntity.canBeSteered());
}
/**
* Updates the task
*/
public void updateTask()
{
EntityNPC entityplayer = (EntityNPC)this.thisEntity.passenger;
EntityLiving entitycreature = (EntityLiving)this.thisEntity;
float f = ExtMath.wrapf(entityplayer.rotYaw - this.thisEntity.rotYaw) * 0.5F;
if (f > 5.0F)
{
f = 5.0F;
}
if (f < -5.0F)
{
f = -5.0F;
}
this.thisEntity.rotYaw = ExtMath.wrapf(this.thisEntity.rotYaw + f);
if (this.currentSpeed < this.maxSpeed)
{
this.currentSpeed += (this.maxSpeed - this.currentSpeed) * 0.01F;
}
if (this.currentSpeed > this.maxSpeed)
{
this.currentSpeed = this.maxSpeed;
}
int i = ExtMath.floord(this.thisEntity.posX);
int j = ExtMath.floord(this.thisEntity.posY);
int k = ExtMath.floord(this.thisEntity.posZ);
float f1 = this.currentSpeed;
if (this.speedBoosted)
{
if (this.speedBoostTime++ > this.maxSpeedBoostTime)
{
this.speedBoosted = false;
}
f1 += f1 * 1.15F * ExtMath.sin((float)this.speedBoostTime / (float)this.maxSpeedBoostTime * (float)Math.PI);
}
float f2 = 0.91F;
if (this.thisEntity.onGround)
{
f2 = this.thisEntity.worldObj.getState(new BlockPos(ExtMath.floorf((float)i), ExtMath.floorf((float)j) - 1, ExtMath.floorf((float)k))).getBlock().slipperiness * 0.91F;
}
float f3 = 0.16277136F / (f2 * f2 * f2);
float f4 = ExtMath.sin(entitycreature.rotYaw * (float)Math.PI / 180.0F);
float f5 = ExtMath.cos(entitycreature.rotYaw * (float)Math.PI / 180.0F);
float f6 = entitycreature.getAIMoveSpeed() * f3;
float f7 = Math.max(f1, 1.0F);
f7 = f6 / f7;
float f8 = f1 * f7;
float f9 = -(f8 * f4);
float f10 = f8 * f5;
if (ExtMath.absf(f9) > ExtMath.absf(f10))
{
if (f9 < 0.0F)
{
f9 -= this.thisEntity.width / 2.0F;
}
if (f9 > 0.0F)
{
f9 += this.thisEntity.width / 2.0F;
}
f10 = 0.0F;
}
else
{
f9 = 0.0F;
if (f10 < 0.0F)
{
f10 -= this.thisEntity.width / 2.0F;
}
if (f10 > 0.0F)
{
f10 += this.thisEntity.width / 2.0F;
}
}
int l = ExtMath.floord(this.thisEntity.posX + (double)f9);
int i1 = ExtMath.floord(this.thisEntity.posZ + (double)f10);
int j1 = ExtMath.floorf(this.thisEntity.width + 1.0F);
int k1 = ExtMath.floorf(this.thisEntity.height + entityplayer.height + 1.0F);
int l1 = ExtMath.floorf(this.thisEntity.width + 1.0F);
if (i != l || k != i1)
{
Block block = this.thisEntity.worldObj.getState(new BlockPos(i, j, k)).getBlock();
boolean flag = !this.isStairOrSlab(block) && (block.getMaterial() != Material.air || !this.isStairOrSlab(this.thisEntity.worldObj.getState(new BlockPos(i, j - 1, k)).getBlock()));
if (flag && 0 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j, i1, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, i, j + 1, k, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j + 1, i1, j1, k1, l1, false, false, true))
{
entitycreature.getJumpHelper().setJumping();
}
}
if (/* !entityplayer.creative && */ this.currentSpeed >= this.maxSpeed * 0.5F && this.thisEntity.getRNG().floatv() < 0.006F && !this.speedBoosted)
{
ItemStack itemstack = entityplayer.getHeldItem();
if (itemstack != null && itemstack.getItem() == Items.carrot_on_a_stick)
{
itemstack.damageItem(1, entityplayer);
if (itemstack.stackSize == 0)
{
ItemStack itemstack1 = new ItemStack(Items.fishing_rod);
itemstack1.setTagCompound(itemstack.getTagCompound());
entityplayer.inventory.mainInventory[entityplayer.inventory.currentItem] = itemstack1;
}
}
}
this.thisEntity.moveEntityWithHeading(0.0F, f1);
}
/**
* True if the block is a stair block or a slab block
*/
private boolean isStairOrSlab(Block blockIn)
{
return blockIn instanceof BlockStairs || blockIn instanceof BlockSlab;
}
/**
* Return whether the entity's speed is boosted.
*/
public boolean isSpeedBoosted()
{
return this.speedBoosted;
}
/**
* Boost the entity's movement speed.
*/
public void boostSpeed()
{
this.speedBoosted = true;
this.speedBoostTime = 0;
this.maxSpeedBoostTime = this.thisEntity.getRNG().zrange(841) + 140;
}
/**
* Return whether the entity is being controlled by a player.
*/
public boolean isControlledByPlayer()
{
return !this.isSpeedBoosted() && this.currentSpeed > this.maxSpeed * 0.3F;
}
}

View file

@ -0,0 +1,118 @@
package game.ai;
import game.block.Block;
import game.block.BlockDoor;
import game.entity.types.EntityLiving;
import game.material.Material;
import game.pathfinding.PathEntity;
import game.pathfinding.PathNavigateGround;
import game.pathfinding.PathPoint;
import game.world.BlockPos;
public abstract class EntityAIDoorInteract extends EntityAIBase
{
protected EntityLiving theEntity;
protected BlockPos doorPosition = BlockPos.ORIGIN;
/** The wooden door block */
protected BlockDoor doorBlock;
/**
* If is true then the Entity has stopped Door Interaction and compoleted the task.
*/
boolean hasStoppedDoorInteraction;
float entityPositionX;
float entityPositionZ;
public EntityAIDoorInteract(EntityLiving entityIn)
{
this.theEntity = entityIn;
if (!(entityIn.getNavigator() instanceof PathNavigateGround))
{
throw new IllegalArgumentException("Unsupported mob type for DoorInteractGoal");
}
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (!this.theEntity.collidedHorizontally)
{
return false;
}
else
{
PathNavigateGround pathnavigateground = (PathNavigateGround)this.theEntity.getNavigator();
PathEntity pathentity = pathnavigateground.getPath();
if (pathentity != null && !pathentity.isFinished() && pathnavigateground.getEnterDoors())
{
for (int i = 0; i < Math.min(pathentity.getCurrentPathIndex() + 2, pathentity.getCurrentPathLength()); ++i)
{
PathPoint pathpoint = pathentity.getPathPointFromIndex(i);
this.doorPosition = new BlockPos(pathpoint.xCoord, pathpoint.yCoord + 1, pathpoint.zCoord);
if (this.theEntity.getDistanceSq((double)this.doorPosition.getX(), this.theEntity.posY, (double)this.doorPosition.getZ()) <= 2.25D)
{
this.doorBlock = this.getBlockDoor(this.doorPosition);
if (this.doorBlock != null)
{
return true;
}
}
}
this.doorPosition = (new BlockPos(this.theEntity)).up();
this.doorBlock = this.getBlockDoor(this.doorPosition);
return this.doorBlock != null;
}
else
{
return false;
}
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.hasStoppedDoorInteraction;
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.hasStoppedDoorInteraction = false;
this.entityPositionX = (float)((double)((float)this.doorPosition.getX() + 0.5F) - this.theEntity.posX);
this.entityPositionZ = (float)((double)((float)this.doorPosition.getZ() + 0.5F) - this.theEntity.posZ);
}
/**
* Updates the task
*/
public void updateTask()
{
float f = (float)((double)((float)this.doorPosition.getX() + 0.5F) - this.theEntity.posX);
float f1 = (float)((double)((float)this.doorPosition.getZ() + 0.5F) - this.theEntity.posZ);
float f2 = this.entityPositionX * f + this.entityPositionZ * f1;
if (f2 < 0.0F)
{
this.hasStoppedDoorInteraction = true;
}
}
private BlockDoor getBlockDoor(BlockPos pos)
{
Block block = this.theEntity.worldObj.getState(pos).getBlock();
return block instanceof BlockDoor && block.getMaterial() == Material.wood ? (BlockDoor)block : null;
}
}

View file

@ -0,0 +1,118 @@
package game.ai;
import java.util.function.Predicate;
import game.Predicates;
import game.block.BlockTallGrass;
import game.entity.animal.EntitySheep;
import game.init.BlockRegistry;
import game.init.Blocks;
import game.init.Config;
import game.pattern.BlockStateHelper;
import game.world.BlockPos;
import game.world.State;
import game.world.World;
public class EntityAIEatGrass extends EntityAIBase
{
private static final Predicate<State> field_179505_b = BlockStateHelper.forBlock(Blocks.tallgrass).where(BlockTallGrass.TYPE, Predicates.equalTo(BlockTallGrass.EnumType.GRASS));
private EntitySheep grassEaterEntity;
private World entityWorld;
int eatingGrassTimer;
public EntityAIEatGrass(EntitySheep grassEaterEntityIn)
{
this.grassEaterEntity = grassEaterEntityIn;
this.entityWorld = grassEaterEntityIn.worldObj;
this.setMutexBits(7);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (this.grassEaterEntity.getRNG().zrange(this.grassEaterEntity.isChild() ? 50 : 1000) != 0)
{
return false;
}
else
{
BlockPos blockpos = new BlockPos(this.grassEaterEntity.posX, this.grassEaterEntity.posY, this.grassEaterEntity.posZ);
return field_179505_b.test(this.entityWorld.getState(blockpos)) ? true : this.entityWorld.getState(blockpos.down()).getBlock() == Blocks.grass;
}
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.eatingGrassTimer = 40;
this.entityWorld.setEntityState(this.grassEaterEntity, (byte)10);
this.grassEaterEntity.getNavigator().clearPathEntity();
}
/**
* Resets the task
*/
public void resetTask()
{
this.eatingGrassTimer = 0;
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return this.eatingGrassTimer > 0;
}
/**
* Number of ticks since the entity started to eat grass
*/
public int getEatingGrassTimer()
{
return this.eatingGrassTimer;
}
/**
* Updates the task
*/
public void updateTask()
{
this.eatingGrassTimer = Math.max(0, this.eatingGrassTimer - 1);
if (this.eatingGrassTimer == 4)
{
BlockPos blockpos = new BlockPos(this.grassEaterEntity.posX, this.grassEaterEntity.posY, this.grassEaterEntity.posZ);
if (field_179505_b.test(this.entityWorld.getState(blockpos)))
{
if (Config.mobGrief)
{
this.entityWorld.destroyBlock(blockpos, false);
}
this.grassEaterEntity.eatGrassBonus();
}
else
{
BlockPos blockpos1 = blockpos.down();
if (this.entityWorld.getState(blockpos1).getBlock() == Blocks.grass)
{
if (Config.mobGrief)
{
this.entityWorld.playAuxSFX(2001, blockpos1, BlockRegistry.getIdFromBlock(Blocks.grass));
this.entityWorld.setState(blockpos1, Blocks.dirt.getState(), 2);
}
this.grassEaterEntity.eatGrassBonus();
}
}
}
}
}

View file

@ -0,0 +1,65 @@
package game.ai;
import game.entity.npc.EntityHaunter;
import game.entity.types.EntityLiving;
public class EntityAIExplode extends EntityAIBase
{
EntityHaunter entity;
EntityLiving target;
public EntityAIExplode(EntityHaunter entity)
{
this.entity = entity;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
EntityLiving entitylivingbase = this.entity.getAttackTarget();
return this.entity.getExplodeState() > 0 || entitylivingbase != null && this.entity.getDistanceSqToEntity(entitylivingbase) < 9.0D;
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.entity.getNavigator().clearPathEntity();
this.target = this.entity.getAttackTarget();
}
/**
* Resets the task
*/
public void resetTask()
{
this.target = null;
}
/**
* Updates the task
*/
public void updateTask()
{
if (this.target == null)
{
this.entity.setExplodeState(-1);
}
else if (this.entity.getDistanceSqToEntity(this.target) > 49.0D)
{
this.entity.setExplodeState(-1);
}
else if (!this.entity.getEntitySenses().canSee(this.target))
{
this.entity.setExplodeState(-1);
}
else
{
this.entity.setExplodeState(1);
}
}
}

View file

@ -0,0 +1,111 @@
package game.ai;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import game.entity.attributes.AttributeInstance;
import game.entity.attributes.Attributes;
import game.entity.types.EntityLiving;
public class EntityAIFindEntityNearest extends EntityAIBase
{
private EntityLiving mob;
private final Predicate<EntityLiving> field_179443_c;
private final EntityAINearestAttackableTarget.Sorter field_179440_d;
private EntityLiving target;
private Class <? extends EntityLiving > field_179439_f;
public EntityAIFindEntityNearest(EntityLiving mobIn, Class <? extends EntityLiving > p_i45884_2_)
{
this.mob = mobIn;
this.field_179439_f = p_i45884_2_;
// if (mobIn instanceof EntityCreature)
// {
// Log.CONFIG.warn("Nutze NearestAttackableTargetGoal.class für PathfinderMob-Mobs!");
// }
this.field_179443_c = new Predicate<EntityLiving>()
{
public boolean test(EntityLiving p_apply_1_)
{
double d0 = EntityAIFindEntityNearest.this.getFollowRange();
if (p_apply_1_.isSneaking())
{
d0 *= 0.800000011920929D;
}
return (double)p_apply_1_.getDistanceToEntity(EntityAIFindEntityNearest.this.mob) > d0 ? false : EntityAITarget.isSuitableTarget(EntityAIFindEntityNearest.this.mob, p_apply_1_, true);
}
};
this.field_179440_d = new EntityAINearestAttackableTarget.Sorter(mobIn);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
double d0 = this.getFollowRange();
List<EntityLiving> list = this.mob.worldObj.<EntityLiving>getEntitiesWithinAABB(this.field_179439_f, this.mob.getEntityBoundingBox().expand(d0, 4.0D, d0), this.field_179443_c);
Collections.sort(list, this.field_179440_d);
if (list.isEmpty())
{
return false;
}
else
{
this.target = (EntityLiving)list.get(0);
return true;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
EntityLiving entitylivingbase = this.mob.getAttackTarget();
if (entitylivingbase == null)
{
return false;
}
else if (!entitylivingbase.isEntityAlive())
{
return false;
}
else
{
double d0 = this.getFollowRange();
return this.mob.getDistanceSqToEntity(entitylivingbase) <= d0 * d0; // ? false : !(entitylivingbase.isPlayer()) || !((EntityNPCMP)entitylivingbase).creative;
}
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.mob.setAttackTarget(this.target);
super.startExecuting();
}
/**
* Resets the task
*/
public void resetTask()
{
this.mob.setAttackTarget((EntityLiving)null);
super.startExecuting();
}
protected double getFollowRange()
{
AttributeInstance iattributeinstance = this.mob.getEntityAttribute(Attributes.FOLLOW_RANGE);
return iattributeinstance == null ? 16.0D : iattributeinstance.getAttributeValue();
}
}

View file

@ -0,0 +1,95 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.rng.Random;
import game.world.BlockPos;
import game.world.Vec3;
import game.world.World;
import game.world.WorldServer;
public class EntityAIFleeSun extends EntityAIBase
{
private EntityLiving theCreature;
private double shelterX;
private double shelterY;
private double shelterZ;
private double movementSpeed;
private World theWorld;
public EntityAIFleeSun(EntityLiving theCreatureIn, double movementSpeedIn)
{
this.theCreature = theCreatureIn;
this.movementSpeed = movementSpeedIn;
this.theWorld = theCreatureIn.worldObj;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (!((WorldServer)this.theWorld).isDaytime())
{
return false;
}
else if (!this.theCreature.isBurning())
{
return false;
}
else if (!this.theWorld.canSeeSky(new BlockPos(this.theCreature.posX, this.theCreature.getEntityBoundingBox().minY, this.theCreature.posZ)))
{
return false;
}
else
{
Vec3 vec3 = this.findPossibleShelter();
if (vec3 == null)
{
return false;
}
else
{
this.shelterX = vec3.xCoord;
this.shelterY = vec3.yCoord;
this.shelterZ = vec3.zCoord;
return true;
}
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.theCreature.getNavigator().noPath();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.theCreature.getNavigator().tryMoveToXYZ(this.shelterX, this.shelterY, this.shelterZ, this.movementSpeed);
}
private Vec3 findPossibleShelter()
{
Random random = this.theCreature.getRNG();
BlockPos blockpos = new BlockPos(this.theCreature.posX, this.theCreature.getEntityBoundingBox().minY, this.theCreature.posZ);
for (int i = 0; i < 10; ++i)
{
BlockPos blockpos1 = blockpos.add(random.zrange(20) - 10, random.zrange(6) - 3, random.zrange(20) - 10);
if (!this.theWorld.canSeeSky(blockpos1) && this.theCreature.getBlockPathWeight(blockpos1) < 0.0F)
{
return new Vec3((double)blockpos1.getX(), (double)blockpos1.getY(), (double)blockpos1.getZ());
}
}
return null;
}
}

View file

@ -0,0 +1,148 @@
package game.ai;
import game.block.Block;
import game.entity.types.EntityLiving;
import game.entity.types.EntityTameable;
import game.init.Blocks;
import game.pathfinding.PathNavigate;
import game.pathfinding.PathNavigateGround;
import game.world.BlockPos;
import game.world.State;
import game.world.World;
public class EntityAIFollowOwner extends EntityAIBase
{
private EntityTameable thePet;
private EntityLiving theOwner;
World theWorld;
private double followSpeed;
private PathNavigate petPathfinder;
private int field_75343_h;
float maxDist;
float minDist;
private boolean field_75344_i;
public EntityAIFollowOwner(EntityTameable thePetIn, double followSpeedIn, float minDistIn, float maxDistIn)
{
this.thePet = thePetIn;
this.theWorld = thePetIn.worldObj;
this.followSpeed = followSpeedIn;
this.petPathfinder = thePetIn.getNavigator();
this.minDist = minDistIn;
this.maxDist = maxDistIn;
this.setMutexBits(3);
if (!(thePetIn.getNavigator() instanceof PathNavigateGround))
{
throw new IllegalArgumentException("Unsupported mob type for FollowOwnerGoal");
}
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
EntityLiving entitylivingbase = this.thePet.getOwner();
if (entitylivingbase == null)
{
return false;
}
// else if (entitylivingbase.isPlayer() && ((EntityNPC)entitylivingbase).isSpectator())
// {
// return false;
// }
else if (this.thePet.isSitting())
{
return false;
}
else if (this.thePet.getDistanceSqToEntity(entitylivingbase) < (double)(this.minDist * this.minDist))
{
return false;
}
else
{
this.theOwner = entitylivingbase;
return true;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.petPathfinder.noPath() && this.thePet.getDistanceSqToEntity(this.theOwner) > (double)(this.maxDist * this.maxDist) && !this.thePet.isSitting();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.field_75343_h = 0;
this.field_75344_i = ((PathNavigateGround)this.thePet.getNavigator()).getAvoidsWater();
((PathNavigateGround)this.thePet.getNavigator()).setAvoidsWater(false);
}
/**
* Resets the task
*/
public void resetTask()
{
this.theOwner = null;
this.petPathfinder.clearPathEntity();
((PathNavigateGround)this.thePet.getNavigator()).setAvoidsWater(true);
}
private boolean func_181065_a(BlockPos p_181065_1_)
{
State iblockstate = this.theWorld.getState(p_181065_1_);
Block block = iblockstate.getBlock();
return block == Blocks.air ? true : !block.isFullCube();
}
/**
* Updates the task
*/
public void updateTask()
{
this.thePet.getLookHelper().setLookPositionWithEntity(this.theOwner, 10.0F, (float)this.thePet.getVerticalFaceSpeed());
if (!this.thePet.isSitting())
{
if (--this.field_75343_h <= 0)
{
this.field_75343_h = 10;
if (!this.petPathfinder.tryMoveToEntityLiving(this.theOwner, this.followSpeed))
{
this.petPathfinder.clearPathEntity();
// if (!this.thePet.getLeashed())
// {
// if (this.thePet.getDistanceSqToEntity(this.theOwner) >= 144.0D)
// {
// int i = ExtMath.floord(this.theOwner.posX) - 2;
// int j = ExtMath.floord(this.theOwner.posZ) - 2;
// int k = ExtMath.floord(this.theOwner.getEntityBoundingBox().minY);
//
// for (int l = 0; l <= 4; ++l)
// {
// for (int i1 = 0; i1 <= 4; ++i1)
// {
// if ((l < 1 || i1 < 1 || l > 3 || i1 > 3) && this.theWorld.isBlockSolid(new BlockPos(i + l, k - 1, j + i1)) && this.func_181065_a(new BlockPos(i + l, k, j + i1)) && this.func_181065_a(new BlockPos(i + l, k + 1, j + i1)))
// {
// this.thePet.setLocationAndAngles((double)((float)(i + l) + 0.5F), (double)k, (double)((float)(j + i1) + 0.5F), this.thePet.rotYaw, this.thePet.rotPitch);
// this.petPathfinder.clearPathEntity();
// return;
// }
// }
// }
// }
// }
}
}
}
}
}

View file

@ -0,0 +1,112 @@
package game.ai;
import java.util.List;
import game.entity.types.EntityAnimal;
public class EntityAIFollowParent extends EntityAIBase
{
private EntityAnimal childAnimal;
private EntityAnimal parentAnimal;
private double speed;
private int delay;
public EntityAIFollowParent(EntityAnimal animal, double speed)
{
this.childAnimal = animal;
this.speed = speed;
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (!this.childAnimal.isChild())
{
return false;
}
else
{
List<EntityAnimal> list = this.childAnimal.worldObj.<EntityAnimal>getEntitiesWithinAABB(this.childAnimal.getClass(), this.childAnimal.getEntityBoundingBox().expand(8.0D, 4.0D, 8.0D));
EntityAnimal entityanimal = null;
double d0 = Double.MAX_VALUE;
for (EntityAnimal entityanimal1 : list)
{
if (!entityanimal1.isChild())
{
double d1 = this.childAnimal.getDistanceSqToEntity(entityanimal1);
if (d1 <= d0)
{
d0 = d1;
entityanimal = entityanimal1;
}
}
}
if (entityanimal == null)
{
return false;
}
else if (d0 < 9.0D)
{
return false;
}
else
{
this.parentAnimal = entityanimal;
return true;
}
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
if (!this.childAnimal.isChild())
{
return false;
}
else if (!this.parentAnimal.isEntityAlive())
{
return false;
}
else
{
double d0 = this.childAnimal.getDistanceSqToEntity(this.parentAnimal);
return d0 >= 9.0D && d0 <= 256.0D;
}
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.delay = 0;
}
/**
* Resets the task
*/
public void resetTask()
{
this.parentAnimal = null;
}
/**
* Updates the task
*/
public void updateTask()
{
if (--this.delay <= 0)
{
this.delay = 10;
this.childAnimal.getNavigator().tryMoveToEntityLiving(this.parentAnimal, this.speed);
}
}
}

View file

@ -0,0 +1,159 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.world.BlockPos;
import game.world.World;
public class EntityAIHarvestFarmland extends EntityAIMoveToBlock
{
// /** Villager that is harvesting */
// private final EntityVillager theVillager;
// private boolean hasFarmItem;
// private boolean field_179503_e;
// private int field_179501_f;
//
public EntityAIHarvestFarmland(EntityLiving entity, double speedIn)
{
super(entity, speedIn, 16);
// this.theVillager = theVillagerIn;
}
//
// /**
// * Returns whether the EntityAIBase should begin execution.
// */
// public boolean shouldExecute()
// {
// if (this.runDelay <= 0)
// {
// if (!Config.mobGriefing || this.theVillager.isChild())
// {
// return false;
// }
//
// this.field_179501_f = -1;
// this.hasFarmItem = this.theVillager.hasFarmItem();
// this.field_179503_e = this.theVillager.needsMoreItems();
// }
//
// return super.shouldExecute();
// }
//
// /**
// * Returns whether an in-progress EntityAIBase should continue executing
// */
// public boolean continueExecuting()
// {
// return this.field_179501_f >= 0 && super.continueExecuting();
// }
//
// /**
// * Execute a one shot task or start executing a continuous task
// */
// public void startExecuting()
// {
// super.startExecuting();
// }
//
// /**
// * Resets the task
// */
// public void resetTask()
// {
// super.resetTask();
// }
//
// /**
// * Updates the task
// */
// public void updateTask()
// {
// super.updateTask();
// this.theVillager.getLookHelper().setLookPosition((double)this.destinationBlock.getX() + 0.5D, (double)(this.destinationBlock.getY() + 1), (double)this.destinationBlock.getZ() + 0.5D, 10.0F, (float)this.theVillager.getVerticalFaceSpeed());
//
// if (this.getIsAboveDestination())
// {
// World world = this.theVillager.worldObj;
// BlockPos blockpos = this.destinationBlock.up();
// IBlockState iblockstate = world.getBlockState(blockpos);
// Block block = iblockstate.getBlock();
//
// if (this.field_179501_f == 0 && block instanceof BlockCrops && ((Integer)iblockstate.getValue(BlockCrops.AGE)).intValue() == 7)
// {
// world.destroyBlock(blockpos, true);
// }
// else if (this.field_179501_f == 1 && block == Blocks.air)
// {
// InventoryBasic inventorybasic = this.theVillager.getFarmInventory();
//
// for (int i = 0; i < inventorybasic.getSizeInventory(); ++i)
// {
// ItemStack itemstack = inventorybasic.getStackInSlot(i);
// boolean flag = false;
//
// if (itemstack != null)
// {
// if (itemstack.getItem() == Items.wheat_seeds)
// {
// world.setBlockState(blockpos, Blocks.wheat.getDefaultState(), 3);
// flag = true;
// }
// else if (itemstack.getItem() == Items.potato)
// {
// world.setBlockState(blockpos, Blocks.potatoes.getDefaultState(), 3);
// flag = true;
// }
// else if (itemstack.getItem() == Items.carrot)
// {
// world.setBlockState(blockpos, Blocks.carrots.getDefaultState(), 3);
// flag = true;
// }
// }
//
// if (flag)
// {
// --itemstack.stackSize;
//
// if (itemstack.stackSize <= 0)
// {
// inventorybasic.setInventorySlotContents(i, (ItemStack)null);
// }
//
// break;
// }
// }
// }
//
// this.field_179501_f = -1;
// this.runDelay = 10;
// }
// }
//
// /**
// * Return true to set given position as destination
// */
protected boolean shouldMoveTo(World worldIn, BlockPos pos)
{
// Block block = worldIn.getBlockState(pos).getBlock();
//
// if (block == Blocks.farmland)
// {
// pos = pos.up();
// IBlockState iblockstate = worldIn.getBlockState(pos);
// block = iblockstate.getBlock();
//
// if (block instanceof BlockCrops && ((Integer)iblockstate.getValue(BlockCrops.AGE)).intValue() == 7 && this.field_179503_e && (this.field_179501_f == 0 || this.field_179501_f < 0))
// {
// this.field_179501_f = 0;
// return true;
// }
//
// if (block == Blocks.air && this.hasFarmItem && (this.field_179501_f == 1 || this.field_179501_f < 0))
// {
// this.field_179501_f = 1;
// return true;
// }
// }
return false;
}
}

View file

@ -0,0 +1,73 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.world.BoundingBox;
public class EntityAIHurtByTarget extends EntityAITarget
{
private boolean entityCallsForHelp;
/** Store the previous revengeTimer value */
private int revengeTimerOld;
private final Class[] targetClasses;
public EntityAIHurtByTarget(EntityLiving creatureIn, boolean entityCallsForHelpIn, Class... targetClassesIn)
{
super(creatureIn, false);
this.entityCallsForHelp = entityCallsForHelpIn;
this.targetClasses = targetClassesIn;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
int i = this.taskOwner.getAttackedTime();
return i != this.revengeTimerOld && this.isSuitableTarget(this.taskOwner.getAttackedBy());
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.taskOwner.setAttackTarget(this.taskOwner.getAttackedBy());
this.revengeTimerOld = this.taskOwner.getAttackedTime();
if (this.entityCallsForHelp)
{
double d0 = this.getTargetDistance();
for (EntityLiving entitycreature : this.taskOwner.worldObj.getEntitiesWithinAABB(this.taskOwner.getClass(), (new BoundingBox(this.taskOwner.posX, this.taskOwner.posY, this.taskOwner.posZ, this.taskOwner.posX + 1.0D, this.taskOwner.posY + 1.0D, this.taskOwner.posZ + 1.0D)).expand(d0, 10.0D, d0)))
{
if (this.taskOwner != entitycreature && /* !(entitycreature.isPlayer()) && */ entitycreature.getAttackTarget() == null) // && !entitycreature.isOnSameTeam(this.taskOwner.getAITarget()))
{
boolean flag = false;
for (Class oclass : this.targetClasses)
{
if (entitycreature.getClass() == oclass)
{
flag = true;
break;
}
}
if (!flag)
{
this.setEntityAttackTarget(entitycreature, this.taskOwner.getAttackedBy());
}
}
}
}
super.startExecuting();
}
protected void setEntityAttackTarget(EntityLiving creatureIn, EntityLiving entityLivingBaseIn)
{
creatureIn.setAttackTarget(entityLivingBaseIn);
}
}

View file

@ -0,0 +1,62 @@
package game.ai;
import game.ExtMath;
import game.entity.types.EntityLiving;
public class EntityAILeapAtTarget extends EntityAIBase
{
/** The entity that is leaping. */
EntityLiving leaper;
/** The entity that the leaper is leaping towards. */
EntityLiving leapTarget;
/** The entity's motionY after leaping. */
float leapMotionY;
public EntityAILeapAtTarget(EntityLiving leapingEntity, float leapMotionYIn)
{
this.leaper = leapingEntity;
this.leapMotionY = leapMotionYIn;
this.setMutexBits(5);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
this.leapTarget = this.leaper.getAttackTarget();
if (this.leapTarget == null)
{
return false;
}
else
{
double d0 = this.leaper.getDistanceSqToEntity(this.leapTarget);
return d0 >= 4.0D && d0 <= 16.0D ? (!this.leaper.onGround ? false : this.leaper.getRNG().zrange(5) == 0) : false;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.leaper.onGround;
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
double d0 = this.leapTarget.posX - this.leaper.posX;
double d1 = this.leapTarget.posZ - this.leaper.posZ;
float f = ExtMath.sqrtd(d0 * d0 + d1 * d1);
this.leaper.motionX += d0 / (double)f * 0.5D * 0.800000011920929D + this.leaper.motionX * 0.20000000298023224D;
this.leaper.motionZ += d1 / (double)f * 0.5D * 0.800000011920929D + this.leaper.motionZ * 0.20000000298023224D;
this.leaper.motionY = (double)this.leapMotionY;
}
}

View file

@ -0,0 +1,27 @@
package game.ai;
import game.entity.npc.EntityNPC;
public class EntityAILookAtTalkingPlayer extends EntityAIWatchClosest
{
private final EntityNPC npc;
public EntityAILookAtTalkingPlayer(EntityNPC npc)
{
super(npc, null, 8.0F);
this.npc = npc;
}
public boolean shouldExecute()
{
if (this.npc.isTalking() && this.npc.getAttackTarget() == null)
{
this.closestEntity = this.npc.getTalking();
return true;
}
else
{
return false;
}
}
}

View file

@ -0,0 +1,62 @@
package game.ai;
import game.entity.types.EntityLiving;
public class EntityAILookIdle extends EntityAIBase
{
/** The entity that is looking idle. */
private EntityLiving idleEntity;
/** X offset to look at */
private double lookX;
/** Z offset to look at */
private double lookZ;
/**
* A decrementing tick that stops the entity from being idle once it reaches 0.
*/
private int idleTime;
public EntityAILookIdle(EntityLiving entitylivingIn)
{
this.idleEntity = entitylivingIn;
this.setMutexBits(3);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
return this.idleEntity.getRNG().floatv() < 0.02F;
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return this.idleTime >= 0;
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
double d0 = (Math.PI * 2D) * this.idleEntity.getRNG().doublev();
this.lookX = Math.cos(d0);
this.lookZ = Math.sin(d0);
this.idleTime = 20 + this.idleEntity.getRNG().zrange(20);
}
/**
* Updates the task
*/
public void updateTask()
{
--this.idleTime;
this.idleEntity.getLookHelper().setLookPosition(this.idleEntity.posX + this.lookX, this.idleEntity.posY + (double)this.idleEntity.getEyeHeight(), this.idleEntity.posZ + this.lookZ, 10.0F, (float)this.idleEntity.getVerticalFaceSpeed());
}
}

View file

@ -0,0 +1,167 @@
package game.ai;
import java.util.List;
import game.entity.item.EntityXp;
import game.entity.npc.EntityNPC;
import game.entity.types.EntityAnimal;
import game.entity.types.EntityLiving;
import game.init.Config;
import game.renderer.particle.ParticleType;
import game.rng.Random;
import game.world.World;
public class EntityAIMate extends EntityAIBase
{
private EntityAnimal theAnimal;
World theWorld;
private EntityAnimal targetMate;
/**
* Delay preventing a baby from spawning immediately when two mate-able animals find each other.
*/
int spawnBabyDelay;
/** The speed the creature moves at during mating behavior. */
double moveSpeed;
public EntityAIMate(EntityAnimal animal, double speedIn)
{
this.theAnimal = animal;
this.theWorld = animal.worldObj;
this.moveSpeed = speedIn;
this.setMutexBits(3);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (!this.theAnimal.isInLove())
{
return false;
}
else
{
this.targetMate = this.getNearbyMate();
return this.targetMate != null;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return this.targetMate.isEntityAlive() && this.targetMate.isInLove() && this.spawnBabyDelay < 60;
}
/**
* Resets the task
*/
public void resetTask()
{
this.targetMate = null;
this.spawnBabyDelay = 0;
}
/**
* Updates the task
*/
public void updateTask()
{
this.theAnimal.getLookHelper().setLookPositionWithEntity(this.targetMate, 10.0F, (float)this.theAnimal.getVerticalFaceSpeed());
this.theAnimal.getNavigator().tryMoveToEntityLiving(this.targetMate, this.moveSpeed);
++this.spawnBabyDelay;
if (this.spawnBabyDelay >= 60 && this.theAnimal.getDistanceSqToEntity(this.targetMate) < 9.0D)
{
this.spawnBaby();
}
}
protected int getGrowingAge() {
return 24000;
}
protected int getMatingCooldown() {
return 6000;
}
/**
* Loops through nearby animals and finds another animal of the same type that can be mated with. Returns the first
* valid mate found.
*/
private EntityAnimal getNearbyMate()
{
float f = 8.0F;
List<EntityAnimal> list = this.theWorld.<EntityAnimal>getEntitiesWithinAABB(this.theAnimal.getClass(), this.theAnimal.getEntityBoundingBox().expand((double)f, (double)f, (double)f));
double d0 = Double.MAX_VALUE;
EntityAnimal entityanimal = null;
for (EntityAnimal entityanimal1 : list)
{
if (this.theAnimal.canMateWith(entityanimal1) && this.theAnimal.getDistanceSqToEntity(entityanimal1) < d0)
{
entityanimal = entityanimal1;
d0 = this.theAnimal.getDistanceSqToEntity(entityanimal1);
}
}
return entityanimal;
}
/**
* Spawns a baby animal of the same type.
*/
private void spawnBaby()
{
EntityLiving entityageable = this.theAnimal.createChild(this.targetMate);
if (entityageable != null)
{
EntityNPC entityplayer = this.theAnimal.getPlayerInLove();
if (entityplayer == null && this.targetMate.getPlayerInLove() != null)
{
entityplayer = this.targetMate.getPlayerInLove();
}
// if (entityplayer != null)
// {
// entityplayer.triggerAchievement(StatRegistry.animalsBredStat);
//
//// if (this.theAnimal instanceof EntityCow)
//// {
//// entityplayer.triggerAchievement(AchievementList.breedCow);
//// }
// }
this.theAnimal.setGrowingAge(this.getMatingCooldown());
this.targetMate.setGrowingAge(this.getMatingCooldown());
this.theAnimal.resetInLove();
this.targetMate.resetInLove();
entityageable.setGrowingAge(-this.getGrowingAge());
entityageable.setLocationAndAngles(this.theAnimal.posX, this.theAnimal.posY, this.theAnimal.posZ, 0.0F, 0.0F);
this.theWorld.spawnEntityInWorld(entityageable);
Random random = this.theAnimal.getRNG();
for (int i = 0; i < 7; ++i)
{
double d0 = random.gaussian() * 0.02D;
double d1 = random.gaussian() * 0.02D;
double d2 = random.gaussian() * 0.02D;
double d3 = random.doublev() * (double)this.theAnimal.width * 2.0D - (double)this.theAnimal.width;
double d4 = 0.5D + random.doublev() * (double)this.theAnimal.height;
double d5 = random.doublev() * (double)this.theAnimal.width * 2.0D - (double)this.theAnimal.width;
this.theWorld.spawnParticle(ParticleType.HEART, this.theAnimal.posX + d3, this.theAnimal.posY + d4, this.theAnimal.posZ + d5, d0, d1, d2);
}
if (entityplayer != null && Config.breedingXP) // FIX xp
{
this.theWorld.spawnEntityInWorld(new EntityXp(this.theWorld, this.theAnimal.posX, this.theAnimal.posY, this.theAnimal.posZ, random.zrange(7) + 1));
}
}
}
}

View file

@ -0,0 +1,104 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.village.Village;
import game.village.VillageDoorInfo;
import game.world.BlockPos;
import game.world.Vec3;
import game.world.WorldServer;
public class EntityAIMoveIndoors extends EntityAIBase
{
private EntityLiving entityObj;
private VillageDoorInfo doorInfo;
private int insidePosX = -1;
private int insidePosZ = -1;
public EntityAIMoveIndoors(EntityLiving entityObjIn)
{
this.entityObj = entityObjIn;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
BlockPos blockpos = new BlockPos(this.entityObj);
if ((!((WorldServer)this.entityObj.worldObj).isDaytime() /* || this.entityObj.worldObj.isRaining() && !this.entityObj.worldObj.getBiomeGenForCoords(blockpos).canRain() */) && !this.entityObj.worldObj.dimension.hasNoLight())
{
if (this.entityObj.getRNG().zrange(50) != 0)
{
return false;
}
else if (this.insidePosX != -1 && this.entityObj.getDistanceSq((double)this.insidePosX, this.entityObj.posY, (double)this.insidePosZ) < 4.0D)
{
return false;
}
else
{
Village village = ((WorldServer)this.entityObj.worldObj).getNearestVillage(blockpos, 14);
if (village == null)
{
return false;
}
else
{
this.doorInfo = village.getDoorInfo(blockpos);
return this.doorInfo != null;
}
}
}
else
{
return false;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.entityObj.getNavigator().noPath();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.insidePosX = -1;
BlockPos blockpos = this.doorInfo.getInsideBlockPos();
int i = blockpos.getX();
int j = blockpos.getY();
int k = blockpos.getZ();
if (this.entityObj.getDistanceSq(blockpos) > 256.0D)
{
Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.entityObj, 14, 3, new Vec3((double)i + 0.5D, (double)j, (double)k + 0.5D));
if (vec3 != null)
{
this.entityObj.getNavigator().tryMoveToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord, 1.0D);
}
}
else
{
this.entityObj.getNavigator().tryMoveToXYZ((double)i + 0.5D, (double)j, (double)k + 0.5D, 1.0D);
}
}
/**
* Resets the task
*/
public void resetTask()
{
this.insidePosX = this.doorInfo.getInsideBlockPos().getX();
this.insidePosZ = this.doorInfo.getInsideBlockPos().getZ();
this.doorInfo = null;
}
}

View file

@ -0,0 +1,174 @@
package game.ai;
import java.util.List;
import game.ExtMath;
import game.collect.Lists;
import game.entity.types.EntityLiving;
import game.pathfinding.PathEntity;
import game.pathfinding.PathNavigateGround;
import game.village.Village;
import game.village.VillageDoorInfo;
import game.world.BlockPos;
import game.world.Vec3;
import game.world.WorldServer;
public class EntityAIMoveThroughVillage extends EntityAIBase
{
private EntityLiving theEntity;
private double movementSpeed;
/** The PathNavigate of our entity. */
private PathEntity entityPathNavigate;
private VillageDoorInfo doorInfo;
private boolean isNocturnal;
private List<VillageDoorInfo> doorList = Lists.<VillageDoorInfo>newArrayList();
public EntityAIMoveThroughVillage(EntityLiving theEntityIn, double movementSpeedIn, boolean isNocturnalIn)
{
this.theEntity = theEntityIn;
this.movementSpeed = movementSpeedIn;
this.isNocturnal = isNocturnalIn;
this.setMutexBits(1);
if (!(theEntityIn.getNavigator() instanceof PathNavigateGround))
{
throw new IllegalArgumentException("Unsupported mob for MoveThroughVillageGoal");
}
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
this.resizeDoorList();
if (this.isNocturnal && ((WorldServer)this.theEntity.worldObj).isDaytime())
{
return false;
}
else
{
Village village = ((WorldServer)this.theEntity.worldObj).getNearestVillage(new BlockPos(this.theEntity), 0);
if (village == null)
{
return false;
}
else
{
this.doorInfo = this.findNearestDoor(village);
if (this.doorInfo == null)
{
return false;
}
else
{
PathNavigateGround pathnavigateground = (PathNavigateGround)this.theEntity.getNavigator();
boolean flag = pathnavigateground.getEnterDoors();
pathnavigateground.setBreakDoors(false);
this.entityPathNavigate = pathnavigateground.getPathToPos(this.doorInfo.getDoorBlockPos());
pathnavigateground.setBreakDoors(flag);
if (this.entityPathNavigate != null)
{
return true;
}
else
{
Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 10, 7, new Vec3((double)this.doorInfo.getDoorBlockPos().getX(), (double)this.doorInfo.getDoorBlockPos().getY(), (double)this.doorInfo.getDoorBlockPos().getZ()));
if (vec3 == null)
{
return false;
}
else
{
pathnavigateground.setBreakDoors(false);
this.entityPathNavigate = this.theEntity.getNavigator().getPathToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord);
pathnavigateground.setBreakDoors(flag);
return this.entityPathNavigate != null;
}
}
}
}
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
if (this.theEntity.getNavigator().noPath())
{
return false;
}
else
{
float f = this.theEntity.width + 4.0F;
return this.theEntity.getDistanceSq(this.doorInfo.getDoorBlockPos()) > (double)(f * f);
}
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.theEntity.getNavigator().setPath(this.entityPathNavigate, this.movementSpeed);
}
/**
* Resets the task
*/
public void resetTask()
{
if (this.theEntity.getNavigator().noPath() || this.theEntity.getDistanceSq(this.doorInfo.getDoorBlockPos()) < 16.0D)
{
this.doorList.add(this.doorInfo);
}
}
private VillageDoorInfo findNearestDoor(Village villageIn)
{
VillageDoorInfo villagedoorinfo = null;
int i = Integer.MAX_VALUE;
for (VillageDoorInfo villagedoorinfo1 : villageIn.getDoorList())
{
int j = villagedoorinfo1.getDistanceSquared(ExtMath.floord(this.theEntity.posX), ExtMath.floord(this.theEntity.posY), ExtMath.floord(this.theEntity.posZ));
if (j < i && !this.doesDoorListContain(villagedoorinfo1))
{
villagedoorinfo = villagedoorinfo1;
i = j;
}
}
return villagedoorinfo;
}
private boolean doesDoorListContain(VillageDoorInfo doorInfoIn)
{
for (VillageDoorInfo villagedoorinfo : this.doorList)
{
if (doorInfoIn.getDoorBlockPos().equals(villagedoorinfo.getDoorBlockPos()))
{
return true;
}
}
return false;
}
private void resizeDoorList()
{
if (this.doorList.size() > 15)
{
this.doorList.remove(0);
}
}
}

View file

@ -0,0 +1,137 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.world.BlockPos;
import game.world.World;
public abstract class EntityAIMoveToBlock extends EntityAIBase
{
private final EntityLiving theEntity;
private final double movementSpeed;
/** Controls task execution delay */
protected int runDelay;
private int timeoutCounter;
private int field_179490_f;
/** Block to move to */
protected BlockPos destinationBlock = BlockPos.ORIGIN;
private boolean isAboveDestination;
private int searchLength;
public EntityAIMoveToBlock(EntityLiving creature, double speedIn, int length)
{
this.theEntity = creature;
this.movementSpeed = speedIn;
this.searchLength = length;
this.setMutexBits(5);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (this.runDelay > 0)
{
--this.runDelay;
return false;
}
else
{
this.runDelay = 200 + this.theEntity.getRNG().zrange(200);
return this.searchForDestination();
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return this.timeoutCounter >= -this.field_179490_f && this.timeoutCounter <= 1200 && this.shouldMoveTo(this.theEntity.worldObj, this.destinationBlock);
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.theEntity.getNavigator().tryMoveToXYZ((double)((float)this.destinationBlock.getX()) + 0.5D, (double)(this.destinationBlock.getY() + 1), (double)((float)this.destinationBlock.getZ()) + 0.5D, this.movementSpeed);
this.timeoutCounter = 0;
this.field_179490_f = this.theEntity.getRNG().zrange(this.theEntity.getRNG().zrange(1200) + 1200) + 1200;
}
/**
* Resets the task
*/
public void resetTask()
{
}
/**
* Updates the task
*/
public void updateTask()
{
if (this.theEntity.getDistanceSqToCenter(this.destinationBlock.up()) > 1.0D)
{
this.isAboveDestination = false;
++this.timeoutCounter;
if (this.timeoutCounter % 40 == 0)
{
this.theEntity.getNavigator().tryMoveToXYZ((double)((float)this.destinationBlock.getX()) + 0.5D, (double)(this.destinationBlock.getY() + 1), (double)((float)this.destinationBlock.getZ()) + 0.5D, this.movementSpeed);
}
}
else
{
this.isAboveDestination = true;
--this.timeoutCounter;
}
}
protected boolean getIsAboveDestination()
{
return this.isAboveDestination;
}
/**
* Searches and sets new destination block and returns true if a suitable block (specified in {@link
* game.ai.EntityAIMoveToBlock#shouldMoveTo(World, BlockPos) EntityAIMoveToBlock#shouldMoveTo(World,
* BlockPos)}) can be found.
*/
protected boolean searchForDestination()
{
int i = this.searchLength;
int j = 1;
BlockPos blockpos = new BlockPos(this.theEntity);
for (int k = 0; k <= 1; k = k > 0 ? -k : 1 - k)
{
for (int l = 0; l < i; ++l)
{
for (int i1 = 0; i1 <= l; i1 = i1 > 0 ? -i1 : 1 - i1)
{
for (int j1 = i1 < l && i1 > -l ? l : 0; j1 <= l; j1 = j1 > 0 ? -j1 : 1 - j1)
{
BlockPos blockpos1 = blockpos.add(i1, k - 1, j1);
if (this.theEntity.isWithinHomeDistanceFromPosition(blockpos1) && this.shouldMoveTo(this.theEntity.worldObj, blockpos1))
{
this.destinationBlock = blockpos1;
return true;
}
}
}
}
}
return false;
}
/**
* Return true to set given position as destination
*/
protected abstract boolean shouldMoveTo(World worldIn, BlockPos pos);
}

View file

@ -0,0 +1,65 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.world.BlockPos;
import game.world.Vec3;
public class EntityAIMoveTowardsRestriction extends EntityAIBase
{
private EntityLiving theEntity;
private double movePosX;
private double movePosY;
private double movePosZ;
private double movementSpeed;
public EntityAIMoveTowardsRestriction(EntityLiving creatureIn, double speedIn)
{
this.theEntity = creatureIn;
this.movementSpeed = speedIn;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (this.theEntity.isWithinHomeDistanceCurrentPosition())
{
return false;
}
else
{
BlockPos blockpos = this.theEntity.getHomePosition();
Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 16, 7, new Vec3((double)blockpos.getX(), (double)blockpos.getY(), (double)blockpos.getZ()));
if (vec3 == null)
{
return false;
}
else
{
this.movePosX = vec3.xCoord;
this.movePosY = vec3.yCoord;
this.movePosZ = vec3.zCoord;
return true;
}
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.theEntity.getNavigator().noPath();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.theEntity.getNavigator().tryMoveToXYZ(this.movePosX, this.movePosY, this.movePosZ, this.movementSpeed);
}
}

View file

@ -0,0 +1,84 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.world.Vec3;
public class EntityAIMoveTowardsTarget extends EntityAIBase
{
private EntityLiving theEntity;
private EntityLiving targetEntity;
private double movePosX;
private double movePosY;
private double movePosZ;
private double speed;
/**
* If the distance to the target entity is further than this, this AI task will not run.
*/
private float maxTargetDistance;
public EntityAIMoveTowardsTarget(EntityLiving creature, double speedIn, float targetMaxDistance)
{
this.theEntity = creature;
this.speed = speedIn;
this.maxTargetDistance = targetMaxDistance;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
this.targetEntity = this.theEntity.getAttackTarget();
if (this.targetEntity == null)
{
return false;
}
else if (this.targetEntity.getDistanceSqToEntity(this.theEntity) > (double)(this.maxTargetDistance * this.maxTargetDistance))
{
return false;
}
else
{
Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 16, 7, new Vec3(this.targetEntity.posX, this.targetEntity.posY, this.targetEntity.posZ));
if (vec3 == null)
{
return false;
}
else
{
this.movePosX = vec3.xCoord;
this.movePosY = vec3.yCoord;
this.movePosZ = vec3.zCoord;
return true;
}
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.theEntity.getNavigator().noPath() && this.targetEntity.isEntityAlive() && this.targetEntity.getDistanceSqToEntity(this.theEntity) < (double)(this.maxTargetDistance * this.maxTargetDistance);
}
/**
* Resets the task
*/
public void resetTask()
{
this.targetEntity = null;
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.theEntity.getNavigator().tryMoveToXYZ(this.movePosX, this.movePosY, this.movePosZ, this.speed);
}
}

View file

@ -0,0 +1,50 @@
package game.ai;
import game.entity.npc.EntityNPC;
import game.inventory.ContainerMerchant;
public class EntityAINagPlayer extends EntityAIBase
{
private EntityNPC npc;
public EntityAINagPlayer(EntityNPC npc)
{
this.npc = npc;
this.setMutexBits(5);
}
public boolean shouldExecute()
{
if (!this.npc.isEntityAlive())
{
return false;
}
else if (this.npc.isInLiquid())
{
return false;
}
else if (!this.npc.onGround)
{
return false;
}
else if (this.npc.veloChanged)
{
return false;
}
else
{
EntityNPC entityplayer = this.npc.getTalking();
return entityplayer == null ? false : (this.npc.getDistanceSqToEntity(entityplayer) > 16.0D ? false : entityplayer.openContainer instanceof ContainerMerchant);
}
}
public void startExecuting()
{
this.npc.getNavigator().clearPathEntity();
}
public void resetTask()
{
this.npc.setTalking(null);
}
}

View file

@ -0,0 +1,133 @@
package game.ai;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
import game.entity.Entity;
import game.entity.types.EntityLiving;
public class EntityAINearestAttackableTarget<T extends EntityLiving> extends EntityAITarget
{
protected final Class<T> targetClass;
private final int targetChance;
/** Instance of EntityAINearestAttackableTargetSorter. */
protected final EntityAINearestAttackableTarget.Sorter theNearestAttackableTargetSorter;
protected Predicate <? super T > targetEntitySelector;
protected EntityLiving targetEntity;
public EntityAINearestAttackableTarget(EntityLiving creature, Class<T> classTarget, boolean checkSight)
{
this(creature, classTarget, checkSight, false);
}
public EntityAINearestAttackableTarget(EntityLiving creature, Class<T> classTarget, boolean checkSight, boolean onlyNearby)
{
this(creature, classTarget, 10, checkSight, onlyNearby, (Predicate <? super T >)null);
}
public EntityAINearestAttackableTarget(EntityLiving creature, Class<T> classTarget, int chance, boolean checkSight, boolean onlyNearby, final Predicate <? super T > targetSelector)
{
super(creature, checkSight, onlyNearby);
this.targetClass = classTarget;
this.targetChance = chance;
this.theNearestAttackableTargetSorter = new EntityAINearestAttackableTarget.Sorter(creature);
this.setMutexBits(1);
this.targetEntitySelector = new Predicate<T>()
{
public boolean test(T p_apply_1_)
{
if (targetSelector != null && !targetSelector.test(p_apply_1_))
{
return false;
}
else
{
if (p_apply_1_.isPlayer())
{
double d0 = EntityAINearestAttackableTarget.this.getTargetDistance();
if (p_apply_1_.isSneaking())
{
d0 *= 0.800000011920929D;
}
// if (p_apply_1_.isInvisible())
// {
// float f = ((EntityNPC)p_apply_1_).getArmorVisibility();
//
// if (f < 0.1F)
// {
// f = 0.1F;
// }
//
// d0 *= (double)(0.7F * f);
// }
if ((double)p_apply_1_.getDistanceToEntity(EntityAINearestAttackableTarget.this.taskOwner) > d0)
{
return false;
}
}
return EntityAINearestAttackableTarget.this.isSuitableTarget(p_apply_1_);
}
}
};
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (this.targetChance > 0 && this.taskOwner.getRNG().zrange(this.targetChance) != 0)
{
return false;
}
else
{
double d0 = this.getTargetDistance();
List<T> list = this.taskOwner.worldObj.<T>getEntitiesWithinAABB(this.targetClass, this.taskOwner.getEntityBoundingBox().expand(d0, 4.0D, d0), this.targetEntitySelector);
Collections.sort(list, this.theNearestAttackableTargetSorter);
if (list.isEmpty())
{
return false;
}
else
{
this.targetEntity = (EntityLiving)list.get(0);
return true;
}
}
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.taskOwner.setAttackTarget(this.targetEntity);
super.startExecuting();
}
public static class Sorter implements Comparator<Entity>
{
private final Entity theEntity;
public Sorter(Entity theEntityIn)
{
this.theEntity = theEntityIn;
}
public int compare(Entity p_compare_1_, Entity p_compare_2_)
{
double d0 = this.theEntity.getDistanceSqToEntity(p_compare_1_);
double d1 = this.theEntity.getDistanceSqToEntity(p_compare_2_);
return d0 < d1 ? -1 : (d0 > d1 ? 1 : 0);
}
}
}

View file

@ -0,0 +1,56 @@
package game.ai;
import game.entity.npc.EntityNPC;
public class EntityAINpcInteract extends EntityAIWatchClosest2
{
private int interactionDelay;
private EntityNPC npc;
public EntityAINpcInteract(EntityNPC npc)
{
super(npc, EntityNPC.class, 3.0F, 0.02F);
this.npc = npc;
}
// public boolean shouldExecute()
// {
// if(super.shouldExecute()) {
// if(this.closestEntity.isPlayer()) {
// this.closestEntity = null;
// return false;
// }
// return true;
// }
// return false;
// }
public void startExecuting()
{
super.startExecuting();
if (this.closestEntity instanceof EntityNPC)
{
this.interactionDelay = 10;
}
else
{
this.interactionDelay = 0;
}
}
public void updateTask()
{
super.updateTask();
if (this.interactionDelay > 0)
{
--this.interactionDelay;
if (this.interactionDelay == 0)
{
}
}
}
}

View file

@ -0,0 +1,108 @@
package game.ai;
import game.entity.Entity;
import game.entity.npc.EntityNPC;
import game.world.World;
import game.world.WorldServer;
public class EntityAINpcMate extends EntityAIBase
{
private EntityNPC npc;
private EntityNPC mate;
private World worldObj;
private int matingTimeout;
public EntityAINpcMate(EntityNPC npc)
{
this.npc = npc;
this.worldObj = npc.worldObj;
this.setMutexBits(3);
}
public boolean shouldExecute()
{
if (this.npc.getGrowingAge() != 0)
{
return false;
}
else if (this.npc.getRNG().zrange(100) != 0)
{
return false;
}
else
{
if (this.npc.getIsWillingToMate(true))
{
Entity entity = ((WorldServer)this.worldObj).findNearestEntityWithinAABB(EntityNPC.class, this.npc.getEntityBoundingBox().expand(8.0D, 3.0D, 8.0D), this.npc);
if (entity == null)
{
return false;
}
else
{
this.mate = (EntityNPC)entity;
return this.mate.getGrowingAge() == 0 && this.mate.getIsWillingToMate(true);
}
}
else
{
return false;
}
}
}
public void startExecuting()
{
this.matingTimeout = 250;
this.npc.setMating(true);
}
public void resetTask()
{
this.mate = null;
this.npc.setMating(false);
}
public boolean continueExecuting()
{
return this.matingTimeout >= 0 && this.npc.getGrowingAge() == 0 && this.npc.getIsWillingToMate(false);
}
public void updateTask()
{
--this.matingTimeout;
this.npc.getLookHelper().setLookPositionWithEntity(this.mate, 10.0F, 30.0F);
if (this.npc.getDistanceSqToEntity(this.mate) > 2.25D)
{
this.npc.getNavigator().tryMoveToEntityLiving(this.mate, 0.25D);
}
else if (this.matingTimeout >= 6)
{
this.matingTimeout -= 5;
}
else if (this.matingTimeout == 0 && this.mate.isMating())
{
this.giveBirth();
}
// if (this.npc.getRNG().nextInt(35) == 0)
// {
// this.worldObj.setEntityState(this.npc, (byte)12);
// }
}
private void giveBirth()
{
EntityNPC entity = this.npc.createChild(this.mate);
this.mate.setGrowingAge(100);
this.npc.setGrowingAge(100);
this.mate.setIsWillingToMate(false);
this.npc.setIsWillingToMate(false);
entity.setGrowingAge(-24000);
entity.setLocationAndAngles(this.npc.posX, this.npc.posY, this.npc.posZ, 0.0F, 0.0F);
this.worldObj.spawnEntityInWorld(entity);
this.worldObj.setEntityState(entity, (byte)12);
}
}

View file

@ -0,0 +1,86 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.world.World;
public class EntityAIOcelotAttack extends EntityAIBase
{
World theWorld;
EntityLiving theEntity;
EntityLiving theVictim;
int attackCountdown;
public EntityAIOcelotAttack(EntityLiving theEntityIn)
{
this.theEntity = theEntityIn;
this.theWorld = theEntityIn.worldObj;
this.setMutexBits(3);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
EntityLiving entitylivingbase = this.theEntity.getAttackTarget();
if (entitylivingbase == null)
{
return false;
}
else
{
this.theVictim = entitylivingbase;
return true;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.theVictim.isEntityAlive() ? false : (this.theEntity.getDistanceSqToEntity(this.theVictim) > 225.0D ? false : !this.theEntity.getNavigator().noPath() || this.shouldExecute());
}
/**
* Resets the task
*/
public void resetTask()
{
this.theVictim = null;
this.theEntity.getNavigator().clearPathEntity();
}
/**
* Updates the task
*/
public void updateTask()
{
this.theEntity.getLookHelper().setLookPositionWithEntity(this.theVictim, 30.0F, 30.0F);
double d0 = (double)(this.theEntity.width * 2.0F * this.theEntity.width * 2.0F);
double d1 = this.theEntity.getDistanceSq(this.theVictim.posX, this.theVictim.getEntityBoundingBox().minY, this.theVictim.posZ);
double d2 = 0.8D;
if (d1 > d0 && d1 < 16.0D)
{
d2 = 1.33D;
}
else if (d1 < 225.0D)
{
d2 = 0.6D;
}
this.theEntity.getNavigator().tryMoveToEntityLiving(this.theVictim, d2);
this.attackCountdown = Math.max(this.attackCountdown - 1, 0);
if (d1 <= d0)
{
if (this.attackCountdown <= 0)
{
this.attackCountdown = 20;
this.theEntity.attackEntityAsMob(this.theVictim);
}
}
}
}

View file

@ -0,0 +1,114 @@
package game.ai;
import game.block.Block;
import game.block.BlockBed;
import game.entity.animal.EntityOcelot;
import game.init.Blocks;
import game.tileentity.TileEntity;
import game.tileentity.TileEntityChest;
import game.world.BlockPos;
import game.world.State;
import game.world.World;
public class EntityAIOcelotSit extends EntityAIMoveToBlock
{
private final EntityOcelot ocelot;
public EntityAIOcelotSit(EntityOcelot ocelotIn, double p_i45315_2_)
{
super(ocelotIn, p_i45315_2_, 8);
this.ocelot = ocelotIn;
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
return this.ocelot.isTamed() && !this.ocelot.isSitting() && super.shouldExecute();
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return super.continueExecuting();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
super.startExecuting();
this.ocelot.getAISit().setSitting(false);
}
/**
* Resets the task
*/
public void resetTask()
{
super.resetTask();
this.ocelot.setSitting(false);
}
/**
* Updates the task
*/
public void updateTask()
{
super.updateTask();
this.ocelot.getAISit().setSitting(false);
if (!this.getIsAboveDestination())
{
this.ocelot.setSitting(false);
}
else if (!this.ocelot.isSitting())
{
this.ocelot.setSitting(true);
}
}
/**
* Return true to set given position as destination
*/
protected boolean shouldMoveTo(World worldIn, BlockPos pos)
{
if (!worldIn.isAirBlock(pos.up()))
{
return false;
}
else
{
State iblockstate = worldIn.getState(pos);
Block block = iblockstate.getBlock();
if (block == Blocks.chest)
{
TileEntity tileentity = worldIn.getTileEntity(pos);
if (tileentity instanceof TileEntityChest && ((TileEntityChest)tileentity).numPlayersUsing < 1)
{
return true;
}
}
else
{
if (block == Blocks.lit_furnace)
{
return true;
}
if (block instanceof BlockBed && iblockstate.getValue(BlockBed.PART) != BlockBed.EnumPartType.HEAD)
{
return true;
}
}
return false;
}
}
}

View file

@ -0,0 +1,58 @@
package game.ai;
import game.entity.types.EntityLiving;
public class EntityAIOpenDoor extends EntityAIDoorInteract
{
/** If the entity close the door */
boolean closeDoor;
/**
* The temporisation before the entity close the door (in ticks, always 20 = 1 second)
*/
int closeDoorTemporisation;
public EntityAIOpenDoor(EntityLiving entitylivingIn, boolean shouldClose)
{
super(entitylivingIn);
this.theEntity = entitylivingIn;
this.closeDoor = shouldClose;
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return this.closeDoor && this.closeDoorTemporisation > 0 && super.continueExecuting();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.closeDoorTemporisation = 20;
this.doorBlock.toggleDoor(this.theEntity.worldObj, this.doorPosition, true);
}
/**
* Resets the task
*/
public void resetTask()
{
if (this.closeDoor)
{
this.doorBlock.toggleDoor(this.theEntity.worldObj, this.doorPosition, false);
}
}
/**
* Updates the task
*/
public void updateTask()
{
--this.closeDoorTemporisation;
super.updateTask();
}
}

View file

@ -0,0 +1,60 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.entity.types.EntityTameable;
public class EntityAIOwnerHurtByTarget extends EntityAITarget
{
EntityTameable theDefendingTameable;
EntityLiving theOwnerAttacker;
private int field_142051_e;
public EntityAIOwnerHurtByTarget(EntityTameable theDefendingTameableIn)
{
super(theDefendingTameableIn, false);
this.theDefendingTameable = theDefendingTameableIn;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (!this.theDefendingTameable.isTamed())
{
return false;
}
else
{
EntityLiving entitylivingbase = this.theDefendingTameable.getOwner();
if (entitylivingbase == null)
{
return false;
}
else
{
this.theOwnerAttacker = entitylivingbase.getAttackedBy();
int i = entitylivingbase.getAttackedTime();
return i != this.field_142051_e && this.isSuitableTarget(this.theOwnerAttacker) && this.theDefendingTameable.shouldAttackEntity(this.theOwnerAttacker, entitylivingbase);
}
}
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.taskOwner.setAttackTarget(this.theOwnerAttacker);
EntityLiving entitylivingbase = this.theDefendingTameable.getOwner();
if (entitylivingbase != null)
{
this.field_142051_e = entitylivingbase.getAttackedTime();
}
super.startExecuting();
}
}

View file

@ -0,0 +1,60 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.entity.types.EntityTameable;
public class EntityAIOwnerHurtTarget extends EntityAITarget
{
EntityTameable theEntityTameable;
EntityLiving theTarget;
private int field_142050_e;
public EntityAIOwnerHurtTarget(EntityTameable theEntityTameableIn)
{
super(theEntityTameableIn, false);
this.theEntityTameable = theEntityTameableIn;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (!this.theEntityTameable.isTamed())
{
return false;
}
else
{
EntityLiving entitylivingbase = this.theEntityTameable.getOwner();
if (entitylivingbase == null)
{
return false;
}
else
{
this.theTarget = entitylivingbase.getLastAttack();
int i = entitylivingbase.getLastAttackTime();
return i != this.field_142050_e && this.isSuitableTarget(this.theTarget) && this.theEntityTameable.shouldAttackEntity(this.theTarget, entitylivingbase);
}
}
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.taskOwner.setAttackTarget(this.theTarget);
EntityLiving entitylivingbase = this.theEntityTameable.getOwner();
if (entitylivingbase != null)
{
this.field_142050_e = entitylivingbase.getLastAttackTime();
}
super.startExecuting();
}
}

View file

@ -0,0 +1,63 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.world.Vec3;
public class EntityAIPanic extends EntityAIBase
{
private EntityLiving theEntityCreature;
protected double speed;
private double randPosX;
private double randPosY;
private double randPosZ;
public EntityAIPanic(EntityLiving creature, double speedIn)
{
this.theEntityCreature = creature;
this.speed = speedIn;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (this.theEntityCreature.getAttackedBy() == null && !this.theEntityCreature.isBurning())
{
return false;
}
else
{
Vec3 vec3 = RandomPositionGenerator.findRandomTarget(this.theEntityCreature, 5, 4);
if (vec3 == null)
{
return false;
}
else
{
this.randPosX = vec3.xCoord;
this.randPosY = vec3.yCoord;
this.randPosZ = vec3.zCoord;
return true;
}
}
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.theEntityCreature.getNavigator().tryMoveToXYZ(this.randPosX, this.randPosY, this.randPosZ, this.speed);
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.theEntityCreature.getNavigator().noPath();
}
}

View file

@ -0,0 +1,72 @@
package game.ai;
import java.util.List;
import game.entity.npc.EntityNPC;
import game.entity.types.EntityLiving;
import game.world.Vec3;
public class EntityAIPlay extends EntityAIBase {
private EntityNPC entity;
private EntityLiving target;
private double speed;
private int time;
public EntityAIPlay(EntityNPC entity, double speed) {
this.entity = entity;
this.speed = speed;
this.setMutexBits(1);
}
public boolean shouldExecute() {
if(!this.entity.canPlay() || this.entity.getRNG().zrange(400) != 0)
return false;
List<EntityNPC> list = this.entity.worldObj.<EntityNPC>getEntitiesWithinAABB(EntityNPC.class,
this.entity.getEntityBoundingBox().expand(6.0D, 3.0D, 6.0D));
double d0 = Double.MAX_VALUE;
for(EntityNPC npc : list) {
if(npc != this.entity && !npc.isPlaying() && npc.canPlay() && !this.entity.canAttack(npc) && !npc.canAttack(this.entity)) {
double d1 = npc.getDistanceSqToEntity(this.entity);
if(d1 <= d0) {
d0 = d1;
this.target = npc;
}
}
}
if(this.target == null) {
Vec3 vec = RandomPositionGenerator.findRandomTarget(this.entity, 16, 3);
if(vec == null)
return false;
}
return true;
}
public boolean continueExecuting() {
return this.time > 0;
}
public void startExecuting() {
if(this.target != null)
this.entity.setPlaying(true);
this.time = 1000;
}
public void resetTask() {
this.entity.setPlaying(false);
this.target = null;
}
public void updateTask() {
--this.time;
if(this.target != null) {
if(this.entity.getDistanceSqToEntity(this.target) > 4.0D)
this.entity.getNavigator().tryMoveToEntityLiving(this.target, this.speed);
}
else if(this.entity.getNavigator().noPath()) {
Vec3 vec = RandomPositionGenerator.findRandomTarget(this.entity, 16, 3);
if(vec == null)
return;
this.entity.getNavigator().tryMoveToXYZ(vec.xCoord, vec.yCoord, vec.zCoord, this.speed);
}
}
}

View file

@ -0,0 +1,85 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.pathfinding.PathNavigateGround;
import game.village.Village;
import game.village.VillageDoorInfo;
import game.world.BlockPos;
import game.world.WorldServer;
public class EntityAIRestrictOpenDoor extends EntityAIBase
{
private EntityLiving entityObj;
private VillageDoorInfo frontDoor;
public EntityAIRestrictOpenDoor(EntityLiving creatureIn)
{
this.entityObj = creatureIn;
if (!(creatureIn.getNavigator() instanceof PathNavigateGround))
{
throw new IllegalArgumentException("Unsupported mob type for RestrictOpenDoorGoal");
}
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (((WorldServer)this.entityObj.worldObj).isDaytime())
{
return false;
}
else
{
BlockPos blockpos = new BlockPos(this.entityObj);
Village village = ((WorldServer)this.entityObj.worldObj).getNearestVillage(blockpos, 16);
if (village == null)
{
return false;
}
else
{
this.frontDoor = village.getNearestDoor(blockpos);
return this.frontDoor == null ? false : (double)this.frontDoor.getDistanceToInsideBlockSq(blockpos) < 2.25D;
}
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return ((WorldServer)this.entityObj.worldObj).isDaytime() ? false : !this.frontDoor.getIsDetachedFromVillageFlag() && this.frontDoor.func_179850_c(new BlockPos(this.entityObj));
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
((PathNavigateGround)this.entityObj.getNavigator()).setBreakDoors(false);
((PathNavigateGround)this.entityObj.getNavigator()).setEnterDoors(false);
}
/**
* Resets the task
*/
public void resetTask()
{
((PathNavigateGround)this.entityObj.getNavigator()).setBreakDoors(true);
((PathNavigateGround)this.entityObj.getNavigator()).setEnterDoors(true);
this.frontDoor = null;
}
/**
* Updates the task
*/
public void updateTask()
{
this.frontDoor.incrementDoorOpeningRestrictionCounter();
}
}

View file

@ -0,0 +1,39 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.pathfinding.PathNavigateGround;
import game.world.WorldServer;
public class EntityAIRestrictSun extends EntityAIBase
{
private EntityLiving theEntity;
public EntityAIRestrictSun(EntityLiving creature)
{
this.theEntity = creature;
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
return ((WorldServer)this.theEntity.worldObj).isDaytime();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
((PathNavigateGround)this.theEntity.getNavigator()).setAvoidSun(true);
}
/**
* Resets the task
*/
public void resetTask()
{
((PathNavigateGround)this.theEntity.getNavigator()).setAvoidSun(false);
}
}

View file

@ -0,0 +1,94 @@
package game.ai;
import game.entity.Entity;
import game.entity.animal.EntityHorse;
import game.entity.npc.EntityNPC;
import game.world.Vec3;
public class EntityAIRunAroundLikeCrazy extends EntityAIBase
{
private EntityHorse horseHost;
private double speed;
private double targetX;
private double targetY;
private double targetZ;
public EntityAIRunAroundLikeCrazy(EntityHorse horse, double speedIn)
{
this.horseHost = horse;
this.speed = speedIn;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (!this.horseHost.isTame() && this.horseHost.passenger != null)
{
Vec3 vec3 = RandomPositionGenerator.findRandomTarget(this.horseHost, 5, 4);
if (vec3 == null)
{
return false;
}
else
{
this.targetX = vec3.xCoord;
this.targetY = vec3.yCoord;
this.targetZ = vec3.zCoord;
return true;
}
}
else
{
return false;
}
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.horseHost.getNavigator().tryMoveToXYZ(this.targetX, this.targetY, this.targetZ, this.speed);
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.horseHost.getNavigator().noPath() && this.horseHost.passenger != null;
}
/**
* Updates the task
*/
public void updateTask()
{
if (this.horseHost.getRNG().zrange(50) == 0)
{
if (this.horseHost.passenger instanceof EntityNPC)
{
int i = this.horseHost.getTemper();
int j = this.horseHost.getMaxTemper();
if (j > 0 && this.horseHost.getRNG().zrange(j) < i)
{
this.horseHost.setHorseTamed(true);
this.horseHost.worldObj.setEntityState(this.horseHost, (byte)7);
return;
}
this.horseHost.increaseTemper(5);
}
this.horseHost.passenger.mountEntity((Entity)null);
this.horseHost.passenger = null;
this.horseHost.makeHorseRearWithSound();
this.horseHost.worldObj.setEntityState(this.horseHost, (byte)6);
}
}
}

View file

@ -0,0 +1,101 @@
package game.ai;
import game.ExtMath;
import game.entity.item.EntityItem;
import game.entity.npc.EntityNPC;
import game.init.Items;
import game.inventory.InventoryBasic;
import game.item.Item;
import game.item.ItemStack;
public class EntityAIShareItems extends EntityAIWatchClosest2
{
private int interactionDelay;
private EntityNPC entity;
public EntityAIShareItems(EntityNPC npc)
{
super(npc, EntityNPC.class, 3.0F, 0.02F);
this.entity = npc;
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
super.startExecuting();
// if (this.entity.canShareItems() && this.closestEntity instanceof EntityNPC && ((EntityNPC)this.closestEntity).needsMoreItems())
// {
// this.interactionDelay = 10;
// }
// else
// {
// this.interactionDelay = 0;
// }
}
/**
* Updates the task
*/
public void updateTask()
{
super.updateTask();
if (this.interactionDelay > 0)
{
--this.interactionDelay;
if (this.interactionDelay == 0)
{
InventoryBasic inventorybasic = this.entity.getExtendedInventory();
for (int i = 0; i < inventorybasic.getSizeInventory(); ++i)
{
ItemStack itemstack = inventorybasic.getStackInSlot(i);
ItemStack itemstack1 = null;
if (itemstack != null)
{
Item item = itemstack.getItem();
if ((item == Items.bread || item == Items.potato || item == Items.carrot) && itemstack.stackSize > 3)
{
int l = itemstack.stackSize / 2;
itemstack.stackSize -= l;
itemstack1 = new ItemStack(item, l, itemstack.getMetadata());
}
else if (item == Items.wheats && itemstack.stackSize > 5)
{
int j = itemstack.stackSize / 2 / 3 * 3;
int k = j / 3;
itemstack.stackSize -= j;
itemstack1 = new ItemStack(Items.bread, k, 0);
}
if (itemstack.stackSize <= 0)
{
inventorybasic.setInventorySlotContents(i, (ItemStack)null);
}
}
if (itemstack1 != null)
{
double d0 = this.entity.posY - 0.30000001192092896D + (double)this.entity.getEyeHeight();
EntityItem entityitem = new EntityItem(this.entity.worldObj, this.entity.posX, d0, this.entity.posZ, itemstack1);
float f = 0.3F;
float f1 = this.entity.headYaw;
float f2 = this.entity.rotPitch;
entityitem.motionX = (double)(-ExtMath.sin(f1 / 180.0F * (float)Math.PI) * ExtMath.cos(f2 / 180.0F * (float)Math.PI) * f);
entityitem.motionZ = (double)(ExtMath.cos(f1 / 180.0F * (float)Math.PI) * ExtMath.cos(f2 / 180.0F * (float)Math.PI) * f);
entityitem.motionY = (double)(-ExtMath.sin(f2 / 180.0F * (float)Math.PI) * f + 0.1F);
entityitem.setDefaultPickupDelay();
this.entity.worldObj.spawnEntityInWorld(entityitem);
break;
}
}
}
}
}
}

View file

@ -0,0 +1,67 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.entity.types.EntityTameable;
public class EntityAISit extends EntityAIBase
{
private EntityTameable theEntity;
/** If the EntityTameable is sitting. */
private boolean isSitting;
public EntityAISit(EntityTameable entityIn)
{
this.theEntity = entityIn;
this.setMutexBits(5);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (!this.theEntity.isTamed())
{
return false;
}
else if (this.theEntity.isInLiquid())
{
return false;
}
else if (!this.theEntity.onGround)
{
return false;
}
else
{
EntityLiving entitylivingbase = this.theEntity.getOwner();
return entitylivingbase == null ? true : (this.theEntity.getDistanceSqToEntity(entitylivingbase) < 144.0D && entitylivingbase.getAttackedBy() != null ? false : this.isSitting);
}
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.theEntity.getNavigator().clearPathEntity();
this.theEntity.setSitting(true);
}
/**
* Resets the task
*/
public void resetTask()
{
this.theEntity.setSitting(false);
}
/**
* Sets the sitting flag.
*/
public void setSitting(boolean sitting)
{
this.isSitting = sitting;
}
}

View file

@ -0,0 +1,35 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.pathfinding.PathNavigateGround;
public class EntityAISwimming extends EntityAIBase
{
private EntityLiving theEntity;
public EntityAISwimming(EntityLiving entitylivingIn)
{
this.theEntity = entitylivingIn;
this.setMutexBits(4);
((PathNavigateGround)entitylivingIn.getNavigator()).setCanSwim(true);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
return this.theEntity.isInLiquid() || this.theEntity.isInMolten();
}
/**
* Updates the task
*/
public void updateTask()
{
if (this.theEntity.getRNG().floatv() < 0.8F)
{
this.theEntity.getJumpHelper().setJumping();
}
}
}

View file

@ -0,0 +1,162 @@
package game.ai;
import java.util.Map;
import game.ExtMath;
import game.block.Block;
import game.collect.Maps;
import game.entity.npc.EntityNPC;
import game.init.Blocks;
import game.init.Config;
import game.init.ItemRegistry;
import game.item.ItemStack;
import game.material.Material;
import game.rng.Random;
import game.world.BlockPos;
import game.world.State;
import game.world.World;
public class EntityAITakePlace extends EntityAIBase
{
private static class StackKey {
public String item;
public int meta;
public StackKey(String str) {
String[] tok = str.split(":", 2);
this.item = tok[0];
this.meta = tok.length > 1 ? Integer.parseInt(tok[1]) : -1;
}
public StackKey(ItemStack stack) {
this.item = ItemRegistry.REGISTRY.getNameForObject(stack.getItem()).toString();
this.meta = stack.getItem().getMaxDamage() <= 0 ? stack.getMetadata() : -1;
}
// public boolean isSame(ItemStack stack) {
// return this.item.equals(ItemRegistry.REGISTRY.getNameForObject(stack.getItem()).toString()) &&
// (stack.getItem().getMaxDamage() > 0 || stack.getMetadata() == this.meta);
// }
public boolean equals(Object other) {
return other instanceof StackKey && ((StackKey)other).item.equals(this.item) && ((StackKey)other).meta == this.meta;
}
public int hashCode() {
return this.item.hashCode() ^ (this.meta << 8);
}
public String toString() {
return this.item + (this.meta == -1 ? "" : (":" + this.meta));
}
}
private static final Map<State, ItemStack> STEALABLE = Maps.newHashMap();
private static final Map<StackKey, State> PLACEABLE = Maps.newHashMap();
private static void addPlaceable(State state, ItemStack stack) {
STEALABLE.put(state, stack);
PLACEABLE.put(new StackKey(stack), state);
}
private static void addPlaceable(Block block) {
addPlaceable(block.getState(), new ItemStack(block));
}
static {
addPlaceable(Blocks.flower);
addPlaceable(Blocks.brown_mushroom);
addPlaceable(Blocks.red_mushroom);
addPlaceable(Blocks.blue_mushroom);
}
private EntityNPC entity;
private boolean place;
public EntityAITakePlace(EntityNPC placer)
{
this.entity = placer;
}
public boolean shouldExecute()
{
if(!Config.mobGrief || this.entity.getAttackTarget() != null)
return false;
if(this.entity.getHeldItem() == null) {
this.place = false;
return this.entity.getRNG().chance(20);
}
else if(this.entity.getRNG().chance(200) && PLACEABLE.containsKey(new StackKey(this.entity.getHeldItem()))) {
this.place = this.entity.getRNG().rarity(10);
return true;
}
return false;
}
public void updateTask()
{
Random random = this.entity.getRNG();
World world = this.entity.worldObj;
int i = ExtMath.floord(this.entity.posX - (this.place ? 1.0 : 2.0) + random.doublev() * (this.place ? 2.0 : 4.0));
int j = ExtMath.floord(this.entity.posY + random.doublev() * (this.place ? 2.0 : 3.0));
int k = ExtMath.floord(this.entity.posZ - (this.place ? 1.0 : 2.0) + random.doublev() * (this.place ? 2.0 : 4.0));
BlockPos blockpos = new BlockPos(i, j, k);
if(this.place) {
ItemStack stack = this.entity.getHeldItem();
if(stack == null || !PLACEABLE.containsKey(new StackKey(this.entity.getHeldItem())))
return;
Block replace = world.getState(blockpos).getBlock();
Block below = world.getState(blockpos.down()).getBlock();
State state = PLACEABLE.get(new StackKey(this.entity.getHeldItem()));
if (state.getBlock().canPlaceBlockAt(world, blockpos) && replace.getMaterial() == Material.air &&
below.getMaterial() != Material.air && below.isFullCube())
{
this.entity.getLookHelper().setLookPosition((double)i + 0.5, (double)j + 0.5, (double)k + 0.5, 10.0F,
(float)this.entity.getVerticalFaceSpeed());
this.entity.swingItem();
world.setState(blockpos, state, 3);
--stack.stackSize;
if(stack.stackSize <= 0)
this.entity.setItemNoUpdate(0, null);
}
}
else {
State state = world.getState(blockpos);
Block block = state.getBlock();
if (STEALABLE.containsKey(state) &&
(this.entity.getHeldItem() == null || (ItemStack.areItemsEqual(STEALABLE.get(state),
this.entity.getHeldItem()) && this.entity.getHeldItem().stackSize < this.entity.getHeldItem().getMaxStackSize())))
{
this.entity.getLookHelper().setLookPosition((double)i + 0.5, (double)j + 0.5, (double)k + 0.5, 10.0F,
(float)this.entity.getVerticalFaceSpeed());
this.entity.swingItem();
world.setState(blockpos, Blocks.air.getState());
if(this.entity.getHeldItem() != null)
++this.entity.getHeldItem().stackSize;
else
this.entity.setItemNoUpdate(0, STEALABLE.get(state).copy());
}
}
}
//private boolean shouldAttackPlayer(EntityNPC player)
//{
// ItemStack itemstack = player.inventory.armorInventory[3];
//
// if (itemstack != null && itemstack.getItem() == ItemRegistry.getItemFromBlock(Blocks.pumpkin))
// {
// return false;
// }
// else
// {
// Vec3 vec3 = player.getLook(1.0F).normalize();
// Vec3 vec31 = new Vec3(this.posX - player.posX, this.getEntityBoundingBox().minY + (double)(this.height / 2.0F) - (player.posY + (double)player.getEyeHeight()), this.posZ - player.posZ);
// double d0 = vec31.lengthVector();
// vec31 = vec31.normalize();
// double d1 = vec3.dotProduct(vec31);
// return d1 > 1.0D - 0.025D / d0 ? player.canEntityBeSeen(this) : false;
// }
//}
//
}

View file

@ -0,0 +1,255 @@
package game.ai;
import game.ExtMath;
import game.entity.attributes.AttributeInstance;
import game.entity.attributes.Attributes;
import game.entity.types.EntityLiving;
import game.entity.types.IEntityOwnable;
import game.init.Config;
import game.pathfinding.PathEntity;
import game.pathfinding.PathPoint;
import game.world.BlockPos;
public abstract class EntityAITarget extends EntityAIBase
{
/** The entity that this task belongs to */
protected final EntityLiving taskOwner;
/**
* If true, EntityAI targets must be able to be seen (cannot be blocked by walls) to be suitable targets.
*/
protected boolean shouldCheckSight;
/**
* When true, only entities that can be reached with minimal effort will be targetted.
*/
private boolean nearbyOnly;
/**
* When nearbyOnly is true: 0 -> No target, but OK to search; 1 -> Nearby target found; 2 -> Target too far.
*/
private int targetSearchStatus;
/**
* When nearbyOnly is true, this throttles target searching to avoid excessive pathfinding.
*/
private int targetSearchDelay;
/**
* If @shouldCheckSight is true, the number of ticks before the interuption of this AITastk when the entity does't
* see the target
*/
private int targetUnseenTicks;
public EntityAITarget(EntityLiving creature, boolean checkSight)
{
this(creature, checkSight, false);
}
public EntityAITarget(EntityLiving creature, boolean checkSight, boolean onlyNearby)
{
this.taskOwner = creature;
this.shouldCheckSight = checkSight;
this.nearbyOnly = onlyNearby;
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
EntityLiving entitylivingbase = this.taskOwner.getAttackTarget();
if (entitylivingbase == null)
{
return false;
}
else if (!entitylivingbase.isEntityAlive())
{
return false;
}
else
{
// Team team = this.taskOwner.getTeam();
// Team team1 = entitylivingbase.getTeam();
//
// if (team != null && team1 == team)
// {
// return false;
// }
// else
// {
double d0 = this.getTargetDistance();
if (this.taskOwner.getDistanceSqToEntity(entitylivingbase) > d0 * d0)
{
return false;
}
else
{
if (this.shouldCheckSight)
{
if (this.taskOwner.getEntitySenses().canSee(entitylivingbase))
{
this.targetUnseenTicks = 0;
}
else if (++this.targetUnseenTicks > 60)
{
return false;
}
}
return Config.mobAttacks;
}
// }
}
}
protected double getTargetDistance()
{
AttributeInstance iattributeinstance = this.taskOwner.getEntityAttribute(Attributes.FOLLOW_RANGE);
return iattributeinstance == null ? 16.0D : iattributeinstance.getAttributeValue();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.targetSearchStatus = 0;
this.targetSearchDelay = 0;
this.targetUnseenTicks = 0;
}
/**
* Resets the task
*/
public void resetTask()
{
this.taskOwner.setAttackTarget((EntityLiving)null);
}
/**
* A static method used to see if an entity is a suitable target through a number of checks.
*/
public static boolean isSuitableTarget(EntityLiving attacker, EntityLiving target, boolean checkSight)
{
if (target == null)
{
return false;
}
else if (target == attacker)
{
return false;
}
else if (!target.isEntityAlive())
{
return false;
}
else if (!Config.infight && target.getClass() == attacker.getClass())
{
return false;
}
else
{
// Team team = attacker.getTeam();
// Team team1 = target.getTeam();
//
// if (team != null && team1 == team)
// {
// return false;
// }
// else
// {
if (attacker instanceof IEntityOwnable // ) // && ((IEntityOwnable)attacker).getOwnerId() != null && !((IEntityOwnable)attacker).getOwnerId().isEmpty())
// {
// if (target instanceof IEntityOwnable && ((IEntityOwnable)attacker).getOwnerId().equalsIgnoreCase(((IEntityOwnable)target).getOwnerId()))
// {
// return false;
// }
// if (
&& target == ((IEntityOwnable)attacker).getOwner())
{
return false;
// }
}
else if (!Config.mobAttacks)
{
return false;
}
return !checkSight || attacker.getEntitySenses().canSee(target);
// }
}
}
/**
* A method used to see if an entity is a suitable target through a number of checks. Args : entity,
* canTargetInvinciblePlayer
*/
protected boolean isSuitableTarget(EntityLiving target)
{
if (!isSuitableTarget(this.taskOwner, target, this.shouldCheckSight))
{
return false;
}
else if (!this.taskOwner.isWithinHomeDistanceFromPosition(new BlockPos(target)))
{
return false;
}
else
{
if (this.nearbyOnly)
{
if (--this.targetSearchDelay <= 0)
{
this.targetSearchStatus = 0;
}
if (this.targetSearchStatus == 0)
{
this.targetSearchStatus = this.canEasilyReach(target) ? 1 : 2;
}
if (this.targetSearchStatus == 2)
{
return false;
}
}
return true;
}
}
/**
* Checks to see if this entity can find a short path to the given target.
*
* @param target the entity to find a path to
*/
private boolean canEasilyReach(EntityLiving target)
{
this.targetSearchDelay = 10 + this.taskOwner.getRNG().zrange(5);
PathEntity pathentity = this.taskOwner.getNavigator().getPathToEntityLiving(target);
if (pathentity == null)
{
return false;
}
else
{
PathPoint pathpoint = pathentity.getFinalPathPoint();
if (pathpoint == null)
{
return false;
}
else
{
int i = pathpoint.xCoord - ExtMath.floord(target.posX);
int j = pathpoint.zCoord - ExtMath.floord(target.posZ);
return (double)(i * i + j * j) <= 2.25D;
}
}
}
}

View file

@ -0,0 +1,25 @@
package game.ai;
import java.util.function.Predicate;
import game.entity.types.EntityLiving;
import game.entity.types.EntityTameable;
public class EntityAITargetNonTamed<T extends EntityLiving> extends EntityAINearestAttackableTarget
{
private EntityTameable theTameable;
public EntityAITargetNonTamed(EntityTameable entityIn, Class<T> classTarget, boolean checkSight, Predicate <? super T > targetSelector)
{
super(entityIn, classTarget, 10, checkSight, false, targetSelector);
this.theTameable = entityIn;
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
return !this.theTameable.isTamed() && super.shouldExecute();
}
}

View file

@ -0,0 +1,173 @@
package game.ai;
import java.util.Iterator;
import java.util.List;
import game.collect.Lists;
public class EntityAITasks
{
private List<EntityAITasks.EntityAITaskEntry> taskEntries = Lists.<EntityAITasks.EntityAITaskEntry>newArrayList();
private List<EntityAITasks.EntityAITaskEntry> executingTaskEntries = Lists.<EntityAITasks.EntityAITaskEntry>newArrayList();
private int tickCount;
private int tickRate = 3;
/**
* Add a now AITask. Args : priority, task
*/
public void addTask(int priority, EntityAIBase task)
{
this.taskEntries.add(new EntityAITasks.EntityAITaskEntry(priority, task));
}
/**
* removes the indicated task from the entity's AI tasks.
*/
public void removeTask(EntityAIBase task)
{
Iterator<EntityAITasks.EntityAITaskEntry> iterator = this.taskEntries.iterator();
while (iterator.hasNext())
{
EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry = (EntityAITasks.EntityAITaskEntry)iterator.next();
EntityAIBase entityaibase = entityaitasks$entityaitaskentry.action;
if (entityaibase == task)
{
if (this.executingTaskEntries.contains(entityaitasks$entityaitaskentry))
{
entityaibase.resetTask();
this.executingTaskEntries.remove(entityaitasks$entityaitaskentry);
}
iterator.remove();
}
}
}
public void onUpdateTasks()
{
// this.theProfiler.start("goalSetup");
if (this.tickCount++ % this.tickRate == 0)
{
Iterator iterator = this.taskEntries.iterator();
label38:
while (true)
{
EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry;
while (true)
{
if (!iterator.hasNext())
{
break label38;
}
entityaitasks$entityaitaskentry = (EntityAITasks.EntityAITaskEntry)iterator.next();
boolean flag = this.executingTaskEntries.contains(entityaitasks$entityaitaskentry);
if (!flag)
{
break;
}
if (!this.canUse(entityaitasks$entityaitaskentry) || !this.canContinue(entityaitasks$entityaitaskentry))
{
entityaitasks$entityaitaskentry.action.resetTask();
this.executingTaskEntries.remove(entityaitasks$entityaitaskentry);
break;
}
}
if (this.canUse(entityaitasks$entityaitaskentry) && entityaitasks$entityaitaskentry.action.shouldExecute())
{
entityaitasks$entityaitaskentry.action.startExecuting();
this.executingTaskEntries.add(entityaitasks$entityaitaskentry);
}
}
}
else
{
Iterator<EntityAITasks.EntityAITaskEntry> iterator1 = this.executingTaskEntries.iterator();
while (iterator1.hasNext())
{
EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry1 = (EntityAITasks.EntityAITaskEntry)iterator1.next();
if (!this.canContinue(entityaitasks$entityaitaskentry1))
{
entityaitasks$entityaitaskentry1.action.resetTask();
iterator1.remove();
}
}
}
// this.theProfiler.end();
// this.theProfiler.start("goalTick");
for (EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry2 : this.executingTaskEntries)
{
entityaitasks$entityaitaskentry2.action.updateTask();
}
// this.theProfiler.end();
}
/**
* Determine if a specific AI Task should continue being executed.
*/
private boolean canContinue(EntityAITasks.EntityAITaskEntry taskEntry)
{
boolean flag = taskEntry.action.continueExecuting();
return flag;
}
/**
* Determine if a specific AI Task can be executed, which means that all running higher (= lower int value) priority
* tasks are compatible with it or all lower priority tasks can be interrupted.
*/
private boolean canUse(EntityAITasks.EntityAITaskEntry taskEntry)
{
for (EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry : this.taskEntries)
{
if (entityaitasks$entityaitaskentry != taskEntry)
{
if (taskEntry.priority >= entityaitasks$entityaitaskentry.priority)
{
if (!this.areTasksCompatible(taskEntry, entityaitasks$entityaitaskentry) && this.executingTaskEntries.contains(entityaitasks$entityaitaskentry))
{
return false;
}
}
else if (!entityaitasks$entityaitaskentry.action.isInterruptible() && this.executingTaskEntries.contains(entityaitasks$entityaitaskentry))
{
return false;
}
}
}
return true;
}
/**
* Returns whether two EntityAITaskEntries can be executed concurrently
*/
private boolean areTasksCompatible(EntityAITasks.EntityAITaskEntry taskEntry1, EntityAITasks.EntityAITaskEntry taskEntry2)
{
return (taskEntry1.action.getMutexBits() & taskEntry2.action.getMutexBits()) == 0;
}
class EntityAITaskEntry
{
public EntityAIBase action;
public int priority;
public EntityAITaskEntry(int priorityIn, EntityAIBase task)
{
this.priority = priorityIn;
this.action = task;
}
}
}

View file

@ -0,0 +1,181 @@
package game.ai;
import game.entity.npc.EntityNPC;
import game.entity.types.EntityLiving;
import game.item.Item;
import game.item.ItemStack;
import game.pathfinding.PathNavigateGround;
public class EntityAITempt extends EntityAIBase
{
/** The entity using this AI that is tempted by the player. */
private EntityLiving temptedEntity;
private double speed;
/** X position of player tempting this mob */
private double targetX;
/** Y position of player tempting this mob */
private double targetY;
/** Z position of player tempting this mob */
private double targetZ;
/** Tempting player's pitch */
private double pitch;
/** Tempting player's yaw */
private double yaw;
/** The player that is tempting the entity that is using this AI. */
private EntityNPC temptingPlayer;
/**
* A counter that is decremented each time the shouldExecute method is called. The shouldExecute method will always
* return false if delayTemptCounter is greater than 0.
*/
private int delayTemptCounter;
/** True if this EntityAITempt task is running */
private boolean isRunning;
private Item temptItem;
private double range;
private double distance;
/**
* Whether the entity using this AI will be scared by the tempter's sudden movement.
*/
private boolean scaredByPlayerMovement;
private boolean avoidWater;
public EntityAITempt(EntityLiving temptedEntityIn, double speedIn, Item temptItemIn, boolean scaredByPlayerMovementIn) {
this(temptedEntityIn, speedIn, temptItemIn, 2.5, 10.0, scaredByPlayerMovementIn);
}
public EntityAITempt(EntityLiving temptedEntityIn, double speedIn, Item temptItemIn, double distance, double range, boolean scaredByPlayerMovementIn)
{
this.temptedEntity = temptedEntityIn;
this.speed = speedIn;
this.temptItem = temptItemIn;
this.distance = distance * distance;
this.range = range;
this.scaredByPlayerMovement = scaredByPlayerMovementIn;
this.setMutexBits(3);
if (!(temptedEntityIn.getNavigator() instanceof PathNavigateGround))
{
throw new IllegalArgumentException("Unsupported mob type for TemptGoal");
}
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (this.delayTemptCounter > 0)
{
--this.delayTemptCounter;
return false;
}
else
{
this.temptingPlayer = this.temptedEntity.worldObj.getClosestPlayerToEntity(this.temptedEntity, this.distance);
if (this.temptingPlayer == null)
{
return false;
}
else
{
if(this.temptItem == null)
return this.temptedEntity.getDistanceSqToEntity(this.temptingPlayer) >= this.distance;
ItemStack itemstack = this.temptingPlayer.getCurrentEquippedItem();
return itemstack == null ? false : itemstack.getItem() == this.temptItem;
}
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
if (this.scaredByPlayerMovement)
{
if (this.temptedEntity.getDistanceSqToEntity(this.temptingPlayer) < 36.0D)
{
if (this.temptingPlayer.getDistanceSq(this.targetX, this.targetY, this.targetZ) > 0.010000000000000002D)
{
return false;
}
if (Math.abs((double)this.temptingPlayer.rotPitch - this.pitch) > 5.0D || Math.abs((double)this.temptingPlayer.rotYaw - this.yaw) > 5.0D)
{
return false;
}
}
else
{
this.targetX = this.temptingPlayer.posX;
this.targetY = this.temptingPlayer.posY;
this.targetZ = this.temptingPlayer.posZ;
}
this.pitch = (double)this.temptingPlayer.rotPitch;
this.yaw = (double)this.temptingPlayer.rotYaw;
}
return this.shouldExecute();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.targetX = this.temptingPlayer.posX;
this.targetY = this.temptingPlayer.posY;
this.targetZ = this.temptingPlayer.posZ;
this.isRunning = true;
this.avoidWater = ((PathNavigateGround)this.temptedEntity.getNavigator()).getAvoidsWater();
((PathNavigateGround)this.temptedEntity.getNavigator()).setAvoidsWater(false);
}
/**
* Resets the task
*/
public void resetTask()
{
this.temptingPlayer = null;
this.temptedEntity.getNavigator().clearPathEntity();
this.delayTemptCounter = 5; // 100;
this.isRunning = false;
((PathNavigateGround)this.temptedEntity.getNavigator()).setAvoidsWater(this.avoidWater);
}
/**
* Updates the task
*/
public void updateTask()
{
this.temptedEntity.getLookHelper().setLookPositionWithEntity(this.temptingPlayer, 30.0F, (float)this.temptedEntity.getVerticalFaceSpeed());
if (this.temptedEntity.getDistanceSqToEntity(this.temptingPlayer) < this.distance)
{
this.temptedEntity.getNavigator().clearPathEntity();
}
else
{
this.temptedEntity.getNavigator().tryMoveToEntityLiving(this.temptingPlayer, this.speed);
}
}
/**
* @see #isRunning
*/
public boolean isRunning()
{
return this.isRunning;
}
}

View file

@ -0,0 +1,94 @@
package game.ai;
import game.entity.types.EntityLiving;
import game.world.Vec3;
public class EntityAIWander extends EntityAIBase
{
private EntityLiving entity;
private double xPosition;
private double yPosition;
private double zPosition;
private double speed;
private int executionChance;
// private boolean mustUpdate;
public EntityAIWander(EntityLiving creatureIn, double speedIn)
{
this(creatureIn, speedIn, 120);
}
public EntityAIWander(EntityLiving creatureIn, double speedIn, int chance)
{
this.entity = creatureIn;
this.speed = speedIn;
this.executionChance = chance;
this.setMutexBits(1);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
// if (!this.mustUpdate)
// {
// if (this.entity.getAge() >= 100)
// {
// return false;
// }
if (this.entity.getRNG().zrange(this.executionChance) != 0)
{
return false;
}
// }
Vec3 vec3 = RandomPositionGenerator.findRandomTarget(this.entity, 10, 7);
if (vec3 == null)
{
return false;
}
else
{
this.xPosition = vec3.xCoord;
this.yPosition = vec3.yCoord;
this.zPosition = vec3.zCoord;
// this.mustUpdate = false;
return true;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.entity.getNavigator().noPath();
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.entity.getNavigator().tryMoveToXYZ(this.xPosition, this.yPosition, this.zPosition, this.speed);
}
// /**
// * Makes task to bypass chance
// */
// public void makeUpdate()
// {
// this.mustUpdate = true;
// }
//
// /**
// * Changes task random possibility for execution
// */
// public void setExecutionChance(int newchance)
// {
// this.executionChance = newchance;
// }
}

View file

@ -0,0 +1,99 @@
package game.ai;
import game.entity.Entity;
import game.entity.types.EntityLiving;
import game.world.WorldServer;
public class EntityAIWatchClosest extends EntityAIBase
{
protected EntityLiving theWatcher;
/** The closest entity which is being watched by this one. */
protected Entity closestEntity;
/** This is the Maximum distance that the AI will look for the Entity */
protected float maxDistanceForPlayer;
private int lookTime;
private float chance;
protected Class <? extends Entity > watchedClass;
public EntityAIWatchClosest(EntityLiving entitylivingIn, Class <? extends Entity > watchTargetClass, float maxDistance)
{
this.theWatcher = entitylivingIn;
this.watchedClass = watchTargetClass;
this.maxDistanceForPlayer = maxDistance;
this.chance = 0.02F;
this.setMutexBits(2);
}
public EntityAIWatchClosest(EntityLiving entitylivingIn, Class <? extends Entity > watchTargetClass, float maxDistance, float chanceIn)
{
this.theWatcher = entitylivingIn;
this.watchedClass = watchTargetClass;
this.maxDistanceForPlayer = maxDistance;
this.chance = chanceIn;
this.setMutexBits(2);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
if (this.theWatcher.getRNG().floatv() >= this.chance)
{
return false;
}
else
{
if (this.theWatcher.getAttackTarget() != null)
{
this.closestEntity = this.theWatcher.getAttackTarget();
}
if (this.watchedClass == null)
{
this.closestEntity = this.theWatcher.worldObj.getClosestPlayerToEntity(this.theWatcher, (double)this.maxDistanceForPlayer);
}
else
{
this.closestEntity = ((WorldServer)this.theWatcher.worldObj).findNearestEntityWithinAABB(this.watchedClass, this.theWatcher.getEntityBoundingBox().expand((double)this.maxDistanceForPlayer, 3.0D, (double)this.maxDistanceForPlayer), this.theWatcher);
}
return this.closestEntity != null;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting()
{
return !this.closestEntity.isEntityAlive() ? false : (this.theWatcher.getDistanceSqToEntity(this.closestEntity) > (double)(this.maxDistanceForPlayer * this.maxDistanceForPlayer) ? false : this.lookTime > 0);
}
/**
* Execute a one shot task or start executing a continuous task
*/
public void startExecuting()
{
this.lookTime = 40 + this.theWatcher.getRNG().zrange(40);
}
/**
* Resets the task
*/
public void resetTask()
{
this.closestEntity = null;
}
/**
* Updates the task
*/
public void updateTask()
{
this.theWatcher.getLookHelper().setLookPosition(this.closestEntity.posX, this.closestEntity.posY + (double)this.closestEntity.getEyeHeight(), this.closestEntity.posZ, 10.0F, (float)this.theWatcher.getVerticalFaceSpeed());
--this.lookTime;
}
}

View file

@ -0,0 +1,13 @@
package game.ai;
import game.entity.Entity;
import game.entity.types.EntityLiving;
public class EntityAIWatchClosest2 extends EntityAIWatchClosest
{
public EntityAIWatchClosest2(EntityLiving entitylivingIn, Class <? extends Entity > watchTargetClass, float maxDistance, float chanceIn)
{
super(entitylivingIn, watchTargetClass, maxDistance, chanceIn);
this.setMutexBits(3);
}
}

View file

@ -0,0 +1,28 @@
package game.ai;
import game.entity.types.EntityLiving;
public class EntityJumpHelper
{
private EntityLiving entity;
protected boolean isJumping;
public EntityJumpHelper(EntityLiving entityIn)
{
this.entity = entityIn;
}
public void setJumping()
{
this.isJumping = true;
}
/**
* Called to actually make the entity jump if isJumping is true.
*/
public void doJump()
{
this.entity.setJumping(this.isJumping);
this.isJumping = false;
}
}

View file

@ -0,0 +1,143 @@
package game.ai;
import game.ExtMath;
import game.entity.Entity;
import game.entity.types.EntityLiving;
public class EntityLookHelper
{
private EntityLiving entity;
/**
* The amount of change that is made each update for an entity facing a direction.
*/
private float deltaLookYaw;
/**
* The amount of change that is made each update for an entity facing a direction.
*/
private float deltaLookPitch;
/** Whether or not the entity is trying to look at something. */
private boolean isLooking;
private double posX;
private double posY;
private double posZ;
public EntityLookHelper(EntityLiving entitylivingIn)
{
this.entity = entitylivingIn;
}
/**
* Sets position to look at using entity
*/
public void setLookPositionWithEntity(Entity entityIn, float deltaYaw, float deltaPitch)
{
this.posX = entityIn.posX;
if (entityIn instanceof EntityLiving)
{
this.posY = entityIn.posY + (double)entityIn.getEyeHeight();
}
else
{
this.posY = (entityIn.getEntityBoundingBox().minY + entityIn.getEntityBoundingBox().maxY) / 2.0D;
}
this.posZ = entityIn.posZ;
this.deltaLookYaw = deltaYaw;
this.deltaLookPitch = deltaPitch;
this.isLooking = true;
}
/**
* Sets position to look at
*/
public void setLookPosition(double x, double y, double z, float deltaYaw, float deltaPitch)
{
this.posX = x;
this.posY = y;
this.posZ = z;
this.deltaLookYaw = deltaYaw;
this.deltaLookPitch = deltaPitch;
this.isLooking = true;
}
/**
* Updates look
*/
public void onUpdateLook()
{
this.entity.rotPitch = 0.0F;
if (this.isLooking)
{
this.isLooking = false;
double d0 = this.posX - this.entity.posX;
double d1 = this.posY - (this.entity.posY + (double)this.entity.getEyeHeight());
double d2 = this.posZ - this.entity.posZ;
double d3 = (double)ExtMath.sqrtd(d0 * d0 + d2 * d2);
float f = (float)(ExtMath.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
float f1 = (float)(-(ExtMath.atan2(d1, d3) * 180.0D / Math.PI));
this.entity.rotPitch = this.updateRotation(this.entity.rotPitch, f1, this.deltaLookPitch);
this.entity.headYaw = this.updateRotation(this.entity.headYaw, f, this.deltaLookYaw);
}
else
{
this.entity.headYaw = this.updateRotation(this.entity.headYaw, this.entity.yawOffset, 10.0F);
}
float f2 = ExtMath.wrapf(this.entity.headYaw - this.entity.yawOffset);
if (!this.entity.getNavigator().noPath())
{
if (f2 < -75.0F)
{
this.entity.headYaw = this.entity.yawOffset - 75.0F;
}
if (f2 > 75.0F)
{
this.entity.headYaw = this.entity.yawOffset + 75.0F;
}
}
}
private float updateRotation(float p_75652_1_, float p_75652_2_, float p_75652_3_)
{
float f = ExtMath.wrapf(p_75652_2_ - p_75652_1_);
if (f > p_75652_3_)
{
f = p_75652_3_;
}
if (f < -p_75652_3_)
{
f = -p_75652_3_;
}
return p_75652_1_ + f;
}
public boolean getIsLooking()
{
return this.isLooking;
}
public double getLookPosX()
{
return this.posX;
}
public double getLookPosY()
{
return this.posY;
}
public double getLookPosZ()
{
return this.posZ;
}
}

View file

@ -0,0 +1,121 @@
package game.ai;
import game.ExtMath;
import game.entity.attributes.Attributes;
import game.entity.types.EntityLiving;
public class EntityMoveHelper
{
/** The EntityLiving that is being moved */
protected EntityLiving entity;
protected double posX;
protected double posY;
protected double posZ;
/** The speed at which the entity should move */
protected double speed;
protected boolean update;
public EntityMoveHelper(EntityLiving entitylivingIn)
{
this.entity = entitylivingIn;
this.posX = entitylivingIn.posX;
this.posY = entitylivingIn.posY;
this.posZ = entitylivingIn.posZ;
}
public boolean isUpdating()
{
return this.update;
}
public double getSpeed()
{
return this.speed;
}
/**
* Sets the speed and location to move to
*/
public void setMoveTo(double x, double y, double z, double speedIn)
{
this.posX = x;
this.posY = y;
this.posZ = z;
this.speed = speedIn;
this.update = true;
}
public void onUpdateMoveHelper()
{
this.entity.setMoveForward(0.0F);
if (this.update)
{
this.update = false;
int i = ExtMath.floord(this.entity.getEntityBoundingBox().minY + 0.5D);
double d0 = this.posX - this.entity.posX;
double d1 = this.posZ - this.entity.posZ;
double d2 = this.posY - (double)i;
double d3 = d0 * d0 + d2 * d2 + d1 * d1;
if (d3 >= 2.500000277905201E-7D)
{
float f = (float)(ExtMath.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F;
this.entity.rotYaw = this.limitAngle(this.entity.rotYaw, f, 30.0F);
this.entity.setAIMoveSpeed((float)(this.speed * this.entity.getEntityAttribute(Attributes.MOVEMENT_SPEED).getAttributeValue()));
if (d2 > 0.0D && d0 * d0 + d1 * d1 < 1.0D)
{
this.entity.getJumpHelper().setJumping();
}
}
}
}
/**
* Limits the given angle to a upper and lower limit.
*/
protected float limitAngle(float p_75639_1_, float p_75639_2_, float p_75639_3_)
{
float f = ExtMath.wrapf(p_75639_2_ - p_75639_1_);
if (f > p_75639_3_)
{
f = p_75639_3_;
}
if (f < -p_75639_3_)
{
f = -p_75639_3_;
}
float f1 = p_75639_1_ + f;
if (f1 < 0.0F)
{
f1 += 360.0F;
}
else if (f1 > 360.0F)
{
f1 -= 360.0F;
}
return f1;
}
public double getX()
{
return this.posX;
}
public double getY()
{
return this.posY;
}
public double getZ()
{
return this.posZ;
}
}

View file

@ -0,0 +1,60 @@
package game.ai;
import java.util.List;
import game.collect.Lists;
import game.entity.Entity;
import game.entity.types.EntityLiving;
public class EntitySenses
{
EntityLiving entityObj;
List<Entity> seenEntities = Lists.<Entity>newArrayList();
List<Entity> unseenEntities = Lists.<Entity>newArrayList();
public EntitySenses(EntityLiving entityObjIn)
{
this.entityObj = entityObjIn;
}
/**
* Clears canSeeCachePositive and canSeeCacheNegative.
*/
public void clearSensingCache()
{
this.seenEntities.clear();
this.unseenEntities.clear();
}
/**
* Checks, whether 'our' entity can see the entity given as argument (true) or not (false), caching the result.
*/
public boolean canSee(Entity entityIn)
{
if (this.seenEntities.contains(entityIn))
{
return true;
}
else if (this.unseenEntities.contains(entityIn))
{
return false;
}
else
{
// this.entityObj.worldObj.profiler.start("canSee");
boolean flag = this.entityObj.canEntityBeSeen(entityIn);
// this.entityObj.worldObj.profiler.end();
if (flag)
{
this.seenEntities.add(entityIn);
}
else
{
this.unseenEntities.add(entityIn);
}
return flag;
}
}
}

View file

@ -0,0 +1,129 @@
package game.ai;
import game.ExtMath;
import game.entity.types.EntityLiving;
import game.rng.Random;
import game.world.BlockPos;
import game.world.Vec3;
public class RandomPositionGenerator
{
/**
* used to store a driection when the user passes a point to move towards or away from. WARNING: NEVER THREAD SAFE.
* MULTIPLE findTowards and findAway calls, will share this var
*/
private static Vec3 staticVector = new Vec3(0.0D, 0.0D, 0.0D);
/**
* finds a random target within par1(x,z) and par2 (y) blocks
*/
public static Vec3 findRandomTarget(EntityLiving entitycreatureIn, int xz, int y)
{
return findRandomTargetBlock(entitycreatureIn, xz, y, (Vec3)null);
}
/**
* finds a random target within par1(x,z) and par2 (y) blocks in the direction of the point par3
*/
public static Vec3 findRandomTargetBlockTowards(EntityLiving entitycreatureIn, int xz, int y, Vec3 targetVec3)
{
staticVector = targetVec3.subtract(entitycreatureIn.posX, entitycreatureIn.posY, entitycreatureIn.posZ);
return findRandomTargetBlock(entitycreatureIn, xz, y, staticVector);
}
/**
* finds a random target within par1(x,z) and par2 (y) blocks in the reverse direction of the point par3
*/
public static Vec3 findRandomTargetBlockAwayFrom(EntityLiving entitycreatureIn, int xz, int y, Vec3 targetVec3)
{
staticVector = (new Vec3(entitycreatureIn.posX, entitycreatureIn.posY, entitycreatureIn.posZ)).subtract(targetVec3);
return findRandomTargetBlock(entitycreatureIn, xz, y, staticVector);
}
/**
* searches 10 blocks at random in a within par1(x,z) and par2 (y) distance, ignores those not in the direction of
* par3Vec3, then points to the tile for which creature.getBlockPathWeight returns the highest number
*/
private static Vec3 findRandomTargetBlock(EntityLiving entitycreatureIn, int xz, int y, Vec3 targetVec3)
{
Random random = entitycreatureIn.getRNG();
boolean flag = false;
int i = 0;
int j = 0;
int k = 0;
float f = -99999.0F;
boolean flag1;
if (entitycreatureIn.hasHome())
{
double d0 = entitycreatureIn.getHomePosition().distanceSq((double)ExtMath.floord(entitycreatureIn.posX), (double)ExtMath.floord(entitycreatureIn.posY), (double)ExtMath.floord(entitycreatureIn.posZ)) + 4.0D;
double d1 = (double)(entitycreatureIn.getMaximumHomeDistance() + (float)xz);
flag1 = d0 < d1 * d1;
}
else
{
flag1 = false;
}
for (int j1 = 0; j1 < 10; ++j1)
{
int l = random.zrange(2 * xz + 1) - xz;
int k1 = random.zrange(2 * y + 1) - y;
int i1 = random.zrange(2 * xz + 1) - xz;
if (targetVec3 == null || (double)l * targetVec3.xCoord + (double)i1 * targetVec3.zCoord >= 0.0D)
{
if (entitycreatureIn.hasHome() && xz > 1)
{
BlockPos blockpos = entitycreatureIn.getHomePosition();
if (entitycreatureIn.posX > (double)blockpos.getX())
{
l -= random.zrange(xz / 2);
}
else
{
l += random.zrange(xz / 2);
}
if (entitycreatureIn.posZ > (double)blockpos.getZ())
{
i1 -= random.zrange(xz / 2);
}
else
{
i1 += random.zrange(xz / 2);
}
}
l = l + ExtMath.floord(entitycreatureIn.posX);
k1 = k1 + ExtMath.floord(entitycreatureIn.posY);
i1 = i1 + ExtMath.floord(entitycreatureIn.posZ);
BlockPos blockpos1 = new BlockPos(l, k1, i1);
if (!flag1 || entitycreatureIn.isWithinHomeDistanceFromPosition(blockpos1))
{
float f1 = entitycreatureIn.getBlockPathWeight(blockpos1);
if (f1 > f)
{
f = f1;
i = l;
j = k1;
k = i1;
flag = true;
}
}
}
}
if (flag)
{
return new Vec3((double)i, (double)j, (double)k);
}
else
{
return null;
}
}
}