public void SetBlockPatches(BlockPatchConfig bpc)
        {
            forestBlocks = BlockForestFloor.InitialiseForestBlocks(worldAccessor);

            underTreePatches = new List <BlockPatch>();
            onTreePatches    = new List <BlockPatch>();

            for (int i = 0; i < bpc.Patches.Length; i++)
            {
                BlockPatch blockPatch = bpc.Patches[i];
                if (blockPatch.Placement == EnumBlockPatchPlacement.UnderTrees || blockPatch.Placement == EnumBlockPatchPlacement.OnSurfacePlusUnderTrees)
                {
                    underTreePatches.Add(blockPatch);
                }
                if (blockPatch.Placement == EnumBlockPatchPlacement.OnTrees)
                {
                    onTreePatches.Add(blockPatch);
                }
            }
        }
        private float GetDistance(ClimateCondition climate, BlockPatch variant)
        {
            float fertDist, rainDist, tempDist, forestDist;

            tempDist = Math.Abs(climate.Temperature * 2 - variant.MaxTemp - variant.MinTemp) / (variant.MaxTemp - variant.MinTemp);
            if (tempDist > 1f)
            {
                return(5f);
            }
            fertDist = Math.Abs(climate.Fertility * 2 - variant.MaxFertility - variant.MinFertility) / (variant.MaxFertility - variant.MinFertility);
            if (fertDist > 1f)
            {
                return(5f);
            }
            rainDist = Math.Abs(climate.Rainfall * 2 - variant.MaxRain - variant.MinRain) / (variant.MaxRain - variant.MinRain);
            if (rainDist > 1.3f)
            {
                return(5f);
            }
            forestDist = Math.Abs((climate.ForestDensity + 0.2f) * 2 - variant.MaxForest - variant.MinForest) / (variant.MaxForest - variant.MinForest);

            return(tempDist * tempDist + fertDist * fertDist + rainDist * rainDist + forestDist * forestDist);
        }
