package crazypants.enderzoo.entity; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.UUID; import crazypants.enderzoo.EnderZoo; import crazypants.enderzoo.vec.Point3i; import crazypants.enderzoo.vec.VecUtil; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.EntityAITasks; import net.minecraft.entity.ai.EntityAITasks.EntityAITaskEntry; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.ai.attributes.IAttribute; import net.minecraft.entity.ai.attributes.IAttributeInstance; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; public class EntityUtil { public static boolean isHardDifficulty(World worldObj) { return worldObj.getDifficulty() == EnumDifficulty.HARD; } public static float getDifficultyMultiplierForLocation(World world, double x, double y, double z) { // Value between 0 and 1 (normal) - 1.5 based on how long a chunk has been // occupied float occupiedDiffcultyMultiplier = world.getDifficultyForLocation(VecUtil.bpos(x, y, z)).getClampedAdditionalDifficulty(); occupiedDiffcultyMultiplier /= 1.5f; // normalize return occupiedDiffcultyMultiplier; } public static String getDisplayNameForEntity(String mobName) { return EnderZoo.proxy.translate("entity." + mobName + ".name"); } public static Vec3d getEntityPosition(Entity entity) { return new Vec3d(entity.posX, entity.posY, entity.posZ); } public static AxisAlignedBB getBoundsAround(Entity entity, double range) { return getBoundsAround(entity.posX, entity.posY, entity.posZ, range); } public static AxisAlignedBB getBoundsAround(Vec3d pos, double range) { return getBoundsAround(pos.x, pos.y, pos.z, range); } public static AxisAlignedBB getBoundsAround(BlockPos pos, int range) { return getBoundsAround(pos.getX(), pos.getY(), pos.getZ(), range); } public static AxisAlignedBB getBoundsAround(double x, double y, double z, double range) { return new AxisAlignedBB(x - range, y - range, z - range, x + range, y + range, z + range); } public static Point3i getEntityPositionI(Entity entity) { return new Point3i((int) entity.posX, (int) entity.posY, (int) entity.posZ); } public static void cancelCurrentTasks(EntityLiving ent) { Iterator<EntityAITaskEntry> iterator = ent.tasks.taskEntries.iterator(); List<EntityAITasks.EntityAITaskEntry> currentTasks = new ArrayList<EntityAITasks.EntityAITaskEntry>(); while (iterator.hasNext()) { EntityAITaskEntry entityaitaskentry = iterator.next(); if (entityaitaskentry != null) { currentTasks.add(entityaitaskentry); } } // Only available way to stop current execution is to remove all current // tasks, then re-add them for (EntityAITaskEntry task : currentTasks) { ent.tasks.removeTask(task.action); ent.tasks.addTask(task.priority, task.action); } ent.getNavigator().clearPathEntity(); } public static IAttributeInstance removeModifier(EntityLivingBase ent, IAttribute p, UUID u) { IAttributeInstance att = ent.getEntityAttribute(p); AttributeModifier curmod = att.getModifier(u); if (curmod != null) { att.removeModifier(curmod); } return att; } public static double getDistanceSqToNearestPlayer(Entity entity, double maxRange) { AxisAlignedBB bounds = getBoundsAround(entity, maxRange); EntityPlayer nearest = (EntityPlayer) entity.getEntityWorld().findNearestEntityWithinAABB(EntityPlayer.class, bounds, entity); if (nearest == null) { return 1; } return nearest.getDistanceSqToEntity(entity); } public static boolean isPlayerWithinRange(Entity entity, double range) { List<EntityPlayer> res = entity.getEntityWorld().getEntitiesWithinAABB(EntityPlayer.class, getBoundsAround(entity, range)); return res != null && !res.isEmpty(); } public static boolean isOnGround(EntityCreature entity) { List<AxisAlignedBB> collides = entity.getEntityWorld().getCollisionBoxes(entity, entity.getEntityBoundingBox().offset(0, -0.1, 0)); if (collides == null || collides.isEmpty()) { return false; } BlockPos groundPos = entity.getPosition().down(); IBlockState bs = entity.getEntityWorld().getBlockState(groundPos); if (bs.getMaterial().isLiquid()) { return false; } return true; } public static BlockPos findRandomLandingSurface(EntityCreature entity, int searchRange, int minY, int maxY, int searchAttempts) { for (int i = 0; i < searchAttempts; i++) { BlockPos res = findRandomLandingSurface(entity, searchRange, minY, maxY); if (res != null) { return res; } } return null; } public static BlockPos findRandomClearArea(EntityCreature entity, int searchRange, int minY, int maxY, int searchAttempts) { BlockPos ep = entity.getPosition(); Vec3d pos = entity.getPositionVector(); World worldObj = entity.getEntityWorld(); for (int i = 0; i < searchAttempts; i++) { int x = ep.getX() + -searchRange + (worldObj.rand.nextInt(searchRange + 1) * 2); int y = minY + worldObj.rand.nextInt(maxY - minY + 1); int z = ep.getZ() + -searchRange + (worldObj.rand.nextInt(searchRange + 1) * 2); entity.setPosition(x + 0.5, y, z + 0.5); boolean isSpace = SpawnUtil.isSpaceAvailableForSpawn(worldObj, entity, false); entity.setPosition(pos.x, pos.y, pos.z); if(isSpace) { return new BlockPos(x,y,z); } } return null; } public static BlockPos findRandomLandingSurface(EntityLiving entity, int searchRange, int minY, int maxY) { BlockPos ep = entity.getPosition(); World worldObj = entity.getEntityWorld(); int x = ep.getX() + -searchRange + (worldObj.rand.nextInt(searchRange + 1) * 2); int z = ep.getZ() + -searchRange + (worldObj.rand.nextInt(searchRange + 1) * 2); return findClearLandingSurface(entity, x, z, minY, maxY); } public static BlockPos findClearLandingSurface(EntityLiving ent, int x, int z, int minY, int maxY) { double origX = ent.posX; double origY = ent.posY; double origZ = ent.posZ; int y = maxY; boolean canLand = canLandAtLocation(ent, x, y, z); while (!canLand) { --y; if (y < minY) { break; } canLand = canLandAtLocation(ent, x, y, z); } ent.setPosition(origX, origY, origZ); if (canLand) { return new BlockPos(x, y, z); } return null; } private static boolean canLandAtLocation(EntityLiving ent, int x, int y, int z) { World world = ent.getEntityWorld(); ent.setPosition(x + 0.5, y, z + 0.5); if (!SpawnUtil.isSpaceAvailableForSpawn(world, ent, false, false)) { return false; } BlockPos below = new BlockPos(x, y, z).down(); IBlockState bs = world.getBlockState(below); if (!bs.getMaterial().isSolid()) { return false; } AxisAlignedBB collides = bs.getCollisionBoundingBox(world, below); return collides != null; } }