예제 #1
0
    protected List <Bounding> SingleFind()
    {
        List <Value2D <T> > list = new List <Value2D <T> >();
        DrawAction <T>      action;

        if (_tester.StrokeAction != null)
        {
            action = _tester.StrokeAction.IfThen(Draw.AddTo(list));
        }
        else if (_tester.UnitAction != null)
        {
            action = _tester.UnitAction.IfThen(Draw.AddTo(list));
        }
        else
        {
            return(new List <Bounding>(0));
        }
        _arr.DrawRect(_scope, action);
        List <Bounding> ret = new List <Bounding>();

        foreach (var v in list)
        {
            ret.Add(new Bounding(v.x, v.x, v.y, v.y));
        }
        return(ret);
    }
예제 #2
0
    public override HashSet <IAffectable> GetTargets(SpellCastInfo castInfo)
    {
        Container2D <GridSpace> level = BigBoss.Levels.Level.Array;
        var targetSpaces = new HashSet <GridSpace>();

        foreach (GridSpace point in castInfo.TargetSpaces)
        {
            level.DrawCircle(point.X, point.Y, Radius, Draw.AddTo(targetSpaces));
        }
        castInfo.TargetSpaces = targetSpaces.ToArray();
        return(base.GetTargets(castInfo));
    }
예제 #3
0
 protected void ConstructBFS(LayoutObject obj,
                             out Queue <Value2D <GenSpace> > queue,
                             out Container2D <bool> visited)
 {
     visited = new MultiMap <bool>();
     queue   = new Queue <Value2D <GenSpace> >();
     obj.GetConnectedGrid().DrawPerimeter(Draw.Not(Draw.IsType <GenSpace>(GridType.NULL)), new StrokedAction <GenSpace>()
     {
         UnitAction   = Draw.SetTo <GenSpace, bool>(visited, true),
         StrokeAction = Draw.AddTo(queue).And(Draw.SetTo <GenSpace, bool>(visited, true))
     }, false);
 }
예제 #4
0
    protected override bool ModifyInternal(RoomSpec spec)
    {
        int secretRoomSize = 2;

        #region DEBUG
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            BigBoss.Debug.printHeader(Logs.LevelGen, "Hidden Room Mod");
            spec.Grids.ToLog(Logs.LevelGen, "Final Room After placing doors");
        }
        #endregion

        RandomPicker <GenSpace> picker;
        spec.Grids.DrawPotentialExternalDoors(Draw.PickRandom(out picker));

        Value2D <GenSpace> doorSpace;
        if (!picker.Pick(spec.Random, out doorSpace))
        {
            return(false);
        }
        var floors = new List <Value2D <GenSpace> >();
        spec.Grids.DrawRect(
            (doorSpace.x - secretRoomSize), (doorSpace.x + secretRoomSize),
            (doorSpace.y - secretRoomSize), (doorSpace.y + secretRoomSize),
            new StrokedAction <GenSpace>()
        {
            UnitAction   = Draw.IsTypeThen(GridType.NULL, Draw.SetTo(GridType.Floor, spec.Theme).And(Draw.AddTo(floors))),
            StrokeAction = Draw.IsType <GenSpace>(GridType.NULL).IfThen(Draw.SetTo(GridType.Wall, spec.Theme))
        });
        bool chest = spec.Random.Percent(.75d);
        if (chest)
        {
            List <Value2D <GenSpace> > chestOptions = new List <Value2D <GenSpace> >();
            spec.Grids.DrawPoints(floors.Cast <Point>(),
                                  Draw.Not(Draw.HasAround(false, Draw.IsType <GenSpace>(GridType.Door)))
                                  .IfThen(Draw.AddTo(chestOptions)));
            spec.Grids.SetTo(chestOptions.Random(spec.Random), GridType.Chest, spec.Theme);
        }
        else
        {
            spec.Grids.SetTo(floors.Random(spec.Random), GridType.SmallLoot, spec.Theme);
        }
        spec.Grids.SetTo(doorSpace, GridType.Door, spec.Theme);
        #region DEBUG
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            spec.Grids.ToLog(Logs.LevelGen, "Final Room After placing doors");
            BigBoss.Debug.printFooter(Logs.LevelGen, "Hidden Room Mod");
        }
        #endregion
        return(true);
    }
예제 #5
0
    public override bool Modify(SpawnSpec spec)
    {
        MultiMap <GridSpace> spawnable = new MultiMap <GridSpace>();

        spec.Room.DrawAll(Draw.If <GridSpace>((g) => g.Spawnable).IfThen(Draw.AddTo(spawnable)));
        Value2D <GridSpace> space;

        if (!spawnable.GetRandom(spec.Random, out space))
        {
            return(false);
        }
        BigBoss.DungeonMaster.SpawnNPC(space.val, space.val.Theme.Keywords);
        return(true);
    }
예제 #6
0
 protected void PlaceDoors()
 {
     #region DEBUG
     if (BigBoss.Debug.logging(Logs.LevelGen))
     {
         BigBoss.Debug.printHeader(Logs.LevelGen, "Place Doors");
     }
     #endregion
     foreach (LayoutObject room in Objects)
     {
         #region DEBUG
         if (BigBoss.Debug.logging(Logs.LevelGen))
         {
             BigBoss.Debug.printHeader(Logs.LevelGen, "Place Doors on " + room);
         }
         #endregion
         var potentialDoors = new MultiMap <GenSpace>();
         room.Grids.DrawPotentialExternalDoors(Draw.AddTo <GenSpace>(potentialDoors));
         int numDoors = Rand.Next(doorsMin, doorsMax);
         #region DEBUG
         if (BigBoss.Debug.logging(Logs.LevelGen))
         {
             potentialDoors.ToLog(Logs.LevelGen, "Potential Doors");
             BigBoss.Debug.w(Logs.LevelGen, "Number of doors to generate: " + numDoors);
         }
         #endregion
         foreach (Value2D <GenSpace> doorSpace in potentialDoors.GetRandom(Rand, numDoors, minDoorSpacing))
         {
             room.Grids.SetTo(doorSpace, GridType.Door, Theme);
         }
         #region DEBUG
         if (BigBoss.Debug.logging(Logs.LevelGen))
         {
             room.ToLog(Logs.LevelGen, "Room After placing doors");
             BigBoss.Debug.printFooter(Logs.LevelGen, "Place Doors on " + room);
         }
         #endregion
     }
     #region DEBUG
     if (BigBoss.Debug.logging(Logs.LevelGen))
     {
         BigBoss.Debug.printFooter(Logs.LevelGen, "Place Doors");
     }
     #endregion
 }
예제 #7
0
    protected override bool ModifyInternal(RoomSpec spec)
    {
        int size = spec.Random.Next(3, 5);

        BigBoss.Debug.w(Logs.LevelGen, "Size: " + size);
        // Add an extra 2 for stroke width for analysis
        size += 2;
        List <Bounding> locations = spec.Grids.FindRectangles(size, size, false, new StrokedAction <GenSpace>()
        {
            UnitAction   = Draw.Or(Draw.IsType <GenSpace>(GridType.Floor), Draw.IsType <GenSpace>(GridType.Wall)).And(Draw.Empty()),
            StrokeAction = Draw.Walkable()
        },
                                                              spec.Grids.Bounding);

        if (locations.Count == 0)
        {
            return(false);
        }
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen) && BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps))
        {
            BigBoss.Debug.w(Logs.LevelGen, locations.Count + " Options: ");
            var save = new MultiMap <GenSpace>();
            var copy = new Array2D <GenSpace>(spec.Grids);
            foreach (Bounding r in locations)
            {
                save.Clear();
                copy.DrawRect(r.XMin + 1, r.XMax - 1, r.YMin + 1, r.YMax - 1, Draw.AddTo(save).And(Draw.SetTo(GridType.Path_Vert, spec.Theme)));
                copy.ToLog(Logs.LevelGen);
                copy.PutAll(save);
            }
        }
        #endregion
        Bounding l = locations.Random(spec.Random);
        // Draw inner square without stroke (stroke was just used to analyze surroundings)
        spec.Grids.DrawRect(l.XMin + 1, l.XMax - 1, l.YMin + 1, l.YMax - 1, Draw.SetTo(GridType.Wall, spec.Theme));
        return(true);
    }
