2020-04-15 14:22:03 +02:00
|
|
|
package com.minelittlepony.unicopia.entity;
|
2020-01-17 14:27:26 +01:00
|
|
|
|
|
|
|
import java.util.Iterator;
|
|
|
|
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
|
|
|
|
import net.minecraft.entity.Entity;
|
|
|
|
import net.minecraft.entity.EntityData;
|
|
|
|
import net.minecraft.entity.EntityType;
|
|
|
|
import net.minecraft.entity.SpawnType;
|
|
|
|
import net.minecraft.nbt.CompoundTag;
|
|
|
|
import net.minecraft.util.math.ChunkPos;
|
|
|
|
import net.minecraft.util.TypeFilterableList;
|
|
|
|
import net.minecraft.util.math.BlockPos;
|
|
|
|
import net.minecraft.util.math.Vec3d;
|
|
|
|
import net.minecraft.world.IWorld;
|
|
|
|
import net.minecraft.world.LocalDifficulty;
|
|
|
|
import net.minecraft.world.World;
|
|
|
|
import net.minecraft.world.biome.Biome.SpawnEntry;
|
|
|
|
import net.minecraft.world.chunk.WorldChunk;
|
|
|
|
|
|
|
|
public class WildCloudEntity extends CloudEntity {
|
|
|
|
|
|
|
|
public static final SpawnEntry SPAWN_ENTRY_LAND = new SpawnEntry(UEntities.WILD_CLOUD, 1, 1, 15);
|
|
|
|
public static final SpawnEntry SPAWN_ENTRY_OCEAN = new SpawnEntry(UEntities.WILD_CLOUD, 1, 1, 7);
|
|
|
|
|
|
|
|
public WildCloudEntity(EntityType<WildCloudEntity> type, World world) {
|
|
|
|
super(type, world);
|
|
|
|
|
2020-01-27 11:05:22 +01:00
|
|
|
inanimate = true;
|
2020-01-17 14:27:26 +01:00
|
|
|
}
|
|
|
|
|
2020-01-27 11:05:22 +01:00
|
|
|
/*@Override
|
2020-01-17 14:27:26 +01:00
|
|
|
public boolean isNotColliding() {
|
|
|
|
Box boundingbox = getBoundingBox();
|
|
|
|
|
|
|
|
return checkNoEntityCollision(boundingbox, this)
|
|
|
|
&& world.isSkyVisible(getBlockPos())
|
|
|
|
&& world.doesNotCollide(this, boundingbox)
|
|
|
|
&& !world.intersectsFluid(boundingbox);
|
2020-01-27 11:05:22 +01:00
|
|
|
}*/
|
2020-01-17 14:27:26 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if there are no solid, live entities in the specified Box, excluding the given entity
|
|
|
|
*
|
|
|
|
* @ref World.checkNoEntityCollision(Box area, Entity entity)
|
|
|
|
*/
|
2020-01-27 11:05:22 +01:00
|
|
|
/*public boolean checkNoEntityCollision(Box area, Entity entity) {
|
|
|
|
ServerWorld s;
|
|
|
|
((ServerWorld)world).intersectsEntities(entity_1, voxelShape_1)
|
2020-01-17 14:27:26 +01:00
|
|
|
|
|
|
|
for (Entity i : world.getEntities(entity, area)) {
|
2020-01-27 11:05:22 +01:00
|
|
|
if (!i.removed && (i.inanimate || i instanceof CloudEntity) && (!entity.hasVehicle() || !entity.isConnectedThroughVehicle(i))) {
|
2020-01-17 14:27:26 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2020-01-27 11:05:22 +01:00
|
|
|
}*/
|
2020-01-17 14:27:26 +01:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean canSpawn(IWorld world, SpawnType type) {
|
|
|
|
if (type == SpawnType.NATURAL) {
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
ChunkPos cpos = new ChunkPos(getBlockPos());
|
|
|
|
|
|
|
|
WorldChunk chunk = world.getChunkManager().getWorldChunk(cpos.x, cpos.z, false);
|
|
|
|
for (TypeFilterableList<Entity> i : chunk.getEntitySectionArray()) {
|
|
|
|
Iterator<CloudEntity> iter = i.getAllOfType(CloudEntity.class).iterator();
|
|
|
|
while (iter.hasNext()) {
|
|
|
|
iter.next();
|
|
|
|
|
|
|
|
if (count++ > 2) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BlockPos pos = getBlockPos().down();
|
|
|
|
return world.getBlockState(pos).allowsSpawning(world, pos, getType());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public EntityData initialize(IWorld world, LocalDifficulty difficulty, SpawnType type, @Nullable EntityData data, @Nullable CompoundTag tag) {
|
|
|
|
data = super.initialize(world, difficulty, type, data, tag);
|
|
|
|
|
|
|
|
if (!(data instanceof PackData)) {
|
|
|
|
float minSpawnHeight = getMinimumFlyingHeight();
|
|
|
|
|
|
|
|
targetAltitude = getRandomFlyingHeight();
|
|
|
|
|
2020-04-22 16:28:20 +02:00
|
|
|
if (getY() < minSpawnHeight) {
|
2020-01-27 11:05:22 +01:00
|
|
|
minSpawnHeight += random.nextInt(Math.max(1, (int)getMaximumFlyingHeight() - (int)minSpawnHeight));
|
2020-01-17 14:27:26 +01:00
|
|
|
|
2020-04-22 16:28:20 +02:00
|
|
|
updatePositionAndAngles(getX(), minSpawnHeight - 1, getZ(), yaw, pitch);
|
2020-01-27 11:05:22 +01:00
|
|
|
moveToBoundingBoxCenter();
|
2020-01-17 14:27:26 +01:00
|
|
|
}
|
|
|
|
|
2020-01-27 11:05:22 +01:00
|
|
|
if (this.world.hasRain(getBlockPos())) {
|
2020-01-17 14:27:26 +01:00
|
|
|
setIsRaining(true);
|
|
|
|
}
|
|
|
|
|
2020-01-27 11:05:22 +01:00
|
|
|
if (this.world.isThundering()) {
|
2020-01-17 14:27:26 +01:00
|
|
|
setIsThundering(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
data = new PackData(this);
|
|
|
|
} else {
|
|
|
|
PackData packData = (PackData)data;
|
|
|
|
targetAltitude = packData.leader.targetAltitude;
|
|
|
|
|
|
|
|
Vec3d position = packData.getUnOccupiedPosition(getCloudSize());
|
|
|
|
|
|
|
|
setIsRaining(packData.leader.getIsRaining());
|
|
|
|
setIsThundering(packData.leader.getIsThundering());
|
|
|
|
|
2020-04-22 16:28:20 +02:00
|
|
|
updatePositionAndAngles(position.x, position.y, position.z, packData.leader.yaw, packData.leader.pitch);
|
2020-01-17 14:27:26 +01:00
|
|
|
checkBlockCollision();
|
|
|
|
}
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static class PackData implements EntityData {
|
|
|
|
|
|
|
|
final CloudEntity leader;
|
|
|
|
|
|
|
|
PackData(CloudEntity leader) {
|
|
|
|
this.leader = leader;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vec3d getUnOccupiedPosition(int size) {
|
|
|
|
return leader.getPos();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|