You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
296 lines
15 KiB
Java
296 lines
15 KiB
Java
package net.minecraft.world;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.block.material.Material;
|
|
import net.minecraft.entity.EntityLiving;
|
|
import net.minecraft.entity.EnumCreatureType;
|
|
import net.minecraft.entity.IEntityLivingData;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.init.Blocks;
|
|
import net.minecraft.util.ChunkCoordinates;
|
|
import net.minecraft.util.MathHelper;
|
|
import net.minecraft.util.WeightedRandom;
|
|
import net.minecraft.world.biome.BiomeGenBase;
|
|
import net.minecraft.world.chunk.Chunk;
|
|
|
|
import cpw.mods.fml.common.eventhandler.Event.Result;
|
|
import net.minecraftforge.event.ForgeEventFactory;
|
|
|
|
public final class SpawnerAnimals
|
|
{
|
|
/** The 17x17 area around the player where mobs can spawn */
|
|
private HashMap eligibleChunksForSpawning = new HashMap();
|
|
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_)
|
|
{
|
|
Chunk chunk = p_151350_0_.getChunkFromChunkCoords(p_151350_1_, p_151350_2_);
|
|
int k = p_151350_1_ * 16 + p_151350_0_.rand.nextInt(16);
|
|
int l = p_151350_2_ * 16 + p_151350_0_.rand.nextInt(16);
|
|
int i1 = p_151350_0_.rand.nextInt(chunk == null ? p_151350_0_.getActualHeight() : chunk.getTopFilledSegment() + 16 - 1);
|
|
return new ChunkPosition(k, i1, l);
|
|
}
|
|
|
|
/**
|
|
* adds all chunks within the spawn radius of the players to eligibleChunksForSpawning. pars: the world,
|
|
* hostileCreatures, passiveCreatures. returns number of eligible chunks.
|
|
*/
|
|
public int findChunksForSpawning(WorldServer p_77192_1_, boolean p_77192_2_, boolean p_77192_3_, boolean p_77192_4_)
|
|
{
|
|
if (!p_77192_2_ && !p_77192_3_)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
this.eligibleChunksForSpawning.clear();
|
|
int i;
|
|
int k;
|
|
|
|
for (i = 0; i < p_77192_1_.playerEntities.size(); ++i)
|
|
{
|
|
EntityPlayer entityplayer = (EntityPlayer)p_77192_1_.playerEntities.get(i);
|
|
int j = MathHelper.floor_double(entityplayer.posX / 16.0D);
|
|
k = MathHelper.floor_double(entityplayer.posZ / 16.0D);
|
|
byte b0 = 8;
|
|
|
|
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);
|
|
|
|
if (!flag3)
|
|
{
|
|
this.eligibleChunksForSpawning.put(chunkcoordintpair, Boolean.valueOf(false));
|
|
}
|
|
else if (!this.eligibleChunksForSpawning.containsKey(chunkcoordintpair))
|
|
{
|
|
this.eligibleChunksForSpawning.put(chunkcoordintpair, Boolean.valueOf(true));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
i = 0;
|
|
ChunkCoordinates chunkcoordinates = p_77192_1_.getSpawnPoint();
|
|
EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values();
|
|
k = aenumcreaturetype.length;
|
|
|
|
for (int k3 = 0; k3 < k; ++k3)
|
|
{
|
|
EnumCreatureType enumcreaturetype = aenumcreaturetype[k3];
|
|
|
|
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)
|
|
{
|
|
Iterator iterator = this.eligibleChunksForSpawning.keySet().iterator();
|
|
ArrayList<ChunkCoordIntPair> tmp = new ArrayList(eligibleChunksForSpawning.keySet());
|
|
Collections.shuffle(tmp);
|
|
iterator = tmp.iterator();
|
|
label110:
|
|
|
|
while (iterator.hasNext())
|
|
{
|
|
ChunkCoordIntPair chunkcoordintpair1 = (ChunkCoordIntPair)iterator.next();
|
|
|
|
if (!((Boolean)this.eligibleChunksForSpawning.get(chunkcoordintpair1)).booleanValue())
|
|
{
|
|
ChunkPosition chunkposition = func_151350_a(p_77192_1_, chunkcoordintpair1.chunkXPos, chunkcoordintpair1.chunkZPos);
|
|
int j1 = chunkposition.chunkPosX;
|
|
int k1 = chunkposition.chunkPosY;
|
|
int l1 = chunkposition.chunkPosZ;
|
|
|
|
if (!p_77192_1_.getBlock(j1, k1, l1).isNormalCube() && p_77192_1_.getBlock(j1, k1, l1).getMaterial() == enumcreaturetype.getCreatureMaterial())
|
|
{
|
|
int i2 = 0;
|
|
int j2 = 0;
|
|
|
|
while (j2 < 3)
|
|
{
|
|
int k2 = j1;
|
|
int l2 = k1;
|
|
int i3 = l1;
|
|
byte b1 = 6;
|
|
BiomeGenBase.SpawnListEntry spawnlistentry = null;
|
|
IEntityLivingData ientitylivingdata = null;
|
|
int j3 = 0;
|
|
|
|
while (true)
|
|
{
|
|
if (j3 < 4)
|
|
{
|
|
label103:
|
|
{
|
|
k2 += p_77192_1_.rand.nextInt(b1) - p_77192_1_.rand.nextInt(b1);
|
|
l2 += p_77192_1_.rand.nextInt(1) - p_77192_1_.rand.nextInt(1);
|
|
i3 += p_77192_1_.rand.nextInt(b1) - p_77192_1_.rand.nextInt(b1);
|
|
|
|
if (canCreatureTypeSpawnAtLocation(enumcreaturetype, p_77192_1_, k2, l2, i3))
|
|
{
|
|
float f = (float)k2 + 0.5F;
|
|
float f1 = (float)l2;
|
|
float f2 = (float)i3 + 0.5F;
|
|
|
|
if (p_77192_1_.getClosestPlayer((double)f, (double)f1, (double)f2, 24.0D) == null)
|
|
{
|
|
float f3 = f - (float)chunkcoordinates.posX;
|
|
float f4 = f1 - (float)chunkcoordinates.posY;
|
|
float f5 = f2 - (float)chunkcoordinates.posZ;
|
|
float f6 = f3 * f3 + f4 * f4 + f5 * f5;
|
|
|
|
if (f6 >= 576.0F)
|
|
{
|
|
if (spawnlistentry == null)
|
|
{
|
|
spawnlistentry = p_77192_1_.spawnRandomCreature(enumcreaturetype, k2, l2, i3);
|
|
|
|
if (spawnlistentry == null)
|
|
{
|
|
break label103;
|
|
}
|
|
}
|
|
|
|
EntityLiving entityliving;
|
|
|
|
try
|
|
{
|
|
entityliving = (EntityLiving)spawnlistentry.entityClass.getConstructor(new Class[] {World.class}).newInstance(new Object[] {p_77192_1_});
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
exception.printStackTrace();
|
|
return i;
|
|
}
|
|
|
|
entityliving.setLocationAndAngles((double)f, (double)f1, (double)f2, p_77192_1_.rand.nextFloat() * 360.0F, 0.0F);
|
|
|
|
Result canSpawn = ForgeEventFactory.canEntitySpawn(entityliving, p_77192_1_, f, f1, f2);
|
|
if (canSpawn == Result.ALLOW || (canSpawn == Result.DEFAULT && entityliving.getCanSpawnHere()))
|
|
{
|
|
++i2;
|
|
p_77192_1_.spawnEntityInWorld(entityliving);
|
|
if (!ForgeEventFactory.doSpecialSpawn(entityliving, p_77192_1_, f, f1, f2))
|
|
{
|
|
ientitylivingdata = entityliving.onSpawnWithEgg(ientitylivingdata);
|
|
}
|
|
|
|
if (j2 >= ForgeEventFactory.getMaxSpawnPackSize(entityliving))
|
|
{
|
|
continue label110;
|
|
}
|
|
}
|
|
|
|
i += i2;
|
|
}
|
|
}
|
|
}
|
|
|
|
++j3;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
++j2;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return i;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns whether or not the specified creature type can spawn at the specified location.
|
|
*/
|
|
public static boolean canCreatureTypeSpawnAtLocation(EnumCreatureType p_77190_0_, World p_77190_1_, int p_77190_2_, int p_77190_3_, int p_77190_4_)
|
|
{
|
|
if (p_77190_0_.getCreatureMaterial() == Material.water)
|
|
{
|
|
return p_77190_1_.getBlock(p_77190_2_, p_77190_3_, p_77190_4_).getMaterial().isLiquid() && p_77190_1_.getBlock(p_77190_2_, p_77190_3_ - 1, p_77190_4_).getMaterial().isLiquid() && !p_77190_1_.getBlock(p_77190_2_, p_77190_3_ + 1, p_77190_4_).isNormalCube();
|
|
}
|
|
else if (!World.doesBlockHaveSolidTopSurface(p_77190_1_, p_77190_2_, p_77190_3_ - 1, p_77190_4_))
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
Block block = p_77190_1_.getBlock(p_77190_2_, p_77190_3_ - 1, p_77190_4_);
|
|
boolean spawnBlock = block.canCreatureSpawn(p_77190_0_, p_77190_1_, p_77190_2_, p_77190_3_ - 1, p_77190_4_);
|
|
return spawnBlock && block != Blocks.bedrock && !p_77190_1_.getBlock(p_77190_2_, p_77190_3_, p_77190_4_).isNormalCube() && !p_77190_1_.getBlock(p_77190_2_, p_77190_3_, p_77190_4_).getMaterial().isLiquid() && !p_77190_1_.getBlock(p_77190_2_, p_77190_3_ + 1, p_77190_4_).isNormalCube();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called during chunk generation to spawn initial creatures.
|
|
*/
|
|
public static void performWorldGenSpawning(World p_77191_0_, BiomeGenBase p_77191_1_, int p_77191_2_, int p_77191_3_, int p_77191_4_, int p_77191_5_, Random p_77191_6_)
|
|
{
|
|
List list = p_77191_1_.getSpawnableList(EnumCreatureType.creature);
|
|
|
|
if (!list.isEmpty())
|
|
{
|
|
while (p_77191_6_.nextFloat() < p_77191_1_.getSpawningChance())
|
|
{
|
|
BiomeGenBase.SpawnListEntry spawnlistentry = (BiomeGenBase.SpawnListEntry)WeightedRandom.getRandomItem(p_77191_0_.rand, list);
|
|
IEntityLivingData ientitylivingdata = null;
|
|
int i1 = spawnlistentry.minGroupCount + p_77191_6_.nextInt(1 + spawnlistentry.maxGroupCount - spawnlistentry.minGroupCount);
|
|
int j1 = p_77191_2_ + p_77191_6_.nextInt(p_77191_4_);
|
|
int k1 = p_77191_3_ + p_77191_6_.nextInt(p_77191_5_);
|
|
int l1 = j1;
|
|
int i2 = k1;
|
|
|
|
for (int j2 = 0; j2 < i1; ++j2)
|
|
{
|
|
boolean flag = false;
|
|
|
|
for (int k2 = 0; !flag && k2 < 4; ++k2)
|
|
{
|
|
int l2 = p_77191_0_.getTopSolidOrLiquidBlock(j1, k1);
|
|
|
|
if (canCreatureTypeSpawnAtLocation(EnumCreatureType.creature, p_77191_0_, j1, l2, k1))
|
|
{
|
|
float f = (float)j1 + 0.5F;
|
|
float f1 = (float)l2;
|
|
float f2 = (float)k1 + 0.5F;
|
|
EntityLiving entityliving;
|
|
|
|
try
|
|
{
|
|
entityliving = (EntityLiving)spawnlistentry.entityClass.getConstructor(new Class[] {World.class}).newInstance(new Object[] {p_77191_0_});
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
exception.printStackTrace();
|
|
continue;
|
|
}
|
|
|
|
entityliving.setLocationAndAngles((double)f, (double)f1, (double)f2, p_77191_6_.nextFloat() * 360.0F, 0.0F);
|
|
p_77191_0_.spawnEntityInWorld(entityliving);
|
|
ientitylivingdata = entityliving.onSpawnWithEgg(ientitylivingdata);
|
|
flag = true;
|
|
}
|
|
|
|
j1 += p_77191_6_.nextInt(5) - p_77191_6_.nextInt(5);
|
|
|
|
for (k1 += p_77191_6_.nextInt(5) - p_77191_6_.nextInt(5); j1 < p_77191_2_ || j1 >= p_77191_2_ + p_77191_4_ || k1 < p_77191_3_ || k1 >= p_77191_3_ + p_77191_4_; k1 = i2 + p_77191_6_.nextInt(5) - p_77191_6_.nextInt(5))
|
|
{
|
|
j1 = l1 + p_77191_6_.nextInt(5) - p_77191_6_.nextInt(5);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |