Example #1
0
    public BuildingSubworldBuilder(Building building, BuildingVoxels vox, BuildingGenerationPlan plan)
    {
        Building = building;
        BuildVox = vox;
        Plan     = plan;
        Size     = new Vec2i(building.Width, building.Height);
        int cWidth  = Mathf.CeilToInt(((float)Size.x) / World.ChunkSize);
        int cHeight = Mathf.CeilToInt(((float)Size.z) / World.ChunkSize);

        if (cWidth < 1)
        {
            cWidth = 1;
        }
        if (cHeight < 1)
        {
            cHeight = 1;
        }
        ChunkSize = new Vec2i(cWidth, cHeight);

        Tiles   = new int[cWidth, cHeight][, ];
        Voxels  = new ChunkVoxelData[cWidth, cHeight];
        Objects = new List <WorldObjectData> [cWidth, cHeight];
        for (int x = 0; x < cWidth; x++)
        {
            for (int z = 0; z < cHeight; z++)
            {
                Tiles[x, z]  = new int[World.ChunkSize, World.ChunkSize];
                Voxels[x, z] = new ChunkVoxelData();
            }
        }
    }
Example #2
0
    /// <summary>
    /// Attempts to place generate a building based on <paramref name="bp"/> in the plot specified
    /// </summary>
    /// <param name="bp"></param>
    /// <param name="plot"></param>
    private bool GenBuildingInPlot(BuildingPlan bp, Plot plot)
    {
        Vec2i entrance = GenerationRandom.RandomFromArray(plot.EntranceSides);
        BuildingGenerationPlan bpPlan = new BuildingGenerationPlan()
        {
            BuildingPlan = bp,
            EntranceSide = entrance,
            MaxHeight    = plot.Bounds.Height,
            MaxWidth     = plot.Bounds.Width
        };

        if (bp.MinSize > plot.Bounds.Width || bp.MinSize > plot.Bounds.Height)
        {
            return(false);
        }



        Building b = BuildingGenerator.CreateBuilding(GenerationRandom, out BuildingVoxels vox, bpPlan);

        Vec2i pos = new Vec2i(plot.Bounds.X, plot.Bounds.Y);

        if (entrance.x == -1)
        {
            pos = new Vec2i(plot.Bounds.X, plot.Bounds.Y + GenerationRandom.RandomIntFromSet(0, plot.Bounds.Height - b.Height));
        }
        else if (entrance.x == 1)
        {
            pos = new Vec2i(plot.Bounds.X + (plot.Bounds.Width - b.Width), plot.Bounds.Y + GenerationRandom.RandomIntFromSet(0, plot.Bounds.Height - b.Height));
        }
        else if (entrance.z == -1)
        {
            pos = new Vec2i(plot.Bounds.X + GenerationRandom.RandomIntFromSet(0, plot.Bounds.Width - b.Width), plot.Bounds.Y);
        }
        else if (entrance.z == 1)
        {
            pos = new Vec2i(plot.Bounds.X + GenerationRandom.RandomIntFromSet(0, plot.Bounds.Width - b.Width), plot.Bounds.Y + (plot.Bounds.Height - b.Height));
        }
        Recti r = AddBuilding(b, vox, pos);

        if (r != null)
        {
            BuildingPlots.Add(r);
            return(true);
        }
        return(false);
    }
Example #3
0
    public static Farm GenerateVegFarm(GenerationRandom genRan, Farm farm, out BuildingVoxels vox, BuildingGenerationPlan plan)
    {
        vox = new BuildingVoxels(farm.Width, World.ChunkHeight, farm.Height);

        Tile[,] tiles = new Tile[farm.Width, farm.Height];
        BuildingGenerator.SetTiles(tiles, 0, 0, farm.Width - 1, farm.Height - 1, Tile.TEST_MAGENTA);

        farm.SetBuilding(tiles);
        BuildingGenerator.BuildBoundingWallRect(vox, farm.Width, farm.Height, 2, Voxel.stone);

        BuildingGenerator.ChooseEntrancePoint(genRan, vox, farm, plan, false);


        return(farm);
    }
