private bool CaveSpawnLogic(int x, int z, ChunkSpawnableEntity entity, AbstractChunk chunk, ByteChunkCursor cursor, FastRandom rnd, out Vector3D entitySpawnLocation) { entitySpawnLocation = default(Vector3D); int y; int columnInfoIndex = x * AbstractChunk.ChunkSize.Z + z; cursor.SetInternalPosition(x, 1, z); //Move up until Air Block while (cursor.Read() != WorldConfiguration.CubeId.Air) { //Move up, if top chunk height exit if (cursor.Move(CursorRelativeMovement.Up) == false) { return(false); } } int YFloorSpawning = cursor.InternalPosition.Y; int MaximumSpawningHeight = chunk.BlockData.ColumnsInfo[columnInfoIndex].MaxGroundHeight - 10; if (MaximumSpawningHeight <= 0) { MaximumSpawningHeight = 1; } //Move up until "solid" Block while (cursor.Read() == WorldConfiguration.CubeId.Air && cursor.InternalPosition.Y <= MaximumSpawningHeight) { //Move up, if top chunk height exit if (cursor.Move(CursorRelativeMovement.Up) == false) { return(false); } } if (cursor.InternalPosition.Y > MaximumSpawningHeight) { return(false); } // Hurray it can spawn ! :D //Add some randomnes on the cube where it will spawn double XOffset, ZOffset; XOffset = rnd.NextDouble(0.2, 0.8); ZOffset = rnd.NextDouble(0.2, 0.8); if (entity.SpawningPlace == ChunkSpawningPlace.FloorInsideCave) { entitySpawnLocation = new Vector3D(chunk.BlockPosition.X + x + XOffset, YFloorSpawning, chunk.BlockPosition.Z + z + ZOffset); } else { entitySpawnLocation = new Vector3D(chunk.BlockPosition.X + x + XOffset, cursor.InternalPosition.Y - 1, chunk.BlockPosition.Z + z + ZOffset); } return(true); }
private bool SurfaceSpawnLogic(int x, int z, ChunkSpawnableEntity entity, AbstractChunk chunk, ByteChunkCursor cursor, FastRandom rnd, out Vector3D entitySpawnLocation) { entitySpawnLocation = default(Vector3D); int y; int columnInfoIndex = x * AbstractChunk.ChunkSize.Z + z; //Y base = Original world generated ground height (Before any player modification) y = chunk.BlockData.ColumnsInfo[columnInfoIndex].MaxGroundHeight; cursor.SetInternalPosition(x, y, z); // verify that we can spawn here var canSpawn = cursor.Read() != WorldConfiguration.CubeId.Air && cursor.Move(CursorRelativeMovement.Up) && cursor.Read() == WorldConfiguration.CubeId.Air && cursor.Move(CursorRelativeMovement.Up) && cursor.Read() == WorldConfiguration.CubeId.Air; // return cursor to the spawn point cursor.Move(CursorRelativeMovement.Down); if (!canSpawn) { return(false); } // Check that the block is well "Solid to entity" BlockProfile blockSpawnProfile = _config.BlockProfiles[cursor.Peek(CursorRelativeMovement.Down)]; if (!blockSpawnProfile.IsSolidToEntity) { return(false); } if (entity.IsWildChunkNeeded) { //Get Chunk master biome byte masterBiomeId = chunk.BlockData.ChunkMetaData.ChunkMasterBiomeType; //Get biome surface block layer byte surfaceBiomeCube = _config.ProcessorParam.Biomes[masterBiomeId].SurfaceCube; //If the entity need a Wild chunk, then it can only spawn on a cube surface equal to the default biome surface cube ! if (surfaceBiomeCube != blockSpawnProfile.Id) { return(false); } } // Hurray it can spawn ! :D //Add some randomnes on the cube where it will spawn double XOffset, ZOffset; XOffset = rnd.NextDouble(0.2, 0.8); ZOffset = rnd.NextDouble(0.2, 0.8); entitySpawnLocation = new Vector3D(chunk.BlockPosition.X + x + XOffset, cursor.InternalPosition.Y, chunk.BlockPosition.Z + z + ZOffset); return(true); }
/// <summary> /// Will create a resource vein /// </summary> /// <param name="cubeId">The resource to be created</param> /// <param name="cursor">Class helper to move inside the Chunk cube data</param> /// <param name="x">InsideChunk X starting position</param> /// <param name="y">InsideChunk Y starting position</param> /// <param name="z">InsideChunk Z starting position</param> /// <param name="qt">Vein size</param> /// <param name="rnd">Random generator for vein creation</param> private void PopulateChunkWithResource(byte cubeId, ByteChunkCursor cursor, int x, int y, int z, int qt, FastRandom rnd) { cursor.SetInternalPosition(x, y, z); int nbrCubePlaced; if (cursor.Read() == UtopiaProcessorParams.CubeId.Stone) { cursor.Write(cubeId); nbrCubePlaced = 1; for (int i = 0; i < qt + 10 && nbrCubePlaced < qt; i++) { int relativeMove = rnd.Next(1, 7); cursor.Move(relativeMove); if (cursor.Read() == UtopiaProcessorParams.CubeId.Stone) { cursor.Write(cubeId); nbrCubePlaced++; } } } }
/// <summary> /// Will insert associated static entities from a landscape entity. /// Ex : /// For the landscape entity "Tree", multiple static entities can be found "around" it : apple, stick, banana, ... /// </summary> /// <param name="dataCursor"></param> /// <param name="chunk"></param> /// <param name="chunkRnd"></param> /// <param name="entityFactory"></param> /// <param name="landscapeEntities"></param> private void InsertMicrolandscapeStaticEntities(ByteChunkCursor dataCursor, GeneratedChunk chunk, FastRandom chunkRnd, EntityFactory entityFactory, List <LandscapeEntity> landscapeEntities) { if (landscapeEntities == null) { return; } Vector2I chunkWorldPosition = new Vector2I(chunk.Position.X * AbstractChunk.ChunkSize.X, chunk.Position.Z * AbstractChunk.ChunkSize.Z); //The entities are sorted by their origine chunk hashcode value foreach (LandscapeEntity entity in landscapeEntities) { bool isLandscapeEntityRootInsideChunk = (entity.RootLocation.X >= 0 && entity.RootLocation.X < AbstractChunk.ChunkSize.X && entity.RootLocation.Z >= 0 && entity.RootLocation.Z < AbstractChunk.ChunkSize.Z); //Get LandscapeEntity var landscapeEntity = _worldParameters.Configuration.LandscapeEntitiesDico[entity.LandscapeEntityId]; foreach (var staticEntity in landscapeEntity.StaticItems) { //Get number of object var nbr = chunkRnd.Next(staticEntity.Quantity.Min, staticEntity.Quantity.Max); if (isLandscapeEntityRootInsideChunk) { //This entity location is inside the correct chunk. //Its a tree ! if (landscapeEntity is TreeBluePrint) { //Create tree soul and attach this entity to the chunk var soul = entityFactory.CreateEntity <TreeSoul>(); soul.Position = new Vector3D(chunkWorldPosition.X + entity.RootLocation.X + 0.5, entity.RootLocation.Y, chunkWorldPosition.Y + entity.RootLocation.Z + 0.5); soul.TreeRndSeed = entity.GenerationSeed; soul.TreeTypeId = entity.LandscapeEntityId; chunk.Entities.Add(soul); } } else { //If Root out of chunk, devide the qt of object to spawn by 2 nbr = (int)(nbr / 2.0); } //Foreach object to create while (nbr > 0) { //find location of the static entity double x = chunkRnd.NextDouble(-staticEntity.SpawningRange, staticEntity.SpawningRange) + entity.RootLocation.X; double z = chunkRnd.NextDouble(-staticEntity.SpawningRange, staticEntity.SpawningRange) + entity.RootLocation.Z; //If out of current chunk, don't create it if (x < 0 || x >= AbstractChunk.ChunkSize.X || z < 0 || z >= AbstractChunk.ChunkSize.Z) { break; } bool groundSpawing; if (staticEntity.SpawningType == SpawningType.Both) { groundSpawing = chunkRnd.NextFloat() > 0.5; } else { groundSpawing = staticEntity.SpawningType == SpawningType.Ground; } StaticEntity landscapeStaticEntity = null; //Find Y spawning position if (groundSpawing) { dataCursor.SetInternalPosition(MathHelper.Floor(x), entity.RootLocation.Y, MathHelper.Floor(z)); //Loop until I hit the ground, with a maximum of Y - 15 blocks for (int y = entity.RootLocation.Y; y > entity.RootLocation.Y - 15 && y > 0; y--) { if (dataCursor.Read() != WorldConfiguration.CubeId.Air) { //Add Static item here on the ground ! landscapeStaticEntity = (StaticEntity)entityFactory.CreateFromBluePrint(staticEntity.ItemblueprintId); landscapeStaticEntity.Position = new Vector3D(x + chunkWorldPosition.X, dataCursor.InternalPosition.Y + 1, z + chunkWorldPosition.Y); break; } dataCursor.Move(CursorRelativeMovement.Down); } } else { dataCursor.SetInternalPosition(MathHelper.Floor(x), entity.RootLocation.Y + 1, MathHelper.Floor(z)); //Loop until I hit the ground, with a maximum of Y + 15 blocks for (int y = entity.RootLocation.Y + 1; y <= entity.RootLocation.Y + 15 && y < AbstractChunk.ChunkSize.Y; y++) { if (dataCursor.Read() != WorldConfiguration.CubeId.Air) { //Add Static item here on the ground ! landscapeStaticEntity = (StaticEntity)entityFactory.CreateFromBluePrint(staticEntity.ItemblueprintId); landscapeStaticEntity.Position = new Vector3D(x + chunkWorldPosition.X, dataCursor.InternalPosition.Y - 0.25, z + chunkWorldPosition.Y); break; } dataCursor.Move(CursorRelativeMovement.Up); } } if (landscapeStaticEntity != null) { chunk.Entities.Add(landscapeStaticEntity); } nbr--; } } } }