Ejemplo n.º 1
0
        //-- Checks every block in the chunk. If that block is an ore within the oreCodeDict, pass the block position and ore code to the SpawnCrystals method. --//
        private void CrystalGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams)
        {
            BlockPos blockPos = new BlockPos();

            for (int x = 0; x < chunkSize; x++)
            {
                blockPos.X = chunkX * chunkSize + x;

                for (int z = 0; z < chunkSize; z++)
                {
                    blockPos.Z = chunkZ * chunkSize + z;

                    for (int y = 0; y < worldBlockAccessor.GetTerrainMapheightAt(blockPos); y++)
                    {
                        blockPos.Y = y;

                        Block block = chunkBlockAccessor.GetBlock(blockPos);
                        if (block is BlockOre)
                        {
                            string code = block.Code.Path;

                            SpawnCrystals(blockPos, code);
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public override bool TryPlaceBlockForWorldGen(IBlockAccessor blockAccessor, BlockPos pos, BlockFacing onBlockFace, LCGRandom worldGenRand)
        {
            if (blockAccessor.GetBlockId(pos) != 0)
            {
                return(false);
            }

            int surfaceY = blockAccessor.GetTerrainMapheightAt(pos);

            if (surfaceY - pos.Y < 30 || pos.Y < 25)
            {
                return(false);
            }

            BlockPos cavepos = getSemiLargeCavePos(blockAccessor, pos);

            if (cavepos == null)
            {
                return(false);
            }

            int dy = 0;

            while (dy < 15 && !blockAccessor.GetBlock(cavepos.X, cavepos.Y + dy, cavepos.Z).SideSolid[BlockFacing.UP.Index])
            {
                dy++;
            }
            if (dy >= 15)
            {
                return(false);
            }
            blockAccessor.SetBlock(this.BlockId, cavepos.AddCopy(0, dy, 0));
            if (EntityClass != null)
            {
                blockAccessor.SpawnBlockEntity(EntityClass, cavepos.AddCopy(0, dy, 0));
            }

            BlockPos tmppos = new BlockPos();
            int      tries  = 55 + worldGenRand.NextInt(55);

            while (tries-- > 0)
            {
                int offX = worldGenRand.NextInt(15) - 7;
                int offY = worldGenRand.NextInt(15) - 7;
                int offZ = worldGenRand.NextInt(15) - 7;

                if (worldGenRand.NextDouble() < 0.4)
                {
                    tryPlaceDecoUp(tmppos.Set(cavepos.X + offX, cavepos.Y + offY, cavepos.Z + offZ), blockAccessor, worldGenRand);
                }
                else
                {
                    tryPlaceDecoDown(tmppos.Set(cavepos.X + offX, cavepos.Y + offY, cavepos.Z + offZ), blockAccessor, worldGenRand);
                }
            }

            return(true);
        }
Ejemplo n.º 3
0
        void PrintProbeResults(IWorldAccessor world, IServerPlayer byPlayer, IItemSlot itemslot, BlockPos pos)
        {
            IBlockAccessor blockAccess = world.BlockAccessor;
            int            chunksize   = blockAccess.ChunkSize;
            int            regsize     = blockAccess.RegionSize;

            int mapheight    = blockAccess.GetTerrainMapheightAt(pos);
            int qchunkblocks = mapheight * chunksize * chunksize;

            IMapRegion reg = world.BlockAccessor.GetMapRegion(pos.X / regsize, pos.Z / regsize);
            int        lx  = pos.X % regsize;
            int        lz  = pos.Z % regsize;

            StringBuilder outtext = new StringBuilder();
            int           found   = 0;

            foreach (var val in reg.OreMaps)
            {
                IntMap map       = val.Value;
                int    noiseSize = map.InnerSize;

                float posXInRegionOre = (float)lx / regsize * noiseSize;
                float posZInRegionOre = (float)lz / regsize * noiseSize;

                int oreDist = map.GetUnpaddedColorLerped(posXInRegionOre, posZInRegionOre);

                double   absAvgq  = absAvgQuantity[val.Key];
                double   factor   = (oreDist & 0xff) / 255.0;
                double   quantity = factor * absAvgq;
                double   relq     = quantity / qchunkblocks;
                double   ppt      = relq * 1000;
                string[] names    = new string[] { "Very poor density", "Poor density", "Decent density", "High density", "Very high density", "Ultra high density" };

                if (factor > 0.05)
                {
                    if (found > 0)
                    {
                        outtext.Append("\n");
                    }
                    outtext.Append(string.Format("{1}: {2} ({0}‰)", ppt.ToString("0.#"), val.Key.Substring(0, 1).ToUpper() + val.Key.Substring(1), names[(int)GameMath.Clamp(factor * 5, 0, 5)]));
                    found++;
                }
            }

            IServerPlayer splr = byPlayer as IServerPlayer;

            if (outtext.Length == 0)
            {
                outtext.Append("No significant resources here.");
            }
            else
            {
                outtext.Insert(0, "Found " + found + " traces of ore\n");
            }
            splr.SendMessage(GlobalConstants.CurrentChatGroup, outtext.ToString(), EnumChatType.Notification);
        }
Ejemplo n.º 4
0
        private void GenRareColorPatch(IBlockAccessor blockAccessor, BlockPos pos, Block block, LCGRandom worldGenRand)
        {
            int      cnt   = 2 + worldGenRand.NextInt(6);
            int      tries = 30;
            BlockPos npos  = pos.Copy();

            while (cnt > 0 && tries-- > 0)
            {
                npos.Set(pos).Add(worldGenRand.NextInt(5) - 2, 0, worldGenRand.NextInt(5) - 2);
                npos.Y = blockAccessor.GetTerrainMapheightAt(npos) + 1;

                Block nblock = blockAccessor.GetBlock(npos);

                if ((nblock.IsReplacableBy(block) || nblock is BlockLupine) && CanPlantStay(blockAccessor, npos))
                {
                    blockAccessor.SetBlock(block.BlockId, npos);
                    cnt--;
                }
            }
        }
        public override bool ShouldExecute()
        {
            if (!entity.Swimming)
            {
                return(false);
            }
            if (rand.NextDouble() > 0.04f)
            {
                return(false);
            }


            target.Y = entity.ServerPos.Y;
            int            tries         = 6;
            int            px            = (int)entity.ServerPos.X;
            int            pz            = (int)entity.ServerPos.Z;
            IBlockAccessor blockAccessor = entity.World.BlockAccessor;

            while (tries-- > 0)
            {
                pos.X = px + rand.Next(21) - 10;
                pos.Z = pz + rand.Next(21) - 10;
                pos.Y = blockAccessor.GetTerrainMapheightAt(pos);

                Cuboidf[] blockBoxes = blockAccessor.GetBlock(pos).GetCollisionBoxes(blockAccessor, pos);
                pos.Y--;
                Cuboidf[] belowBoxes = blockAccessor.GetBlock(pos).GetCollisionBoxes(blockAccessor, pos);

                bool canStep  = blockBoxes == null || blockBoxes.Max((cuboid) => cuboid.Y2) <= 1f;
                bool canStand = belowBoxes != null && belowBoxes.Length > 0;

                if (canStand && canStep)
                {
                    target.Set(pos.X + 0.5, pos.Y + 1, pos.Z + 0.5);
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 6
0
        public override bool TryPlaceBlockForWorldGen(IBlockAccessor blAcc, BlockPos pos, BlockFacing onBlockFace, Random worldgenRand)
        {
            int   cnt          = 2 + worldgenRand.Next(25);
            float depth        = GameMath.Sqrt(GameMath.Sqrt(cnt));
            float craterRadius = GameMath.Sqrt(cnt) * 1.25f;

            // Look for even or downwards curved ground
            if (pos.Y > 250 ||
                !IsSolid(blAcc, pos.X, pos.Y - 3, pos.Z) ||
                !IsSolid(blAcc, pos.X, pos.Y - (int)depth, pos.Z) ||
                !IsSolid(blAcc, pos.X + (int)craterRadius, pos.Y - 1, pos.Z) ||
                !IsSolid(blAcc, pos.X - (int)craterRadius, pos.Y - 1, pos.Z) ||
                !IsSolid(blAcc, pos.X, pos.Y - 1, pos.Z - (int)craterRadius) ||
                !IsSolid(blAcc, pos.X, pos.Y - 1, pos.Z + (int)craterRadius)
                )
            {
                return(false);
            }

            int y1 = blAcc.GetTerrainMapheightAt(tmpPos.Set(pos.X - 5, pos.Y, pos.Z));
            int y2 = blAcc.GetTerrainMapheightAt(tmpPos.Set(pos.X + 5, pos.Y, pos.Z));
            int y3 = blAcc.GetTerrainMapheightAt(tmpPos.Set(pos.X - 0, pos.Y, pos.Z + 5));
            int y4 = blAcc.GetTerrainMapheightAt(tmpPos.Set(pos.X - 0, pos.Y, pos.Z - 5));

            if ((GameMath.Max(y1, y2, y3, y4) - GameMath.Min(y1, y2, y3, y4)) > 4)
            {
                return(false);
            }



            tmpPos = tmpPos.Set(pos.X, pos.Y - (int)depth - 2, pos.Z);
            while (cnt-- > 0)
            {
                tmpPos.X += worldgenRand.Next(3) == 0 ? (worldgenRand.Next(3) - 1) : 0;
                tmpPos.Y += worldgenRand.Next(8) == 0 ? (worldgenRand.Next(3) - 1) : 0;
                tmpPos.Z += worldgenRand.Next(3) == 0 ? (worldgenRand.Next(3) - 1) : 0;

                blAcc.SetBlock(this.BlockId, tmpPos);
            }



            int sueviteBlockId      = api.World.GetBlock(new AssetLocation("rock-suevite")).BlockId;
            int fragmentBlockId     = api.World.GetBlock(new AssetLocation("loosestones-meteorite-iron")).BlockId;
            int looseSueviteBlockId = api.World.GetBlock(new AssetLocation("loosestones-suevite")).BlockId;

            float impactRockRadius = craterRadius * 1.2f;
            int   range            = (int)Math.Ceiling(impactRockRadius);
            int   chunksize        = api.World.BlockAccessor.ChunkSize;
            Vec2i vecTmp           = new Vec2i();

            // 1. Generate a basin of suevite and lower terrain
            for (int dx = -range; dx <= range; dx++)
            {
                for (int dz = -range; dz <= range; dz++)
                {
                    float distImpactRockEdge = (dx * dx + dz * dz) / (impactRockRadius * impactRockRadius);
                    if (distImpactRockEdge > 1)
                    {
                        continue;
                    }

                    tmpPos.X = pos.X + dx;
                    tmpPos.Z = pos.Z + dz;
                    int surfaceY = blAcc.GetTerrainMapheightAt(tmpPos);
                    tmpPos.Y = surfaceY - (int)depth;

                    vecTmp.X = tmpPos.X / chunksize;
                    vecTmp.Y = tmpPos.Z / chunksize;
                    IMapChunk mapchunk = blAcc.GetMapChunk(vecTmp);


                    float q = 3 * Math.Max(0, 2 * (1 - distImpactRockEdge) - 0.2f);
                    tmpPos.Y -= (int)q + 1;


                    while (q > 0)
                    {
                        if (q < 1 && worldgenRand.NextDouble() > q)
                        {
                            break;
                        }

                        Block block = blAcc.GetBlock(tmpPos);

                        if (block != this && block.BlockMaterial == EnumBlockMaterial.Stone)
                        {
                            blAcc.SetBlock(sueviteBlockId, tmpPos);
                        }
                        q--;
                        tmpPos.Y++;
                    }

                    float distToCraterEdge = (dx * dx + dz * dz) / (craterRadius * craterRadius) + (float)worldgenRand.NextDouble() * 0.1f;
                    if (distToCraterEdge > 1)
                    {
                        continue;
                    }

                    q = depth * (1 - distToCraterEdge);

                    tmpPos.Y = surfaceY;
                    Block surfaceblock      = blAcc.GetBlock(tmpPos);
                    Block abovesurfaceblock = blAcc.GetBlock(tmpPos.X, tmpPos.Y + 1, tmpPos.Z);

                    for (int i = -1; i <= (int)q; i++)
                    {
                        tmpPos.Y = surfaceY - i;
                        int id = i == (int)q ? surfaceblock.BlockId : 0;
                        blAcc.SetBlock(id, tmpPos);
                    }

                    mapchunk.WorldGenTerrainHeightMap[(tmpPos.Z % chunksize) * chunksize + (tmpPos.X % chunksize)] -= (ushort)q;

                    tmpPos.Y = blAcc.GetTerrainMapheightAt(tmpPos) + 1;

                    blAcc.SetBlock(abovesurfaceblock.BlockId, tmpPos);
                }
            }

            int quantityFragments = 0;

            if (worldgenRand.Next(10) == 0)
            {
                quantityFragments = worldgenRand.Next(10);
            }
            else if (worldgenRand.Next(5) == 0)
            {
                quantityFragments = worldgenRand.Next(5);
            }

            while (quantityFragments-- > 0)
            {
                tmpPos.Set(
                    pos.X + (worldgenRand.Next(11) + worldgenRand.Next(11)) / 2 - 5,
                    0,
                    pos.Z + (worldgenRand.Next(11) + worldgenRand.Next(11)) / 2 - 5
                    );
                tmpPos.Y = blAcc.GetTerrainMapheightAt(tmpPos) + 1;

                if (!blAcc.GetBlock(tmpPos.X, tmpPos.Y - 1, tmpPos.Z).SideSolid[BlockFacing.UP.Index])
                {
                    continue;
                }

                if (worldgenRand.NextDouble() < 0.3)
                {
                    blAcc.SetBlock(fragmentBlockId, tmpPos);
                }
                else
                {
                    blAcc.SetBlock(looseSueviteBlockId, tmpPos);
                }
            }

            //blAcc.SetBlock(61, pos.AddCopy(0, 20, 0));


            return(true);
        }
        internal bool TryGenerateAtSurface(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos pos)
        {
            int num    = rand.NextInt(schematicDatas.Length);
            int orient = rand.NextInt(4);
            BlockSchematicStructure schematic = schematicDatas[num][orient];

            int wdthalf = (int)Math.Ceiling(schematic.SizeX / 2f);
            int lenhalf = (int)Math.Ceiling(schematic.SizeZ / 2f);
            int wdt     = schematic.SizeX;
            int len     = schematic.SizeZ;


            tmpPos.Set(pos.X + wdthalf, 0, pos.Z + lenhalf);
            int centerY = blockAccessor.GetTerrainMapheightAt(tmpPos);

            // Probe all 4 corners + center if they are on the same height
            tmpPos.Set(pos.X, 0, pos.Z);
            int topLeftY = blockAccessor.GetTerrainMapheightAt(tmpPos);

            tmpPos.Set(pos.X + wdt, 0, pos.Z);
            int topRightY = blockAccessor.GetTerrainMapheightAt(tmpPos);

            tmpPos.Set(pos.X, 0, pos.Z + len);
            int botLeftY = blockAccessor.GetTerrainMapheightAt(tmpPos);

            tmpPos.Set(pos.X + wdt, 0, pos.Z + len);
            int botRightY = blockAccessor.GetTerrainMapheightAt(tmpPos);


            int diff = GameMath.Max(centerY, topLeftY, topRightY, botLeftY, botRightY) - GameMath.Min(centerY, topLeftY, topRightY, botLeftY, botRightY);

            if (diff != 0)
            {
                return(false);
            }

            pos.Y += centerY - pos.Y + 1 + OffsetY;


            // Ensure not floating on water
            tmpPos.Set(pos.X + wdthalf, pos.Y - 1, pos.Z + lenhalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }


            tmpPos.Set(pos.X, pos.Y - 1, pos.Z);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X + wdt, pos.Y - 1, pos.Z);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X, pos.Y - 1, pos.Z + len);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X + wdt, pos.Y - 1, pos.Z + len);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            // Ensure not submerged in water
            tmpPos.Set(pos.X, pos.Y, pos.Z);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }


            tmpPos.Set(pos.X + wdt, pos.Y - 1, pos.Z + len);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X + wdt, pos.Y, pos.Z);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X, pos.Y, pos.Z + len);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X + wdt, pos.Y, pos.Z + len);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }



            tmpPos.Set(pos.X, pos.Y + 1, pos.Z);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X + wdt, pos.Y + 1, pos.Z);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X, pos.Y + 1, pos.Z + len);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X + wdt, pos.Y + 1, pos.Z + len);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }


            if (!satisfiesMinDistance(pos, worldForCollectibleResolve))
            {
                return(false);
            }
            if (isStructureAt(pos, worldForCollectibleResolve))
            {
                return(false);
            }

            LastPlacedSchematicLocation.Set(pos.X, pos.Y, pos.Z, pos.X + schematic.SizeX, pos.Y + schematic.SizeY, pos.Z + schematic.SizeZ);
            LastPlacedSchematic = schematic;
            schematic.PlaceRespectingBlockLayers(blockAccessor, worldForCollectibleResolve, pos, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight, replaceblockids);
            return(true);
        }
Ejemplo n.º 8
0
        internal bool TryGenerateRuinAtSurface(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos pos)
        {
            int chunksize = blockAccessor.ChunkSize;
            int climate   = GameMath.BiLerpRgbColor((float)(pos.X % chunksize) / chunksize, (float)(pos.Z % chunksize) / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

            int num    = rand.NextInt(schematicDatas.Length);
            int orient = rand.NextInt(4);
            BlockSchematicStructure schematic = schematicDatas[num][orient];


            int widthHalf  = (int)Math.Ceiling(schematic.SizeX / 2f);
            int lengthHalf = (int)Math.Ceiling(schematic.SizeZ / 2f);



            // Probe all 4 corners + center if they either touch the surface or are sightly below ground

            int centerY = blockAccessor.GetTerrainMapheightAt(pos);


            tmpPos.Set(pos.X - widthHalf, 0, pos.Z - lengthHalf);
            int topLeftY = blockAccessor.GetTerrainMapheightAt(tmpPos);

            tmpPos.Set(pos.X + widthHalf, 0, pos.Z - lengthHalf);
            int topRightY = blockAccessor.GetTerrainMapheightAt(tmpPos);

            tmpPos.Set(pos.X - widthHalf, 0, pos.Z + lengthHalf);
            int botLeftY = blockAccessor.GetTerrainMapheightAt(tmpPos);

            tmpPos.Set(pos.X + widthHalf, 0, pos.Z + lengthHalf);
            int botRightY = blockAccessor.GetTerrainMapheightAt(tmpPos);


            int maxY = GameMath.Max(centerY, topLeftY, topRightY, botLeftY, botRightY);
            int minY = GameMath.Min(centerY, topLeftY, topRightY, botLeftY, botRightY);
            int diff = Math.Abs(maxY - minY);

            if (diff > 3)
            {
                return(false);
            }

            pos.Y = minY;


            // Ensure not deeply submerged in water

            tmpPos.Set(pos.X - widthHalf, pos.Y + 1 + OffsetY, pos.Z - lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X + widthHalf, pos.Y + 1 + OffsetY, pos.Z - lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X - widthHalf, pos.Y + 1 + OffsetY, pos.Z + lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X + widthHalf, pos.Y + 1 + OffsetY, pos.Z + lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }


            pos.Y--;

            if (!satisfiesMinDistance(pos, worldForCollectibleResolve))
            {
                return(false);
            }
            if (isStructureAt(pos, worldForCollectibleResolve))
            {
                return(false);
            }

            LastPlacedSchematicLocation.Set(pos.X, pos.Y, pos.Z, pos.X + schematic.SizeX, pos.Y + schematic.SizeY, pos.Z + schematic.SizeZ);
            LastPlacedSchematic = schematic;
            schematic.PlaceRespectingBlockLayers(blockAccessor, worldForCollectibleResolve, pos, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight, replaceblockids);

            return(true);
        }
Ejemplo n.º 9
0
        protected BlockSchematicStructure GetGeneratableStructure(VillageSchematic schem, IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos pos)
        {
            int chunksize = blockAccessor.ChunkSize;
            int climate   = GameMath.BiLerpRgbColor((float)(pos.X % chunksize) / chunksize, (float)(pos.Z % chunksize) / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);


            int num = rand.NextInt(schem.Structures.Length);
            BlockSchematicStructure schematic = schem.Structures[num];

            int widthHalf  = (int)Math.Ceiling(schematic.SizeX / 2f);
            int lengthHalf = (int)Math.Ceiling(schematic.SizeZ / 2f);

            pos.Y += schem.OffsetY;

            // Probe all 4 corners + center if they are on the same height

            int centerY = blockAccessor.GetTerrainMapheightAt(pos);

            tmpPos.Set(pos.X - widthHalf, 0, pos.Z - lengthHalf);
            int topLeftY = blockAccessor.GetTerrainMapheightAt(tmpPos);

            tmpPos.Set(pos.X + widthHalf, 0, pos.Z - lengthHalf);
            int topRightY = blockAccessor.GetTerrainMapheightAt(tmpPos);

            tmpPos.Set(pos.X - widthHalf, 0, pos.Z + lengthHalf);
            int botLeftY = blockAccessor.GetTerrainMapheightAt(tmpPos);

            tmpPos.Set(pos.X + widthHalf, 0, pos.Z + lengthHalf);
            int botRightY = blockAccessor.GetTerrainMapheightAt(tmpPos);


            int diff = GameMath.Max(centerY, topLeftY, topRightY, botLeftY, botRightY) - GameMath.Min(centerY, topLeftY, topRightY, botLeftY, botRightY);

            if (diff > 2)
            {
                return(null);
            }

            pos.Y += centerY - pos.Y + 1 + schem.OffsetY;
            if (pos.Y <= 0)
            {
                return(null);
            }

            // Ensure not floating on water
            tmpPos.Set(pos.X - widthHalf, pos.Y - 1, pos.Z - lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            tmpPos.Set(pos.X + widthHalf, pos.Y - 1, pos.Z - lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            tmpPos.Set(pos.X - widthHalf, pos.Y - 1, pos.Z + lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            tmpPos.Set(pos.X + widthHalf, pos.Y - 1, pos.Z + lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            // Ensure not submerged in water
            tmpPos.Set(pos.X - widthHalf, pos.Y, pos.Z - lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            tmpPos.Set(pos.X + widthHalf, pos.Y, pos.Z - lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            tmpPos.Set(pos.X - widthHalf, pos.Y, pos.Z + lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            tmpPos.Set(pos.X + widthHalf, pos.Y, pos.Z + lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }



            tmpPos.Set(pos.X - widthHalf, pos.Y + 1, pos.Z - lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            tmpPos.Set(pos.X + widthHalf, pos.Y + 1, pos.Z - lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            tmpPos.Set(pos.X - widthHalf, pos.Y + 1, pos.Z + lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            tmpPos.Set(pos.X + widthHalf, pos.Y + 1, pos.Z + lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(null);
            }

            if (!TestUndergroundCheckPositions(blockAccessor, pos, schematic.UndergroundCheckPositions))
            {
                return(null);
            }

            if (isStructureAt(pos, worldForCollectibleResolve))
            {
                return(null);
            }

            return(schematic);
        }
Ejemplo n.º 10
0
        public bool TryGenerate(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos pos, int climateUpLeft, int climateUpRight, int climateBotLeft, int climateBotRight, DidGenerate didGenerateStructure)
        {
            this.climateUpLeft   = climateUpLeft;
            this.climateUpRight  = climateUpRight;
            this.climateBotLeft  = climateBotLeft;
            this.climateBotRight = climateBotRight;

            float    cnt         = QuantityStructures.nextFloat();
            int      minQuantity = (int)cnt;
            BlockPos schemPos    = pos.Copy();
            Cuboidi  location    = new Cuboidi();

            rand.InitPositionSeed(pos.X, pos.Z);

            List <GeneratableStructure> generatables = new List <GeneratableStructure>();

            while (cnt-- > 0)
            {
                if (cnt < 1 && rand.NextDouble() > cnt)
                {
                    break;
                }

                int tries = 30;
                while (tries-- > 0)
                {
                    schemPos.Set(pos);
                    schemPos.Add(rand.NextInt(50) - 25, 0, rand.NextInt(50) - 25);
                    schemPos.Y = blockAccessor.GetTerrainMapheightAt(schemPos);

                    double           rndVal = rand.NextDouble() * totalWeight;
                    int              i      = 0;
                    VillageSchematic schem  = null;
                    while (rndVal > 0)
                    {
                        schem   = Schematics[i++];
                        rndVal -= schem.Weight;
                    }
                    BlockSchematicStructure struc = GetGeneratableStructure(schem, blockAccessor, worldForCollectibleResolve, schemPos);

                    if (struc != null)
                    {
                        location.Set(schemPos.X, schemPos.Y, schemPos.Z, schemPos.X + struc.SizeX, schemPos.Y + struc.SizeY, schemPos.Z + struc.SizeZ);
                        bool intersect = false;
                        for (int k = 0; k < generatables.Count; k++)
                        {
                            if (location.IntersectsOrTouches(generatables[k].location))
                            {
                                intersect = true;
                                break;
                            }
                        }

                        if (!intersect)
                        {
                            generatables.Add(new GeneratableStructure()
                            {
                                struc = struc, pos = schemPos.Copy(), location = location.Clone()
                            });
                        }
                        break;
                    }
                }
            }

            if (generatables.Count >= minQuantity)
            {
                foreach (var val in generatables)
                {
                    val.struc.PlaceRespectingBlockLayers(blockAccessor, worldForCollectibleResolve, val.pos, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight, replaceblockids);
                    didGenerateStructure(val.location, val.struc);
                }
            }

            return(true);
        }
Ejemplo n.º 11
0
        internal void CreateForestFloor(IBlockAccessor blockAccessor, TreeGenConfig config, BlockPos pos, LCGRandom rnd, int treesInChunkGenerated)
        {
            int grassLevelOffset = 0;
            // More grass coverage for jungles
            ClimateCondition climate = blockAccessor.GetClimateAt(pos, EnumGetClimateMode.WorldGenValues);

            if (climate.Temperature > 24 && climate.Rainfall > 160)
            {
                grassLevelOffset = 2;
            }

            short[] outline = outlineThreadSafe.Value;
            this.api = blockAccessor;

            float forestness = climate.ForestDensity * climate.ForestDensity * 4 * (climate.Fertility + 0.25f);


            // Only replace soil with forestFloor in certain climate conditions
            if (climate.Fertility <= 0.25 || forestness <= 0.4)
            {
                return;
            }

            // Otherwise adjust the strength of the effect according to forest density and fertility (fertility is higher for tropical forests)
            for (int i = 0; i < outline.Length; i++)
            {
                outline[i] = (short)(outline[i] * forestness + 0.3f);
            }

            // Blend the canopy outline outwards from the center in a way that ensures smoothness
            for (int pass = 0; pass < 7; pass++)
            {
                bool noChange = true;

                for (int x = 0; x < 16; x++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        if (x == 0 && z == 0)
                        {
                            continue;
                        }
                        int o = Math.Min((int)outline[(16 + z) * 33 + (16 + x)], 18 * 9);
                        if (o == 0)
                        {
                            continue;
                        }

                        int n1 = (17 + z) * 33 + (16 + x);
                        int n2 = (16 + z) * 33 + (17 + x);
                        if (outline[n1] < o - 18)
                        {
                            outline[n1] = (short)(o - 18);
                            noChange    = false;
                        }
                        if (outline[n2] < o - 18)
                        {
                            outline[n2] = (short)(o - 18);
                            noChange    = false;
                        }

                        o  = Math.Min((int)outline[(16 - z) * 33 + (16 + x)], 18 * 9);
                        n1 = (15 - z) * 33 + (16 + x);
                        n2 = (16 - z) * 33 + (17 + x);
                        if (outline[n1] < o - 18)
                        {
                            outline[n1] = (short)(o - 18);
                            noChange    = false;
                        }
                        if (outline[n2] < o - 18)
                        {
                            outline[n2] = (short)(o - 18);
                            noChange    = false;
                        }
                    }

                    for (int z = 0; z < 16; z++)
                    {
                        if (x == 0 && z == 0)
                        {
                            continue;
                        }
                        int o  = Math.Min((int)outline[(16 + z) * 33 + (16 - x)], 18 * 9);
                        int n1 = (17 + z) * 33 + (16 - x);
                        int n2 = (16 + z) * 33 + (15 - x);
                        if (outline[n1] < o - 18)
                        {
                            outline[n1] = (short)(o - 18);
                            noChange    = false;
                        }
                        if (outline[n2] < o - 18)
                        {
                            outline[n2] = (short)(o - 18);
                            noChange    = false;
                        }

                        o  = Math.Min((int)outline[(16 - z) * 33 + (16 - x)], 18 * 9);
                        n1 = (15 - z) * 33 + (16 - x);
                        n2 = (16 - z) * 33 + (15 - x);
                        if (outline[n1] < o - 18)
                        {
                            outline[n1] = (short)(o - 18);
                            noChange    = false;
                        }
                        if (outline[n2] < o - 18)
                        {
                            outline[n2] = (short)(o - 18);
                            noChange    = false;
                        }
                    }
                }
                if (noChange)
                {
                    break;
                }
            }


            BlockPos currentPos = new BlockPos();

            for (int canopyIndex = 0; canopyIndex < outline.Length; canopyIndex++)
            {
                int intensity = outline[canopyIndex];
                if (intensity == 0)
                {
                    continue;
                }

                int dz = canopyIndex / 33 - 16;
                int dx = canopyIndex % 33 - 16;
                currentPos.Set(pos.X + dx, pos.Y, pos.Z + dz);
                currentPos.Y = blockAccessor.GetTerrainMapheightAt(currentPos);

                if (currentPos.Y - pos.Y < 4)  //Don't place forest floor above approximate height of the canopy of this tree
                {
                    CheckAndReplaceForestFloor(currentPos, intensity, grassLevelOffset);
                }
            }

            GenPatches(blockAccessor, pos, forestness, config.Treetype, rnd);
        }
Ejemplo n.º 12
0
        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);
                    }
                }
            }
        }
Ejemplo n.º 13
0
        internal bool TryGenerateAtSurface(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos pos)
        {
            int chunksize = blockAccessor.ChunkSize;
            int climate   = GameMath.BiLerpRgbColor((float)(pos.X % chunksize) / chunksize, (float)(pos.Z % chunksize) / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);


            int num    = rand.Next(schematicDatas.Length);
            int orient = rand.Next(4);
            BlockSchematicStructure schematic = schematicDatas[num][orient];


            int widthHalf  = (int)Math.Ceiling(schematic.SizeX / 2f);
            int lengthHalf = (int)Math.Ceiling(schematic.SizeZ / 2f);

            // Ensure not submerged in water

            tmpPos.Set(pos.X - widthHalf, pos.Y + OffsetY, pos.Z - lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X + widthHalf, pos.Y + OffsetY, pos.Z - lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X - widthHalf, pos.Y + OffsetY, pos.Z + lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }

            tmpPos.Set(pos.X + widthHalf, pos.Y + OffsetY, pos.Z + lengthHalf);
            if (blockAccessor.GetBlock(tmpPos).IsLiquid())
            {
                return(false);
            }



            // Probe all 4 corners + center if they either touch the surface or are sightly below ground

            int centerDiff = blockAccessor.GetTerrainMapheightAt(pos) - pos.Y;


            tmpPos.Set(pos.X - widthHalf, 0, pos.Z - lengthHalf);
            int topLeftDiff = blockAccessor.GetTerrainMapheightAt(tmpPos) - pos.Y;

            tmpPos.Set(pos.X + widthHalf, 0, pos.Z - lengthHalf);
            int topRightDiff = blockAccessor.GetTerrainMapheightAt(tmpPos) - pos.Y;

            tmpPos.Set(pos.X - widthHalf, 0, pos.Z + lengthHalf);
            int botLeftDiff = blockAccessor.GetTerrainMapheightAt(tmpPos) - pos.Y;

            tmpPos.Set(pos.X + widthHalf, 0, pos.Z + lengthHalf);
            int botRightDiff = blockAccessor.GetTerrainMapheightAt(tmpPos) - pos.Y;

            bool ok =
                centerDiff >= -3 && centerDiff <= 1 &&
                topLeftDiff >= -3 && topLeftDiff <= 1 &&
                topRightDiff >= -3 && topRightDiff <= 1 &&
                botLeftDiff >= -3 && botLeftDiff <= 1 &&
                botRightDiff >= -3 && botRightDiff <= 1
            ;


            if (ok)
            {
                schematic.PlaceRespectingBlockLayers(blockAccessor, worldForCollectibleResolve, pos, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight, replaceblockids);
            }

            return(ok);
        }