Ejemplo n.º 1
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.º 2
0
        public void Init(ICoreServerAPI api, BlockLayerConfig config, LCGRandom rand)
        {
            this.rand   = rand;
            totalWeight = 0;

            for (int i = 0; i < Schematics.Length; i++)
            {
                List <BlockSchematicStructure> schematics = new List <BlockSchematicStructure>();

                string   error = "";
                IAsset[] assets;

                VillageSchematic schem = Schematics[i];

                totalWeight += schem.Weight;

                if (schem.Path.EndsWith("*"))
                {
                    assets = api.Assets.GetMany("worldgen/schematics/" + schem.Path.Substring(0, schem.Path.Length - 1)).ToArray();
                }
                else
                {
                    assets = new IAsset[] { api.Assets.Get("worldgen/schematics/" + Schematics[i].Path + ".json") };
                }

                for (int j = 0; j < assets.Length; j++)
                {
                    IAsset asset = assets[j];

                    BlockSchematicStructure schematic = asset.ToObject <BlockSchematicStructure>();

                    if (schematic == null)
                    {
                        api.World.Logger.Warning("Could not load {0}: {1}", Schematics[i], error);
                        continue;
                    }


                    schematic.FromFileName = asset.Name;

                    BlockSchematicStructure[] rotations = new BlockSchematicStructure[4];
                    rotations[0] = schematic;

                    for (int k = 0; k < 4; k++)
                    {
                        if (k > 0)
                        {
                            rotations[k] = rotations[0].Clone();
                            rotations[k].TransformWhilePacked(api.World, EnumOrigin.BottomCenter, k * 90);
                        }
                        rotations[k].blockLayerConfig = config;
                        rotations[k].Init(api.World.BlockAccessor);
                        rotations[k].LoadMetaInformationAndValidate(api.World.BlockAccessor, api.World, schematic.FromFileName);
                    }

                    schematics.AddRange(rotations);
                }

                schem.Structures = schematics.ToArray();
            }


            if (ReplaceWithBlocklayers != null)
            {
                replaceblockids = new int[ReplaceWithBlocklayers.Length];
                for (int i = 0; i < replaceblockids.Length; i++)
                {
                    Block block = api.World.GetBlock(ReplaceWithBlocklayers[i]);
                    if (block == null)
                    {
                        throw new Exception(string.Format("Schematic with code {0} has replace block layer {1} defined, but no such block found!", Code, ReplaceWithBlocklayers[i]));
                    }
                    else
                    {
                        replaceblockids[i] = (ushort)block.Id;
                    }
                }
            }
        }
Ejemplo n.º 3
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);
        }