예제 #8
0
    protected override bool ModifyInternal(RoomSpec spec)
    {
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            BigBoss.Debug.printHeader(Logs.LevelGen, "Splitter Mod");
        }
        #endregion
        Bounding   bounds     = spec.Grids.Bounding;
        List <int> options    = new List <int>();
        bool       horizontal = spec.Random.NextBool();
        int        from       = bounds.GetMin(horizontal);
        int        to         = bounds.GetMax(horizontal);
        int        fromAlt    = bounds.GetMin(!horizontal);
        int        toAlt      = bounds.GetMax(!horizontal);

        // Iterate and find all viable options
        for (int i = fromAlt; i <= toAlt; i++)
        {
            Counter floorCount;
            Counter side1;
            Counter side2;
            if (spec.Grids.DrawLine(from, to, i, horizontal,
                                    // If no doors around
                                    Draw.Not(Draw.Around(false, Draw.IsType <GenSpace>(GridType.Door)))
                                    // Not blocking walking
                                    .And(Draw.Not(Draw.Blocking <GenSpace>(Draw.Walkable())))
                                    // Count floors on line as well as sides
                                    .And(Draw.IsType <GenSpace>(GridType.Floor).IfThen(Draw.Count <GenSpace>(out floorCount)))
                                    .And(Draw.Loc(horizontal ? GridLocation.TOP : GridLocation.LEFT,
                                                  Draw.IsTypeThen(GridType.Floor, Draw.Count <GenSpace>(out side1))))
                                    .And(Draw.Loc(horizontal ? GridLocation.BOTTOM : GridLocation.RIGHT,
                                                  Draw.IsTypeThen(GridType.Floor, Draw.Count <GenSpace>(out side2)))))
                // Has a floor in each
                && floorCount > 0 && side1 > 0 && side2 > 0
                )
            {
                options.Add(i);
            }
        }
        if (options.Count == 0)
        {
            return(false);
        }
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen) && BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps))
        {
            foreach (int i in options)
            {
                Container2D <GenSpace> copy = new Array2D <GenSpace>(spec.Grids);
                copy.DrawLine(from, to, i, horizontal, Draw.IsType <GenSpace>(GridType.NULL).IfNotThen(Draw.SetTo(GridType.INTERNAL_RESERVED_BLOCKED, spec.Theme)));
                copy.ToLog(Logs.LevelGen);
            }
        }
        #endregion

        // Draw selected splitter
        int          picked = options.Random(spec.Random);
        List <Point> walls  = new List <Point>();
        spec.Grids.DrawLine(from, to, picked, horizontal, Draw.Not(Draw.IsType <GenSpace>(GridType.NULL)).IfThen(Draw.SetTo(GridType.Wall, spec.Theme).And(Draw.AddTo <GenSpace>(walls))));
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            BigBoss.Debug.w(Logs.LevelGen, "Picked splitter:");
            spec.Grids.ToLog(Logs.LevelGen);
        }
        #endregion

        spec.Grids.PlaceSomeDoors(walls, spec.Theme, spec.Random, 5);
        #region DEBUG
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            BigBoss.Debug.printFooter(Logs.LevelGen, "Splitter Mod");
        }
        #endregion
        return(true);
    }
