package net.minecraft.server;
import com.google.common.collect.Lists;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;
public class PersistentVillage extends PersistentBase {
private World world;
private final List<BlockPosition> c = Lists.newArrayList();
private final List<VillageDoor> d = Lists.newArrayList();
private final List<Village> villages = Lists.newArrayList();
private int time;
public PersistentVillage(String s) {
super(s);
}
public PersistentVillage(World world) {
super(a(world.worldProvider));
this.world = world;
this.c();
}
public void a(World world) {
this.world = world;
Iterator iterator = this.villages.iterator();
while (iterator.hasNext()) {
Village village = (Village) iterator.next();
village.a(world);
}
}
public void a(BlockPosition blockposition) {
if (this.c.size() <= 64) {
if (!this.e(blockposition)) {
this.c.add(blockposition);
}
}
}
public void tick() {
++this.time;
Iterator iterator = this.villages.iterator();
while (iterator.hasNext()) {
Village village = (Village) iterator.next();
village.a(this.time);
}
this.e();
this.f();
this.g();
if (this.time % 400 == 0) {
this.c();
}
}
private void e() {
Iterator iterator = this.villages.iterator();
while (iterator.hasNext()) {
Village village = (Village) iterator.next();
if (village.g()) {
iterator.remove();
this.c();
}
}
}
public List<Village> getVillages() {
return this.villages;
}
public Village getClosestVillage(BlockPosition blockposition, int i) {
Village village = null;
double d0 = 3.4028234663852886E38D;
Iterator iterator = this.villages.iterator();
while (iterator.hasNext()) {
Village village1 = (Village) iterator.next();
double d1 = village1.a().n(blockposition);
if (d1 < d0) {
float f = (float) (i + village1.b());
if (d1 <= (double) (f * f)) {
village = village1;
d0 = d1;
}
}
}
return village;
}
private void f() {
if (!this.c.isEmpty()) {
this.b((BlockPosition) this.c.remove(0));
}
}
private void g() {
for (int i = 0; i < this.d.size(); ++i) {
VillageDoor villagedoor = (VillageDoor) this.d.get(i);
Village village = this.getClosestVillage(villagedoor.d(), 32);
if (village == null) {
village = new Village(this.world);
this.villages.add(village);
this.c();
}
village.a(villagedoor);
}
this.d.clear();
}
private void b(BlockPosition blockposition) {
boolean flag = true;
boolean flag1 = true;
boolean flag2 = true;
for (int i = -16; i < 16; ++i) {
for (int j = -4; j < 4; ++j) {
for (int k = -16; k < 16; ++k) {
BlockPosition blockposition1 = blockposition.a(i, j, k);
if (this.f(blockposition1)) {
VillageDoor villagedoor = this.c(blockposition1);
if (villagedoor == null) {
this.d(blockposition1);
} else {
villagedoor.a(this.time);
}
}
}
}
}
}
@Nullable
private VillageDoor c(BlockPosition blockposition) {
Iterator iterator = this.d.iterator();
VillageDoor villagedoor;
do {
if (!iterator.hasNext()) {
iterator = this.villages.iterator();
VillageDoor villagedoor1;
do {
if (!iterator.hasNext()) {
return null;
}
Village village = (Village) iterator.next();
villagedoor1 = village.e(blockposition);
} while (villagedoor1 == null);
return villagedoor1;
}
villagedoor = (VillageDoor) iterator.next();
} while (villagedoor.d().getX() != blockposition.getX() || villagedoor.d().getZ() != blockposition.getZ() || Math.abs(villagedoor.d().getY() - blockposition.getY()) > 1);
return villagedoor;
}
private void d(BlockPosition blockposition) {
EnumDirection enumdirection = BlockDoor.f(this.world, blockposition);
EnumDirection enumdirection1 = enumdirection.opposite();
int i = this.a(blockposition, enumdirection, 5);
int j = this.a(blockposition, enumdirection1, i + 1);
if (i != j) {
this.d.add(new VillageDoor(blockposition, i < j ? enumdirection : enumdirection1, this.time));
}
}
private int a(BlockPosition blockposition, EnumDirection enumdirection, int i) {
int j = 0;
for (int k = 1; k <= 5; ++k) {
if (this.world.h(blockposition.shift(enumdirection, k))) {
++j;
if (j >= i) {
return j;
}
}
}
return j;
}
private boolean e(BlockPosition blockposition) {
Iterator iterator = this.c.iterator();
BlockPosition blockposition1;
do {
if (!iterator.hasNext()) {
return false;
}
blockposition1 = (BlockPosition) iterator.next();
} while (!blockposition1.equals(blockposition));
return true;
}
private boolean f(BlockPosition blockposition) {
IBlockData iblockdata = this.world.getType(blockposition);
Block block = iblockdata.getBlock();
return block instanceof BlockDoor ? iblockdata.getMaterial() == Material.WOOD : false;
}
public void a(NBTTagCompound nbttagcompound) {
this.time = nbttagcompound.getInt("Tick");
NBTTagList nbttaglist = nbttagcompound.getList("Villages", 10);
for (int i = 0; i < nbttaglist.size(); ++i) {
NBTTagCompound nbttagcompound1 = nbttaglist.get(i);
Village village = new Village(world); // Paper
village.a(nbttagcompound1);
this.villages.add(village);
}
}
public NBTTagCompound b(NBTTagCompound nbttagcompound) {
nbttagcompound.setInt("Tick", this.time);
NBTTagList nbttaglist = new NBTTagList();
Iterator iterator = this.villages.iterator();
while (iterator.hasNext()) {
Village village = (Village) iterator.next();
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
village.b(nbttagcompound1);
nbttaglist.add(nbttagcompound1);
}
nbttagcompound.set("Villages", nbttaglist);
return nbttagcompound;
}
public static String a(WorldProvider worldprovider) {
return "villages" + worldprovider.getDimensionManager().c();
}
}