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); }
private void PopulateChunkWithItems(ByteChunkCursor cursor, GeneratedChunk chunk, ref Vector3D chunkWorldPosition, ushort bluePrintId, int x, int y, int z, FastRandom rnd, EntityFactory entityFactory, bool isBlockCentered = true) { cursor.SetInternalPosition(x, y, z); //Check that the block above is "Air" if (cursor.Peek(CursorRelativeMovement.Up) != UtopiaProcessorParams.CubeId.Air) { return; } //Check that the block below is "solid" byte blockBelow = cursor.Read(); BlockProfile blockBelowProfile = _config.BlockProfiles[blockBelow]; if (blockBelowProfile.IsSolidToEntity) { //Cloning the Entity Blue Print ! var entity = entityFactory.CreateFromBluePrint(bluePrintId); if (entity is IBlockLinkedEntity) { Vector3I linkedCubePosition = new Vector3I(chunkWorldPosition.X + x, y, chunkWorldPosition.Z + z); ((IBlockLinkedEntity)entity).LinkedCube = linkedCubePosition; } if (entity is BlockLinkedItem) { Vector3I LocationCube = new Vector3I(chunkWorldPosition.X + x, y + 1, chunkWorldPosition.Z + z); ((BlockLinkedItem)entity).BlockLocationRoot = LocationCube; } double XOffset = 0.5; double ZOffset = 0.5; if (isBlockCentered == false) { XOffset = rnd.NextDouble(0.2, 0.8); ZOffset = rnd.NextDouble(0.2, 0.8); } entity.Position = new Vector3D(chunkWorldPosition.X + x + XOffset, y + 1, chunkWorldPosition.Z + z + ZOffset); chunk.Entities.Add((StaticEntity)entity); } }
/// <summary> /// Will create a single Liquid "Source" /// </summary> /// <param name="cubeId">the liquid CubeId</param> /// <param name="cursor">Class helper to move inside the chunk</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> private void PopulateChunkWithLiquidSources(byte cubeId, ByteChunkCursor cursor, int x, int y, int z, int liquidPower) { cursor.SetInternalPosition(x, y, z); //Check if this source is candidate as valid source = Must be surrended by 5 solid blocks and ahave one side block going to Air if (cursor.Read() != UtopiaProcessorParams.CubeId.Air) { //Looking Up for Air if (_config.BlockProfiles[cursor.Peek(CursorRelativeMovement.Up)].IsBlockingWater == false || cursor.Peek(CursorRelativeMovement.Up) == UtopiaProcessorParams.CubeId.Snow) { return; } if (_config.BlockProfiles[cursor.Peek(CursorRelativeMovement.Down)].IsBlockingWater == false) { return; } int cpt = 0; //Counting the number of holes arround the source if (_config.BlockProfiles[cursor.Peek(CursorRelativeMovement.East)].IsBlockingWater == false) { cpt++; } if (_config.BlockProfiles[cursor.Peek(CursorRelativeMovement.West)].IsBlockingWater == false) { cpt++; } if (_config.BlockProfiles[cursor.Peek(CursorRelativeMovement.North)].IsBlockingWater == false) { cpt++; } if (_config.BlockProfiles[cursor.Peek(CursorRelativeMovement.South)].IsBlockingWater == false) { cpt++; } //Only one face touching air ==> Createing the Liquid Source ! if (cpt != 1) { return; } cursor.Write(cubeId); Queue <Tuple <ByteChunkCursor, int> > sourcesWithPower = new Queue <Tuple <ByteChunkCursor, int> >(); sourcesWithPower.Enqueue(new Tuple <ByteChunkCursor, int>(cursor, liquidPower)); PropagateLiquidSources(sourcesWithPower, cubeId); } }