initial commit
This commit is contained in:
parent
3c9ee26b06
commit
22186c33b9
1458 changed files with 282792 additions and 0 deletions
209
java/src/game/world/Spawner.java
Executable file
209
java/src/game/world/Spawner.java
Executable file
|
@ -0,0 +1,209 @@
|
|||
package game.world;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.biome.Biome;
|
||||
import game.block.Block;
|
||||
import game.collect.Sets;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityWaterMob;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.rng.Random;
|
||||
import game.rng.WeightedList;
|
||||
|
||||
public abstract class Spawner {
|
||||
private static final int MOB_COUNT_DIV = (int)Math.pow(17.0D, 2.0D);
|
||||
private static final Set<ChunkPos> CHUNKS = Sets.<ChunkPos>newHashSet();
|
||||
|
||||
public static boolean canSpawnAt(boolean water, WorldServer world, BlockPos pos) {
|
||||
if(!World.isValidXZ(pos)) {
|
||||
return false;
|
||||
}
|
||||
Block block = world.getState(pos).getBlock();
|
||||
if(water) {
|
||||
return block.getMaterial().isLiquid() && world.getState(pos.down()).getBlock().getMaterial().isLiquid()
|
||||
&& !world.getState(pos.up()).getBlock().isNormalCube();
|
||||
}
|
||||
// else if(place == SpawnRegistry.Placement.IN_AIR) {
|
||||
// return pos.getY() >= 118;
|
||||
// }
|
||||
else {
|
||||
BlockPos down = pos.down();
|
||||
if(!world.isBlockSolid(down)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
Block below = world.getState(down).getBlock();
|
||||
return below != Blocks.bedrock && !block.isNormalCube() && !block.getMaterial().isLiquid()
|
||||
&& !world.getState(pos.up()).getBlock().isNormalCube();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int spawn(WorldServer world) {
|
||||
// if(!hostile && !peaceful) {
|
||||
// return 0;
|
||||
// }
|
||||
CHUNKS.clear();
|
||||
int locs = 0;
|
||||
int range = Math.max(Config.mobSpawnDist, 1);
|
||||
for(EntityNPC player : world.players) {
|
||||
// if(Config.spectatorSpawning || !player.isSpectator()) {
|
||||
int x = ExtMath.floord(player.posX / 16.0D);
|
||||
int z = ExtMath.floord(player.posZ / 16.0D);
|
||||
for(int cx = -range; cx <= range; ++cx) {
|
||||
for(int cz = -range; cz <= range; ++cz) {
|
||||
boolean flag = cx == -range || cx == range || cz == -range || cz == range;
|
||||
ChunkPos coord = new ChunkPos(cx + x, cz + z);
|
||||
if(!CHUNKS.contains(coord)) {
|
||||
++locs;
|
||||
if(!flag && coord.x << 4 >= -World.MAX_SIZE + 64 && coord.z << 4 >= -World.MAX_SIZE + 64
|
||||
&& coord.x << 4 < World.MAX_SIZE - 64 && coord.z << 4 < World.MAX_SIZE - 64) {
|
||||
CHUNKS.add(coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
// boolean animals = (time % Math.max(Config.animalSpawnDelay, 1)) == 0;
|
||||
int spawned = 0;
|
||||
int mobSpread = Math.max(Config.spawnGroupDist, 1);
|
||||
// double spawnDist = (double)Config.mobSpawnDistance;
|
||||
double playerDist = (double)Config.mobPlayerDist;
|
||||
// BlockPos spawn = world.isPrimary() ? Server.getSpawnPoint() : null;
|
||||
// for(EnumCreatureType type : EnumCreatureType.values()) {
|
||||
// if((!type.isPeaceful() || peaceful) && (type.isPeaceful() || hostile) && (!type.isAnimal() || animals)) {
|
||||
int cur = world.countEntities(EntityLiving.class);
|
||||
int max = Config.maxMobs * locs / MOB_COUNT_DIV;
|
||||
if(cur <= max) {
|
||||
typeLabel:
|
||||
for(ChunkPos coord : CHUNKS) {
|
||||
Chunk chunk = world.getChunk(coord.x, coord.z);
|
||||
int x = coord.x * 16 + world.rand.zrange(16);
|
||||
int z = coord.z * 16 + world.rand.zrange(16);
|
||||
int h = chunk.getHeight(new BlockPos(x, 0, z)) + 1;
|
||||
if(h > 0) {
|
||||
int m = h % 16;
|
||||
h = m == 0 ? h : h + 16 - m;
|
||||
}
|
||||
h = h == 0 ? 16 : (h > 0 ? h : chunk.getTopSegment() + 16 - 1);
|
||||
int y = world.rand.excl(h <= 8 ? 0 : 8, h);
|
||||
BlockPos pos = new BlockPos(x, y, z);
|
||||
Block block = world.getState(pos).getBlock();
|
||||
if(!block.isNormalCube()) {
|
||||
int group = 0;
|
||||
Object data = null;
|
||||
for(int n = 0; n < Config.spawnGroups; ++n) {
|
||||
int mx = x;
|
||||
int my = y;
|
||||
int mz = z;
|
||||
Biome.RngSpawn entry = null;
|
||||
int cmax = 4;
|
||||
for(int m = 0; m < cmax; ++m) {
|
||||
mx += world.rand.zrange(mobSpread) - world.rand.zrange(mobSpread);
|
||||
my += world.rand.zrange(1) - world.rand.zrange(1);
|
||||
mz += world.rand.zrange(mobSpread) - world.rand.zrange(mobSpread);
|
||||
BlockPos mpos = new BlockPos(mx, my, mz);
|
||||
float fx = (float)mx + 0.5F;
|
||||
float fz = (float)mz + 0.5F;
|
||||
if(!world.isAnyPlayerWithinRangeAt((double)fx, (double)my, (double)fz, playerDist)) {
|
||||
// && (spawn == null || spawn.distanceSq((double)fx, (double)my, (double)fz) >= spawnDist)) {
|
||||
if(entry == null) {
|
||||
entry = world.getSpawnListEntryForTypeAt(mpos);
|
||||
if(entry == null) {
|
||||
break;
|
||||
}
|
||||
cmax = m + entry.minGroupCount + world.rand.zrange(1 + entry.maxGroupCount - entry.minGroupCount);
|
||||
}
|
||||
if(world.canCreatureTypeSpawnHere(entry, mpos)
|
||||
&& canSpawnAt(EntityWaterMob.class.isAssignableFrom(entry.entityClass), world, mpos)) {
|
||||
EntityLiving entity;
|
||||
try {
|
||||
entity = entry.entityClass.getConstructor(World.class).newInstance(world);
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
return spawned + group;
|
||||
}
|
||||
entity.setLocationAndAngles((double)fx, (double)my, (double)fz, world.rand.floatv() * 360.0F, 0.0F);
|
||||
if(entity.getCanSpawnHere() && entity.isNotColliding()) {
|
||||
data = entity.onInitialSpawn(data);
|
||||
if(entity.isNotColliding()) {
|
||||
++group;
|
||||
world.spawnEntityInWorld(entity);
|
||||
}
|
||||
if(group >= entity.getMaxChunkSpawns()) {
|
||||
spawned += group;
|
||||
continue typeLabel;
|
||||
}
|
||||
else if(!entity.isPropogatingSpawnData(m >= cmax - 1)) {
|
||||
data = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
spawned += group;
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
||||
}
|
||||
return spawned;
|
||||
}
|
||||
|
||||
public static void generate(WorldServer world, Biome biome, int x, int z, int sx, int sz, Random rand) {
|
||||
int iters = 0;
|
||||
while(rand.floatv() < biome.getSpawningChance()) {
|
||||
if(iters++ == 10)
|
||||
break;
|
||||
WeightedList<Biome.RngSpawn> list = biome.getSpawnableList();
|
||||
if(list.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Biome.RngSpawn entry = list.pick(world.rand);
|
||||
int count = entry.minGroupCount + rand.zrange(1 + entry.maxGroupCount - entry.minGroupCount);
|
||||
Object data = null;
|
||||
int mx = x + rand.zrange(sx);
|
||||
int mz = z + rand.zrange(sz);
|
||||
int gx = mx;
|
||||
int gz = mz;
|
||||
for(int n = 0; n < count; ++n) {
|
||||
boolean flag = false;
|
||||
for(int m = 0; !flag && m < 4; ++m) {
|
||||
BlockPos pos = world.getTopSolidOrLiquidBlock(new BlockPos(mx, 0, mz));
|
||||
if(canSpawnAt(EntityWaterMob.class.isAssignableFrom(entry.entityClass), world, pos)) {
|
||||
EntityLiving entity;
|
||||
try {
|
||||
entity = entry.entityClass.getConstructor(World.class).newInstance(world);
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
entity.setLocationAndAngles((double)((float)mx + 0.5F), (double)pos.getY(), (double)((float)mz + 0.5F),
|
||||
rand.floatv() * 360.0F, 0.0F);
|
||||
if(entity.getCanSpawnHere() && entity.isNotColliding()) {
|
||||
data = entity.onInitialSpawn(data);
|
||||
if(entity.isNotColliding())
|
||||
world.spawnEntityInWorld(entity);
|
||||
if(!entity.isPropogatingSpawnData(false))
|
||||
data = null;
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
mx += rand.zrange(5) - rand.zrange(5);
|
||||
for(mz += rand.zrange(5) - rand.zrange(5); mx < x || mx >= x + sx || mz < z
|
||||
|| mz >= z + sx; mz = gz + rand.zrange(5) - rand.zrange(5)) {
|
||||
mx = gx + rand.zrange(5) - rand.zrange(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue