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);
        }
示例#2
0
        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);
            }
        }
示例#3
0
        /// <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);
            }
        }