예제 #9
0
    public static List <Value2D <GenSpace> > PlaceSomeDoors(this Container2D <GenSpace> arr, IEnumerable <Point> points, Theme theme, System.Random rand, int desiredWallToDoorRatio = -1, Point shift = null)
    {
        if (desiredWallToDoorRatio < 0)
        {
            desiredWallToDoorRatio = LevelGenerator.desiredWallToDoorRatio;
        }
        var     acceptablePoints   = new MultiMap <GenSpace>();
        Counter numPoints          = new Counter();
        DrawAction <GenSpace> call = Draw.Count <GenSpace>(numPoints).And(Draw.CanDrawDoor().IfThen(Draw.AddTo(acceptablePoints)));

        if (shift != null)
        {
            call = call.Shift <GenSpace>(shift.x, shift.y);
        }
        arr.DrawPoints(points, call);
        if (DoorRatioPicker == null)
        {
            DoorRatioPicker = new ProbabilityList <int>();
            DoorRatioPicker.Add(-2, .25);
            DoorRatioPicker.Add(-1, .5);
            DoorRatioPicker.Add(0, 1);
            DoorRatioPicker.Add(1, .5);
            DoorRatioPicker.Add(2, .25);
        }
        int numDoors = numPoints / desiredWallToDoorRatio;

        numDoors += DoorRatioPicker.Get(rand);
        if (numDoors <= 0)
        {
            numDoors = 1;
        }
        List <Value2D <GenSpace> > pickedPts = acceptablePoints.GetRandom(rand, numDoors, 1);

        foreach (Point picked in pickedPts)
        {
            arr.SetTo(picked, GridType.Door, theme);
        }
        return(pickedPts);
    }
예제 #10
0
    protected void ConfirmConnection()
    {
        #region DEBUG
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            BigBoss.Debug.printHeader(Logs.LevelGen, "Confirm Connections");
        }
        #endregion
        DrawAction <GenSpace> passTest = Draw.ContainedIn <GenSpace>(Path.PathTypes).Or(Draw.CanDrawDoor());
        var layoutCopy            = Container.GetGrid().Array;
        List <LayoutObject> rooms = new List <LayoutObject>(Layout.Rooms.Cast <LayoutObject>());
        var runningConnected      = Container2D <GenSpace> .CreateArrayFromBounds(layoutCopy);

        // Create initial queue and visited
        var startingRoom = rooms.Take();
        startingRoom.GetConnectedGrid().DrawAll(Draw.AddTo(runningConnected));
        Container2D <bool>          visited;
        Queue <Value2D <GenSpace> > queue;
        ConstructBFS(startingRoom, out queue, out visited);
        visited = visited.Array;
        LayoutObject fail;
        while (!startingRoom.ConnectedTo(rooms, out fail))
        {
            // Find start points
            #region DEBUG
            if (BigBoss.Debug.logging(Logs.LevelGen))
            {
                runningConnected.ToLog(Logs.LevelGen, "Source Setup");
                fail.ToLog(Logs.LevelGen, "Failed to connect to this");
            }
            #endregion
            Value2D <GenSpace> startPoint;
            Value2D <GenSpace> endPoint;
            LayoutObject       hit;
            if (!FindNextPathPoints(layoutCopy, runningConnected, out hit, passTest, queue, visited, out startPoint, out endPoint))
            {
                throw new ArgumentException("Cannot find path to fail room");
            }
            // Connect
            #region DEBUG
            if (BigBoss.Debug.logging(Logs.LevelGen))
            {
                layoutCopy.SetTo(startPoint, GridType.INTERNAL_RESERVED_CUR, Theme);
                layoutCopy.ToLog(Logs.LevelGen, "Largest after putting blocked");
                BigBoss.Debug.w(Logs.LevelGen, "Start Point:" + startPoint);
            }
            #endregion
            var hitConnected = hit.GetConnectedGrid();
            var stack        = layoutCopy.DrawJumpTowardsSearch(
                startPoint.x,
                startPoint.y,
                3,
                5,
                Draw.IsType <GenSpace>(GridType.NULL).And(Draw.Inside <GenSpace>(layoutCopy.Bounding.Expand(5))),
                passTest.And(Draw.ContainedIn(hitConnected)),
                Rand,
                endPoint,
                true);
            var path = new Path(stack);
            if (path.Valid)
            {
                #region DEBUG
                if (BigBoss.Debug.logging(Logs.LevelGen))
                {
                    path.Bake(null).ToLog(Logs.LevelGen, "Connecting Path");
                }
                #endregion
                path.Simplify();
                Point        first = path.FirstEnd;
                Point        second = path.SecondEnd;
                LayoutObject leaf1, leaf2;
                LayoutObject pathObj = path.Bake(Theme);
                Container.ConnectTo(first, pathObj, first, out leaf1, out pathObj);
                Container.ConnectTo(second, pathObj, second, out leaf2, out pathObj);
                if (leaf1[first].Type == GridType.Wall)
                {
                    leaf1.SetTo(first, GridType.Door, Theme);
                }
                if (leaf2[second].Type == GridType.Wall)
                {
                    leaf2.SetTo(second, GridType.Door, Theme);
                }
                foreach (var v in pathObj)
                {
                    layoutCopy[v] = v.val;
                    runningConnected.Put(v);
                    if (!visited[v])
                    {
                        queue.Enqueue(v);
                    }
                    visited[v] = true;
                }
                foreach (var p in path)
                {
                    layoutCopy.DrawAround(p.x, p.y, false, Draw.IsType <GenSpace>(GridType.NULL).IfThen(Draw.SetTo(pathObj, GridType.Floor, Theme).And(Draw.SetTo(GridType.Floor, Theme))));
                    layoutCopy.DrawCorners(p.x, p.y, new DrawAction <GenSpace>((arr, x, y) =>
                    {
                        if (!arr.IsType(x, y, GridType.NULL))
                        {
                            return(false);
                        }
                        return(arr.Cornered(x, y, Draw.IsType <GenSpace>(GridType.Floor)));
                    }).IfThen(Draw.SetTo(pathObj, GridType.Floor, Theme)));
                }
                Container.Objects.Add(pathObj);
                hitConnected.DrawAll(Draw.AddTo(runningConnected));
                #region DEBUG
                if (BigBoss.Debug.logging(Logs.LevelGen))
                {
                    Container.ToLog(Logs.LevelGen, "Final Connection");
                }
                #endregion
            }
            else
            {
                throw new ArgumentException("Cannot create path to hit room");
            }
        }
        #region DEBUG
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            BigBoss.Debug.printFooter(Logs.LevelGen, "Confirm Connections");
        }
        #endregion
    }
