List of usage examples for net.minecraftforge.event ForgeEventFactory getMaxSpawnPackSize
public static int getMaxSpawnPackSize(MobEntity entity)
From source file:cubicchunks.world.CubeWorldEntitySpawner.java
License:MIT License
private int spawnCreatureTypeInAllChunks(EnumCreatureType mobType, ICubicWorldServer world, ArrayList<CubePos> chunkList) { BlockPos spawnPoint = world.getSpawnPoint(); BlockPos.MutableBlockPos blockPos = new BlockPos.MutableBlockPos(); int totalSpawned = 0; nextChunk: for (CubePos currentChunkPos : chunkList) { BlockPos blockpos = getRandomChunkPosition(world, currentChunkPos); if (blockpos == null) { continue nextChunk; }//from w ww.ja v a2 s . c o m IBlockState block = world.getBlockState(blockpos); if (block.isNormalCube()) { continue; } int blockX = blockpos.getX(); int blockY = blockpos.getY(); int blockZ = blockpos.getZ(); int currentPackSize = 0; for (int k2 = 0; k2 < 3; ++k2) { int entityBlockX = blockX; int entityY = blockY; int entityBlockZ = blockZ; int searchRadius = 6; Biome.SpawnListEntry biomeMobs = null; IEntityLivingData entityData = null; int numSpawnAttempts = MathHelper.ceiling_double_int(Math.random() * 4.0D); Random rand = world.getRand(); for (int spawnAttempt = 0; spawnAttempt < numSpawnAttempts; ++spawnAttempt) { entityBlockX += rand.nextInt(searchRadius) - rand.nextInt(searchRadius); entityY += rand.nextInt(1) - rand.nextInt(1); entityBlockZ += rand.nextInt(searchRadius) - rand.nextInt(searchRadius); blockPos.setPos(entityBlockX, entityY, entityBlockZ); float entityX = (float) entityBlockX + 0.5F; float entityZ = (float) entityBlockZ + 0.5F; if (world.isAnyPlayerWithinRangeAt(entityX, entityY, entityZ, 24.0D) || spawnPoint.distanceSq(entityX, entityY, entityZ) < 576.0D) { continue; } if (biomeMobs == null) { biomeMobs = world.getSpawnListEntryForTypeAt(mobType, blockPos); if (biomeMobs == null) { break; } } if (!world.canCreatureTypeSpawnHere(mobType, biomeMobs, blockPos) || !canCreatureTypeSpawnAtLocation( EntitySpawnPlacementRegistry.getPlacementForEntity(biomeMobs.entityClass), (World) world, blockPos)) { continue; } EntityLiving toSpawn; try { toSpawn = biomeMobs.entityClass.getConstructor(new Class[] { World.class }) .newInstance(world); } catch (Exception exception) { exception.printStackTrace(); //TODO: throw when entity creation fails return totalSpawned; } toSpawn.setLocationAndAngles(entityX, entityY, entityZ, rand.nextFloat() * 360.0F, 0.0F); Event.Result canSpawn = ForgeEventFactory.canEntitySpawn(toSpawn, (World) world, entityX, entityY, entityZ); if (canSpawn == Event.Result.ALLOW || (canSpawn == Event.Result.DEFAULT && toSpawn.getCanSpawnHere() && toSpawn.isNotColliding())) { if (!ForgeEventFactory.doSpecialSpawn(toSpawn, (World) world, entityX, entityY, entityZ)) entityData = toSpawn.onInitialSpawn( world.getDifficultyForLocation(new BlockPos(toSpawn)), entityData); if (toSpawn.isNotColliding()) { ++currentPackSize; world.spawnEntityInWorld(toSpawn); } else { toSpawn.setDead(); } if (blockZ >= ForgeEventFactory.getMaxSpawnPackSize(toSpawn)) { continue nextChunk; } } totalSpawned += currentPackSize; } } } return totalSpawned; }
From source file:org.blockartistry.world.SpawnerAnimals.java
License:MIT License
/** * adds all chunks within the spawn radius of the players to * eligibleChunksForSpawning. pars: the world, hostileCreatures, * passiveCreatures. returns number of eligible chunks. *//*from ww w. j av a2 s . com*/ @SuppressWarnings("unchecked") public int findChunksForSpawning(WorldServer world, boolean hostileMobs, boolean peacefulMobs, boolean animals) { if ((!hostileMobs && !peacefulMobs) || world.playerEntities.size() == 0) { return 0; } // Vanilla does fancy stuff with map of booleans. This version // creates a single list that has chunk candidates, and adds a // factor to the size to come up with chunkCount to take into // account the player region "border". Since most players keep // separate this is close to being accurate with Vanilla. Worse case // is if players share a common region the border chunks will be // counted twice meaning a slightly higher density of mobs. final Set<ChunkCoordIntPair> candidates = new HashSet<ChunkCoordIntPair>(); for (final EntityPlayer player : (List<EntityPlayer>) world.playerEntities) { final int centerX = MathHelper.floor_double(player.posX / 16.0D); final int centerY = MathHelper.floor_double(player.posZ / 16.0D); for (int l = -RANGE; l <= RANGE; ++l) for (int i1 = -RANGE; i1 <= RANGE; ++i1) candidates.add(new ChunkCoordIntPair(l + centerX, i1 + centerY)); } // Estimate what the count needs to be adjusted by because we ignored // the border chunks in the scan. Horse shoes and hand grenades... final int chunkCount = candidates.size() + (PLAYER_COUNT_FACTOR * world.playerEntities.size()); // Need to make into a list for shuffling. Do an initial shuffle // to help mitigate the deterministic nature of the list because // of how it was generated (i.e. there is an order to it). Supply // our own random function because it will be replaced with a fast // random when Forge loads the mod. final List<ChunkCoordIntPair> eligibleChunksForSpawning = new ArrayList<ChunkCoordIntPair>(candidates); Collections.shuffle(eligibleChunksForSpawning, world.rand); int i = 0; final ChunkCoordinates spawnPoint = world.getSpawnPoint(); for (final EnumCreatureType critter : EnumCreatureType.values()) { // The below logic is interesting in that creature counts are based on // current logged on players. I have seen cases where the bulk of the // creatures spawn around a player rather than being evenly distributed // throughout the possible chunks. It's pretty funny, actually. if ((!critter.getPeacefulCreature() || peacefulMobs) && (critter.getPeacefulCreature() || hostileMobs) && (!critter.getAnimal() || animals) && countEntities(world, critter) <= (critter.getMaxNumberOfCreature() * chunkCount) / CHUNKS_PER_PLAYER) { Collections.shuffle(eligibleChunksForSpawning, world.rand); label110: for (final ChunkCoordIntPair coords : eligibleChunksForSpawning) { final ChunkPosition chunkPosition = func_151350_a(world, coords.chunkXPos, coords.chunkZPos); final int critterX = chunkPosition.chunkPosX; final int critterY = chunkPosition.chunkPosY; final int critterZ = chunkPosition.chunkPosZ; final Block block = world.getBlock(critterX, critterY, critterZ); if (!block.isNormalCube() && block.getMaterial() == critter.getCreatureMaterial()) { int i2 = 0; int j2 = 0; while (j2 < 3) { int cX = critterX; int cY = critterY; int cZ = critterZ; final int noise = 6; BiomeGenBase.SpawnListEntry spawnEntry = null; IEntityLivingData livingData = null; int j3 = 0; while (true) { if (j3 < 4) { label103: { cX += world.rand.nextInt(noise) - world.rand.nextInt(noise); cY += world.rand.nextInt(1) - world.rand.nextInt(1); cZ += world.rand.nextInt(noise) - world.rand.nextInt(noise); // Rearrange conditions from least // to most expensive in terms // of computation. Computations are // ints rather than floats to make // things a little bit faster. if (dSquared(spawnPoint, cX, cY, cZ) >= 576 && !anyPlayersWithin(world, cX, cY, cZ, 24) && canCreatureTypeSpawnAtLocation(critter, world, cX, cY, cZ)) { if (spawnEntry == null) { spawnEntry = world.spawnRandomCreature(critter, cX, cY, cZ); if (spawnEntry == null) { break label103; } } final EntityLiving entityliving = createCritter(world, spawnEntry.entityClass); if (entityliving == null) return i; final float cXf = (float) cX + 0.5F; final float cYf = (float) cY; final float cZf = (float) cZ + 0.5F; entityliving.setLocationAndAngles((double) cXf, (double) cYf, (double) cZf, world.rand.nextFloat() * 360.0F, 0.0F); final Result canSpawn = ForgeEventFactory.canEntitySpawn(entityliving, world, cXf, cYf, cZf); if (canSpawn == Result.ALLOW || (canSpawn == Result.DEFAULT && entityliving.getCanSpawnHere())) { ++i2; world.spawnEntityInWorld(entityliving); if (!ForgeEventFactory.doSpecialSpawn(entityliving, world, cXf, cYf, cZf)) { livingData = entityliving.onSpawnWithEgg(livingData); } if (j2 >= ForgeEventFactory.getMaxSpawnPackSize(entityliving)) { continue label110; } } i += i2; } ++j3; continue; } } ++j2; break; } } } } } } return i; }