--- ../src-base/minecraft/net/minecraft/world/SpawnerAnimals.java +++ ../src-work/minecraft/net/minecraft/world/SpawnerAnimals.java @@ -22,9 +22,15 @@ import cpw.mods.fml.common.eventhandler.Event.Result; import net.minecraftforge.event.ForgeEventFactory; +// CraftBukkit start +import org.bukkit.craftbukkit.util.LongHash; +import org.bukkit.craftbukkit.util.LongObjectHashMap; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +// CraftBukkit end + public final class SpawnerAnimals { - private HashMap eligibleChunksForSpawning = new HashMap(); + private LongObjectHashMap eligibleChunksForSpawning = new LongObjectHashMap(); // CraftBukkit - HashMap -> LongObjectHashMap private static final String __OBFID = "CL_00000152"; protected static ChunkPosition func_151350_a(World p_151350_0_, int p_151350_1_, int p_151350_2_) @@ -54,22 +60,30 @@ int j = MathHelper.floor_double(entityplayer.posX / 16.0D); k = MathHelper.floor_double(entityplayer.posZ / 16.0D); byte b0 = 8; + // Spigot Start + b0 = p_77192_1_.getSpigotConfig().mobSpawnRange; // Cauldron + b0 = (b0 > p_77192_1_.getSpigotConfig().viewDistance) ? (byte) p_77192_1_.spigotConfig.viewDistance : b0; // Cauldron + b0 = (b0 > 8) ? 8 : b0; + // Spigot End for (int l = -b0; l <= b0; ++l) { for (int i1 = -b0; i1 <= b0; ++i1) { boolean flag3 = l == -b0 || l == b0 || i1 == -b0 || i1 == b0; - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(l + j, i1 + k); + // CraftBukkit start + long chunkCoords = LongHash.toLong(l + j, i1 + k); if (!flag3) { - this.eligibleChunksForSpawning.put(chunkcoordintpair, Boolean.valueOf(false)); + this.eligibleChunksForSpawning.put(chunkCoords, false); } - else if (!this.eligibleChunksForSpawning.containsKey(chunkcoordintpair)) + else if (!this.eligibleChunksForSpawning.containsKey(chunkCoords)) { - this.eligibleChunksForSpawning.put(chunkcoordintpair, Boolean.valueOf(true)); + this.eligibleChunksForSpawning.put(chunkCoords, true); } + + // CraftBukkit end } } } @@ -82,22 +96,46 @@ for (int k3 = 0; k3 < k; ++k3) { EnumCreatureType enumcreaturetype = aenumcreaturetype[k3]; + // CraftBukkit start - Use per-world spawn limits + int limit = enumcreaturetype.getMaxNumberOfCreature(); - if ((!enumcreaturetype.getPeacefulCreature() || p_77192_3_) && (enumcreaturetype.getPeacefulCreature() || p_77192_2_) && (!enumcreaturetype.getAnimal() || p_77192_4_) && p_77192_1_.countEntities(enumcreaturetype, true) <= enumcreaturetype.getMaxNumberOfCreature() * this.eligibleChunksForSpawning.size() / 256) + switch (enumcreaturetype) { + case monster: + limit = p_77192_1_.getWorld().getMonsterSpawnLimit(); + break; + case creature: + limit = p_77192_1_.getWorld().getAnimalSpawnLimit(); + break; + case waterCreature: + limit = p_77192_1_.getWorld().getWaterAnimalSpawnLimit(); + break; + case ambient: + limit = p_77192_1_.getWorld().getAmbientSpawnLimit(); + break; + } + + if (limit == 0) + { + continue; + } + + // CraftBukkit end + + if ((!enumcreaturetype.getPeacefulCreature() || p_77192_3_) && (enumcreaturetype.getPeacefulCreature() || p_77192_2_) && (!enumcreaturetype.getAnimal() || p_77192_4_) && p_77192_1_.countEntities(enumcreaturetype.getCreatureClass()) <= limit * eligibleChunksForSpawning.size() / 256) // CraftBukkit - use per-world limits + { Iterator iterator = this.eligibleChunksForSpawning.keySet().iterator(); - ArrayList tmp = new ArrayList(eligibleChunksForSpawning.keySet()); - Collections.shuffle(tmp); - iterator = tmp.iterator(); label110: while (iterator.hasNext()) { - ChunkCoordIntPair chunkcoordintpair1 = (ChunkCoordIntPair)iterator.next(); + // CraftBukkit start + long key = ((Long) iterator.next()).longValue(); - if (!((Boolean)this.eligibleChunksForSpawning.get(chunkcoordintpair1)).booleanValue()) + if (!(this.eligibleChunksForSpawning.get(key))) { - ChunkPosition chunkposition = func_151350_a(p_77192_1_, chunkcoordintpair1.chunkXPos, chunkcoordintpair1.chunkZPos); + ChunkPosition chunkposition = func_151350_a(p_77192_1_, LongHash.msw(key), LongHash.lsw(key)); + // CraftBukkit end int j1 = chunkposition.chunkPosX; int k1 = chunkposition.chunkPosY; int l1 = chunkposition.chunkPosZ; @@ -170,7 +208,8 @@ if (canSpawn == Result.ALLOW || (canSpawn == Result.DEFAULT && entityliving.getCanSpawnHere())) { ++i2; - p_77192_1_.spawnEntityInWorld(entityliving); + // CraftBukkit start - Added a reason for spawning this creature, moved entityliving.onSpawnWithEgg(ientitylivingdata) up + p_77192_1_.addEntity(entityliving, SpawnReason.NATURAL); if (!ForgeEventFactory.doSpecialSpawn(entityliving, p_77192_1_, f, f1, f2)) { ientitylivingdata = entityliving.onSpawnWithEgg(ientitylivingdata); @@ -266,8 +305,10 @@ } entityliving.setLocationAndAngles((double)f, (double)f1, (double)f2, p_77191_6_.nextFloat() * 360.0F, 0.0F); - p_77191_0_.spawnEntityInWorld(entityliving); + // CraftBukkit start - Added a reason for spawning this creature, moved entityliving.a(ientitylivingdata) up ientitylivingdata = entityliving.onSpawnWithEgg(ientitylivingdata); + p_77191_0_.addEntity(entityliving, SpawnReason.CHUNK_GEN); + // CraftBukkit end flag = true; }