Example #4
0
    public static void ChooseEntrancePoint(GenerationRandom genRan, BuildingVoxels vox, Building build, BuildingGenerationPlan plan, bool requiredSubworld = true)
    {
        Vec2i entranceSide = plan.EntranceSide;

        Vec2i mid  = new Vec2i(build.Width / 2, build.Height / 2);
        Vec2i entr = null;

        //Travel out iterativly till we reach the wall
        for (int r = 0; r < Mathf.Max(build.Width, build.Height); r++)
        {
            Vec2i v = mid + entranceSide * r;
            if (v.x < 0 || v.z < 0 || v.x >= build.Width || v.z >= build.Height)
            {
                break;
            }
            if (vox.GetVoxel(v.x, 1, v.z) != Voxel.none)
            {
                entr = v;
                break;
            }
        }

        if (entr == null)
        {
            entr = new Vec2i(2, 2);
        }
        build.SetEntrancePoint(entr);
        for (int y = 0; y < 4; y++)
        {
            vox.ClearVoxel(entr.x, y, entr.z);
        }
        if (requiredSubworld)
        {
            Door interior = new Door();
            interior.SetRotation(Vector2.Angle(Vector2.up, entranceSide));
            interior.SetPosition(entr);
            build.InternalEntranceObject = interior;
            AddObject(build, vox, interior, true);

            Door external = new Door();
            external.SetPosition(entr);
            external.SetRotation(Vector2.Angle(Vector2.up, entranceSide));

            build.ExternalEntranceObject = external;
            build.AddExternalObject(external);
        }
    }
