Exemplo n.º 1
0
 public GenRect(GenRect rect)
 {
     MinX = rect.MinX;
     MaxX = rect.MaxX;
     MinY = rect.MinY;
     MaxY = rect.MaxY;
 }
Exemplo n.º 2
0
    public static bool IsInDirection4(GenRect rect, int gx, int gy, params Direction4[] dir)
    {
        Direction8[] other = new Direction8[dir.Length];
        for (int i = 0; i < dir.Length; i++)
        {
            Direction8 target = Direction8.Bottom;
            switch (dir[i])
            {
            case Direction4.Right:
                target = Direction8.Right;
                break;

            case Direction4.Bottom:
                target = Direction8.Bottom;
                break;

            case Direction4.Left:
                target = Direction8.Left;
                break;

            case Direction4.Top:
                target = Direction8.Top;
                break;

            default:
                break;
            }
            other[i] = target;
        }
        return(IsInOctant(rect, gx, gy, other));
    }
Exemplo n.º 3
0
    public GenRect Union(GenRect other)
    {
        GenRect rect =
            new GenRect(
                Mathf.Max(other.MinX, MinX),
                Mathf.Min(other.MaxX, MaxX),
                Mathf.Max(other.MinY, MinY),
                Mathf.Min(other.MaxY, MaxY));

        return(rect);
    }
Exemplo n.º 4
0
 public GenTile[,] GetTiles(GenRect rect)
 {
     GenTile[,] tiles = new GenTile[rect.WidthT, rect.HeightT];
     for (int x = 0; x < tiles.GetLength(0); x++)
     {
         for (int y = 0; y < tiles.GetLength(1); y++)
         {
             tiles[x, y] = GetTile(rect.MinX + x, rect.MinY + y);
         }
     }
     return(tiles);
 }
Exemplo n.º 5
0
    /// <summary>
    /// returns a symetric version of a feature based on a room
    /// </summary>
    /// <param name="feature">the features described by tiles to be placed</param>
    /// <param name="gx">Global position X if position changes this will change</param>
    /// <param name="gy">Global position Y if position changes this will change</param>
    /// <param name="room">The room the symetry should be in</param>
    /// <param name="axis">The axis symetry should be created in</param>
    /// <returns>The complete feature</returns>
    public static GenTile[,] GetSymetry(GenTile[,] feature, ref int gx, ref int gy, GenRoom room, Axis axis)
    {
        GenRect size      = new GenRect(gx, gx + feature.GetLength(0) - 1, gy, gy + feature.GetLength(1) - 1);
        GenRect checkRect = new GenRect(size);



        if (axis.HasFlag(Axis.Vertical))
        {
            do
            {
                checkRect.Transform(0, 1, 0, 0);
            } while (!TouchesWall(checkRect, room));
            checkRect.Transform(0, -1, 0, 0);

            do
            {
                checkRect.Transform(0, 0, 0, 1);
            } while (!TouchesWall(checkRect, room));
            checkRect.Transform(0, 0, 0, -1);

            GenTile[,] resize = checkRect.ResizeTiles(feature, ref gx, ref gy);

            GenTile[,] flip = resize.GetCopy().GetFlip(Axis.Vertical);
            resize          = resize.Place(0, 0, flip);

            feature = resize;
        }

        if (axis.HasFlag(Axis.Horizontal))
        {
            do
            {
                checkRect.Transform(1, 0, 0, 0);
            } while (!TouchesWall(checkRect, room));
            checkRect.Transform(-1, 0, 0, 0);

            do
            {
                checkRect.Transform(0, 0, 1, 0);
            } while (!TouchesWall(checkRect, room));
            checkRect.Transform(0, 0, -1, 0);

            GenTile[,] resize = checkRect.ResizeTiles(feature, ref gx, ref gy);

            GenTile[,] flip = resize.GetCopy().GetFlip(Axis.Horizontal);
            resize          = resize.Place(0, 0, flip);

            feature = resize;
        }

        return(feature);
    }
Exemplo n.º 6
0
    public void FixOverlap()
    {
        for (int i = 0; i < Rooms.Count - 1; i++)
        {
            for (int j = i + 1; j < Rooms.Count; j++)
            {
                GenRoom a = Rooms[i];
                GenRoom b = Rooms[j];

                if (a.Outer.Overlaps(b.Outer))
                {
                    GenRect rA = a.Outer;
                    GenRect rB = b.Outer;
                    // find the union of both
                    int     uLeft  = Mathf.Max(rA.MinX, rB.MinX);
                    int     uTop   = Mathf.Max(rA.MinY, rB.MinY);
                    int     uRight = Mathf.Min(rA.MaxX, rB.MaxX);
                    int     uBot   = Mathf.Min(rA.MaxY, rB.MaxY);
                    GenRect union  =
                        new GenRect(uLeft, uRight, uTop, uBot);

                    GenRoom dominant = a.SpacePriority > b.SpacePriority ? a : b;
                    GenRoom weaker   = a.SpacePriority > b.SpacePriority ? b : a;

                    HashSet <GenPositionTile> dominantEdge = dominant.GetEdge();

                    for (int x = union.MinX; x <= union.MaxX; x++)
                    {
                        for (int y = union.MinY; y <= union.MaxY; y++)
                        {
                            // check if on the edge
                            if (dominantEdge.Any(e => e.Tile == dominant.GetAtWorldspaceG(x, y)))
                            {
                                // this Tile is on the Edge and should be shared
                                weaker.SetTileAtG(x, y, dominant.GetAtWorldspaceG(x, y));
                            }
                            else
                            {
                                // remove the tile from weaker one
                                weaker.RemoveTileAtG(x, y);
                            }
                        }
                    }
                }
            }
        }
    }
