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.º 2
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);
        }