public void CreateMigration() { int tries = 0; float padding = 2.0f; while (tries < 10) { int side = MathFunctions.Random.Next(4); BoundingBox bounds = World.ChunkManager.Bounds; Vector3 pos = Vector3.Zero; switch (side) { case 0: pos = new Vector3(bounds.Min.X + padding, bounds.Max.Y - padding, MathFunctions.Rand(bounds.Min.Z + padding, bounds.Max.Z - padding)); break; case 1: pos = new Vector3(bounds.Max.X - padding, bounds.Max.Y - padding, MathFunctions.Rand(bounds.Min.Z + padding, bounds.Max.Z - padding)); break; case 2: pos = new Vector3(MathFunctions.Rand(bounds.Min.X + padding, bounds.Max.X - padding), bounds.Max.Y - padding, bounds.Min.Z + padding); break; case 3: pos = new Vector3(MathFunctions.Rand(bounds.Min.X + padding, bounds.Max.X - padding), bounds.Max.Y - padding, bounds.Max.Z - padding); break; } var biome = Overworld.GetBiomeAt(pos); if (biome.Fauna.Count == 0) { tries++; continue; } var randomFauna = Datastructures.SelectRandom(biome.Fauna); var testCreature = EntityFactory.CreateEntity <GameComponent>(randomFauna.Name, Vector3.Zero); if (testCreature == null) { tries++; continue; } var testCreatureAI = testCreature.GetRoot().GetComponent <CreatureAI>(); if (testCreatureAI == null || testCreatureAI.Movement.IsSessile) { testCreature.GetRoot().Delete(); tries++; continue; } var count = Creature.GetNumSpecies(testCreatureAI.Creature.Species); testCreature.GetRoot().Delete(); if (count < 30) { var randomNum = Math.Min(MathFunctions.RandInt(1, 3), 30 - count); for (int i = 0; i < randomNum; i++) { var randompos = MathFunctions.Clamp(pos + MathFunctions.RandVector3Cube() * 2, World.ChunkManager.Bounds); var vox = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(pos))); if (!vox.IsValid) { continue; } EntityFactory.CreateEntity <GameComponent>(randomFauna.Name, vox.GetBoundingBox().Center() + Vector3.Up * 1.5f); } } break; } }