Exemplo n.º 7
0
 public static bool TouchesWall(GenRect rect, GenRoom room)
 {
     for (int x = rect.MinX; x <= rect.MaxX; x++)
     {
         for (int y = rect.MinY; y <= rect.MaxY; y++)
         {
             GenTile check = room.GetAtWorldspaceG(x, y);
             if (check != null)
             {
                 if (check.AnyTypes(GenDetail.DetailType.Wall))
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
Exemplo n.º 8
0
    /// <summary>
    /// grows a room to wanted size
    /// </summary>
    /// <param name="gx">global starting positon</param>
    /// <param name="gy">global starting position</param>
    /// <param name="tWidth">target Width</param>
    /// <param name="tHeight">target Height</param>
    /// <param name="rect">the resulting Rect/best match</param>
    /// <param name="connectToWall">When hitting a wall should it be used?</param>
    /// <param name="startDir">the direction the rect should start growing in</param>
    /// <returns>if the procedure was successful</returns>
    public bool TryGrowRect(
        int gx,
        int gy,
        int tWidth,
        int tHeight,
        out GenRect rect,
        bool connectToWall          = false,
        GenUtil.Direction4 startDir = GenUtil.Direction4.Right,
        GrowSettings extra          = new GrowSettings()) // merge to wall
    {
        // create base rect
        rect = new GenRect(gx, gx, gy, gy);
        GenRect helper = new GenRect(rect);
        // this is used to confirm what is inside the rect and already allowed
        List <GenTile> Confirmed = new List <GenTile>();
        // add the current tile to it
        var s = GetTiles(rect).ToList();

        Confirmed.AddRange(s);
        // used to get easier access to

        // if we reached max growth in this direction
        // -1 is not reached
        // 0 is reached
        // 1 reached but grow 1 in the end
        int top   = extra.Top - 1;
        int right = extra.Right - 1;
        int bot   = extra.Bot - 1;
        int left  = extra.Left - 1;

        GenUtil.Direction4 direction = startDir;

        int width  = rect.WidthT;
        int height = rect.HeightT;
        int ohNo   = 100;

        while (width < tWidth || height < tHeight)
        {
            Confirmed.Clear();
            s = GetTiles(rect).ToList();
            Confirmed.AddRange(s);

            ohNo--;
            helper = rect;
            switch (direction)
            {
            case GenUtil.Direction4.Right:
                if (width == tWidth || right >= 0)
                {
                    break;
                }
                helper = helper.Transform(0, 0, 1, 0);
                List <GenTile> addR = GetTiles(helper).ToList();
                addR = addR.Except(Confirmed).ToList();
                if (addR.Any(t => t.AnyTypes(GenDetail.DetailType.Wall)))
                {
                    // we hit a wall next to us
                    // they are automatically allowed

                    Confirmed.AddRange(addR);
                    rect  = helper.Transform(0, 0, -1, 0);
                    right = 1;
                }
                else
                {
                    // we check the next one for safety

                    helper = helper.Transform(0, 0, 1, 0);
                    List <GenTile> query = GetTiles(helper).ToList();
                    query = query.Except(Confirmed).ToList();

                    if (query.Any(t => t.AnyTypes(GenDetail.DetailType.Wall)))
                    {
                        if (connectToWall)
                        {
                            // try and pull the other way
                            if (left < 1)
                            {
                                helper = helper.Transform(-1, 0, 0, 0);
                                left   = -1;
                            }

                            // we connect without problem
                            Confirmed.AddRange(query);
                            rect  = helper.Transform(0, 0, -1, 0);
                            right = 1;
                        }
                        else
                        {
                            // we prevent connection and transform 2 back
                            helper = helper.Transform(0, 0, -2, 0);
                            right  = 0;

                            rect = helper;
                        }
                    }
                    else
                    {
                        helper.Transform(0, 0, -1, 0);
                        rect = helper;
                    }
                }
                break;

            case GenUtil.Direction4.Bottom:
                if (height == tHeight || bot >= 0)
                {
                    break;
                }
                helper = helper.Transform(0, 0, 0, 1);
                List <GenTile> addB = GetTiles(helper).ToList();
                addB = addB.Except(Confirmed).ToList();
                if (addB.Any(t => t.AnyTypes(GenDetail.DetailType.Wall)))
                {
                    // we hit a wall next to us
                    // they are automatically allowed

                    Confirmed.AddRange(addB);
                    rect = helper.Transform(0, 0, 0, -1);
                    bot  = 1;
                }
                else
                {
                    // we check the next one for safety

                    helper = helper.Transform(0, 0, 0, 1);
                    List <GenTile> query = GetTiles(helper).ToList();
                    query = query.Except(Confirmed).ToList();

                    if (query.Any(t => t.AnyTypes(GenDetail.DetailType.Wall)))
                    {
                        if (connectToWall)
                        {
                            if (top < 1)
                            {
                                helper = helper.Transform(0, -1, 0, 0);
                                top    = -1;
                            }

                            // we connect without problem
                            Confirmed.AddRange(query);
                            rect = helper.Transform(0, 0, 0, -1);
                            bot  = 1;
                        }
                        else
                        {
                            // we prevent connection and transform 2 back
                            helper = helper.Transform(0, 0, -0, -2);
                            bot    = 0;

                            rect = helper;
                        }
                    }
                    else
                    {
                        helper.Transform(0, 0, 0, -1);
                        rect = helper;
                    }
                }

                break;

            case GenUtil.Direction4.Left:
                if (width == tWidth || left >= 0)
                {
                    break;
                }
                helper = helper.Transform(1, 0, 0, 0);
                List <GenTile> addL = GetTiles(helper).ToList();
                addL = addL.Except(Confirmed).ToList();
                if (addL.Any(t => t.AnyTypes(GenDetail.DetailType.Wall)))
                {
                    // we hit a wall next to us
                    // they are automatically allowed

                    Confirmed.AddRange(addL);
                    rect = helper.Transform(-1, 0, 0, 0);
                    left = 1;
                }
                else
                {
                    // we check the next one for safety

                    helper = helper.Transform(1, 0, 0, 0);
                    List <GenTile> query = GetTiles(helper).ToList();
                    query = query.Except(Confirmed).ToList();

                    if (query.Any(t => t.AnyTypes(GenDetail.DetailType.Wall)))
                    {
                        if (connectToWall)
                        {
                            // try and pull the other way
                            if (right < 1)
                            {
                                helper = helper.Transform(0, 0, -1, 0);
                                right  = -1;
                            }
                            // we connect without problem
                            Confirmed.AddRange(query);
                            rect = helper.Transform(-1, 0, 0, 0);
                            left = 1;
                        }
                        else
                        {
                            // we prevent connection and transform 2 back
                            helper = helper.Transform(-2, 0, 0, 0);
                            left   = 0;

                            rect = helper;
                        }
                    }
                    else
                    {
                        helper.Transform(-1, 0, 0, 0);
                        rect = helper;
                    }
                }

                break;

            case GenUtil.Direction4.Top:
                if (height == tHeight || top >= 0)
                {
                    break;
                }
                helper = helper.Transform(0, 1, 0, 0);
                List <GenTile> addT = GetTiles(helper).ToList();
                addT = addT.Except(Confirmed).ToList();
                if (addT.Any(t => t.AnyTypes(GenDetail.DetailType.Wall)))
                {
                    // we hit a wall next to us
                    // they are automatically allowed

                    Confirmed.AddRange(addT);
                    rect = helper.Transform(0, -1, 0, 0);
                    top  = 1;
                }
                else
                {
                    // we check the next one for safety

                    helper = helper.Transform(0, 1, 0, 0);
                    List <GenTile> query = GetTiles(helper).ToList();
                    query = query.Except(Confirmed).ToList();

                    if (query.Any(t => t.AnyTypes(GenDetail.DetailType.Wall)))
                    {
                        if (connectToWall)
                        {
                            // try and pull the other way
                            if (bot < 1)
                            {
                                helper = helper.Transform(0, 0, 0, -1);
                                bot    = -1;
                            }
                            // we connect without problem
                            Confirmed.AddRange(query);
                            rect = helper.Transform(0, -1, 0, 0);
                            top  = 1;
                        }
                        else
                        {
                            // we prevent connection and transform 2 back
                            helper = helper.Transform(0, -2, 0, 0);
                            top    = 0;

                            rect = helper;
                        }
                    }
                    else
                    {
                        helper.Transform(0, -1, 0, 0);
                        rect = helper;
                    }
                }

                break;

            default:
                break;
            }

            width = rect.WidthT;
            if (left > 0)
            {
                width++;
            }
            if (right > 0)
            {
                width++;
            }
            height = rect.HeightT;
            if (top > 0)
            {
                height++;
            }
            if (bot > 0)
            {
                height++;
            }

            if (top >= 0 && right >= 0 && bot >= 0 && left >= 0)
            {
                break;
            }
            if (ohNo <= 0)
            {
                break;
            }
            direction = GenUtil.Rotate(direction, 1);
        }

        rect = rect.Transform(Mathf.Max(0, left), Mathf.Max(0, top), Mathf.Max(0, right), Mathf.Max(0, bot));

        if (rect.WidthT == tWidth && rect.HeightT == tHeight)
        {
            return(true);
        }
        return(false);
    }
Exemplo n.º 9
0
    public static IEnumerator GetSimpleTemple()
    {
        GenData temple = new GenData(Random.Range(TempleWidth.start, TempleWidth.end), Random.Range(TempleHeight.start, TempleHeight.end));

        List <GenRoom> AutoFillRoom = new List <GenRoom>();

        // list of all rooms that are not allowed to be used for door placement
        List <GenRoom> NoAutoDoor  = new List <GenRoom>();
        List <GenRoom> SecretRooms = new List <GenRoom>();

        GenTile Chest = GenTile.GetEmpty();

        Chest.Details.Add(new GenDetail()
        {
            Char = '=', Type = GenDetail.DetailType.Entity, Entity = GenDetail.EntityType.Chest
        });

        GenTile pillar = GenTile.GetEmpty();

        //pillar.Details.Add(new GenDetail() { Char = '\u01C1', Type = GenDetail.DetailType.Decoration });
        pillar.Details.Add(new GenDetail()
        {
            Char = 'O', Type = GenDetail.DetailType.Decoration
        });

        GenTile[,] pillars = new GenTile[, ]
        {
            { GenTile.Copy(pillar), GenTile.Copy(pillar) },
            { GenTile.Copy(pillar), GenTile.Copy(pillar) }
        };

        GenTile Door = GenTile.GetEmpty();

        Door.Details.Add(new GenDetail()
        {
            Char = '+', Type = GenDetail.DetailType.Door, Entity = GenDetail.EntityType.Door
        });


        GenRoom outer = GenRoom.Sized(temple.Width, temple.Height);

        outer.FillFloor('+');
        outer.SpacePriority = -2;
        temple.PlaceRoom(0, 0, outer);
        temple.EdgeWalls('#', outer);


        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------


        int w = Random.Range(9, 12);
        int h = Random.Range(10, 16);

        // EntryHall
        temple.TryGrowRect(1, outer.Outer.GetCenter().y, w, h, out GenRect EntrySize, false);
        GenRoom EntryHall = GenRoom.At(EntrySize.MinX, EntrySize.MinY, EntrySize.WidthT, EntrySize.HeightT);

        EntryHall.FillFloor('.');
        temple.PlaceRoom(EntrySize.MinX, EntrySize.MinY, EntryHall);
        temple.EdgeWalls('#');
        EntryHall.GetAtWorldspaceG(
            EntrySize.MinX + 1, EntrySize.GetCenter().y)
        .Details
        .Add(new GenDetail()
        {
            Char = '>', Type = GenDetail.DetailType.Entity, Entity = GenDetail.EntityType.StairsDown
        });


        int posX = EntrySize.MinX + 2;
        int posy = EntrySize.MinY + 2;

        GenTile[,] sym = GenUtil.GetSymetry(pillars.GetCopy(), ref posX, ref posy, EntryHall, GenUtil.Axis.Horizontal | GenUtil.Axis.Vertical);

        EntryHall.PlaceDetailsAt(posX, posy, sym);
        temple.FixOverlap();

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        // hall to big thing
        int whall = Random.Range(10, 25);
        int hhall = Random.Range(5, 7);
        int space = Random.Range(2, 4);

        temple.TryGrowRect(EntrySize.MaxX + 1, EntrySize.GetCenter().y, whall, hhall, out GenRect HallSize);
        GenRoom PillarHall = GenRoom.Sized(HallSize.WidthT, HallSize.HeightT);

        PillarHall.FillFloor('.');
        PillarHall.SpacePriority = 3;
        temple.PlaceRoom(HallSize.MinX, HallSize.MinY, PillarHall);
        temple.EdgeWalls('#', PillarHall);

        NoAutoDoor.Add(PillarHall);

        // place doors to the entry
        if (hhall == 5)
        {
            // a single door in the middle
            PillarHall.AddDetails(HallSize.MinX, HallSize.MinY + 2, GenTile.Copy(Door));
            PillarHall.AddDetails(HallSize.MaxX, HallSize.MinY + 2, GenTile.Copy(Door));
        }
        else
        {
            // place symetric doors
            PillarHall.AddDetails(HallSize.MinX, HallSize.MinY + 2, GenTile.Copy(Door));
            PillarHall.AddDetails(HallSize.MinX, HallSize.MinY + 3, GenTile.Copy(Door));

            PillarHall.AddDetails(HallSize.MaxX, HallSize.MinY + 2, GenTile.Copy(Door));
            PillarHall.AddDetails(HallSize.MaxX, HallSize.MinY + 3, GenTile.Copy(Door));
        }

        int currBar = HallSize.MinX + space;

        GenTile[,] singlePillar = new GenTile[, ] {
            { GenTile.Copy(pillar) }
        };
        while (temple.IsInsideRoom(currBar, HallSize.MinY + 1, PillarHall))
        {
            int fx = currBar;
            int fy = HallSize.MinY + 1;
            GenTile[,] feature = GenUtil.GetSymetry(singlePillar, ref fx, ref fy, PillarHall, GenUtil.Axis.Vertical);
            PillarHall.PlaceDetailsAt(fx, fy, feature);
            currBar += space;
        }
        temple.FixOverlap();

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        // holy water or something

        int waterHeight      = Random.Range(2, 4);
        int waterWidth       = Random.Range(2, 4);
        int waterPillarWidth = Random.Range(2, 3);

        int waterRoomHeight = waterHeight + 4 + waterPillarWidth * 2;
        int waterRoomWidth  = waterWidth + 6 + waterPillarWidth * 2;

        temple.TryGrowRect(HallSize.MaxX + 1, HallSize.GetCenter().y, waterRoomWidth, waterRoomHeight, out GenRect WaterSize, false, GenUtil.Direction4.Top);

        GenRoom waterRoom = GenRoom.Sized(WaterSize.WidthT, WaterSize.HeightT);

        waterRoom.FillFloor();
        waterRoom.SpacePriority = 2;
        temple.PlaceRoom(WaterSize.MinX, WaterSize.MinY, waterRoom);
        temple.EdgeWalls('#', waterRoom);


        int BackDoorWater = Random.Range(1, waterRoom.Height / 2);

        waterRoom.AddDetails(WaterSize.MaxX, WaterSize.MinY + BackDoorWater, GenTile.Copy(Door));
        waterRoom.AddDetails(WaterSize.MaxX, WaterSize.MaxY - BackDoorWater, GenTile.Copy(Door));


        GenTile waterSingle = GenTile.GetEmpty();

        waterSingle.Details.Add(new GenDetail()
        {
            Char = '~', Type = GenDetail.DetailType.Background
        });
        GenTile[,] water = GenUtil.Fill(waterWidth, waterHeight, waterSingle);

        waterRoom.PlaceDetailsAt(WaterSize.MinX + 3 + waterPillarWidth, WaterSize.MinY + 2 + waterPillarWidth, water);

        int waterPX = WaterSize.MinX + 3;
        int waterPY = WaterSize.MinY + 2;

        GenTile[,] waterPillarPlace = GenUtil.GetSymetry(pillars.GetCopy(), ref waterPX, ref waterPY, waterRoom, GenUtil.Axis.Horizontal | GenUtil.Axis.Vertical);
        waterRoom.PlaceDetailsAt(waterPX, waterPY, waterPillarPlace);


        temple.FixOverlap();

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        // pillar spam
        int spamWidth  = Random.Range(10, 20);
        int spamHeight = WaterSize.HeightT + Random.Range(8, 15);

        temple.TryGrowRect(WaterSize.MaxX + 1, WaterSize.GetCenter().y, spamWidth, spamHeight, out GenRect SpamSize, true, GenUtil.Direction4.Top);
        GenRoom Spam = GenRoom.Sized(SpamSize.WidthT, SpamSize.HeightT);

        Spam.FillFloor();
        Spam.SpacePriority = 1;
        temple.PlaceRoom(SpamSize.MinX, SpamSize.MinY, Spam);
        temple.EdgeWalls('#', Spam);

        int spamPX = SpamSize.MinX + 2;
        int spamPY = SpamSize.MinY + 2;

        for (int x = spamPX; temple.IsInsideRoom(x, spamPY, Spam); x += 2)
        {
            for (int y = spamPY; temple.IsInsideRoom(x, y, Spam); y += 2)
            {
                GenTile p = GenTile.Copy(pillar);
                Spam.AddDetails(x, y, p);
            }
        }
        Spam.AddDetail(
            SpamSize.MaxX - 1,
            SpamSize.GetCenter().y,
            new GenDetail()
        {
            Char = '<', Type = GenDetail.DetailType.Entity, Entity = GenDetail.EntityType.StairsUp
        });

        temple.FixOverlap();

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        //temple.Rooms.Remove(outer); // we dont have boundries
        for (int x = outer.Inner.MinX; x < outer.Outer.MaxX; x++)
        {
            for (int y = outer.Inner.MinY; y < outer.Outer.MaxY; y++)
            {
                outer.RemoveTileAtG(x, y);
            }
        }


        //GenRoom Mark = GenRoom.Sized(0, 0);
        //Mark.FillFloor('X');
        //Mark.SpacePriority = 100;


        // lets go ham with randomly sized rooms
        int spawnAttemptsRemaining = 1000;

        while (spawnAttemptsRemaining-- > 0)// lol the arrow
        {
            int rWidth  = Random.Range(RandomWidth.start, RandomWidth.end);
            int rHeight = Random.Range(RandomHeight.start, RandomHeight.end);

            int     rX        = Random.Range(2, temple.Width - 2);
            int     rY        = Random.Range(2, temple.Height - 2);
            GenRect rHopeSize = new GenRect(rX, rX + rWidth + 1, rY, rY + rWidth - 1);


            if (temple.IsInsideRoom(rX, rY) || temple.GetTile(rX, rY) != null)
            {
                continue;
            }

            temple.TryGrowRect(rX, rY, rWidth, rHeight, out GenRect rSize, true);

            GenRoom add = GenRoom.Sized(rSize.WidthT, rSize.HeightT);
            add.FillFloor();
            add.SpacePriority = 01;

            temple.PlaceRoom(rSize.MinX, rSize.MinY, add);

            AutoFillRoom.Add(add);

            temple.EdgeWalls('#', add);

            temple.FixOverlap();

            /*
             * if (rWidth * 2 < rHeight || rHeight * 2 < rWidth)
             * {
             *  if (Random.Range(0,10)>4)
             *  {
             *      // we are making a hallway
             *
             *      //TODO: hallway
             *
             *      temple.PlaceRoom(rX, rY, Mark);
             *      Log(temple);
             *      if (Logging!=null)
             *  {
             *      yield return new WaitForSeconds(0.25f);
             *  }
             *      temple.Rooms.Remove(Mark);
             *      continue;
             *  }
             * }
             */

            /*
             * int randomChance = Random.Range(0, 4);
             * switch (randomChance)
             * {
             *  case 0:
             *      // random pillars in the room
             *
             *      for (int i = 0; i < 7 + (rSize.WidthT + rSize.HeightT)/5; i++)
             *      {
             *          int px = Random.Range(rSize.MinX + 1, rSize.MaxX);
             *          int py = Random.Range(rSize.MinY + 1, rSize.MaxY);
             *          add.AddDetails(px, py, pillar);
             *      }
             *
             *      break;
             *  case 1:
             *      // random water
             *      for (int i = 0; i < 15 + (rSize.WidthT + rSize.HeightT)/3; i++)
             *      {
             *          int px = Random.Range(rSize.MinX + 1, rSize.MaxX);
             *          int py = Random.Range(rSize.MinY + 1, rSize.MaxY);
             *          GenDetail littleWater= new GenDetail() { Char = '~', Type = GenDetail.DetailType.Background};
             *          add.AddDetail(px, py, littleWater);
             *      }
             *      break;
             *  case 2:
             *      // random room inside if possible else empty
             *      if (rSize.WidthT>=7&& rSize.HeightT >= 7)
             *      {
             *          int insideX = rSize.GetCenter().x;
             *          int insideY = rSize.GetCenter().y;
             *
             *          temple.TryGrowRect(insideX, insideY, 100, 100, out GenRect insideSize, false);
             *          GenRoom inside = GenRoom.Sized(insideSize.WidthT, insideSize.HeightT);
             *          inside.FillFloor();
             *          inside.SpacePriority = 2;
             *          temple.PlaceRoom(insideSize.MinX, insideSize.MinY, inside);
             *          temple.EdgeWalls('#',inside);
             *          temple.FixOverlap();
             *
             *      }
             *      else
             *      {
             *          for (int i = 0; i < 7; i++)
             *          {
             *              int px = Random.Range(rSize.MinX + 1, rSize.MaxX);
             *              int py = Random.Range(rSize.MinY + 1, rSize.MaxY);
             *              add.AddDetails(px, py, pillar);
             *          }
             *      }
             *      break;
             *  default:
             *      break;
             * }
             *
             * Log(temple);
             * if (Logging!=null)
             *  {
             *      yield return new WaitForSeconds(0.25f);
             *  }
             */
        }

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        // now fill the rooms with things

        var adjList = temple.GetAdjacentRoomMap();
        // remove any Room that is too small and have no connections

        List <GenRoom> tooSmall = new List <GenRoom>();

        foreach (var room in temple.Rooms)
        {
            if (room.Width >= 5 && room.Height == 3)
            {
                tooSmall.Add(room);
                continue;
            }
            if (room.Height >= 5 && room.Width == 3)
            {
                tooSmall.Add(room);
                continue;
            }
            if (room.Height <= 3 && room.Width <= 3)
            {
                tooSmall.Add(room);
                continue;
            }
            if (adjList[room].Count == 0)
            {
                tooSmall.Add(room);
                continue;
            }
        }
        foreach (var room in tooSmall)
        {
            temple.Rooms.Remove(room);
        }

        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        List <GenRoom> PotentialSecret = new List <GenRoom>();

        foreach (var room in temple.Rooms)
        {
            if (room.Width + room.Height <= 12)
            {
                PotentialSecret.Add(room);
            }
        }

        Debug.Log("potential " + PotentialSecret.Count + "Secret rooms");

        // 1 room --> 0,1,2,3
        // 2 room --> 4,5
        int SecretCount = Mathf.Min(Mathf.FloorToInt(Mathf.Sqrt(Random.Range(1, 6))), PotentialSecret.Count); // this goes to 5

        Debug.Log(SecretCount + " Secret rooms chosen");
        foreach (var secret in PotentialSecret.GetRandom(SecretCount))
        {
            // we get random door
            // add a chest
            // remove it from door spawn
            GenPositionTile entry = temple.GetDoorableTiles(secret.GetAllTiles()).GetRandom();
            secret.AddDetail(entry.PositionG.x, entry.PositionG.y,
                             new GenDetail()
            {
                Char = '*', Entity = GenDetail.EntityType.Door, Type = GenDetail.DetailType.Door
            });

            GenPositionTile myChest = secret
                                      .GetAllTiles()
                                      .Where(t => temple.IsInsideRoom(t.PositionG.x, t.PositionG.y, secret) && temple.IsCornerGR(t.PositionG.x, t.PositionG.y, secret))
                                      .ToList()
                                      .GetRandom();
            secret.AddDetails(myChest.PositionG.x, myChest.PositionG.y, GenTile.Copy(Chest));

            AutoFillRoom.Remove(secret);
            SecretRooms.Add(secret);
            NoAutoDoor.Add(secret);
        }
        // -----------
        Log(temple);
        if (Logging != null)
        {
            yield return(new WaitForSeconds(0.25f));
        }
        // -----------

        // go through all other rooms and determin what they are

        foreach (GenRoom room in AutoFillRoom)
        {
            // -----------
            Log(temple);
            if (Logging != null)
            {
                yield return(new WaitForSeconds(0.25f));
            }
            // -----------

            // pillar hallway
            if (room.Height <= 7 && room.Height >= 5 && room.Width > 6)
            {
                // potential horizontal hallway
                if (Random.value < 0.4f)
                {
                    // hallway confirmed
                    // left to right

                    GenTile[,] p = new GenTile[, ]
                    {
                        { GenTile.Copy(pillar) }
                    };
                    int spacing = Random.Range(2, 5);

                    int tmpX = room.Outer.MinX + spacing;
                    int tmpY = room.Outer.MinY + 1;


                    p = GenUtil.GetSymetry(p, ref tmpX, ref tmpY, room, GenUtil.Axis.Vertical);

                    while (temple.IsInsideRoom(tmpX, tmpY, room))
                    {
                        room.PlaceDetailsAt(tmpX, tmpY, p);

                        tmpX = tmpX + spacing;
                    }
                    int enemyCount = Random.Range(0, 4);
                    for (int i = 0; i < enemyCount; i++)
                    {
                        SpawnEnemy(temple, room);
                    }
                    int itemCount = Random.Range(-1, 3);
                    for (int i = 0; i < itemCount; i++)
                    {
                        SpawnItem(temple, room, true);
                    }
                    int chestCount = Random.Range(-2, 2);
                    for (int i = 0; i < chestCount; i++)
                    {
                        SpawnChest(temple, room, true);
                    }
                    continue;
                }
            }
            if (room.Width <= 7 && room.Width >= 5 && room.Height > 6)
            {
                // potential horizontal hallway
                if (Random.value < 0.4f)
                {
                    // hallway confirmed
                    // left to right

                    GenTile[,] p = new GenTile[, ]
                    {
                        { GenTile.Copy(pillar) }
                    };
                    int spacing = Random.Range(2, 5);

                    int tmpX = room.Outer.MinX + 1;
                    int tmpY = room.Outer.MinY + spacing;


                    p = GenUtil.GetSymetry(p, ref tmpX, ref tmpY, room, GenUtil.Axis.Horizontal);

                    while (temple.IsInsideRoom(tmpX, tmpY, room))
                    {
                        room.PlaceDetailsAt(tmpX, tmpY, p);

                        tmpY = tmpY + spacing;
                    }
                    int enemyCount = Random.Range(0, 4);
                    for (int i = 0; i < enemyCount; i++)
                    {
                        SpawnEnemy(temple, room);
                    }
                    int itemCount = Random.Range(-1, 3);
                    for (int i = 0; i < itemCount; i++)
                    {
                        SpawnItem(temple, room, true);
                    }
                    int chestCount = Random.Range(-2, 2);
                    for (int i = 0; i < chestCount; i++)
                    {
                        SpawnChest(temple, room, true);
                    }
                    continue;
                }
            }

            if (room.Height >= 8 && room.Width >= 8)
            {
                // can either be pillar spam or room in room

                if (Random.value < 0.6f)
                {
                    if (Random.value < 0.7f && room.Width % 2 == 1 && room.Height % 2 == 1)
                    {
                        // pillar spam

                        for (int x = 2; x < room.Width - 2; x += 2)
                        {
                            for (int y = 2; y < room.Height - 2; y += 2)
                            {
                                room.AddDetails(room.PosX + x, room.PosY + y, GenTile.Copy(pillar));
                            }
                        }
                        int enemyCount = Random.Range(0, 5);
                        for (int i = 0; i < enemyCount; i++)
                        {
                            SpawnEnemy(temple, room);
                        }
                        int itemCount = Random.Range(-1, 3);
                        for (int i = 0; i < itemCount; i++)
                        {
                            SpawnItem(temple, room, true);
                        }
                        int chestCount = Random.Range(-3, 3);
                        for (int i = 0; i < chestCount; i++)
                        {
                            SpawnChest(temple, room, true);
                        }
                    }
                    else
                    {
                        // room in room

                        // find where to put the inner room
                        temple.TryGrowRect(room.Inner.GetCenter().x, room.Inner.GetCenter().y, 100, 100, out GenRect InnerSize);


                        if (InnerSize.WidthT >= 4 && InnerSize.HeightT >= 4)
                        {
                            if (InnerSize.WidthT >= 10 || InnerSize.HeightT >= 10)
                            {
                                if (Mathf.Abs(InnerSize.WidthT - InnerSize.HeightT) > 3)
                                {
                                    // we want to divide
                                    if (InnerSize.WidthT > InnerSize.HeightT)
                                    {
                                        // divide left and right
                                        int singleWidth = InnerSize.WidthT / 2 - 2;
                                        // left
                                        GenRect LeftRoom = new GenRect(InnerSize.MinX, InnerSize.MinX + singleWidth, InnerSize.MinY, InnerSize.MaxY);
                                        // right
                                        GenRect RightRoom = new GenRect(InnerSize.MaxX - singleWidth, InnerSize.MaxX, InnerSize.MinY, InnerSize.MaxY);

                                        GenRoom left = GenRoom.Sized(LeftRoom.WidthT, LeftRoom.HeightT);
                                        left.FillFloor();
                                        left.SpacePriority = 4;
                                        GenRoom right = GenRoom.Sized(RightRoom.WidthT, RightRoom.HeightT);
                                        right.FillFloor();
                                        right.SpacePriority = 4;
                                        temple.PlaceRoom(LeftRoom.MinX, LeftRoom.MinY, left);
                                        temple.PlaceRoom(RightRoom.MinX, RightRoom.MinY, right);

                                        NoAutoDoor.Add(left);
                                        NoAutoDoor.Add(right);

                                        temple.EdgeWalls('#', left);
                                        temple.EdgeWalls('#', right);

                                        temple.FixOverlap();
                                        // -----------
                                        Log(temple);
                                        if (Logging != null)
                                        {
                                            yield return(new WaitForSeconds(0.25f));
                                        }
                                        // -----------

                                        var leftDoor  = temple.GetDoorableTiles(left.GetAllTiles()).GetRandom(1);
                                        var rightDoor = temple.GetDoorableTiles(right.GetAllTiles()).GetRandom(1);

                                        for (int i = 0; i < leftDoor.Count; i++)
                                        {
                                            left.AddDetails(leftDoor[i].PositionG.x, leftDoor[i].PositionG.y, GenTile.Copy(Door));
                                        }
                                        for (int i = 0; i < rightDoor.Count; i++)
                                        {
                                            right.AddDetails(rightDoor[i].PositionG.x, rightDoor[i].PositionG.y, GenTile.Copy(Door));
                                        }
                                        SpawnItem(temple, left);
                                        SpawnItem(temple, right);
                                        if (Random.value < 0.4f)
                                        {
                                            SpawnItem(temple, right);
                                        }
                                        if (Random.value < 0.4f)
                                        {
                                            SpawnItem(temple, left);
                                        }
                                        if (Random.value < 0.2f)
                                        {
                                            SpawnChest(temple, left, true);
                                        }
                                        if (Random.value < 0.2f)
                                        {
                                            SpawnChest(temple, left, true);
                                        }
                                    }
                                    else
                                    {
                                        // divide top bot
                                        Debug.Log("currently not implemented, sorry");
                                    }
                                }
                            }
                            else
                            {
                                // one single room
                                if (InnerSize.WidthT > 5)
                                {
                                    InnerSize = InnerSize.Transform(-1, 0, -1, 0);
                                }
                                if (InnerSize.HeightT > 5)
                                {
                                    InnerSize = InnerSize.Transform(0, -1, 0, -1);
                                }

                                Debug.Log("HERE");

                                GenRoom single = GenRoom.Sized(InnerSize.WidthT, InnerSize.HeightT);
                                single.SpacePriority = 4;
                                single.FillFloor();
                                NoAutoDoor.Add(single);

                                temple.PlaceRoom(InnerSize.MinX, InnerSize.MinY, single);
                                temple.EdgeWalls('#', single);
                                temple.FixOverlap();
                                // -----------
                                Log(temple);
                                if (Logging != null)
                                {
                                    yield return(new WaitForSeconds(0.25f));
                                }
                                // -----------



                                // double doors
                                var doorables = single.GetAllTiles();// single.GetEdge().ToList();
                                var theDoors  = temple.GetDoorableTiles(doorables).GetRandom(2);

                                for (int i = 0; i < theDoors.Count; i++)
                                {
                                    single.AddDetails(theDoors[i].PositionG.x, theDoors[i].PositionG.y, GenTile.Copy(Door));
                                }

                                SpawnItem(temple, single);

                                if (Random.value < 0.2f)
                                {
                                    SpawnChest(temple, single, true);
                                }
                                if (Random.value < 0.2f)
                                {
                                    SpawnChest(temple, single, true);
                                }
                            }
                        }

                        SpawnEnemy(temple, room);
                        if (Random.value < 0.5f)
                        {
                            SpawnEnemy(temple, room);
                        }
                        if (Random.value < 0.2f)
                        {
                            SpawnEnemy(temple, room);
                        }
                    }
                    continue;
                }
            }
            // something random
            //room.FillFloor('~');

            SpawnEnemy(temple, room);
            SpawnEnemy(temple, room);

            if (Random.value < 0.5f)
            {
                SpawnEnemy(temple, room);
            }
            if (Random.value < 0.2f)
            {
                SpawnEnemy(temple, room);
            }
            SpawnItem(temple, room);
            if (Random.value < 0.3f)
            {
                SpawnItem(temple, room);
            }
            if (Random.value < 0.3f)
            {
                SpawnItem(temple, room);
            }
            if (Random.value < 0.4f)
            {
                SpawnChest(temple, room);
            }
            if (Random.value < 0.1f)
            {
                SpawnChest(temple, room);
            }
        }


        List <GenRoom> RequireDoor = new List <GenRoom>(temple.Rooms);

        foreach (var doo in NoAutoDoor)
        {
            RequireDoor.Remove(doo);
        }
        List <GenRoom> DoorIteration = new List <GenRoom>(RequireDoor);
        GenRoom        start         = EntryHall;

        Dictionary <GenRoom, List <GenRoom> > adj = temple.GetAdjacentRoomMap();

        void RandomDoorTo(GenRoom a, GenRoom b)
        {
            var tiles    = temple.GetDoorableTiles(temple.GetConnectingTiles(a, b));
            var location = tiles.GetRandom();

            a.AddDetails(location.PositionG.x, location.PositionG.y, GenTile.Copy(Door));
        }

        while (RequireDoor.Count > 0)
        {
            DoorIteration.Clear();
            DoorIteration.AddRange(RequireDoor);
            foreach (var room in DoorIteration)
            {
                if (temple.IsReachable(start, room))
                {
                    // reachable so we dont have to do a thing
                    RequireDoor.Remove(room);
                }
                else
                {
                    // place random door
                    var available = adj[room];
                    RandomDoorTo(room, available.GetRandom());
                }
                // -----------
                Log(temple);
                if (Logging != null)
                {
                    yield return(new WaitForSeconds(0.1f));
                }

                // -----------
            }
        }


        foreach (var room in adj[Spam].GetRandom(2))
        {
            RandomDoorTo(Spam, room);
        }

        Log(temple);
        Debug.Log("Done");


        LastOutput = GenUtil.Print(temple, false);
        Done?.Invoke();
    }
Exemplo n.º 10
0
 public bool IsEnclosing(GenRect other)
 {
     return(MinX < other.MinX && MinY < other.MinY && MaxX > other.MaxX && MaxY > other.MaxY);
 }
Exemplo n.º 11
0
 public bool IsInside(GenRect other)
 {
     return(other.MinX < MinX && other.MinY < MinY && other.MaxX > MaxX && other.MaxY > MaxY);
 }
Exemplo n.º 12
0
 public bool Overlaps(GenRect rect)
 {
     return(MinX <= rect.MaxX && MaxX >= rect.MinX && MinY <= rect.MaxY && MaxY >= rect.MinY);
 }
Exemplo n.º 13
0
    public static bool IsInOctant(GenRect rect, int gx, int gy, params Direction8[] dir)
    {
        //NOTE: does not check if in rect
        float tx = (rect.MinX + rect.MaxX) / 2f;
        float ty = (rect.MinY + rect.MaxY) / 2f;

        // to a range of -1 to 1

        // relativ position
        float cx = gx - tx;
        float cy = gy - ty;

        cx = cx / (rect.WidthT / 2);
        cy = cy / (rect.WidthT / 2);



        // regular directions
        if (dir.Contains(Direction8.Top))
        {
            if (cy <= 0 && Mathf.Abs(cx) <= Mathf.Abs(cy))
            {
                return(true);
            }
        }
        if (dir.Contains(Direction8.Right))
        {
            if (cx >= 0 && Mathf.Abs(cy) <= Mathf.Abs(cx))
            {
                return(true);
            }
        }
        if (dir.Contains(Direction8.Bottom))
        {
            if (cy >= 0 && Mathf.Abs(cx) <= Mathf.Abs(cy))
            {
                return(true);
            }
        }
        if (dir.Contains(Direction8.Left))
        {
            if (cx <= 0 && Mathf.Abs(cy) <= Mathf.Abs(cx))
            {
                return(true);
            }
        }

        // quadrants
        if (dir.Contains(Direction8.TopLeft))
        {
            if (cy <= 0 && cx <= 0)
            {
                return(true);
            }
        }
        if (dir.Contains(Direction8.TopRight))
        {
            if (cy <= 0 && cx >= 0)
            {
                return(true);
            }
        }
        if (dir.Contains(Direction8.BottomRight))
        {
            if (cy >= 0 && cx >= 0)
            {
                return(true);
            }
        }
        if (dir.Contains(Direction8.BottomLeft))
        {
            if (cy >= 0 && cx <= 0)
            {
                return(true);
            }
        }

        return(false);
    }