package net.minecraft.village;
import com.google.common.collect.Lists;
import java.util.Iterator;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.material.Material;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.WorldSavedData;
public class VillageCollection extends WorldSavedData
{
private World worldObj;
/**
* This is a black hole. You can add data to this list through a public interface, but you can't query that
* information in any way and it's not used internally either.
*/
private final List villagerPositionsList = Lists.newArrayList();
private final List newDoors = Lists.newArrayList();
private final List villageList = Lists.newArrayList();
private int tickCounter;
private static final String __OBFID = "CL_00001635";
public VillageCollection(String p_i1677_1_)
{
super(p_i1677_1_);
}
public VillageCollection(World worldIn)
{
super(func_176062_a(worldIn.provider));
this.worldObj = worldIn;
this.markDirty();
}
public void func_82566_a(World worldIn)
{
this.worldObj = worldIn;
Iterator var2 = this.villageList.iterator();
while (var2.hasNext())
{
Village var3 = (Village)var2.next();
var3.func_82691_a(worldIn);
}
}
public void func_176060_a(BlockPos p_176060_1_)
{
if (this.villagerPositionsList.size() <= 64)
{
if (!this.func_176057_e(p_176060_1_))
{
this.villagerPositionsList.add(p_176060_1_);
}
}
}
/**
* Runs a single tick for the village collection
*/
public void tick()
{
++this.tickCounter;
Iterator var1 = this.villageList.iterator();
while (var1.hasNext())
{
Village var2 = (Village)var1.next();
var2.tick(this.tickCounter);
}
this.removeAnnihilatedVillages();
this.dropOldestVillagerPosition();
this.addNewDoorsToVillageOrCreateVillage();
if (this.tickCounter % 400 == 0)
{
this.markDirty();
}
}
private void removeAnnihilatedVillages()
{
Iterator var1 = this.villageList.iterator();
while (var1.hasNext())
{
Village var2 = (Village)var1.next();
if (var2.isAnnihilated())
{
var1.remove();
this.markDirty();
}
}
}
/**
* Get a list of villages.
*/
public List getVillageList()
{
return this.villageList;
}
public Village func_176056_a(BlockPos p_176056_1_, int p_176056_2_)
{
Village var3 = null;
double var4 = 3.4028234663852886E38D;
Iterator var6 = this.villageList.iterator();
while (var6.hasNext())
{
Village var7 = (Village)var6.next();
double var8 = var7.func_180608_a().distanceSq(p_176056_1_);
if (var8 < var4)
{
float var10 = (float)(p_176056_2_ + var7.getVillageRadius());
if (var8 <= (double)(var10 * var10))
{
var3 = var7;
var4 = var8;
}
}
}
return var3;
}
private void dropOldestVillagerPosition()
{
if (!this.villagerPositionsList.isEmpty())
{
this.func_180609_b((BlockPos)this.villagerPositionsList.remove(0));
}
}
private void addNewDoorsToVillageOrCreateVillage()
{
for (int var1 = 0; var1 < this.newDoors.size(); ++var1)
{
VillageDoorInfo var2 = (VillageDoorInfo)this.newDoors.get(var1);
Village var3 = this.func_176056_a(var2.func_179852_d(), 32);
if (var3 == null)
{
var3 = new Village(this.worldObj);
this.villageList.add(var3);
this.markDirty();
}
var3.addVillageDoorInfo(var2);
}
this.newDoors.clear();
}
private void func_180609_b(BlockPos p_180609_1_)
{
byte var2 = 16;
byte var3 = 4;
byte var4 = 16;
for (int var5 = -var2; var5 < var2; ++var5)
{
for (int var6 = -var3; var6 < var3; ++var6)
{
for (int var7 = -var4; var7 < var4; ++var7)
{
BlockPos var8 = p_180609_1_.add(var5, var6, var7);
if (this.func_176058_f(var8))
{
VillageDoorInfo var9 = this.func_176055_c(var8);
if (var9 == null)
{
this.func_176059_d(var8);
}
else
{
var9.func_179849_a(this.tickCounter);
}
}
}
}
}
}
private VillageDoorInfo func_176055_c(BlockPos p_176055_1_)
{
Iterator var2 = this.newDoors.iterator();
VillageDoorInfo var3;
do
{
if (!var2.hasNext())
{
var2 = this.villageList.iterator();
VillageDoorInfo var4;
do
{
if (!var2.hasNext())
{
return null;
}
Village var5 = (Village)var2.next();
var4 = var5.func_179864_e(p_176055_1_);
}
while (var4 == null);
return var4;
}
var3 = (VillageDoorInfo)var2.next();
}
while (var3.func_179852_d().getX() != p_176055_1_.getX() || var3.func_179852_d().getZ() != p_176055_1_.getZ() || Math.abs(var3.func_179852_d().getY() - p_176055_1_.getY()) > 1);
return var3;
}
private void func_176059_d(BlockPos p_176059_1_)
{
EnumFacing var2 = BlockDoor.func_176517_h(this.worldObj, p_176059_1_);
EnumFacing var3 = var2.getOpposite();
int var4 = this.func_176061_a(p_176059_1_, var2, 5);
int var5 = this.func_176061_a(p_176059_1_, var3, var4 + 1);
if (var4 != var5)
{
this.newDoors.add(new VillageDoorInfo(p_176059_1_, var4 < var5 ? var2 : var3, this.tickCounter));
}
}
private int func_176061_a(BlockPos p_176061_1_, EnumFacing p_176061_2_, int p_176061_3_)
{
int var4 = 0;
for (int var5 = 1; var5 <= 5; ++var5)
{
if (this.worldObj.isAgainstSky(p_176061_1_.offset(p_176061_2_, var5)))
{
++var4;
if (var4 >= p_176061_3_)
{
return var4;
}
}
}
return var4;
}
private boolean func_176057_e(BlockPos p_176057_1_)
{
Iterator var2 = this.villagerPositionsList.iterator();
BlockPos var3;
do
{
if (!var2.hasNext())
{
return false;
}
var3 = (BlockPos)var2.next();
}
while (!var3.equals(p_176057_1_));
return true;
}
private boolean func_176058_f(BlockPos p_176058_1_)
{
Block var2 = this.worldObj.getBlockState(p_176058_1_).getBlock();
return var2 instanceof BlockDoor ? var2.getMaterial() == Material.wood : false;
}
/**
* reads in data from the NBTTagCompound into this MapDataBase
*/
public void readFromNBT(NBTTagCompound nbt)
{
this.tickCounter = nbt.getInteger("Tick");
NBTTagList var2 = nbt.getTagList("Villages", 10);
for (int var3 = 0; var3 < var2.tagCount(); ++var3)
{
NBTTagCompound var4 = var2.getCompoundTagAt(var3);
Village var5 = new Village();
var5.readVillageDataFromNBT(var4);
this.villageList.add(var5);
}
}
/**
* write data to NBTTagCompound from this MapDataBase, similar to Entities and TileEntities
*/
public void writeToNBT(NBTTagCompound nbt)
{
nbt.setInteger("Tick", this.tickCounter);
NBTTagList var2 = new NBTTagList();
Iterator var3 = this.villageList.iterator();
while (var3.hasNext())
{
Village var4 = (Village)var3.next();
NBTTagCompound var5 = new NBTTagCompound();
var4.writeVillageDataToNBT(var5);
var2.appendTag(var5);
}
nbt.setTag("Villages", var2);
}
public static String func_176062_a(WorldProvider p_176062_0_)
{
return "villages" + p_176062_0_.getInternalNameSuffix();
}
}