    001    package net.minecraft.src;
    002
    003    import java.util.ArrayList;
    004    import java.util.Iterator;
    005    import java.util.List;
    006
    007    public class VillageCollection
    008    {
    009        private World worldObj;
    010
    011        /**
    012         * This is a black hole. You can add data to this list through a public interface, but you can't query that
    013         * information in any way and it's not used internally either.
    014         */
    015        private final List villagerPositionsList = new ArrayList();
    016        private final List newDoors = new ArrayList();
    017        private final List villageList = new ArrayList();
    018        private int tickCounter = 0;
    019
    020        public VillageCollection(World par1World)
    021        {
    022            this.worldObj = par1World;
    023        }
    024
    025        /**
    026         * This is a black hole. You can add data to this list through a public interface, but you can't query that
    027         * information in any way and it's not used internally either.
    028         */
    029        public void addVillagerPosition(int par1, int par2, int par3)
    030        {
    031            if (this.villagerPositionsList.size() <= 64)
    032            {
    033                if (!this.isVillagerPositionPresent(par1, par2, par3))
    034                {
    035                    this.villagerPositionsList.add(new ChunkCoordinates(par1, par2, par3));
    036                }
    037            }
    038        }
    039
    040        /**
    041         * Runs a single tick for the village collection
    042         */
    043        public void tick()
    044        {
    045            ++this.tickCounter;
    046            Iterator var1 = this.villageList.iterator();
    047
    048            while (var1.hasNext())
    049            {
    050                Village var2 = (Village)var1.next();
    051                var2.tick(this.tickCounter);
    052            }
    053
    054            this.removeAnnihilatedVillages();
    055            this.dropOldestVillagerPosition();
    056            this.addNewDoorsToVillageOrCreateVillage();
    057        }
    058
    059        private void removeAnnihilatedVillages()
    060        {
    061            Iterator var1 = this.villageList.iterator();
    062
    063            while (var1.hasNext())
    064            {
    065                Village var2 = (Village)var1.next();
    066
    067                if (var2.isAnnihilated())
    068                {
    069                    var1.remove();
    070                }
    071            }
    072        }
    073
    074        /**
    075         * Get a list of villages.
    076         */
    077        public List getVillageList()
    078        {
    079            return this.villageList;
    080        }
    081
    082        /**
    083         * Finds the nearest village, but only the given coordinates are withing it's bounding box plus the given the
    084         * distance.
    085         */
    086        public Village findNearestVillage(int par1, int par2, int par3, int par4)
    087        {
    088            Village var5 = null;
    089            float var6 = Float.MAX_VALUE;
    090            Iterator var7 = this.villageList.iterator();
    091
    092            while (var7.hasNext())
    093            {
    094                Village var8 = (Village)var7.next();
    095                float var9 = var8.getCenter().getDistanceSquared(par1, par2, par3);
    096
    097                if (var9 < var6)
    098                {
    099                    int var10 = par4 + var8.getVillageRadius();
    100
    101                    if (var9 <= (float)(var10 * var10))
    102                    {
    103                        var5 = var8;
    104                        var6 = var9;
    105                    }
    106                }
    107            }
    108
    109            return var5;
    110        }
    111
    112        private void dropOldestVillagerPosition()
    113        {
    114            if (!this.villagerPositionsList.isEmpty())
    115            {
    116                this.addUnassignedWoodenDoorsAroundToNewDoorsList((ChunkCoordinates)this.villagerPositionsList.remove(0));
    117            }
    118        }
    119
    120        private void addNewDoorsToVillageOrCreateVillage()
    121        {
    122            Iterator var1 = this.newDoors.iterator();
    123
    124            while (var1.hasNext())
    125            {
    126                VillageDoorInfo var2 = (VillageDoorInfo)var1.next();
    127                boolean var3 = false;
    128                Iterator var4 = this.villageList.iterator();
    129
    130                while (true)
    131                {
    132                    if (var4.hasNext())
    133                    {
    134                        Village var5 = (Village)var4.next();
    135                        int var6 = (int)var5.getCenter().getDistanceSquared(var2.posX, var2.posY, var2.posZ);
    136                        int var7 = 32 + var5.getVillageRadius();
    137
    138                        if (var6 > var7 * var7)
    139                        {
    140                            continue;
    141                        }
    142
    143                        var5.addVillageDoorInfo(var2);
    144                        var3 = true;
    145                    }
    146
    147                    if (!var3)
    148                    {
    149                        Village var8 = new Village(this.worldObj);
    150                        var8.addVillageDoorInfo(var2);
    151                        this.villageList.add(var8);
    152                    }
    153
    154                    break;
    155                }
    156            }
    157
    158            this.newDoors.clear();
    159        }
    160
    161        private void addUnassignedWoodenDoorsAroundToNewDoorsList(ChunkCoordinates par1ChunkCoordinates)
    162        {
    163            byte var2 = 16;
    164            byte var3 = 4;
    165            byte var4 = 16;
    166
    167            for (int var5 = par1ChunkCoordinates.posX - var2; var5 < par1ChunkCoordinates.posX + var2; ++var5)
    168            {
    169                for (int var6 = par1ChunkCoordinates.posY - var3; var6 < par1ChunkCoordinates.posY + var3; ++var6)
    170                {
    171                    for (int var7 = par1ChunkCoordinates.posZ - var4; var7 < par1ChunkCoordinates.posZ + var4; ++var7)
    172                    {
    173                        if (this.isWoodenDoorAt(var5, var6, var7))
    174                        {
    175                            VillageDoorInfo var8 = this.getVillageDoorAt(var5, var6, var7);
    176
    177                            if (var8 == null)
    178                            {
    179                                this.addDoorToNewListIfAppropriate(var5, var6, var7);
    180                            }
    181                            else
    182                            {
    183                                var8.lastActivityTimestamp = this.tickCounter;
    184                            }
    185                        }
    186                    }
    187                }
    188            }
    189        }
    190
    191        private VillageDoorInfo getVillageDoorAt(int par1, int par2, int par3)
    192        {
    193            Iterator var4 = this.newDoors.iterator();
    194            VillageDoorInfo var5;
    195
    196            do
    197            {
    198                if (!var4.hasNext())
    199                {
    200                    var4 = this.villageList.iterator();
    201                    VillageDoorInfo var6;
    202
    203                    do
    204                    {
    205                        if (!var4.hasNext())
    206                        {
    207                            return null;
    208                        }
    209
    210                        Village var7 = (Village)var4.next();
    211                        var6 = var7.getVillageDoorAt(par1, par2, par3);
    212                    }
    213                    while (var6 == null);
    214
    215                    return var6;
    216                }
    217
    218                var5 = (VillageDoorInfo)var4.next();
    219            }
    220            while (var5.posX != par1 || var5.posZ != par3 || Math.abs(var5.posY - par2) > 1);
    221
    222            return var5;
    223        }
    224
    225        private void addDoorToNewListIfAppropriate(int par1, int par2, int par3)
    226        {
    227            int var4 = ((BlockDoor)Block.doorWood).getDoorOrientation(this.worldObj, par1, par2, par3);
    228            int var5;
    229            int var6;
    230
    231            if (var4 != 0 && var4 != 2)
    232            {
    233                var5 = 0;
    234
    235                for (var6 = -5; var6 < 0; ++var6)
    236                {
    237                    if (this.worldObj.canBlockSeeTheSky(par1, par2, par3 + var6))
    238                    {
    239                        --var5;
    240                    }
    241                }
    242
    243                for (var6 = 1; var6 <= 5; ++var6)
    244                {
    245                    if (this.worldObj.canBlockSeeTheSky(par1, par2, par3 + var6))
    246                    {
    247                        ++var5;
    248                    }
    249                }
    250
    251                if (var5 != 0)
    252                {
    253                    this.newDoors.add(new VillageDoorInfo(par1, par2, par3, 0, var5 > 0 ? -2 : 2, this.tickCounter));
    254                }
    255            }
    256            else
    257            {
    258                var5 = 0;
    259
    260                for (var6 = -5; var6 < 0; ++var6)
    261                {
    262                    if (this.worldObj.canBlockSeeTheSky(par1 + var6, par2, par3))
    263                    {
    264                        --var5;
    265                    }
    266                }
    267
    268                for (var6 = 1; var6 <= 5; ++var6)
    269                {
    270                    if (this.worldObj.canBlockSeeTheSky(par1 + var6, par2, par3))
    271                    {
    272                        ++var5;
    273                    }
    274                }
    275
    276                if (var5 != 0)
    277                {
    278                    this.newDoors.add(new VillageDoorInfo(par1, par2, par3, var5 > 0 ? -2 : 2, 0, this.tickCounter));
    279                }
    280            }
    281        }
    282
    283        private boolean isVillagerPositionPresent(int par1, int par2, int par3)
    284        {
    285            Iterator var4 = this.villagerPositionsList.iterator();
    286            ChunkCoordinates var5;
    287
    288            do
    289            {
    290                if (!var4.hasNext())
    291                {
    292                    return false;
    293                }
    294
    295                var5 = (ChunkCoordinates)var4.next();
    296            }
    297            while (var5.posX != par1 || var5.posY != par2 || var5.posZ != par3);
    298
    299            return true;
    300        }
    301
    302        private boolean isWoodenDoorAt(int par1, int par2, int par3)
    303        {
    304            int var4 = this.worldObj.getBlockId(par1, par2, par3);
    305            return var4 == Block.doorWood.blockID;
    306        }
    307    }