示例#3
0
        void genPatches(int chunkX, int chunkZ)
        {
            int   dx, dz, x, z;
            Block block;

            for (int i = 0; i < bpc.Patches.Length; i++)
            {
                BlockPatch blockPatch = bpc.Patches[i];
                if (!blockPatch.PrePass)
                {
                    continue;
                }

                float chance = blockPatch.Chance * bpc.ChanceMultiplier.nextFloat();

                while (chance-- > rnd.NextDouble())
                {
                    dx = rnd.Next(chunksize);
                    dz = rnd.Next(chunksize);
                    x  = dx + chunkX * chunksize;
                    z  = dz + chunkZ * chunksize;

                    int y = heightmap[dz * chunksize + dx];
                    if (y <= 0 || y >= worldheight - 15)
                    {
                        continue;
                    }

                    tmpPos.Set(x, y, z);
                    block = blockAccessor.GetBlock(tmpPos);

                    // Place according to forest value
                    int climate = GameMath.BiLerpRgbColor((float)dx / chunksize, (float)dz / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

                    if (bpc.IsPatchSuitableAt(blockPatch, block, api.WorldManager, climate, y, 0))
                    {
                        int  firstBlockId = 0;
                        bool found        = true;

                        if (blockPatch.BlocksByRockType != null)
                        {
                            found = false;
                            int dy = 1;
                            while (dy < 5 && y - dy > 0)
                            {
                                string lastCodePart = blockAccessor.GetBlock(x, y - dy, z).LastCodePart();
                                if (RockBlockIdsByType.TryGetValue(lastCodePart, out firstBlockId))
                                {
                                    found = true; break;
                                }
                                dy++;
                            }
                        }

                        if (found)
                        {
                            blockPatch.Generate(blockAccessor, rnd, x, y, z, firstBlockId);
                        }
                    }
                }
            }
        }
        void genPatches(int chunkX, int chunkZ, bool postPass)
        {
            int   dx, dz, x, z;
            Block block;
            int   mapsizeY = blockAccessor.MapSizeY;

            var mapregion = sapi?.WorldManager.GetMapRegion((chunkX * chunksize) / regionSize, (chunkZ * chunksize) / regionSize);


            for (int i = 0; i < bpc.PatchesNonTree.Length; i++)
            {
                BlockPatch blockPatch = bpc.PatchesNonTree[i];
                if (blockPatch.PostPass != postPass)
                {
                    continue;
                }

                float chance = blockPatch.Chance * bpc.ChanceMultiplier.nextFloat();

                while (chance-- > rnd.NextDouble())
                {
                    dx = rnd.NextInt(chunksize);
                    dz = rnd.NextInt(chunksize);
                    x  = dx + chunkX * chunksize;
                    z  = dz + chunkZ * chunksize;

                    int y = heightmap[dz * chunksize + dx];
                    if (y <= 0 || y >= worldheight - 15)
                    {
                        continue;
                    }

                    tmpPos.Set(x, y, z);
                    block = blockAccessor.GetBlock(tmpPos);

                    // Place according to forest value
                    float forestRel = GameMath.BiLerp(forestUpLeft, forestUpRight, forestBotLeft, forestBotRight, (float)dx / chunksize, (float)dz / chunksize) / 255f;
                    forestRel = GameMath.Clamp(forestRel + forestMod, 0, 1);

                    float shrubRel = GameMath.BiLerp(shrubUpLeft, shrubUpRight, shrubBotLeft, shrubBotRight, (float)dx / chunksize, (float)dz / chunksize) / 255f;
                    shrubRel = GameMath.Clamp(shrubRel + shrubMod, 0, 1);

                    int climate = GameMath.BiLerpRgbColor((float)dx / chunksize, (float)dz / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

                    if (bpc.IsPatchSuitableAt(blockPatch, block, mapsizeY, climate, y, forestRel, shrubRel))
                    {
                        if (blockPatch.MapCode != null && rnd.NextInt(255) > GetPatchDensity(blockPatch.MapCode, x, z, mapregion))
                        {
                            continue;
                        }

                        int  firstBlockId = 0;
                        bool found        = true;

                        if (blockPatch.BlocksByRockType != null)
                        {
                            found = false;
                            int dy = 1;
                            while (dy < 5 && y - dy > 0)
                            {
                                string lastCodePart = blockAccessor.GetBlock(x, y - dy, z).LastCodePart();
                                if (RockBlockIdsByType.TryGetValue(lastCodePart, out firstBlockId))
                                {
                                    found = true; break;
                                }
                                dy++;
                            }
                        }

                        if (found)
                        {
                            blockPatch.Generate(blockAccessor, rnd, x, y, z, firstBlockId);
                        }
                    }
                }
            }
        }
 private int GetRandomBlock(BlockPatch blockPatch)
 {
     return(blockPatch.Blocks[0].Id);
 }
        private void GenPatches(IBlockAccessor blockAccessor, BlockPos pos, float forestNess, EnumTreeType treetype, LCGRandom rnd)
        {
            var bpc         = genPatchesSystem.bpc;
            int radius      = 5;
            int worldheight = blockAccessor.MapSizeY;

            int cnt = underTreePatches?.Count ?? 0;

            for (int i = 0; i < cnt; i++)
            {
                BlockPatch bPatch = underTreePatches[i];
                if (bPatch.TreeType != EnumTreeType.Any && bPatch.TreeType != treetype)
                {
                    continue;
                }

                float chance = 0.003f * forestNess * bPatch.Chance * bpc.ChanceMultiplier.nextFloat();

                //if (bPatch.blockCodes[0].Path.Contains("mushroom")) chance *= 20; - for debugging

                while (chance-- > rnd.NextDouble())
                {
                    int dx = rnd.NextInt(2 * radius) - radius;
                    int dz = rnd.NextInt(2 * radius) - radius;

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

                    int y = blockAccessor.GetTerrainMapheightAt(tmpPos);
                    if (y <= 0 || y >= worldheight - 8)
                    {
                        continue;
                    }

                    tmpPos.Y = y;

                    var climate = blockAccessor.GetClimateAt(tmpPos, EnumGetClimateMode.WorldGenValues);
                    if (climate == null)
                    {
                        continue;
                    }

                    if (bpc.IsPatchSuitableUnderTree(bPatch, worldheight, climate, y))
                    {
                        int regionX = pos.X / blockAccessor.RegionSize;
                        int regionZ = pos.Z / blockAccessor.RegionSize;
                        if (bPatch.MapCode != null && rnd.NextInt(255) > genPatchesSystem.GetPatchDensity(bPatch.MapCode, tmpPos.X, tmpPos.Z, blockAccessor.GetMapRegion(regionX, regionZ)))
                        {
                            continue;
                        }

                        int  firstBlockId = 0;
                        bool found        = true;

                        if (bPatch.BlocksByRockType != null)
                        {
                            found = false;
                            int dy = 1;
                            while (dy < 5 && y - dy > 0)
                            {
                                string lastCodePart = blockAccessor.GetBlock(tmpPos.X, y - dy, tmpPos.Z).LastCodePart();
                                if (genPatchesSystem.RockBlockIdsByType.TryGetValue(lastCodePart, out firstBlockId))
                                {
                                    found = true; break;
                                }
                                dy++;
                            }
                        }

                        if (found)
                        {
                            bPatch.Generate(blockAccessor, rnd, tmpPos.X, tmpPos.Y, tmpPos.Z, firstBlockId);
                        }
                    }
                }
            }

            cnt = onTreePatches?.Count ?? 0;
            for (int i = 0; i < cnt; i++)
            {
                BlockPatch blockPatch = onTreePatches[i];

                float chance = 3 * forestNess * blockPatch.Chance * bpc.ChanceMultiplier.nextFloat();

                while (chance-- > rnd.NextDouble())
                {
                    int dx = 1 - rnd.NextInt(2) * 2;
                    int dy = rnd.NextInt(5);
                    int dz = 1 - rnd.NextInt(2) * 2;

                    tmpPos.Set(pos.X + dx, pos.Y + dy, pos.Z + dz);

                    var block = api.GetBlock(tmpPos);
                    if (block.Id != 0)
                    {
                        continue;
                    }
                    BlockFacing facing = null;

                    for (int j = 0; j < 4; j++)
                    {
                        var f      = BlockFacing.HORIZONTALS[j];
                        var nblock = api.GetBlock(tmpPos.X + f.Normali.X, tmpPos.Y, tmpPos.Z + f.Normali.Z);
                        if (nblock is BlockLog && nblock.Variant["type"] != "resin")
                        {
                            facing = f;
                            break;
                        }
                    }
                    if (facing == null)
                    {
                        break;
                    }

                    var climate = blockAccessor.GetClimateAt(tmpPos, EnumGetClimateMode.WorldGenValues);
                    if (climate == null)
                    {
                        continue;
                    }

                    if (bpc.IsPatchSuitableUnderTree(blockPatch, worldheight, climate, tmpPos.Y))
                    {
                        int regionX = pos.X / blockAccessor.RegionSize;
                        int regionZ = pos.Z / blockAccessor.RegionSize;
                        if (blockPatch.MapCode != null && rnd.NextInt(255) > genPatchesSystem.GetPatchDensity(blockPatch.MapCode, tmpPos.X, tmpPos.Z, blockAccessor.GetMapRegion(regionX, regionZ)))
                        {
                            continue;
                        }

                        int index = rnd.NextInt(blockPatch.Blocks.Length);
                        blockPatch.Blocks[index].TryPlaceBlockForWorldGen(blockAccessor, tmpPos, facing, rnd);
                    }
                }
            }
        }