package com.minelittlepony.unicopia.entity; import java.util.Iterator; import net.minecraft.entity.Entity; import net.minecraft.entity.IEntityLivingData; import net.minecraft.util.ClassInheritanceMultiMap; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; import net.minecraft.world.biome.Biome.SpawnListEntry; import net.minecraft.world.chunk.Chunk; public class EntityWildCloud extends EntityCloud { public static final SpawnListEntry SPAWN_ENTRY_LAND = new SpawnListEntry(EntityWildCloud.class, 1, 1, 15); public static final SpawnListEntry SPAWN_ENTRY_OCEAN = new SpawnListEntry(EntityWildCloud.class, 1, 1, 7); public EntityWildCloud(World world) { super(world); preventEntitySpawning = true; } @Override public boolean isNotColliding() { AxisAlignedBB boundingbox = getEntityBoundingBox(); return checkNoEntityCollision(boundingbox, this) && world.canBlockSeeSky(new BlockPos(this)) && world.getCollisionBoxes(this, boundingbox).isEmpty() && !world.containsAnyLiquid(boundingbox); } /** * Returns true if there are no solid, live entities in the specified AxisAlignedBB, excluding the given entity * * @ref World.checkNoEntityCollision(AxisAlignedBB area, Entity entity) */ public boolean checkNoEntityCollision(AxisAlignedBB area, Entity entity) { for (Entity i : world.getEntitiesWithinAABBExcludingEntity(entity, area)) { if (!i.isDead && (i.preventEntitySpawning || i instanceof EntityCloud) && (!entity.isRiding() || !entity.isRidingOrBeingRiddenBy(i))) { return false; } } return true; } @Override public boolean getCanSpawnHere() { int count = 0; BlockPos pos = new BlockPos(this); Chunk chunk = world.getChunk(pos); for (ClassInheritanceMultiMap i : chunk.getEntityLists()) { Iterator iter = i.getByClass(EntityCloud.class).iterator(); while (iter.hasNext()) { iter.next(); if (count++ > 2) { return false; } } } return world.getBlockState(pos.down()).canEntitySpawn(this); } @Override public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData pack) { pack = super.onInitialSpawn(difficulty, pack); if (!(pack instanceof PackData)) { float minSpawnHeight = getMinimumFlyingHeight(); targetAltitude = getRandomFlyingHeight(); if (posY < minSpawnHeight) { minSpawnHeight += world.rand.nextInt(Math.max(1, (int)getMaximumFlyingHeight() - (int)minSpawnHeight)); setLocationAndAngles(posX, minSpawnHeight - 1, posZ, rotationYaw, rotationPitch); collideWithNearbyEntities(); } if (world.isRainingAt(getPosition())) { setIsRaining(true); } if (world.isThundering()) { setIsThundering(true); } pack = new PackData(this); } else { PackData packData = (PackData)pack; targetAltitude = packData.leader.targetAltitude; Vec3d position = packData.getUnOccupiedPosition(getCloudSize()); setIsRaining(packData.leader.getIsRaining()); setIsThundering(packData.leader.getIsThundering()); setLocationAndAngles(position.x, position.y, position.z, packData.leader.rotationYaw, packData.leader.rotationPitch); collideWithNearbyEntities(); } return pack; } static class PackData implements IEntityLivingData { EntityCloud leader; PackData(EntityCloud leader) { this.leader = leader; } Vec3d getUnOccupiedPosition(int size) { return leader.getPositionVector(); } } }