예제 #11
0
    protected void ClusterAround(LayoutObjectContainer cluster, LayoutObject obj)
    {
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            BigBoss.Debug.printHeader("Cluster Around");
        }
        #endregion
        obj.ShiftOutside(cluster, new Point(1, 0), null, false, false);
        obj.Shift(-1, 0); // Shift to overlapping slightly
        MultiMap <bool> visited = new MultiMap <bool>();
        visited[0, 0] = true;
        ProbabilityList <ClusterInfo> shiftOptions = new ProbabilityList <ClusterInfo>();
        Queue <Point> shiftQueue = new Queue <Point>();
        shiftQueue.Enqueue(new Point());
        Container2D <GenSpace> clusterGrid = cluster.GetGrid();
        Container2D <GenSpace> objGrid     = obj.GetGrid();
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            var tmp = new MultiMap <GenSpace>();
            tmp.PutAll(obj.GetGrid());
            tmp.PutAll(cluster.GetGrid());
            tmp.ToLog(Logs.LevelGen, "Starting placement");
        }
        #endregion
        while (shiftQueue.Count > 0)
        {
            Point curShift = shiftQueue.Dequeue();
            #region Debug
            if (BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps) && BigBoss.Debug.logging(Logs.LevelGen))
            {
                var tmpMap = new MultiMap <GenSpace>();
                tmpMap.PutAll(clusterGrid);
                tmpMap.PutAll(objGrid, curShift);
                tmpMap.ToLog(Logs.LevelGen, "Analyzing at shift " + curShift);
            }
            #endregion
            // Test if pass
            List <Point> intersectPoints = new List <Point>();
            if (objGrid.DrawAll((arr, x, y) =>
            {
                if (GridTypeEnum.EdgeType(arr[x, y].GetGridType()))
                {
                    GridType clusterType = clusterGrid[x + curShift.x, y + curShift.y].GetGridType();
                    if (clusterType == GridType.NULL)
                    {
                        return(true);
                    }
                    intersectPoints.Add(new Point(x, y));
                    return(GridTypeEnum.EdgeType(clusterType));
                }
                else
                {
                    return(!clusterGrid.Contains(x + curShift.x, y + curShift.y));
                }
            }) &&
                intersectPoints.Count > 0)
            { // Passed test
                // queue surrounding points
                visited.DrawAround(curShift.x, curShift.y, true, Draw.Not(Draw.EqualTo(true)).IfThen(Draw.AddTo <bool>(shiftQueue).And(Draw.SetTo(true))));

                #region Debug
                if (BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps) && BigBoss.Debug.logging(Logs.LevelGen))
                {
                    BigBoss.Debug.w(Logs.LevelGen, "passed with " + intersectPoints.Count);
                }
                #endregion
                shiftOptions.Add(new ClusterInfo()
                {
                    Shift = curShift, Intersects = intersectPoints
                }, Math.Pow(intersectPoints.Count, 3));
            }
        }
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            shiftOptions.ToLog(Logs.LevelGen, "Shift options");
        }
        #endregion
        List <Point> clusterDoorOptions = new List <Point>();
        ClusterInfo  info;
        var          placed = new List <Value2D <GenSpace> >(0);
        while (shiftOptions.Take(Rand, out info))
        {
            clusterGrid.DrawPoints(info.Intersects, Draw.CanDrawDoor().IfThen(Draw.AddTo <GenSpace>(clusterDoorOptions)).Shift(info.Shift));
            #region Debug
            if (BigBoss.Debug.logging(Logs.LevelGen))
            {
                BigBoss.Debug.w(Logs.LevelGen, "selected " + info.Shift);
                var tmpMap = new MultiMap <GenSpace>();
                clusterGrid.DrawAll(Draw.CopyTo(tmpMap));
                objGrid.DrawAll(Draw.CopyTo(tmpMap, info.Shift));
                tmpMap.DrawPoints(info.Intersects, Draw.SetTo(GridType.INTERNAL_RESERVED_CUR, Theme).Shift(info.Shift));
                tmpMap.ToLog(Logs.LevelGen, "Intersect Points");
                tmpMap = new MultiMap <GenSpace>();
                clusterGrid.DrawAll(Draw.CopyTo(tmpMap));
                objGrid.DrawAll(Draw.CopyTo(tmpMap, info.Shift));
                tmpMap.DrawPoints(clusterDoorOptions, Draw.SetTo(GridType.Door, Theme));
                tmpMap.ToLog(Logs.LevelGen, "Cluster door options");
            }
            #endregion
            if (clusterDoorOptions.Count > 0)
            { // Cluster side has door options
                obj.Shift(info.Shift.x, info.Shift.y);
                placed = obj.PlaceSomeDoors(clusterDoorOptions, Theme, Rand);
                if (placed.Count != 0)
                { // Placed a door
                    foreach (Point p in placed)
                    {
                        LayoutObject clusterObj;
                        cluster.GetObjAt(p, out clusterObj);
                        obj.Connect(clusterObj);
                    }
                    break;
                }
                else
                {
                    #region Debug
                    if (BigBoss.Debug.logging(Logs.LevelGen))
                    {
                        BigBoss.Debug.w(Logs.LevelGen, "selected point failed to match " + info.Shift + ". Backing up");
                    }
                    #endregion
                    obj.Shift(-info.Shift.x, -info.Shift.y);
                }
            }
        }
        if (placed.Count == 0)
        {
            throw new ArgumentException("Could not cluster rooms");
        }
        #region Debug
        if (BigBoss.Debug.logging(Logs.LevelGen))
        {
            var tmpMap = new MultiMap <GenSpace>();
            tmpMap.PutAll(clusterGrid);
            tmpMap.PutAll(obj.GetGrid());
            tmpMap.ToLog(Logs.LevelGen, "Final setup " + info.Shift);
            BigBoss.Debug.printFooter("Cluster Around");
        }
        #endregion
    }