Example #5
0
    public static Building CreateBuilding(GenerationRandom genRan, out BuildingVoxels vox, BuildingGenerationPlan plan)
    {
        Vec2i zero      = new Vec2i(0, 0);
        int   maxWidth  = (plan.DesiredSize == null || plan.DesiredSize == zero) ?Mathf.Min(plan.BuildingPlan.MaxSize, plan.MaxWidth): plan.DesiredSize.x;
        int   maxHeight = (plan.DesiredSize == null || plan.DesiredSize == zero)? Mathf.Min(plan.BuildingPlan.MaxSize, plan.MaxHeight) : plan.DesiredSize.z;
        int   width     = genRan.RandomInt(plan.BuildingPlan.MinSize, maxWidth);
        int   height    = genRan.RandomInt(plan.BuildingPlan.MinSize, maxHeight);

        if (plan.BuildingPlan == Building.BLACKSMITH)
        {
            Blacksmith smith = BlacksmithGenerator.GenerateBlacksmith(genRan, new Blacksmith(width, height), out vox, plan);
            return(smith);
        }
        if (plan.BuildingPlan == Building.BARACKS)
        {
            Barracks barr = BarracksGenerator.GenerateBarracks(genRan, new Barracks(width, height), out vox, plan);
            return(barr);
        }
        if (plan.BuildingPlan == Building.TAVERN)
        {
            return(TavernGenerator.GenerateTavern(genRan, new Tavern(width, height), out vox, plan));
        }
        if (plan.BuildingPlan == Building.VEGFARM)
        {
            Farm farm = FarmGenerator.GenerateVegFarm(genRan, new Farm(width, height), out vox, plan);
            return(farm);
        }
        if (plan.BuildingPlan == Building.WHEATFARM)
        {
            Farm farm = FarmGenerator.GenerateWheatFarm(genRan, new Farm(width, height), out vox, plan);
            return(farm);
        }

        House house = HouseGenerator.GenerateHouse(genRan, new House(width, height), out vox, plan);

        return(house);
        //return GenerateHouse(out vox, width, height);
    }
    public static Blacksmith GenerateBlacksmith(GenerationRandom genRan, Blacksmith smith, out BuildingVoxels vox, BuildingGenerationPlan plan)
    {
        vox = new BuildingVoxels(smith.Width, World.ChunkHeight, smith.Height);
        ChooseWallBounds(genRan, smith);
        BuildingGenerator.ConnectBoundingWall(vox, smith.BoundingWall, Voxel.stone);
        Tile[,] tileMap = new Tile[smith.Width, smith.Height];
        //Make the whole floor stone
        BuildingGenerator.SetTiles(tileMap, 0, 0, smith.Width - 1, smith.Height - 1, Tile.STONE_FLOOR);

        Vec2i outSideMin = null;
        Vec2i outSideMax = null;

        //Find the outdoor part and make the floor dirt
        for (int i = 0; i < smith.BoundingWall.Length; i++)
        {
            Vec2i p = smith.BoundingWall[i];
            //If this boundry point does not lie on any of the edges, then it is indented into the
            //building. This means this point defines the outside region of the building.
            if ((p.x != 0 && p.x != smith.Width - 1) && (p.z != 0 && p.z != smith.Height - 1))
            {
                //We get the 2 neigboring wall points, as these define the outside region
                Vec2i nm1 = smith.BoundingWall[(i - 1 + smith.BoundingWall.Length) % smith.BoundingWall.Length];
                Vec2i np1 = smith.BoundingWall[(i + 1) % smith.BoundingWall.Length];

                int minX = Mathf.Min(p.x, nm1.x, np1.x);
                int minZ = Mathf.Min(p.z, nm1.z, np1.z);
                int maxX = Mathf.Max(p.x, nm1.x, np1.x);
                int maxZ = Mathf.Max(p.z, nm1.z, np1.z);
                BuildingGenerator.SetTiles(tileMap, minX, minZ, maxX - minX, maxZ - minZ, Tile.DIRT);
                outSideMin = new Vec2i(minX, minZ);
                outSideMax = new Vec2i(maxX, maxZ);
                break;
            }
        }
        smith.SetBuilding(tileMap);
        PlaceOutsideObjects(genRan, smith, vox, outSideMin, outSideMax);



        BuildingGenerator.ChooseEntrancePoint(genRan, vox, smith, plan);
        BuildingGenerator.AddWindow(genRan, vox, smith);
        BuildingGenerator.AddWindow(genRan, vox, smith);
        BuildingGenerator.AddWindow(genRan, vox, smith, autoReattempt: false);
        BuildingGenerator.AddWindow(genRan, vox, smith, autoReattempt: false);

        BuildingGenerator.PlaceObjectAgainstWall(genRan, new Chest(), 0, vox, smith, .1f, attemptsCount: 20, distToEntr: 4);
        BuildingGenerator.PlaceObjectAgainstWall(genRan, new WeaponStand(), 0, vox, smith, 0.1f, distToEntr: 4);
        BuildingGenerator.PlaceObjectAgainstWall(genRan, new ArmourStand(), 0, vox, smith, .1f, distToEntr: 4);

        WorkBuildingData wbd = new WorkBuildingData(new NPCJob[] { new NPCJobMerchant(smith), new NPCJobBlackSmith(smith), new NPCJobBlackSmith(smith) });

        smith.SetWorkBuildingData(wbd);

        for (int i = 0; i < 10; i++)
        {
            smith.Inventory.AddItem(new Shirt(new ItemMetaData().SetColor(Color.blue)));
        }

        return(smith);
    }
Example #7
0
    public static Barracks GenerateBarracks(GenerationRandom genRan, Barracks barr, out BuildingVoxels vox, BuildingGenerationPlan plan)
    {
        vox = new BuildingVoxels(barr.Width, World.ChunkHeight, barr.Height);
        ChooseWallBounds(genRan, barr);
        BuildingGenerator.ConnectBoundingWall(vox, barr.BoundingWall, Voxel.stone);
        Tile[,] tileMap = new Tile[barr.Width, barr.Height];
        BuildingGenerator.ChooseEntrancePoint(genRan, vox, barr, plan);
        BuildingGenerator.SetTiles(tileMap, 0, 0, barr.Width / 2, barr.Height - 1, Tile.STONE_FLOOR);
        BuildingGenerator.SetTiles(tileMap, barr.Width / 2, 0, barr.Width / 2 - 1, barr.Height - 1, Tile.DIRT);

        List <NPCJob> jobs = new List <NPCJob>();

        for (int x = 2; x < barr.Height; x += 3)
        {
            Vector3       pos      = new Vector3(barr.Width - 2, 0, x);
            float         rotation = Vec2i.Angle(Vec2i.Forward, BuildingGenerator.GetWallPointDirection(barr, new Vec2i(barr.Width - 2, x)));
            TrainingDummy obj      = new TrainingDummy().SetPosition(pos).SetRotation(rotation) as TrainingDummy;
            if (BuildingGenerator.AddObject(barr, vox, obj))
            {
                jobs.Add(new NPCJobSoldier(barr));
            }
        }



        WorkBuildingData wbd = new WorkBuildingData(jobs.ToArray());

        barr.SetWorkBuildingData(wbd);
        barr.SetBuilding(tileMap);

        return(barr);
    }
Example #8
0
    /// <summary>
    /// Attempts to place multiple buildings inside this plot
    /// Works in order. i.e, if we can fit the first, we try to fit the second
    /// If we can't fit the second, we do no further checks
    /// If we can, we check the third..  and so on
    /// We return the number of buildings succesfully placed
    /// </summary>
    /// <param name="bps"></param>
    /// <param name="startIndex">The index of the first building to place</param>
    /// <param name="plot"></param>
    /// <returns>The number of buildings placed in this plot, between 0 and 4 (incusive)</returns>
    private int GenMultipleBuildingsInPlot(List <BuildingPlan> bps, int startIndex, Plot plot)
    {
        //Represents 4 points for 4 corners of plot
        bool[,] isCornerPossible = new bool[2, 2];
        bool[] sideHasPath = new bool[4];
        //Iterate all entrances
        foreach (Vec2i v in plot.EntranceSides)
        {
            if (v.x == -1)
            {
                sideHasPath[0]         = true;
                isCornerPossible[0, 0] = true;
                isCornerPossible[0, 1] = true;
            }
            else if (v.x == 1)
            {
                sideHasPath[1]         = true;
                isCornerPossible[1, 0] = true;
                isCornerPossible[1, 1] = true;
            }
            if (v.z == -1)
            {
                sideHasPath[2]         = true;
                isCornerPossible[0, 0] = true;
                isCornerPossible[1, 0] = true;
            }
            else if (v.z == 1)
            {
                sideHasPath[3]         = true;
                isCornerPossible[0, 1] = true;
                isCornerPossible[1, 1] = true;
            }
        }
        //Buildings sorted by the corner they have been placed in


        Recti[,] bounds = new Recti[2, 2];
        int j = 0;

        for (int x = 0; x < 2; x++)
        {
            for (int z = 0; z < 2; z++)
            {
                //Index of adjacect x, and adjacent z
                int adjX = (x + 1) % 2;
                int adjZ = (x + 1) % 2;

                Recti adjacentX       = bounds[adjX, z];
                int   adjacentXWidth  = adjacentX == null ? 0 : adjacentX.Width;
                Recti adjacentZ       = bounds[x, adjZ];
                int   adjacentZHeight = adjacentZ == null ? 0 : adjacentZ.Height;

                //check this corner is free
                if (isCornerPossible[x, z])
                {
                    if (startIndex + j >= bps.Count)
                    {
                        return(j);
                    }

                    BuildingPlan plan = bps[startIndex + j];


                    int maxWidth  = plot.Bounds.Width - adjacentXWidth;
                    int maxHeight = plot.Bounds.Height - adjacentZHeight;

                    //If it won't fit, we continue
                    if (maxWidth < plan.MinSize || maxHeight < plan.MinSize)
                    {
                        continue;
                    }

                    int desWidth  = GenerationRandom.RandomInt(plan.MinSize, Mathf.Min(plan.MaxSize, maxWidth));
                    int desHeight = GenerationRandom.RandomInt(plan.MinSize, Mathf.Min(plan.MaxSize, maxHeight));

                    List <Vec2i> posSides     = new List <Vec2i>();
                    Vec2i        entranceSide = null;
                    Vec2i        pos          = null;
                    //We calculate the entrance side and position of each building
                    if (x == 0 && z == 0)
                    {
                        if (sideHasPath[2])
                        {
                            posSides.Add(new Vec2i(0, -1));
                        }
                        if (sideHasPath[0])
                        {
                            posSides.Add(new Vec2i(-1, 0));
                        }
                        if (posSides.Count == 0)
                        {
                            continue;
                        }
                        entranceSide = GenerationRandom.RandomFromList(posSides);

                        pos = new Vec2i(plot.Bounds.X, plot.Bounds.Y);
                    }
                    else if (x == 0 && z == 1)
                    {
                        if (sideHasPath[3])
                        {
                            posSides.Add(new Vec2i(0, 1));
                        }
                        if (sideHasPath[0])
                        {
                            posSides.Add(new Vec2i(-1, 0));
                        }
                        if (posSides.Count == 0)
                        {
                            continue;
                        }
                        entranceSide = GenerationRandom.RandomFromList(posSides);
                        pos          = new Vec2i(plot.Bounds.X + 2, plot.Bounds.Y + plot.Bounds.Height - desHeight);
                    }
                    else if (x == 1 && z == 1)
                    {
                        if (sideHasPath[3])
                        {
                            posSides.Add(new Vec2i(0, 1));
                        }
                        if (sideHasPath[1])
                        {
                            posSides.Add(new Vec2i(1, 0));
                        }
                        if (posSides.Count == 0)
                        {
                            continue;
                        }
                        entranceSide = GenerationRandom.RandomFromList(posSides);
                        pos          = new Vec2i(plot.Bounds.X + plot.Bounds.Width - desWidth, plot.Bounds.Y + plot.Bounds.Height - desHeight);
                    }
                    else if (x == 1 && z == 0)
                    {
                        if (sideHasPath[2])
                        {
                            posSides.Add(new Vec2i(0, -1));
                        }
                        if (sideHasPath[1])
                        {
                            posSides.Add(new Vec2i(1, 0));
                        }
                        if (posSides.Count == 0)
                        {
                            continue;
                        }
                        entranceSide = GenerationRandom.RandomFromList(posSides);
                        pos          = new Vec2i(plot.Bounds.X + plot.Bounds.Width - desWidth, plot.Bounds.Y);
                    }

                    Recti curBound  = new Recti(pos.x, pos.z, desWidth, desHeight);
                    bool  intersect = false;
                    foreach (Recti ri in bounds)
                    {
                        if (ri != null)
                        {
                            if (ri.Intersects(curBound))
                            {
                                intersect = true;
                            }
                        }
                    }
                    if (intersect)
                    {
                        continue;
                    }
                    bounds[x, z] = curBound;

                    BuildingGenerationPlan curCorn = new BuildingGenerationPlan()
                    {
                        BuildingPlan = bps[startIndex + j],
                        MaxWidth     = maxWidth,
                        MaxHeight    = maxHeight,
                        EntranceSide = entranceSide,
                        DesiredSize  = new Vec2i(desWidth, desHeight)
                    };

                    Building build = BuildingGenerator.CreateBuilding(GenerationRandom, out BuildingVoxels vox, curCorn);
                    Recti    r     = AddBuilding(build, vox, pos);
                    if (r != null)
                    {
                        BuildingPlots.Add(r);
                        j++;
                    }
                }
            }
        }
        return(j);
    }
