Improved Zephyr and Aerwhale AI.

This commit is contained in:
bconlon 2020-06-21 13:21:57 -07:00
parent 4d20588543
commit c0f163d091
7 changed files with 254 additions and 227 deletions

View file

@ -21,6 +21,11 @@ version = "1.7.10-v1.0.2"
group= "com.legacy.aether" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "aether_legacy"
sourceCompatibility = targetCompatibility = '1.8'
compileJava {
sourceCompatibility = targetCompatibility = '1.8'
}
minecraft {
version = "1.7.10-10.13.4.1558-1.7.10"
runDir = "eclipse"

View file

@ -26,7 +26,7 @@ public class ZephyrRenderer extends RenderLiving {
}
protected void renderZephyrMovement(EntityZephyr zephyr, float partialTickTime) {
float f1 = ((float) zephyr.shootingAI.prevAttackCounter + (float) (zephyr.shootingAI.attackCounter - zephyr.shootingAI.prevAttackCounter) * partialTickTime) / 20.0F;
float f1 = ((float) zephyr.prevAttackCounter + (float) (zephyr.attackCounter - zephyr.prevAttackCounter) * partialTickTime) / 20.0F;
if (f1 < 0.0F) {
f1 = 0.0F;

View file

@ -25,7 +25,7 @@ public class AerwhaleAITravelCourse extends EntityAIBase {
public AerwhaleAITravelCourse(EntityAerwhale aerwhale) {
this.aerwhale = aerwhale;
this.worldObj = aerwhale.worldObj;
this.setMutexBits(4);
this.setMutexBits(2);
}
@Override
@ -74,15 +74,30 @@ public class AerwhaleAITravelCourse extends EntityAIBase {
this.aerwhale.rotationPitch += 0.1D * this.motionPitch;
this.aerwhale.rotationYaw += 0.1D * this.motionYaw;
this.aerwhale.aerwhaleRotationPitch += 0.1D * this.motionPitch;
this.aerwhale.aerwhaleRotationYaw += 0.1D * this.motionYaw;
if (this.aerwhale.rotationPitch < -60F) {
this.aerwhale.rotationPitch = -60F;
}
if (this.aerwhale.aerwhaleRotationPitch < -60D)
{
this.aerwhale.aerwhaleRotationPitch = -60D;
}
if (this.aerwhale.rotationPitch > 60F) {
this.aerwhale.rotationPitch = 60F;
}
if (this.aerwhale.aerwhaleRotationPitch < -60D)
{
this.aerwhale.aerwhaleRotationPitch = -60D;
}
this.aerwhale.rotationPitch *= 0.99D;
this.aerwhale.aerwhaleRotationPitch *= 0.99D;
this.aerwhale.motionX += 0.005D * Math.cos((this.aerwhale.rotationYaw / 180D) * 3.1415926535897931D) * Math.cos((this.aerwhale.rotationPitch / 180D) * 3.1415926535897931D);
this.aerwhale.motionY += 0.005D * Math.sin((this.aerwhale.rotationPitch / 180D) * 3.1415926535897931D);
@ -120,10 +135,6 @@ public class AerwhaleAITravelCourse extends EntityAIBase {
this.motionYaw += 10F;
}
// System.out.println(this.aerwhale.motionY);
//this.aerwhale.moveEntityWithHeading(this.aerwhale.moveStrafing, this.aerwhale.moveForward);
//this.aerwhale.moveFlying(p_70060_1_, p_70060_2_, p_70060_3_);
this.aerwhale.moveFlying((float) this.aerwhale.motionX, (float) this.aerwhale.motionY, (float) this.aerwhale.motionZ);
}
@ -145,7 +156,7 @@ public class AerwhaleAITravelCourse extends EntityAIBase {
double standard = 50D;
float yaw = this.aerwhale.rotationYaw + rotationYawOffset;
float pitch = this.aerwhale.rotationYaw + rotationYawOffset;
float pitch = this.aerwhale.rotationPitch + rotationPitchOffset;
float f3 = MathHelper.cos(-yaw * 0.01745329F - 3.141593F);
float f4 = MathHelper.sin(-yaw * 0.01745329F - 3.141593F);

View file

@ -0,0 +1,100 @@
package com.legacy.aether.entities.ai.aerwhale;
import com.google.common.collect.Lists;
import com.legacy.aether.entities.passive.EntityAerwhale;
import net.minecraft.block.Block;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
import java.util.*;
public class AerwhaleAIUnstuck extends EntityAIBase
{
private EntityAerwhale aerwhale;
private World worldObj;
private boolean isStuckWarning = false;
private long checkTime = 0L;
private double[] checkPos = new double[3];
public AerwhaleAIUnstuck(EntityAerwhale aerwhale)
{
this.aerwhale = aerwhale;
this.worldObj = aerwhale.worldObj;
this.setMutexBits(4);
}
@Override
public boolean shouldExecute()
{
return !this.aerwhale.isDead;
}
@Override
public void updateTask()
{
double[] posUp = new double[] {this.aerwhale.posX, this.aerwhale.posY + 3, this.aerwhale.posZ};
double[] posDown = new double[] {this.aerwhale.posX, this.aerwhale.posY - 1, this.aerwhale.posZ};
double[] posEast = new double[] {this.aerwhale.posX + 1, this.aerwhale.posY + 2, this.aerwhale.posZ};
double[] posWest = new double[] {this.aerwhale.posX - 3, this.aerwhale.posY + 2, this.aerwhale.posZ};
double[] posSouth = new double[] {this.aerwhale.posX, this.aerwhale.posY + 2, this.aerwhale.posZ + 1};
double[] posNorth = new double[] {this.aerwhale.posX, this.aerwhale.posY + 2, this.aerwhale.posZ - 3};
if (this.checkRegion(new double[] {posUp[0] - 2, posUp[1], posUp[2] - 2}, posUp))
{
this.aerwhale.motionY -= 0.002;
}
if (this.checkRegion(new double[] {posDown[0] - 2, posDown[1], posDown[2] - 2}, posDown))
{
this.aerwhale.motionY += 0.002;
}
if (this.checkRegion(new double[] {posEast[0], posEast[1] - 2, posEast[2] - 2}, posEast))
{
this.aerwhale.motionX -= 0.002;
this.aerwhale.motionY += 0.002;
}
if (this.checkRegion(new double[] {posWest[0], posWest[1] - 2, posWest[2] - 2}, posWest))
{
this.aerwhale.motionX += 0.002;
this.aerwhale.motionY += 0.002;
}
if (this.checkRegion(new double[] {posSouth[0] - 2, posSouth[1] - 2, posSouth[2]}, posSouth))
{
this.aerwhale.motionZ -= 0.002;
this.aerwhale.motionY += 0.002;
}
if (this.checkRegion(new double[] {posNorth[0] - 2, posNorth[1] - 2, posNorth[2]}, posNorth))
{
this.aerwhale.motionZ += 0.002;
this.aerwhale.motionY += 0.002;
}
}
public boolean checkRegion(double[] pos1, double[] pos2)
{
ArrayList<Block> blockList = Lists.newArrayListWithCapacity(9);
for (int x = (int) pos1[0]; x < (int) pos2[0] + 1; x++)
{
for (int z = (int) pos1[2]; z < (int) pos2[2] + 1; z++)
{
for (int y = (int) pos1[1]; y < (int) pos2[1] + 1; y++)
{
blockList.add(this.worldObj.getBlock(x, y, z));
}
}
}
Set<Block> blockSet = new HashSet<>(blockList);
if (blockSet.size() == 1)
{
return blockList.get(1) != Blocks.air;
}
else return blockSet.size() > 1;
}
}

View file

@ -1,43 +1,37 @@
package com.legacy.aether.entities.hostile;
import com.legacy.aether.entities.projectile.EntityZephyrSnowball;
import net.minecraft.entity.EntityFlying;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.World;
import com.legacy.aether.blocks.BlocksAether;
import com.legacy.aether.entities.ai.EntityAIUpdateState;
import com.legacy.aether.entities.ai.zephyr.ZephyrAIShootTarget;
import com.legacy.aether.entities.ai.zephyr.ZephyrAITravelCourse;
public class EntityZephyr extends EntityFlying implements IMob {
public ZephyrAIShootTarget shootingAI;
public int courseCooldown;
public int courseChangeCooldown;
public double waypointX, waypointY, waypointZ;
public int prevAttackCounter;
public int attackCounter;
private final float base;
public EntityZephyr(World world) {
super(world);
this.setSize(4F, 4F);
this.tasks.addTask(1, this.shootingAI = new ZephyrAIShootTarget(this));
this.tasks.addTask(0, new EntityAIUpdateState(this));
this.tasks.addTask(2, new ZephyrAITravelCourse(this));
this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.tasks.addTask(6, new EntityAILookIdle(this));
}
@Override
protected boolean isAIEnabled() {
return true;
this.attackCounter = 0;
this.base = (this.getRNG().nextFloat() - this.getRNG().nextFloat()) * 0.2F + 1.0F;
}
@Override
@ -55,29 +49,112 @@ public class EntityZephyr extends EntityFlying implements IMob {
}
@Override
public void onEntityUpdate() {
super.onEntityUpdate();
if (this.worldObj.isRemote) {
this.shootingAI.updateTask();
}
if (this.posY < -2D || this.posY > 255D) {
this.despawnEntity();
}
if (this.getAttackTarget() != null && this.getAttackTarget().isDead) {
this.setAttackTarget(null);
}
if (!this.worldObj.isRemote && this.worldObj.difficultySetting == EnumDifficulty.PEACEFUL) {
protected void updateEntityActionState()
{
if (!this.worldObj.isRemote && this.worldObj.difficultySetting == EnumDifficulty.PEACEFUL)
{
this.setDead();
}
this.despawnEntity();
this.prevAttackCounter = this.attackCounter;
double d0 = this.waypointX - this.posX;
double d1 = this.waypointY - this.posY;
double d2 = this.waypointZ - this.posZ;
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
if (d3 < 1.0D || d3 > 3600.0D)
{
this.waypointX = this.posX + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
this.waypointY = this.posY + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
this.waypointZ = this.posZ + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
}
if (this.courseChangeCooldown-- <= 0)
{
this.courseChangeCooldown += this.rand.nextInt(5) + 2;
d3 = (double)MathHelper.sqrt_double(d3);
if (this.isCourseTraversable(this.waypointX, this.waypointY, this.waypointZ, d3))
{
this.motionX += d0 / d3 * 0.1D;
this.motionY += d1 / d3 * 0.1D;
this.motionZ += d2 / d3 * 0.1D;
}
else
{
this.waypointX = this.posX;
this.waypointY = this.posY;
this.waypointZ = this.posZ;
}
}
this.prevAttackCounter = this.attackCounter;
if (this.getAttackTarget() == null) {
if (this.attackCounter > 0) {
this.attackCounter--;
}
this.setAttackTarget(this.worldObj.getClosestVulnerablePlayerToEntity(this, 100D));
} else {
if (this.getAttackTarget() instanceof EntityPlayer && (((EntityPlayer) this.getAttackTarget()).capabilities.isCreativeMode)) {
this.setAttackTarget(null);
return;
}
if (this.getAttackTarget().getDistanceSqToEntity(this) < 4096.0D && this.canEntityBeSeen(this.getAttackTarget())) {
double x = this.getAttackTarget().posX - this.posX;
double y = (this.getAttackTarget().boundingBox.minY + (this.getAttackTarget().height / 2.0F)) - (this.posY + (this.height / 2.0F));
double z = this.getAttackTarget().posZ - this.posZ;
this.rotationYaw = (-(float) Math.atan2(x, z) * 180F) / 3.141593F;
++this.attackCounter;
if (this.attackCounter == 10) {
this.playSound("aether_legacy:aemob.zephyr.call", 3F, this.base);
} else if (this.attackCounter == 20) {
this.playSound("aether_legacy:aemob.zephyr.call", 3F, this.base);
EntityZephyrSnowball projectile = new EntityZephyrSnowball(this.worldObj, this, x, y, z);
Vec3 lookVector = this.getLook(1.0F);
projectile.posX = this.posX + lookVector.xCoord * 4D;
projectile.posY = this.posY + (double) (this.height / 2.0F) + 0.5D;
projectile.posZ = this.posZ + lookVector.zCoord * 4D;
if (!this.worldObj.isRemote) {
projectile.setThrowableHeading(x, y, z, 1.2F, 1.0F);
this.worldObj.spawnEntityInWorld(projectile);
}
this.attackCounter = -40;
}
} else if (this.attackCounter > 0) {
this.attackCounter--;
}
}
}
@Override
protected void updateEntityActionState() {
super.updateEntityActionState();
private boolean isCourseTraversable(double p_70790_1_, double p_70790_3_, double p_70790_5_, double p_70790_7_)
{
double d4 = (this.waypointX - this.posX) / p_70790_7_;
double d5 = (this.waypointY - this.posY) / p_70790_7_;
double d6 = (this.waypointZ - this.posZ) / p_70790_7_;
AxisAlignedBB axisalignedbb = this.boundingBox.copy();
for (int i = 1; (double)i < p_70790_7_; ++i)
{
axisalignedbb.offset(d4, d5, d6);
if (!this.worldObj.getCollidingBoundingBoxes(this, axisalignedbb).isEmpty())
{
return false;
}
}
return true;
}
@Override

View file

@ -1,5 +1,7 @@
package com.legacy.aether.entities.passive;
import com.legacy.aether.entities.ai.aerwhale.AerwhaleAITravelCourse;
import com.legacy.aether.entities.ai.aerwhale.AerwhaleAIUnstuck;
import net.minecraft.entity.EntityFlying;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAILookIdle;
@ -9,6 +11,7 @@ import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.util.Vec3;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.World;
import com.legacy.aether.blocks.BlocksAether;
@ -27,13 +30,13 @@ public class EntityAerwhale extends EntityFlying implements IMob {
public EntityAerwhale(World world) {
super(world);
this.setSize(4F, 4F);
this.setSize(3F, 3F);
this.isImmuneToFire = true;
this.ignoreFrustumCheck = true;
this.rotationYaw = 360F * this.getRNG().nextFloat();
this.rotationPitch = 90F * this.getRNG().nextFloat() - 45F;
this.tasks.addTask(0, new EntityAIUpdateState(this));
this.tasks.addTask(6, new EntityAILookIdle(this));
this.tasks.addTask(1, new AerwhaleAIUnstuck(this));
this.tasks.addTask(5, new AerwhaleAITravelCourse(this));
}
@Override
@ -65,192 +68,23 @@ public class EntityAerwhale extends EntityFlying implements IMob {
@Override
public void onUpdate() {
super.onUpdate();
this.extinguish();
this.updateEntityActionState();
}
@Override
public void updateEntityActionState() {
if (this.riddenByEntity != null) {
return;
}
int x = MathHelper.floor_double(this.posX);
int y = MathHelper.floor_double(this.boundingBox.minY);
int z = MathHelper.floor_double(this.posZ);
double[] distances = new double[5];
distances[0] = this.checkForTravelableCourse(0F, 0F);
distances[1] = this.checkForTravelableCourse(45F, 0F);
distances[2] = this.checkForTravelableCourse(0F, 45F);
distances[3] = this.checkForTravelableCourse(-45F, 0F);
distances[4] = this.checkForTravelableCourse(0, -45F);
int course = this.getCorrectCourse(distances);
if (course == 0) {
if (distances[0] == 50D) {
this.motionYaw *= 0.9F;
this.motionPitch *= 0.9F;
if (this.posY > 100) {
this.motionPitch -= 2F;
}
if (this.posY < 20) {
this.motionPitch += 2F;
}
} else {
this.rotationPitch = -this.rotationPitch;
this.rotationYaw = -this.rotationYaw;
}
} else if (course == 1) {
this.motionYaw += 5F;
} else if (course == 2) {
this.motionPitch -= 5F;
} else if (course == 3) {
this.motionYaw -= 5F;
} else {
this.motionPitch += 5F;
}
if (this.posY < -64.0D) {
if (this.posY < -64.0D)
{
this.setDead();
}
this.motionYaw += 2F * this.getRNG().nextFloat() - 1F;
this.motionPitch += 2F * this.getRNG().nextFloat() - 1F;
this.rotationPitch += 0.1D * this.motionPitch;
this.rotationYaw += 0.1D * this.motionYaw;
this.aerwhaleRotationPitch += 0.1D * this.motionPitch;
this.aerwhaleRotationYaw += 0.1D * this.motionYaw;
if (this.rotationPitch < -60F) {
this.rotationPitch = -60F;
}
if (this.aerwhaleRotationPitch < -60D) {
this.aerwhaleRotationPitch = -60D;
}
if (this.rotationPitch > 60F) {
this.rotationPitch = 60F;
}
if (this.aerwhaleRotationPitch > 60D) {
this.aerwhaleRotationPitch = 60D;
}
this.rotationPitch *= 0.99D;
this.aerwhaleRotationPitch *= 0.99D;
if (!this.worldObj.isRemote) {
this.motionX += 0.01D * Math.cos((this.aerwhaleRotationYaw / 180D) * 3.1415926535897931D) * Math.cos((this.aerwhaleRotationPitch / 180D) * 3.1415926535897931D);
this.motionY += 0.01D * Math.sin((this.aerwhaleRotationPitch / 180D) * Math.PI);
this.motionZ += 0.01D * Math.sin((this.aerwhaleRotationYaw / 180D) * 3.1415926535897931D) * Math.cos((this.aerwhaleRotationPitch / 180D) * 3.1415926535897931D);
this.motionX *= 0.98D;
this.motionY *= 0.98D;
this.motionZ *= 0.98D;
}
if (this.motionX > 0D && this.worldObj.getBlock(x + 1, y, z) != Blocks.air) {
if (!this.worldObj.isRemote) {
this.motionX = -this.motionX;
}
this.motionYaw -= 10F;
} else if (this.motionX < 0D && this.worldObj.getBlock(x - 1, y, z) != Blocks.air) {
if (!this.worldObj.isRemote) {
this.motionX = -this.motionX;
}
this.motionYaw += 10F;
}
if (this.motionY > 0D && this.worldObj.getBlock(x, y + 1, z) != Blocks.air) {
if (!this.worldObj.isRemote) {
this.motionY = -this.motionY;
}
this.motionPitch -= 20F;
} else if (this.motionY < 0D && this.worldObj.getBlock(x, y - 1, z) != Blocks.air) {
if (!this.worldObj.isRemote) {
this.motionY = -this.motionY;
}
this.motionPitch += 20F;
}
if (this.motionZ > 0D && this.worldObj.getBlock(x, y, z + 1) != Blocks.air) {
if (!this.worldObj.isRemote) {
this.motionZ = -this.motionZ;
}
this.motionYaw -= 10F;
} else if (this.motionZ < 0D && this.worldObj.getBlock(x, y, z - 1) != Blocks.air) {
if (!this.worldObj.isRemote) {
this.motionZ = -this.motionZ;
}
this.motionYaw += 10F;
}
if (!this.worldObj.isRemote) {
this.moveEntity(this.motionX, this.motionY, this.motionZ);
}
this.aerwhaleRotationYaw = this.rotationYaw;
this.aerwhaleRotationPitch = this.rotationPitch;
}
private int getCorrectCourse(double[] distances) {
int correctCourse = 0;
for (int i = 1; i < 5; i++) {
if (distances[i] > distances[correctCourse]) {
correctCourse = i;
}
}
return correctCourse;
}
private double checkForTravelableCourse(float rotationYawOffset, float rotationPitchOffset) {
double standard = 50D;
float yaw = this.rotationYaw + rotationYawOffset;
float pitch = this.rotationYaw + rotationYawOffset;
float f3 = MathHelper.cos(-yaw * 0.01745329F - 3.141593F);
float f4 = MathHelper.sin(-yaw * 0.01745329F - 3.141593F);
float f5 = MathHelper.cos(-pitch * 0.01745329F);
float f6 = MathHelper.sin(-pitch * 0.01745329F);
float f7 = f4 * f5;
float f8 = f6;
float f9 = f3 * f5;
Vec3 vec3d = Vec3.createVectorHelper(this.posX, this.boundingBox.minY, this.posZ);
Vec3 vec3d1 = vec3d.addVector((double) f7 * standard, (double) f8 * standard, (double) f9 * standard);
MovingObjectPosition movingobjectposition = this.worldObj.rayTraceBlocks(vec3d, vec3d1, true);
if (movingobjectposition == null) {
return standard;
}
if (movingobjectposition.typeOfHit == MovingObjectType.BLOCK) {
double i = movingobjectposition.blockX - this.posX;
double j = movingobjectposition.blockY - this.boundingBox.minY;
double k = movingobjectposition.blockZ - this.posZ;
return Math.sqrt(i * i + j * j + k * k);
}
return standard;
@Override
public void moveEntityWithHeading(float p_70612_1_, float p_70612_2_)
{
this.stepHeight = 0.5F;
this.jumpMovementFactor = 0.02F;
super.moveEntityWithHeading(p_70612_1_, p_70612_2_);
}
@Override

View file

@ -69,7 +69,7 @@ public class AetherBiome extends BiomeGenBase {
private void addMobEntry(ArrayList<SpawnListEntry> list) {
list.add(new SpawnListEntry(EntityWhirlwind.class, 8, 2, 2));
list.add(new SpawnListEntry(EntityCockatrice.class, 4, 4, 4));
list.add(new SpawnListEntry(EntityAerwhale.class, 7, 3, 3));
list.add(new SpawnListEntry(EntityAerwhale.class, 3, 1, 1));
list.add(new SpawnListEntry(EntityZephyr.class, 4, 1, 1));
list.add(new SpawnListEntry(EntityAechorPlant.class, 2, 3, 3));
}