示例#1
0
        public override bool TryPlaceBlockForWorldGen(IBlockAccessor blockAccessor, BlockPos pos, BlockFacing onBlockFace, Random worldgenRand)
        {
            //blockAccessor.SetBlock(blockAccessor.GetBlock(new AssetLocation("creativeblock-60")).BlockId, pos);

            for (int i = 1; i < 4; i++)
            {
                Block aboveBlock = blockAccessor.GetBlock(pos.X, pos.Y - i, pos.Z);

                if (
                    (aboveBlock.BlockMaterial == EnumBlockMaterial.Wood || aboveBlock.BlockMaterial == EnumBlockMaterial.Plant) && aboveBlock.SideSolid[BlockFacing.DOWN.Index]
                    )
                {
                    BlockPos atpos = new BlockPos(pos.X, pos.Y - i - 1, pos.Z);

                    Block block = blockAccessor.GetBlock(atpos);

                    if (
                        block.BlockMaterial == EnumBlockMaterial.Wood &&
                        aboveBlock.BlockMaterial == EnumBlockMaterial.Wood &&
                        blockAccessor.GetBlock(pos.X, pos.Y - i - 2, pos.Z).BlockMaterial == EnumBlockMaterial.Wood &&
                        aboveBlock.LastCodePart() == "ud"
                        )
                    {
                        blockAccessor.SetBlock(blockAccessor.GetBlock(new AssetLocation("wildbeehive-inlog-" + aboveBlock.FirstCodePart(2))).BlockId, atpos);
                        if (EntityClass != null)
                        {
                            blockAccessor.SpawnBlockEntity(EntityClass, atpos);
                        }

                        return(true);
                    }

                    if (block.BlockMaterial != EnumBlockMaterial.Plant && block.BlockMaterial != EnumBlockMaterial.Air)
                    {
                        continue;
                    }

                    int dx       = pos.X % blockAccessor.ChunkSize;
                    int dz       = pos.Z % blockAccessor.ChunkSize;
                    int surfacey = blockAccessor.GetMapChunkAtBlockPos(atpos).WorldGenTerrainHeightMap[dz * blockAccessor.ChunkSize + dx];

                    if (pos.Y - surfacey < 4)
                    {
                        return(false);
                    }

                    blockAccessor.SetBlock(BlockId, atpos);
                    if (EntityClass != null)
                    {
                        blockAccessor.SpawnBlockEntity(EntityClass, atpos);
                    }
                    return(true);
                }
            }

            return(false);
        }
示例#2
0
        //mostly copied from BlockBeehive
        public override bool TryPlaceBlockForWorldGen(IBlockAccessor blockAccessor, BlockPos pos, BlockFacing onBlockFace, LCGRandom worldgenRand)
        {
            Block cinnamon = blockAccessor.GetBlock(new AssetLocation("harvestcraftloader:fruits-cinnamon-ripe"));

            for (int i = 1; i < 4; i++)
            {
                Block aboveBlock = blockAccessor.GetBlock(pos.X, pos.Y - i, pos.Z);

                if ((aboveBlock.BlockMaterial == EnumBlockMaterial.Wood || aboveBlock.BlockMaterial == EnumBlockMaterial.Leaves) && aboveBlock.SideSolid[BlockFacing.DOWN.Index])
                {
                    BlockPos atpos = new BlockPos(pos.X, pos.Y - i - 1, pos.Z);

                    Block block = blockAccessor.GetBlock(atpos);

                    if (block.BlockMaterial == EnumBlockMaterial.Wood && aboveBlock.BlockMaterial == EnumBlockMaterial.Wood && blockAccessor.GetBlock(pos.X, pos.Y - i - 2, pos.Z).BlockMaterial == EnumBlockMaterial.Wood && aboveBlock.LastCodePart() == "ud")
                    {
                        blockAccessor.SetBlock(cinnamon.BlockId, atpos);
                        if (EntityClass != null)
                        {
                            blockAccessor.SpawnBlockEntity(EntityClass, atpos);
                        }

                        return(true);
                    }

                    if (aboveBlock.BlockMaterial == EnumBlockMaterial.Wood || Id == cinnamon.Id || (block.BlockMaterial != EnumBlockMaterial.Leaves && block.BlockMaterial != EnumBlockMaterial.Air))
                    {
                        continue;
                    }

                    int dx       = pos.X % blockAccessor.ChunkSize;
                    int dz       = pos.Z % blockAccessor.ChunkSize;
                    int surfacey = blockAccessor.GetMapChunkAtBlockPos(atpos).WorldGenTerrainHeightMap[dz * blockAccessor.ChunkSize + dx];

                    if (pos.Y - surfacey < 4)
                    {
                        return(false);
                    }

                    blockAccessor.SetBlock(BlockId, atpos);
                    if (EntityClass != null)
                    {
                        blockAccessor.SpawnBlockEntity(EntityClass, atpos);
                    }

                    return(true);
                }
            }

            return(false);
        }