Example #9
0
 public static House GenerateHouse(GenerationRandom genRan, House house, out BuildingVoxels vox, BuildingGenerationPlan plan)
 {
     return(GenerateShack(genRan, house, out vox, plan));
 }
Example #10
0
    /// <summary>
    /// Generates the simplest type of house - a shack
    /// A shack is made of either (cobble?) stone or wood,
    /// it consists of only 1 room, with basic objects inside (bed, chair, table)
    /// </summary>
    /// <param name="house"></param>
    /// <param name="vox"></param>
    /// <returns></returns>
    public static House GenerateShack(GenerationRandom genRan, House house, out BuildingVoxels vox, BuildingGenerationPlan plan)
    {
        vox           = new BuildingVoxels(house.Width, World.ChunkHeight, house.Height);
        Tile[,] floor = new Tile[house.Width, house.Height];

        BuildingGenerator.BuildBoundingWallRect(vox, house.Width, house.Height, 6, Voxel.wood);
        //BuildingGenerator.ConnectBoundingWall(vox, house.BoundingWall, Voxel.wood, 5);
        BuildingGenerator.SetTiles(floor, 0, 0, house.Width - 1, house.Height - 1, Tile.STONE_FLOOR);
        house.SetBuilding(floor);

        BuildingGenerator.ChooseEntrancePoint(genRan, vox, house, plan);
        BuildingGenerator.AddWindow(genRan, vox, house, size: genRan.RandomInt(1, 4), autoReattempt: true);
        BuildingGenerator.AddWindow(genRan, vox, house, size: genRan.RandomInt(1, 4), autoReattempt: true);
        BuildingGenerator.AddWindow(genRan, vox, house, size: genRan.RandomInt(1, 4), autoReattempt: false);
        BuildingGenerator.AddWindow(genRan, vox, house, size: genRan.RandomInt(1, 4), autoReattempt: false);
        BuildingGenerator.AddWindow(genRan, vox, house, size: genRan.RandomInt(1, 4), autoReattempt: false);
        house.InsideWallPoints = BuildingGenerator.FindInsideWallBoundryPoints(vox, house);

        /*foreach (Vec2i v in house.InsideWallPoints)
         * {
         *  //house.AddObjectReference(new Chest().SetPosition(v));
         *  WorldObjectData bed = new Bed().SetPosition(v);
         *  bed.SetRotation(Vec2i.Angle(Vec2i.Forward, BuildingGenerator.GetWallPointDirection(house, v)));
         *  if(!house.ObjectIntersects(bed))
         *      house.AddObjectReference(bed);
         * }*/

        BuildingGenerator.PlaceObjectAgainstWall(genRan, new DoubleBed(), 0, vox, house, .3f, distToEntr: 4, attemptsCount: 40);
        BuildingGenerator.PlaceObjectAgainstWall(genRan, new Chest(), 0, vox, house, 0.1f, distToEntr: 3, attemptsCount: 40);

        for (int i = 0; i < house.BoundingWall.Length; i++)
        {
            BuildingGenerator.PlaceObjectAgainstWall(genRan, new WallTorch(), 1.5f, vox, house, 0f, requireWallBacking: true);
        }
        house.AddExternalObject(new BuildingInternalNoWalkFloor(new Vector3(1, 0, 1), new Vector3(house.Width - 2, 5, house.Height - 2)));
        BuildingGenerator.AddRoof(genRan, vox, house, Voxel.thatch);

        BuildingSubworldBuilder b = new BuildingSubworldBuilder(house, vox, plan);

        b.CreateSubworld();
        //ChunkData[,] subChunks = new ChunkData[1, 1];


        return(house);
    }
    public static Tavern GenerateTavern(GenerationRandom genRan, Tavern tavern, out BuildingVoxels vox, BuildingGenerationPlan plan)
    {
        vox = new BuildingVoxels(tavern.Width, World.ChunkHeight, tavern.Height);
        BuildingGenerator.BuildBoundingWallRect(vox, tavern.Width, tavern.Height, 6, Voxel.wood);
        BuildingGenerator.ChooseEntrancePoint(genRan, vox, tavern, plan);

        Tile[,] tileMap = new Tile[tavern.Width, tavern.Height];

        BuildingGenerator.SetTiles(tileMap, 0, 0, tavern.Width, tavern.Height, Tile.WOOD_FLOOR);
        tavern.SetBuilding(tileMap);
        BuildingGenerator.AddWindow(genRan, vox, tavern, autoReattempt: true);
        BuildingGenerator.AddWindow(genRan, vox, tavern, autoReattempt: true);
        BuildingGenerator.AddWindow(genRan, vox, tavern, autoReattempt: true);
        BuildingGenerator.AddWindow(genRan, vox, tavern, autoReattempt: false);
        BuildingGenerator.AddWindow(genRan, vox, tavern, autoReattempt: false);
        FirePlace fp = new FirePlace();

        BuildingGenerator.PlaceObjectAgainstWall(genRan, fp, 0, vox, tavern, 0, true, 4, true, 20);
        BuildingGenerator.PlaceObjectAgainstWall(genRan, new WallTorch(), 1.5f, vox, tavern, 0, true, 2);
        NPCJob[] jobs = new NPCJob[] { new NPCJobMerchant(tavern, "Tavern Keep"), new NPCJobMerchant(tavern, "Tavern Keep") };
        tavern.SetWorkBuildingData(new WorkBuildingData(jobs));
        BuildingGenerator.AddRoof(genRan, vox, tavern, Voxel.thatch);
        return(tavern);
    }