package net.minecraft.village; import com.google.common.collect.Lists; import java.util.Iterator; import java.util.List; import java.util.TreeMap; import net.minecraft.block.Block; import net.minecraft.block.BlockDoor; import net.minecraft.block.material.Material; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.monster.EntityIronGolem; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.BlockPos; import net.minecraft.util.MathHelper; import net.minecraft.util.Vec3; import net.minecraft.world.World; public class Village { private World worldObj; /** list of VillageDoorInfo objects */ private final List villageDoorInfoList = Lists.newArrayList(); /** * This is the sum of all door coordinates and used to calculate the actual village center by dividing by the number * of doors. */ private BlockPos centerHelper; /** This is the actual village center. */ private BlockPos center; private int villageRadius; private int lastAddDoorTimestamp; private int tickCounter; private int numVillagers; /** Timestamp of tick count when villager last bred */ private int noBreedTicks; /** List of player reputations with this village */ private TreeMap playerReputation; private List villageAgressors; private int numIronGolems; private static final String __OBFID = "CL_00001631"; public Village() { this.centerHelper = BlockPos.ORIGIN; this.center = BlockPos.ORIGIN; this.playerReputation = new TreeMap(); this.villageAgressors = Lists.newArrayList(); } public Village(World worldIn) { this.centerHelper = BlockPos.ORIGIN; this.center = BlockPos.ORIGIN; this.playerReputation = new TreeMap(); this.villageAgressors = Lists.newArrayList(); this.worldObj = worldIn; } public void func_82691_a(World worldIn) { this.worldObj = worldIn; } /** * Called periodically by VillageCollection */ public void tick(int p_75560_1_) { this.tickCounter = p_75560_1_; this.removeDeadAndOutOfRangeDoors(); this.removeDeadAndOldAgressors(); if (p_75560_1_ % 20 == 0) { this.updateNumVillagers(); } if (p_75560_1_ % 30 == 0) { this.updateNumIronGolems(); } int var2 = this.numVillagers / 10; if (this.numIronGolems < var2 && this.villageDoorInfoList.size() > 20 && this.worldObj.rand.nextInt(7000) == 0) { Vec3 var3 = this.func_179862_a(this.center, 2, 4, 2); if (var3 != null) { EntityIronGolem var4 = new EntityIronGolem(this.worldObj); var4.setPosition(var3.xCoord, var3.yCoord, var3.zCoord); this.worldObj.spawnEntityInWorld(var4); ++this.numIronGolems; } } } private Vec3 func_179862_a(BlockPos p_179862_1_, int p_179862_2_, int p_179862_3_, int p_179862_4_) { for (int var5 = 0; var5 < 10; ++var5) { BlockPos var6 = p_179862_1_.add(this.worldObj.rand.nextInt(16) - 8, this.worldObj.rand.nextInt(6) - 3, this.worldObj.rand.nextInt(16) - 8); if (this.func_179866_a(var6) && this.func_179861_a(new BlockPos(p_179862_2_, p_179862_3_, p_179862_4_), var6)) { return new Vec3((double)var6.getX(), (double)var6.getY(), (double)var6.getZ()); } } return null; } private boolean func_179861_a(BlockPos p_179861_1_, BlockPos p_179861_2_) { if (!World.doesBlockHaveSolidTopSurface(this.worldObj, p_179861_2_.offsetDown())) { return false; } else { int var3 = p_179861_2_.getX() - p_179861_1_.getX() / 2; int var4 = p_179861_2_.getZ() - p_179861_1_.getZ() / 2; for (int var5 = var3; var5 < var3 + p_179861_1_.getX(); ++var5) { for (int var6 = p_179861_2_.getY(); var6 < p_179861_2_.getY() + p_179861_1_.getY(); ++var6) { for (int var7 = var4; var7 < var4 + p_179861_1_.getZ(); ++var7) { if (this.worldObj.getBlockState(new BlockPos(var5, var6, var7)).getBlock().isNormalCube()) { return false; } } } } return true; } } private void updateNumIronGolems() { List var1 = this.worldObj.getEntitiesWithinAABB(EntityIronGolem.class, new AxisAlignedBB((double)(this.center.getX() - this.villageRadius), (double)(this.center.getY() - 4), (double)(this.center.getZ() - this.villageRadius), (double)(this.center.getX() + this.villageRadius), (double)(this.center.getY() + 4), (double)(this.center.getZ() + this.villageRadius))); this.numIronGolems = var1.size(); } private void updateNumVillagers() { List var1 = this.worldObj.getEntitiesWithinAABB(EntityVillager.class, new AxisAlignedBB((double)(this.center.getX() - this.villageRadius), (double)(this.center.getY() - 4), (double)(this.center.getZ() - this.villageRadius), (double)(this.center.getX() + this.villageRadius), (double)(this.center.getY() + 4), (double)(this.center.getZ() + this.villageRadius))); this.numVillagers = var1.size(); if (this.numVillagers == 0) { this.playerReputation.clear(); } } public BlockPos func_180608_a() { return this.center; } public int getVillageRadius() { return this.villageRadius; } /** * Actually get num village door info entries, but that boils down to number of doors. Called by * EntityAIVillagerMate and VillageSiege */ public int getNumVillageDoors() { return this.villageDoorInfoList.size(); } public int getTicksSinceLastDoorAdding() { return this.tickCounter - this.lastAddDoorTimestamp; } public int getNumVillagers() { return this.numVillagers; } public boolean func_179866_a(BlockPos p_179866_1_) { return this.center.distanceSq(p_179866_1_) < (double)(this.villageRadius * this.villageRadius); } /** * called only by class EntityAIMoveThroughVillage */ public List getVillageDoorInfoList() { return this.villageDoorInfoList; } public VillageDoorInfo func_179865_b(BlockPos p_179865_1_) { VillageDoorInfo var2 = null; int var3 = Integer.MAX_VALUE; Iterator var4 = this.villageDoorInfoList.iterator(); while (var4.hasNext()) { VillageDoorInfo var5 = (VillageDoorInfo)var4.next(); int var6 = var5.func_179848_a(p_179865_1_); if (var6 < var3) { var2 = var5; var3 = var6; } } return var2; } public VillageDoorInfo func_179863_c(BlockPos p_179863_1_) { VillageDoorInfo var2 = null; int var3 = Integer.MAX_VALUE; Iterator var4 = this.villageDoorInfoList.iterator(); while (var4.hasNext()) { VillageDoorInfo var5 = (VillageDoorInfo)var4.next(); int var6 = var5.func_179848_a(p_179863_1_); if (var6 > 256) { var6 *= 1000; } else { var6 = var5.getDoorOpeningRestrictionCounter(); } if (var6 < var3) { var2 = var5; var3 = var6; } } return var2; } public VillageDoorInfo func_179864_e(BlockPos p_179864_1_) { if (this.center.distanceSq(p_179864_1_) > (double)(this.villageRadius * this.villageRadius)) { return null; } else { Iterator var2 = this.villageDoorInfoList.iterator(); VillageDoorInfo var3; do { if (!var2.hasNext()) { return null; } var3 = (VillageDoorInfo)var2.next(); } while (var3.func_179852_d().getX() != p_179864_1_.getX() || var3.func_179852_d().getZ() != p_179864_1_.getZ() || Math.abs(var3.func_179852_d().getY() - p_179864_1_.getY()) > 1); return var3; } } public void addVillageDoorInfo(VillageDoorInfo p_75576_1_) { this.villageDoorInfoList.add(p_75576_1_); this.centerHelper = this.centerHelper.add(p_75576_1_.func_179852_d()); this.updateVillageRadiusAndCenter(); this.lastAddDoorTimestamp = p_75576_1_.getInsidePosY(); } /** * Returns true, if there is not a single village door left. Called by VillageCollection */ public boolean isAnnihilated() { return this.villageDoorInfoList.isEmpty(); } public void addOrRenewAgressor(EntityLivingBase p_75575_1_) { Iterator var2 = this.villageAgressors.iterator(); Village.VillageAgressor var3; do { if (!var2.hasNext()) { this.villageAgressors.add(new Village.VillageAgressor(p_75575_1_, this.tickCounter)); return; } var3 = (Village.VillageAgressor)var2.next(); } while (var3.agressor != p_75575_1_); var3.agressionTime = this.tickCounter; } public EntityLivingBase findNearestVillageAggressor(EntityLivingBase p_75571_1_) { double var2 = Double.MAX_VALUE; Village.VillageAgressor var4 = null; for (int var5 = 0; var5 < this.villageAgressors.size(); ++var5) { Village.VillageAgressor var6 = (Village.VillageAgressor)this.villageAgressors.get(var5); double var7 = var6.agressor.getDistanceSqToEntity(p_75571_1_); if (var7 <= var2) { var4 = var6; var2 = var7; } } return var4 != null ? var4.agressor : null; } public EntityPlayer func_82685_c(EntityLivingBase p_82685_1_) { double var2 = Double.MAX_VALUE; EntityPlayer var4 = null; Iterator var5 = this.playerReputation.keySet().iterator(); while (var5.hasNext()) { String var6 = (String)var5.next(); if (this.isPlayerReputationTooLow(var6)) { EntityPlayer var7 = this.worldObj.getPlayerEntityByName(var6); if (var7 != null) { double var8 = var7.getDistanceSqToEntity(p_82685_1_); if (var8 <= var2) { var4 = var7; var2 = var8; } } } } return var4; } private void removeDeadAndOldAgressors() { Iterator var1 = this.villageAgressors.iterator(); while (var1.hasNext()) { Village.VillageAgressor var2 = (Village.VillageAgressor)var1.next(); if (!var2.agressor.isEntityAlive() || Math.abs(this.tickCounter - var2.agressionTime) > 300) { var1.remove(); } } } private void removeDeadAndOutOfRangeDoors() { boolean var1 = false; boolean var2 = this.worldObj.rand.nextInt(50) == 0; Iterator var3 = this.villageDoorInfoList.iterator(); while (var3.hasNext()) { VillageDoorInfo var4 = (VillageDoorInfo)var3.next(); if (var2) { var4.resetDoorOpeningRestrictionCounter(); } if (!this.func_179860_f(var4.func_179852_d()) || Math.abs(this.tickCounter - var4.getInsidePosY()) > 1200) { this.centerHelper = this.centerHelper.add(var4.func_179852_d().multiply(-1)); var1 = true; var4.func_179853_a(true); var3.remove(); } } if (var1) { this.updateVillageRadiusAndCenter(); } } private boolean func_179860_f(BlockPos p_179860_1_) { Block var2 = this.worldObj.getBlockState(p_179860_1_).getBlock(); return var2 instanceof BlockDoor ? var2.getMaterial() == Material.wood : false; } private void updateVillageRadiusAndCenter() { int var1 = this.villageDoorInfoList.size(); if (var1 == 0) { this.center = new BlockPos(0, 0, 0); this.villageRadius = 0; } else { this.center = new BlockPos(this.centerHelper.getX() / var1, this.centerHelper.getY() / var1, this.centerHelper.getZ() / var1); int var2 = 0; VillageDoorInfo var4; for (Iterator var3 = this.villageDoorInfoList.iterator(); var3.hasNext(); var2 = Math.max(var4.func_179848_a(this.center), var2)) { var4 = (VillageDoorInfo)var3.next(); } this.villageRadius = Math.max(32, (int)Math.sqrt((double)var2) + 1); } } /** * Return the village reputation for a player */ public int getReputationForPlayer(String p_82684_1_) { Integer var2 = (Integer)this.playerReputation.get(p_82684_1_); return var2 != null ? var2.intValue() : 0; } /** * Set the village reputation for a player. */ public int setReputationForPlayer(String p_82688_1_, int p_82688_2_) { int var3 = this.getReputationForPlayer(p_82688_1_); int var4 = MathHelper.clamp_int(var3 + p_82688_2_, -30, 10); this.playerReputation.put(p_82688_1_, Integer.valueOf(var4)); return var4; } /** * Return whether this player has a too low reputation with this village. */ public boolean isPlayerReputationTooLow(String p_82687_1_) { return this.getReputationForPlayer(p_82687_1_) <= -15; } /** * Read this village's data from NBT. */ public void readVillageDataFromNBT(NBTTagCompound p_82690_1_) { this.numVillagers = p_82690_1_.getInteger("PopSize"); this.villageRadius = p_82690_1_.getInteger("Radius"); this.numIronGolems = p_82690_1_.getInteger("Golems"); this.lastAddDoorTimestamp = p_82690_1_.getInteger("Stable"); this.tickCounter = p_82690_1_.getInteger("Tick"); this.noBreedTicks = p_82690_1_.getInteger("MTick"); this.center = new BlockPos(p_82690_1_.getInteger("CX"), p_82690_1_.getInteger("CY"), p_82690_1_.getInteger("CZ")); this.centerHelper = new BlockPos(p_82690_1_.getInteger("ACX"), p_82690_1_.getInteger("ACY"), p_82690_1_.getInteger("ACZ")); NBTTagList var2 = p_82690_1_.getTagList("Doors", 10); for (int var3 = 0; var3 < var2.tagCount(); ++var3) { NBTTagCompound var4 = var2.getCompoundTagAt(var3); VillageDoorInfo var5 = new VillageDoorInfo(new BlockPos(var4.getInteger("X"), var4.getInteger("Y"), var4.getInteger("Z")), var4.getInteger("IDX"), var4.getInteger("IDZ"), var4.getInteger("TS")); this.villageDoorInfoList.add(var5); } NBTTagList var6 = p_82690_1_.getTagList("Players", 10); for (int var7 = 0; var7 < var6.tagCount(); ++var7) { NBTTagCompound var8 = var6.getCompoundTagAt(var7); this.playerReputation.put(var8.getString("Name"), Integer.valueOf(var8.getInteger("S"))); } } /** * Write this village's data to NBT. */ public void writeVillageDataToNBT(NBTTagCompound p_82689_1_) { p_82689_1_.setInteger("PopSize", this.numVillagers); p_82689_1_.setInteger("Radius", this.villageRadius); p_82689_1_.setInteger("Golems", this.numIronGolems); p_82689_1_.setInteger("Stable", this.lastAddDoorTimestamp); p_82689_1_.setInteger("Tick", this.tickCounter); p_82689_1_.setInteger("MTick", this.noBreedTicks); p_82689_1_.setInteger("CX", this.center.getX()); p_82689_1_.setInteger("CY", this.center.getY()); p_82689_1_.setInteger("CZ", this.center.getZ()); p_82689_1_.setInteger("ACX", this.centerHelper.getX()); p_82689_1_.setInteger("ACY", this.centerHelper.getY()); p_82689_1_.setInteger("ACZ", this.centerHelper.getZ()); NBTTagList var2 = new NBTTagList(); Iterator var3 = this.villageDoorInfoList.iterator(); while (var3.hasNext()) { VillageDoorInfo var4 = (VillageDoorInfo)var3.next(); NBTTagCompound var5 = new NBTTagCompound(); var5.setInteger("X", var4.func_179852_d().getX()); var5.setInteger("Y", var4.func_179852_d().getY()); var5.setInteger("Z", var4.func_179852_d().getZ()); var5.setInteger("IDX", var4.func_179847_f()); var5.setInteger("IDZ", var4.func_179855_g()); var5.setInteger("TS", var4.getInsidePosY()); var2.appendTag(var5); } p_82689_1_.setTag("Doors", var2); NBTTagList var7 = new NBTTagList(); Iterator var8 = this.playerReputation.keySet().iterator(); while (var8.hasNext()) { String var9 = (String)var8.next(); NBTTagCompound var6 = new NBTTagCompound(); var6.setString("Name", var9); var6.setInteger("S", ((Integer)this.playerReputation.get(var9)).intValue()); var7.appendTag(var6); } p_82689_1_.setTag("Players", var7); } /** * Prevent villager breeding for a fixed interval of time */ public void endMatingSeason() { this.noBreedTicks = this.tickCounter; } /** * Return whether villagers mating refractory period has passed */ public boolean isMatingSeason() { return this.noBreedTicks == 0 || this.tickCounter - this.noBreedTicks >= 3600; } public void setDefaultPlayerReputation(int p_82683_1_) { Iterator var2 = this.playerReputation.keySet().iterator(); while (var2.hasNext()) { String var3 = (String)var2.next(); this.setReputationForPlayer(var3, p_82683_1_); } } class VillageAgressor { public EntityLivingBase agressor; public int agressionTime; private static final String __OBFID = "CL_00001632"; VillageAgressor(EntityLivingBase p_i1674_2_, int p_i1674_3_) { this.agressor = p_i1674_2_; this.agressionTime = p_i1674_3_; } } }