示例#3
0
        private void generateUpGrowingMushrooms(IBlockAccessor blockAccessor, IRandom rnd)
        {
            int          cnt       = 2 + rnd.NextInt(11);
            BlockPos     pos       = new BlockPos();
            int          chunkSize = blockAccessor.ChunkSize;
            List <Vec3i> offsets   = new List <Vec3i>();

            if (!isChunkAreaLoaded(blockAccessor, growRange))
            {
                return;
            }

            while (cnt-- > 0)
            {
                int dx = growRange - rnd.NextInt(2 * growRange + 1);
                int dz = growRange - rnd.NextInt(2 * growRange + 1);

                pos.Set(Pos.X + dx, 0, Pos.Z + dz);

                var mapChunk = blockAccessor.GetMapChunkAtBlockPos(pos);

                int lx = GameMath.Mod(pos.X, chunkSize);
                int lz = GameMath.Mod(pos.Z, chunkSize);

                pos.Y = mapChunk.WorldGenTerrainHeightMap[lz * blockAccessor.ChunkSize + lx] + 1;

                Block hereBlock  = blockAccessor.GetBlock(pos);
                Block belowBlock = blockAccessor.GetBlock(pos.X, pos.Y - 1, pos.Z);

                if (belowBlock.Fertility < 10 || hereBlock.LiquidCode != null)
                {
                    continue;
                }

                if ((mushroomsGrownTotalDays == 0 && hereBlock.Replaceable >= 6000) || hereBlock.Id == 0)
                {
                    blockAccessor.SetBlock(mushroomBlock.Id, pos);
                    offsets.Add(new Vec3i(dx, pos.Y - Pos.Y, dz));
                }
            }

            this.grownMushroomOffsets = offsets.ToArray();
        }
        /// <summary>
        /// For placement of ruins during worldgen, replaces the topsoil with the area specific soil (e.g. sand)
        /// </summary>
        /// <param name="blockAccessor"></param>
        /// <param name="blocks"></param>
        /// <param name="startPos"></param>
        /// <param name="climateUpLeft"></param>
        /// <param name="climateUpRight"></param>
        /// <param name="climateBotLeft"></param>
        /// <param name="climateBotRight"></param>
        /// <param name="replaceblockids"></param>
        /// <returns></returns>
        public int PlaceRespectingBlockLayers(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos startPos, int climateUpLeft, int climateUpRight, int climateBotLeft, int climateBotRight, int[] replaceblockids, bool replaceMetaBlocks = true)
        {
            BlockPos curPos    = new BlockPos();
            int      placed    = 0;
            int      chunksize = blockAccessor.ChunkSize;


            for (int x = 0; x < SizeX; x++)
            {
                for (int z = 0; z < SizeZ; z++)
                {
                    curPos.Set(x + startPos.X, startPos.Y, z + startPos.Z);
                    IMapChunk mapchunk    = blockAccessor.GetMapChunkAtBlockPos(curPos);
                    int       rockblockid = mapchunk.TopRockIdMap[(curPos.Z % chunksize) * chunksize + curPos.X % chunksize];
                    int       depth       = 0;

                    int maxY = -1;

                    for (int y = SizeY - 1; y >= 0; y--)
                    {
                        curPos.Set(x + startPos.X, y + startPos.Y, z + startPos.Z);
                        Block newBlock = blocksByPos[x, y, z];
                        if (newBlock == null)
                        {
                            continue;
                        }

                        if (replaceMetaBlocks && newBlock == undergroundBlock)
                        {
                            continue;
                        }


                        if (newBlock.Replaceable < 1000)
                        {
                            if (replaceblockids.Length > depth && newBlock.BlockId == replaceblockids[depth])
                            {
                                int climate = GameMath.BiLerpRgbColor((float)x / chunksize, (float)z / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

                                newBlock = GetBlockLayerBlock((climate >> 8) & 0xff, (climate >> 16) & 0xff, startPos.Y, rockblockid, depth, newBlock, worldForCollectibleResolve.Blocks);
                            }
                            depth++;
                        }

                        Block oldBlock = blockAccessor.GetBlock(curPos);
                        int   p        = handler(blockAccessor, curPos, oldBlock, newBlock);
                        placed += p;

                        if (p > 0 && !newBlock.RainPermeable)
                        {
                            if (newBlock == fillerBlock || newBlock == pathwayBlock)
                            {
                                int lx = curPos.X % chunksize;
                                int lz = curPos.Z % chunksize;
                                if (mapchunk.RainHeightMap[lz * chunksize + lx] == curPos.Y)
                                {
                                    mapchunk.RainHeightMap[lz * chunksize + lx]--;
                                }
                            }
                            else
                            {
                                maxY = Math.Max(curPos.Y, maxY);
                            }
                        }


                        byte[] lightHsv = newBlock.GetLightHsv(blockAccessor, curPos);

                        if (lightHsv[2] > 0 && blockAccessor is IWorldGenBlockAccessor)
                        {
                            ((IWorldGenBlockAccessor)blockAccessor).ScheduleBlockLightUpdate(curPos.Copy(), oldBlock.BlockId, newBlock.BlockId);
                        }
                    }

                    // In the post pass the rain map does not update, so let's set it ourselves
                    if (maxY >= 0)
                    {
                        int lx = curPos.X % chunksize;
                        int lz = curPos.Z % chunksize;
                        int y  = mapchunk.RainHeightMap[lz * chunksize + lx];
                        mapchunk.RainHeightMap[lz * chunksize + lx] = (ushort)Math.Max(y, maxY);
                    }
                }
            }

            PlaceEntitiesAndBlockEntities(blockAccessor, worldForCollectibleResolve, startPos);

            return(placed);
        }
示例#5
0
        public override bool TryPlaceBlockForWorldGen(IBlockAccessor blockAccessor, BlockPos pos, BlockFacing onBlockFace, LCGRandom worldgenRand)
        {
            //blockAccessor.SetBlock(blockAccessor.GetBlock(new AssetLocation("creativeblock-60")).BlockId, pos);

            for (int i = 1; i < 4; i++)
            {
                atPos.Set(pos.X, pos.Y - i, pos.Z);
                Block aboveBlock = blockAccessor.GetBlock(atPos);

                var abovemat = aboveBlock.GetBlockMaterial(blockAccessor, atPos);

                if ((abovemat == EnumBlockMaterial.Wood || abovemat == EnumBlockMaterial.Leaves) && aboveBlock.SideSolid[BlockFacing.DOWN.Index])
                {
                    atPos.Set(pos.X, pos.Y - i - 1, pos.Z);

                    Block block = blockAccessor.GetBlock(atPos);
                    var   mat   = block.GetBlockMaterial(blockAccessor, atPos);

                    BlockPos belowPos = new BlockPos(pos.X, pos.Y - i - 2, pos.Z);

                    if (
                        mat == EnumBlockMaterial.Wood &&
                        abovemat == EnumBlockMaterial.Wood &&
                        blockAccessor.GetBlock(belowPos).GetBlockMaterial(blockAccessor, belowPos) == EnumBlockMaterial.Wood &&
                        aboveBlock.LastCodePart() == "ud"
                        )
                    {
                        Block inlogblock = blockAccessor.GetBlock(new AssetLocation("wildbeehive-inlog-" + aboveBlock.Variant["wood"]));

                        blockAccessor.SetBlock(inlogblock.BlockId, atPos);
                        if (EntityClass != null)
                        {
                            blockAccessor.SpawnBlockEntity(EntityClass, atPos);
                        }

                        return(true);
                    }

                    if (mat != EnumBlockMaterial.Leaves && mat != EnumBlockMaterial.Air)
                    {
                        continue;
                    }

                    int dx       = pos.X % blockAccessor.ChunkSize;
                    int dz       = pos.Z % blockAccessor.ChunkSize;
                    int surfacey = blockAccessor.GetMapChunkAtBlockPos(atPos).WorldGenTerrainHeightMap[dz * blockAccessor.ChunkSize + dx];

                    if (pos.Y - surfacey < 4)
                    {
                        return(false);
                    }

                    blockAccessor.SetBlock(BlockId, atPos);
                    if (EntityClass != null)
                    {
                        blockAccessor.SpawnBlockEntity(EntityClass, atPos);
                    }

                    //BlockPos test = pos.Copy();
                    //test.Y = 160;
                    //blockAccessor.SetBlock(blockAccessor.GetBlock(new AssetLocation("creativeblock-60")).BlockId, test);

                    return(true);
                }
            }

            return(false);
        }
示例#6
0
        /// <summary>
        /// For placement of ruins during worldgen, replaces the topsoil with the area specific soil (e.g. sand)
        /// </summary>
        /// <param name="blockAccessor"></param>
        /// <param name="blocks"></param>
        /// <param name="startPos"></param>
        /// <param name="climateUpLeft"></param>
        /// <param name="climateUpRight"></param>
        /// <param name="climateBotLeft"></param>
        /// <param name="climateBotRight"></param>
        /// <param name="replaceblockids"></param>
        /// <returns></returns>
        public int PlaceRespectingBlockLayers(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos startPos, int climateUpLeft, int climateUpRight, int climateBotLeft, int climateBotRight, ushort[] replaceblockids)
        {
            BlockPos curPos    = new BlockPos();
            int      placed    = 0;
            int      chunksize = blockAccessor.ChunkSize;


            for (int x = 0; x < SizeX; x++)
            {
                for (int z = 0; z < SizeZ; z++)
                {
                    curPos.Set(x + startPos.X, startPos.Y, z + startPos.Z);
                    ushort rockblockid = blockAccessor.GetMapChunkAtBlockPos(curPos).TopRockIdMap[(curPos.Z % chunksize) * chunksize + curPos.X % chunksize];
                    int    depth       = 0;

                    for (int y = SizeY - 1; y >= 0; y--)
                    {
                        curPos.Set(x + startPos.X, y + startPos.Y, z + startPos.Z);
                        Block newBlock = blocksByPos[x, y, z];
                        if (newBlock == null)
                        {
                            continue;
                        }

                        if (newBlock.Replaceable < 1000)
                        {
                            if (replaceblockids.Length > depth && newBlock.BlockId == replaceblockids[depth])
                            {
                                int climate = GameMath.BiLerpRgbColor((float)x / chunksize, (float)z / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

                                newBlock = GetBlockLayerBlock((climate >> 8) & 0xff, (climate >> 16) & 0xff, startPos.Y, rockblockid, depth, newBlock, worldForCollectibleResolve.Blocks);
                            }
                            depth++;
                        }

                        Block oldBlock = blockAccessor.GetBlock(curPos);
                        placed += handler(blockAccessor, curPos, oldBlock, newBlock);

                        byte[] lightHsv = newBlock.GetLightHsv(blockAccessor, curPos);

                        if (lightHsv[2] > 0 && blockAccessor is IWorldGenBlockAccessor)
                        {
                            int chunkSize = blockAccessor.ChunkSize;
                            ((IWorldGenBlockAccessor)blockAccessor).ScheduleBlockLightUpdate(curPos.Copy(), oldBlock.BlockId, newBlock.BlockId);
                        }
                    }
                }
            }

            foreach (var val in BlockEntities)
            {
                uint index = val.Key;
                int  dx    = (int)(index & 0x1ff);
                int  dy    = (int)((index >> 20) & 0x1ff);
                int  dz    = (int)((index >> 10) & 0x1ff);

                curPos.Set(startPos.X + dx, startPos.Y + dy, startPos.Z + dz);

                BlockEntity be = blockAccessor.GetBlockEntity(curPos);
                if (be != null)
                {
                    be.FromTreeAtributes(DecodeBlockEntityData(val.Value), worldForCollectibleResolve);
                    be.OnLoadCollectibleMappings(worldForCollectibleResolve, BlockCodes, ItemCodes);
                    be.pos = curPos.Copy();
                }
            }

            return(placed);
        }
示例#7
0
        private void TrySpawnGroupAt(BlockPos origin, Vec3d posAsVec, EntityProperties entityType, EntityProperties[] grouptypes)
        {
            BlockPos pos = origin.Copy();

            float xRel = (float)(posAsVec.X % chunksize) / chunksize;
            float zRel = (float)(posAsVec.Z % chunksize) / chunksize;

            int   climate       = GameMath.BiLerpRgbColor(xRel, zRel, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);
            float temp          = TerraGenConfig.GetScaledAdjustedTemperatureFloat((climate >> 16) & 0xff, (int)posAsVec.Y - TerraGenConfig.seaLevel);
            float rain          = ((climate >> 8) & 0xff) / 255f;
            float forestDensity = GameMath.BiLerp(forestUpLeft, forestUpRight, forestBotLeft, forestBotRight, xRel, zRel);
            float shrubDensity  = GameMath.BiLerp(shrubsUpLeft, shrubsUpRight, shrubsBotLeft, shrubsBotRight, xRel, zRel);

            int spawned = 0;

            WorldGenSpawnConditions sc = entityType.Server.SpawnConditions.Worldgen;
            bool hasCompanions         = sc.Companions != null && sc.Companions.Length > 0;

            spawnPositions.Clear();

            int nextGroupSize = 0;
            int tries         = 10;

            while (nextGroupSize <= 0 && tries-- > 0)
            {
                float val = sc.GroupSize.nextFloat();
                nextGroupSize = (int)val + ((val - (int)val) > rnd.NextDouble() ? 1 : 0);
            }


            for (int i = 0; i < nextGroupSize * 4 + 5; i++)
            {
                if (spawned >= nextGroupSize)
                {
                    break;
                }

                EntityProperties typeToSpawn = entityType;

                // First entity 80% chance to spawn the dominant creature, every subsequent only 20% chance for males (or even lower if more than 5 companion types)
                double dominantChance = i == 0 ? 0.8 : Math.Min(0.2, 1f / grouptypes.Length);

                if (grouptypes.Length > 1 && rnd.NextDouble() > dominantChance)
                {
                    typeToSpawn = grouptypes[1 + rnd.Next(grouptypes.Length - 1)];
                }

                posAsVec.Set(pos.X + 0.5, pos.Y + 0.005, pos.Z + 0.5);

                IBlockAccessor blockAccesssor = wgenBlockAccessor.GetChunkAtBlockPos(pos.X, pos.Y, pos.Z) == null ? api.World.BlockAccessor : wgenBlockAccessor;

                IMapChunk mapchunk = blockAccesssor.GetMapChunkAtBlockPos(pos);
                if (mapchunk != null)
                {
                    ushort[] heightMap = mapchunk.WorldGenTerrainHeightMap;

                    pos.Y =
                        sc.TryOnlySurface ?
                        heightMap[((int)pos.Z % chunksize) * chunksize + ((int)pos.X % chunksize)] + 1 :
                        pos.Y
                    ;

                    xRel = (float)(posAsVec.X % chunksize) / chunksize;
                    zRel = (float)(posAsVec.Z % chunksize) / chunksize;

                    climate       = GameMath.BiLerpRgbColor(xRel, zRel, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);
                    temp          = TerraGenConfig.GetScaledAdjustedTemperatureFloat((climate >> 16) & 0xff, (int)posAsVec.Y - TerraGenConfig.seaLevel);
                    rain          = ((climate >> 8) & 0xff) / 255f;
                    forestDensity = GameMath.BiLerp(forestUpLeft, forestUpRight, forestBotLeft, forestBotRight, xRel, zRel) / 255f;
                    shrubDensity  = GameMath.BiLerp(shrubsUpLeft, shrubsUpRight, shrubsBotLeft, shrubsBotRight, xRel, zRel) / 255f;


                    if (CanSpawnAt(blockAccesssor, typeToSpawn, pos, posAsVec, sc, rain, temp, forestDensity, shrubDensity))
                    {
                        spawnPositions.Add(new SpawnOppurtunity()
                        {
                            ForType = typeToSpawn, Pos = posAsVec.Clone()
                        });
                        spawned++;
                    }
                }

                pos.X = origin.X + ((rnd.Next(11) - 5) + (rnd.Next(11) - 5)) / 2;
                pos.Z = origin.Z + ((rnd.Next(11) - 5) + (rnd.Next(11) - 5)) / 2;
            }


            // Only spawn if the group reached the minimum group size
            if (spawnPositions.Count >= nextGroupSize)
            {
                long herdId = api.WorldManager.GetNextHerdId();

                foreach (SpawnOppurtunity so in spawnPositions)
                {
                    Entity ent = CreateEntity(so.ForType, so.Pos);
                    if (ent is EntityAgent)
                    {
                        (ent as EntityAgent).HerdId = herdId;
                    }

                    if (wgenBlockAccessor.GetChunkAtBlockPos(pos.X, pos.Y, pos.Z) == null)
                    {
                        api.World.SpawnEntity(ent);
                    }
                    else
                    {
                        wgenBlockAccessor.AddEntity(ent);
                    }
                }

                //Console.WriteLine("Spawn a group of {0}x{1} at {2}", spawnPositions.Count, entityType.Code, origin);
            }
        }