SHARE
TWEET

Untitled

a guest Jul 22nd, 2019 73 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using uRandom = UnityEngine.Random;
  5. using UnityEngine.Tilemaps;
  6. using System.Threading;
  7. using System.Linq;
  8. using System;
  9.  
  10. public class GenerateTilemap : MonoBehaviour
  11. {
  12.  
  13.     private Tilemap m_Tilemap;
  14.     [SerializeField] private TileBase m_Tile;
  15.  
  16.     [SerializeField] private Vector2 startEndEmptySpace = new Vector2(10, 5);
  17.  
  18.     private int[,] gridArray;
  19.     private RoomClass[,] roomMap;
  20.  
  21.     /* Level Size Variables */
  22.     private const int xMax = 225;
  23.     private const int yMax = 125;
  24.  
  25.     private const int roomsX = 5;
  26.     private const int roomsY = 5;
  27.  
  28.     private RelativeNeighbors directions = new RelativeNeighbors();
  29.  
  30.     public Player playerPrefab;
  31.     public RoomClass roomPrefab;
  32.  
  33.     public RoomClass startRoom;
  34.     public RoomClass exitRoom;
  35.     public Player player;
  36.  
  37.     public Camera camera;
  38.  
  39.     public Vector2 startTilePos;
  40.     public Vector2 endTilePos;
  41.  
  42.     public bool[,] visitedRooms;
  43.  
  44.     Dictionary<Vector2, Action> roomsPlacementList;
  45.  
  46.  
  47.     // Start is called before the first frame update
  48.     void Start()
  49.     {
  50.         roomsPlacementList = new Dictionary<Vector2, Action>();
  51.  
  52.         gridArray = GenerateArray(xMax, yMax, true);
  53.  
  54.         //player = Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
  55.         player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
  56.         startRoom = Instantiate(roomPrefab, Vector3.zero, Quaternion.identity);
  57.         exitRoom = Instantiate(roomPrefab, Vector3.zero, Quaternion.identity);
  58.  
  59.         startRoom.SetName("startRoom");
  60.         exitRoom.SetName("exitRoom");
  61.  
  62.         ChooseStartAndEnd(ref startRoom, ref exitRoom);
  63.  
  64.         m_Tilemap = GetComponent<Tilemap>();
  65.         camera = GameObject.Find("Main Camera").GetComponent<Camera>();
  66.         camera.transform.SetParent(player.transform);
  67.         camera.transform.localPosition = new Vector3(0, 0, -1);
  68.  
  69.         directions.Up = new Vector2(0, 1);
  70.         directions.Down = new Vector2(0, -1);
  71.         directions.Left = new Vector2(-1, 0);
  72.         directions.Right = new Vector2(1, 0);
  73.  
  74.         directions.GetRandomDirection = delegate ()
  75.         {
  76.  
  77.             int rand = uRandom.Range(0, 3);
  78.             Vector2 randD = new Vector2(0, 0);
  79.  
  80.             switch (rand)
  81.             {
  82.                 case 0:
  83.                     randD = this.directions.Up;
  84.                     break;
  85.                 case 1:
  86.                     randD = this.directions.Down;
  87.                     break;
  88.                 case 2:
  89.                     randD = this.directions.Left;
  90.                     break;
  91.                 case 3:
  92.                     randD = this.directions.Right;
  93.                     break;
  94.                 default:
  95.                     break;
  96.             }
  97.  
  98.             return randD;
  99.         };
  100.  
  101.         //directions.GetDirectionByIndex = new public delegate Vector2 (int index)
  102.         //{
  103.         //    return Vector2.zero
  104.         //}
  105.  
  106.         //// Remove tiles based on areas we need cleared
  107.         //startRoom.PlaceRoom(ref gridArray);
  108.         //exitRoom.PlaceRoom(ref gridArray);
  109.  
  110.         //for (int i = 0; i < 10; i++)
  111.         //{
  112.         //    int randSizeX = (int) Mathf.Abs(uRandom.Range(5, 25));
  113.         //    int randSizeY = (int) Mathf.Abs(uRandom.Range(4, 15));
  114.  
  115.         //    int randPosX = (int) Mathf.Abs(uRandom.Range(0 + Mathf.Ceil(randSizeX / 2), xMax - Mathf.Ceil(randSizeX / 2)));
  116.         //    int randPosY = (int)Mathf.Abs(uRandom.Range(0 + Mathf.Ceil(randSizeY / 2), yMax - Mathf.Ceil(randSizeY / 2)));
  117.  
  118.         //    if (CanPlaceRoom(gridArray, new Vector2(randPosX, randPosY), randSizeX, randSizeY))
  119.         //    {
  120.         //        RoomClass newRoom = Instantiate(roomPrefab, Vector3.zero, Quaternion.identity);
  121.         //        newRoom.SetName("GeneratedRoom"+i);
  122.         //        newRoom.SetParams(new Vector2(randPosX, randPosY), new Vector2(randSizeX, randSizeY));
  123.         //        newRoom.UpdateCorners();
  124.         //        newRoom.SetRoomCorners(newRoom.GetRoomCorners());
  125.         //        newRoom.setDrawRoom(true);
  126.  
  127.         //        this.roomsPlacementList.Add(newRoom.GetRoomPos(true), () => {
  128.         //            newRoom.PlaceRoom(ref gridArray);
  129.         //         });
  130.         //    }
  131.  
  132.         //}
  133.  
  134.         //foreach (Action action in roomsPlacementList.Values)
  135.         //{
  136.         //    action();
  137.         //}
  138.  
  139.         roomMap = new RoomClass[roomsX, roomsY];
  140.  
  141.         for (int x = 0; x <= roomMap.GetUpperBound(0); x++)
  142.         {
  143.             for (int y = 0; y <= roomMap.GetUpperBound(1); y++)
  144.             {
  145.                 RoomClass newRoom = Instantiate(roomPrefab, Vector3.zero, Quaternion.identity);
  146.  
  147.                 Vector2 roomSize = new Vector2( (int) Mathf.Floor(xMax / roomsX), (int) Mathf.Floor(yMax / roomsY) );
  148.                 Vector2 tilePos = new Vector2(x * roomSize.x, y * roomSize.y);
  149.                 newRoom.SetName("Room (" + x + ", " + y + ")");
  150.                 newRoom.SetParams(tilePos, roomSize);
  151.                 newRoom.SetRoomMapPos(new Vector2(x, y));
  152.                 newRoom.setDrawRoom(true);
  153.  
  154.                 roomMap[x, y] = newRoom;
  155.             }
  156.         }
  157.  
  158.         GeneratePath();
  159.  
  160.         RenderMap(gridArray, m_Tilemap, m_Tile);
  161.     }
  162.  
  163.     /* Methodology used:
  164.      *  Using a grid of 5x5 rooms, we create a weaved maze representing the flow of rooms the player needs to navigate in order to exit the level
  165.      *  We use this method or our room navigation: https://weblog.jamisbuck.org/2011/1/27/maze-generation-growing-tree-algorithm
  166.      *  We use this method for allowing "weaves" making the map more visually appealing: https://weblog.jamisbuck.org/2011/3/4/maze-generation-weave-mazes
  167.      *  We will probably be using a 75/25 split (75% of the time it's Newest or Backtracking method and 25% of the time, it's random or Prim)
  168.      *  We'll need to ensure navigability in each room similar to the Spelunky method: http://tinysubversions.com/spelunkyGen/
  169.      *  We want to ensure a clean "flow" for out monster generation and room types using a "Director AI" like here: https://steamcdn-a.akamaihd.net/apps/valve/2009/ai_systems_of_l4d_mike_booth.pdf
  170.      *  Some more details on how that Director AI can work for Metroidvanias: https://www.gamasutra.com/blogs/SebastienBENARD/20170329/294642/Building_the_Level_Design_of_a_procedurally_generated_Metroidvania_a_hybrid_approach.php
  171.      *  
  172.      */
  173.  
  174.     public RoomClass[,] GeneratePath()
  175.     {
  176.  
  177.         /* This is our "C" */
  178.         List<RoomClass> placedRooms = new List<RoomClass>();
  179.  
  180.         int count = 0;
  181.  
  182.         int randX = (int)uRandom.Range(roomMap.GetLowerBound(0), roomMap.GetUpperBound(0));
  183.         int randY = (int)uRandom.Range(roomMap.GetLowerBound(1), roomMap.GetUpperBound(1));
  184.  
  185.         Vector2 start = new Vector2(randX, randY);
  186.         RoomClass thisRoom = this.roomMap[randX, randY];
  187.  
  188.         //thisRoom.SetRoomMapPos(start);
  189.         thisRoom.SetVisitedOnGenerateMap(true);
  190.         placedRooms.Add(thisRoom);
  191.  
  192.         int iterationCount = 0;
  193.  
  194.         Dictionary<Vector2, RoomClass> roomPath = new Dictionary<Vector2, RoomClass>();
  195.  
  196.         List<Vector2> unplacedRooms = new List<Vector2>();
  197.  
  198.         for (int x = 0; x < roomMap.GetUpperBound(0); x++)
  199.         {
  200.             for (int y = 0; y < roomMap.GetUpperBound(1); y++)
  201.             {
  202.                 unplacedRooms.Add(new Vector2(x, y));
  203.             }
  204.         }
  205.  
  206.         Vector2 currentRoom = unplacedRooms[uRandom.Range(0, unplacedRooms.Count())];
  207.  
  208.         roomPath.Add(currentRoom, roomMap[(int) currentRoom.x, (int) currentRoom.y]);
  209.         unplacedRooms.Remove(currentRoom);
  210.  
  211.         Vector2[] directions =
  212.         {
  213.             Vector2.up,
  214.             Vector2.down,
  215.             Vector2.left,
  216.             Vector2.right
  217.         };
  218.  
  219.         Vector2 chosenDirection = Vector2.zero;
  220.  
  221.         while (true)
  222.         {
  223.             List<Vector2> neighborsChecked = new List<Vector2>();
  224.             foreach (Vector2 thisDirection in directions)
  225.             {
  226.                 Vector2 roomChecked = currentRoom + thisDirection;
  227.                 if (!roomPath.ContainsKey(roomChecked) && unplacedRooms.Contains(roomChecked)) /* If there is no room in the direction we checked */
  228.                 {
  229.                     neighborsChecked.Add(roomChecked);
  230.                 }
  231.             }
  232.  
  233.             if (neighborsChecked.Count() == 0)                
  234.             {
  235.                 break;
  236.             }
  237.  
  238.             int randomIndex = uRandom.Range(0, neighborsChecked.Count());
  239.             Vector2 nextRoom = neighborsChecked[randomIndex];
  240.  
  241.             roomPath.Add(nextRoom, roomMap[(int)nextRoom.x, (int)nextRoom.y]);
  242.             unplacedRooms.Remove(nextRoom);
  243.  
  244.             Vector2 wallToRemove = nextRoom - currentRoom;
  245.  
  246.             /* Set the current room we're checking from and carve out the wall in the direction we're checking */
  247.             RoomClass currentRoomObject = roomPath[currentRoom];
  248.             RoomType newType = RemoveWallInDirection( currentRoomObject.GetRoomType(), wallToRemove);
  249.             currentRoomObject.SetRoomType(newType);
  250.  
  251.             /* invert the direction so that we're removing the wall where we came FROM */
  252.             RoomClass nextRoomObject = roomPath[nextRoom];
  253.             wallToRemove *= -1;
  254.             newType = RemoveWallInDirection(nextRoomObject.GetRoomType(), wallToRemove);
  255.             nextRoomObject.SetRoomType(newType);
  256.  
  257.             /* Draw the rooms immediately to improve debugging */
  258.             currentRoomObject.DrawRoom();
  259.             nextRoomObject.DrawRoom();
  260.  
  261.             currentRoom = nextRoom;
  262.  
  263.             if (unplacedRooms.Count() == 0)
  264.             {
  265.                 break;
  266.             }
  267.         }
  268.  
  269.         foreach (Vector2 key in roomPath.Keys)
  270.         {
  271.             RoomClass room = roomPath[key];
  272.             roomMap[(int) room.GetRoomMapPos().x, (int) room.GetRoomMapPos().x] = room;
  273.         }
  274.  
  275.         //while (placedRooms.Count() > 0 && iterationCount < 1000)
  276.         //{
  277.         //    iterationCount++;
  278.  
  279.         //    /* Choose a cell from the list of placed rooms */
  280.         //    RoomClass aRoom;
  281.  
  282.         //    /* 75% of the time, we'll use the last room we placed, and 25% of the time we'll grab a random room from the list */
  283.         //    if (uRandom.Range(0, 1) < 1.01f)
  284.         //    {
  285.         //        aRoom = placedRooms[placedRooms.Count - 1];
  286.         //    } else {
  287.         //        aRoom = placedRooms[(int)uRandom.Range(0, placedRooms.Count() - 1)];
  288.         //    }
  289.  
  290.         //    /* turn the by value reference into the actual instantiate game object */
  291.         //    //aRoom = aRoom.GetComponent<MonoBehaviour>();
  292.  
  293.         //    int visitedCount = 0;
  294.  
  295.         //    Vector2[] directions =
  296.         //    {
  297.         //        Vector2.up,
  298.         //        Vector2.down,
  299.         //        Vector2.left,
  300.         //        Vector2.right
  301.         //    };
  302.  
  303.         //    //while (directions.Count() > 0)
  304.         //    //{
  305.         //    //    int directionIndex = uRandom.Range(0, directions.Count());
  306.         //    //    Vector2 thisDirection = directions[directionIndex];
  307.         //    //    RoomClass checkedRoom = this.getRoomInDirection(aRoom, thisDirection);
  308.         //    //    bool roomVisited = IsRoomVisited(checkedRoom);
  309.         //    //    if (roomVisited)
  310.         //    //    {
  311.         //    //        visitedCount++;
  312.  
  313.         //    //        break;
  314.         //    //    } else
  315.         //    //    {
  316.         //    //        /* Set the current room we're checking from and carve out the wall in the direction we're checking */
  317.         //    //        Vector2 wallToRemove = thisDirection;
  318.         //    //        RoomType newType = RemoveWallInDirection(aRoom.GetRoomType(), wallToRemove);
  319.         //    //        aRoom.SetRoomType(newType);
  320.  
  321.         //    //        /* Set the checked room status to "visited" */
  322.         //    //        checkedRoom.SetVisitedOnGenerateMap(true);
  323.  
  324.         //    //        /* invert the direction so that we're removing the wall where we came FROM */
  325.         //    //        wallToRemove = thisDirection * new Vector2(-1, -1);
  326.         //    //        newType = RemoveWallInDirection(checkedRoom.GetRoomType(), wallToRemove);
  327.         //    //        checkedRoom.SetRoomType(newType);
  328.  
  329.         //    //        /* Draw the rooms immediately to improve debugging */
  330.         //    //        aRoom.DrawRoom();
  331.         //    //        checkedRoom.DrawRoom();
  332.  
  333.         //    //        placedRooms.Add(checkedRoom);
  334.  
  335.         //    //        break;
  336.         //    //    }
  337.  
  338.         //    //    directions = directions.Where(val => val != thisDirection).ToArray();
  339.         //    //}
  340.  
  341.         //    if (visitedCount == 4)
  342.         //    {
  343.         //        removeFromList(ref placedRooms, aRoom);
  344.         //    }
  345.  
  346.         //    RoomClass nextRoom = this.getRoomInDirection(thisRoom, this.directions.GetRandomDirection());
  347.         //}
  348.  
  349.         print( "Generate Path iterated x times: " + iterationCount);
  350.         print("Ended with " + placedRooms.Count() + " rooms in placedRooms list");
  351.  
  352.         return roomMap;
  353.     }
  354.  
  355.     private Vector2 GetStartRoom()
  356.     {
  357.         throw new NotImplementedException();
  358.     }
  359.  
  360.     public bool IsRoomVisited(RoomClass room)
  361.     {
  362.         if (room == null)
  363.         {
  364.             return true;
  365.         }
  366.         return room.GetVisitedOnGenerateMap();
  367.     }
  368.  
  369.     public void removeFromList(ref List<RoomClass> list, RoomClass room)
  370.     {
  371.         RoomClass roomToRemove = null;
  372.  
  373.         foreach (RoomClass thisRoom in list)
  374.         {
  375.             if (thisRoom.GetRoomMapPos() == room.GetRoomMapPos())
  376.             {
  377.                 roomToRemove = thisRoom;
  378.                 break;
  379.             }                
  380.         }
  381.  
  382.         if (roomToRemove != null)
  383.         {
  384.             list.Remove(roomToRemove);
  385.         }        
  386.     }
  387.  
  388.     public void Update()
  389.     {
  390.  
  391.     }
  392.  
  393.     void ChooseStartAndEnd(ref RoomClass startRoom, ref RoomClass exitRoom, int x = xMax, int y = yMax, int paddingX = 0, int paddingY = 0)
  394.     {
  395.         if (paddingX == 0 || paddingY == 0)
  396.         {
  397.             paddingX = (int)this.startEndEmptySpace.x;
  398.             paddingY = (int)this.startEndEmptySpace.y;
  399.         }
  400.  
  401.         Vector2 quadrant = Vector2.zero;
  402.  
  403.         if (Mathf.RoundToInt(uRandom.Range(0.0f, 1.0f)) == 0)
  404.         {
  405.             quadrant.x = -1;
  406.         }
  407.         else
  408.         {
  409.             quadrant.x = 1;
  410.         }
  411.  
  412.         if (Mathf.RoundToInt(uRandom.Range(0.0f, 1.0f)) == 0)
  413.         {
  414.             quadrant.y = -1;
  415.         }
  416.         else
  417.         {
  418.             quadrant.y = 1;
  419.         }
  420.  
  421.         // Calculate a random position between 0 and half of x, then repeat for y
  422.         Vector2 startPos = new Vector2(Mathf.RoundToInt(uRandom.Range(0, x / 2 - paddingX)), Mathf.RoundToInt(uRandom.Range(0, y / 2 - paddingY)));
  423.         Vector2 endPos = new Vector2(Mathf.RoundToInt(uRandom.Range(0, x / 2 - paddingX)), Mathf.RoundToInt(uRandom.Range(0, y / 2 - paddingY)));
  424.         startTilePos = startPos;
  425.         endTilePos = endPos;
  426.         // Multiply the random position by the Quadrant Vector to get the start position
  427.         startPos *= quadrant;
  428.         // Invert the quadrant vector
  429.         quadrant *= new Vector2(-1, -1);
  430.         // Multiply the new position by the quadrant vector to get the exit.
  431.         endPos *= quadrant;
  432.  
  433.         startTilePos = WorldPosToTilePos(startPos * new Vector2(16, 16));
  434.         endTilePos = WorldPosToTilePos(endPos * new Vector2(16, 16));
  435.  
  436.         //player.transform.Translate(TilePosToWorldPos(startTilePos, Utils.worldSpaceOriginVectors.bottomLeft));
  437.  
  438.         //startRoom.transform.Translate(startPos);
  439.         //startRoom.SetParams(startTilePos, new Vector2(paddingX, paddingY));
  440.         //startRoom.PlaceRoom(ref this.gridArray);
  441.  
  442.         //exitRoom.transform.Translate(endPos);
  443.         //exitRoom.SetParams(endTilePos, new Vector2(paddingX, paddingY));
  444.         //exitRoom.PlaceRoom(ref this.gridArray);
  445.  
  446.     }
  447.  
  448.     public int[,] GenerateArray(int width, int height, bool initEmpty = true)
  449.     {
  450.         bool empty = initEmpty;
  451.         int[,] map = new int[width, height];
  452.         for (int x = 0; x < map.GetUpperBound(0); x++)
  453.         {
  454.  
  455.             for (int y = 0; y < map.GetUpperBound(1); y++)
  456.             {
  457.                 empty = initEmpty;
  458.                 //empty = (Mathf.RoundToInt(Random.Range(0.0f, 1.0f)) == 1 ? true : false);
  459.  
  460.                 //// Make sure we are not close to the start, or the exit
  461.                 //// Check for player within a certain number of tiles
  462.                 //float distToPlayer = Mathf.Abs(Vector2.Distance(TilePosToWorldPos(new Vector2(x, y)), player.transform.position))/16;
  463.                 //float distToExit = Mathf.Abs(Vector2.Distance(TilePosToWorldPos(new Vector2(x, y)), exit.transform.position))/16;
  464.  
  465.                 //if (distToPlayer <= startEndEmptySpace || distToExit <= startEndEmptySpace)
  466.                 //{
  467.                 //    empty = true;
  468.                 //}
  469.  
  470.                 if (x == map.GetUpperBound(0) - 1 || x == 0)
  471.                 {
  472.                     empty = false;
  473.                 }
  474.  
  475.                 if (y == map.GetUpperBound(1) - 1 || y == 0)
  476.                 {
  477.                     empty = false;
  478.                 }
  479.  
  480.  
  481.                 if (empty)
  482.                 {
  483.                     map[x, y] = 0;
  484.                 }
  485.                 else
  486.                 {
  487.                     map[x, y] = 1;
  488.                 }
  489.             }
  490.         }
  491.         return map;
  492.     }
  493.  
  494.     public int[,] RadiusCleanMap(int[,] map, Vector2 pos, int radius)
  495.     {
  496.         for (int x = 0; x < map.GetUpperBound(0); x++)
  497.         {
  498.             for (int y = 0; y < map.GetUpperBound(1); y++)
  499.             {
  500.                 int distance = Mathf.RoundToInt(Mathf.Abs(Vector2.Distance(TilePosToWorldPos(new Vector2(x, y), Utils.worldSpaceOriginVectors.center), pos)) / 16);
  501.                 if (distance <= radius)
  502.                 {
  503.                     map[x, y] = 0; // 0 = empty position. No tile
  504.                 }
  505.  
  506.                 // If it's an outside edge, don't remove it
  507.                 if (x == map.GetUpperBound(0) - 1 || x == 0)
  508.                 {
  509.                     map[x, y] = 1; // 1 = tile
  510.                 }
  511.                 if (y == map.GetUpperBound(1) - 1 || y == 0)
  512.                 {
  513.                     map[x, y] = 1; // 1 = tile
  514.                 }
  515.  
  516.             }
  517.         }
  518.  
  519.  
  520.         return map;
  521.     }
  522.  
  523.     public int[,] SquareCleanMap(ref int[,] map, Vector2 pos, int sizeX, int sizeY, bool useTile = false)
  524.     {
  525.         if (!useTile)
  526.         {
  527.             pos = WorldPosToTilePos(pos);
  528.         }
  529.  
  530.         int startX = (int)Mathf.Floor(pos.x);
  531.         int startY = (int)Mathf.Floor(pos.y);
  532.  
  533.         int stopX = (int)Mathf.Floor(pos.x + sizeX);
  534.         int stopY = (int)Mathf.Floor(pos.y + sizeY);
  535.  
  536.         // Iterate from posX to posX + sizeX
  537.         for (int x = startX; x <= stopX; x++)
  538.         {
  539.             // Iterate from posX to posX + sizeY
  540.             for (int y = startY; y <= stopY; y++)
  541.             {
  542.                 // Clean that space
  543.                 map[x, y] = 0;
  544.  
  545.                 // If it's an outside edge, put it back
  546.                 if (x == map.GetUpperBound(0) - 1 || x == 0)
  547.                 {
  548.                     map[x, y] = 1; // 1 = tile
  549.                 }
  550.                 if (y == map.GetUpperBound(1) - 1 || y == 0)
  551.                 {
  552.                     map[x, y] = 1; // 1 = tile
  553.                 }
  554.  
  555.             }
  556.         }
  557.  
  558.  
  559.         return map;
  560.     }
  561.  
  562.     public static Vector2 WorldPosToTilePos(Vector2 vector)
  563.     {
  564.         int thisX = Mathf.RoundToInt(vector.x / 16 + (xMax / 2));
  565.         int thisY = Mathf.RoundToInt(vector.y / 16 + (yMax / 2));
  566.  
  567.         return new Vector2(thisX, thisY);
  568.     }
  569.  
  570.     // 0,0 = 50%, 50%
  571.  
  572.     public static Vector2 TilePosToWorldPos(Vector2 vector, Vector2 worldSpaceOrigin)
  573.     {
  574.         int thisX = Mathf.RoundToInt((vector.x) - (xMax / 2));
  575.         int thisY = Mathf.RoundToInt((vector.y) - (yMax / 2));
  576.         int returnX = thisX * 16;
  577.         int returnY = thisY * 16;
  578.  
  579.  
  580.  
  581.         return new Vector2(returnX, returnY) + (8 * worldSpaceOrigin);
  582.     }
  583.  
  584.     public bool CanPlaceRoom(int[,] map, Vector2 pos, int sizeX, int sizeY, int padding = 1)
  585.     {
  586.  
  587.         int minX = Mathf.Clamp(Mathf.FloorToInt(pos.x - Mathf.CeilToInt(sizeX / 2)) - padding, 0, map.GetUpperBound(0));
  588.         int minY = Mathf.Clamp(Mathf.FloorToInt(pos.y - Mathf.CeilToInt(sizeY / 2)) - padding, 0, map.GetUpperBound(1));
  589.         int maxX = Mathf.Clamp(Mathf.CeilToInt(pos.x + Mathf.CeilToInt(sizeX / 2)) + padding, 0, map.GetUpperBound(0));
  590.         int maxY = Mathf.Clamp(Mathf.CeilToInt(pos.y + Mathf.CeilToInt(sizeY / 2)) + padding, 0, map.GetUpperBound(1));
  591.  
  592.         for (int x = minX; x < maxX; x++)
  593.         {
  594.             for (int y = minY; y < maxY; y++)
  595.             {
  596.                 int tmp = map[x, y];
  597.                 if (tmp == 0 /* This is empty space, so there's a room or hallway here */)
  598.                 {
  599.                     return false;
  600.                 }
  601.             }
  602.         }
  603.  
  604.         // <= This point
  605.         return true;
  606.     }
  607.  
  608.     public static void RenderMap(int[,] map, Tilemap tilemap, TileBase tile)
  609.     {
  610.         int halfX = map.GetUpperBound(0) / 2;
  611.         int halfY = map.GetUpperBound(1) / 2;
  612.         //Clear the map (ensures we dont overlap)
  613.         tilemap.ClearAllTiles();
  614.         //Loop through the width of the map
  615.         for (int x = 0; x < map.GetUpperBound(0); x++)
  616.         {
  617.             //Loop through the height of the map
  618.             for (int y = 0; y < map.GetUpperBound(1); y++)
  619.             {
  620.                 // 1 = tile, 0 = no tile
  621.                 if (map[x, y] == 1)
  622.                 {
  623.                     tilemap.SetTile(new Vector3Int(Mathf.RoundToInt(x - halfX), Mathf.RoundToInt(y - halfY), 0), tile);
  624.                 }
  625.             }
  626.         }
  627.     }
  628.  
  629.     public RoomClass getRoomInDirection(RoomClass room, Vector2 direction)
  630.     {
  631.         RoomClass empty = null;
  632.  
  633.         /* return an empty Vector2 if there is no room in that direction */
  634.         if (   room.GetRoomMapPos().x + direction.x > this.roomMap.GetUpperBound(0) || room.GetRoomMapPos().x + direction.x < this.roomMap.GetLowerBound(0)
  635.             || room.GetRoomMapPos().y + direction.y > this.roomMap.GetUpperBound(1) || room.GetRoomMapPos().y + direction.y < this.roomMap.GetLowerBound(1) )
  636.         {
  637.             return empty;
  638.         }
  639.  
  640.         Vector2 expectedRoomPos = room.GetRoomMapPos() + direction;
  641.  
  642.         /* Perform a check to see if a room with that position already exists on the room map */
  643.         foreach (RoomClass thisRoom in this.roomMap)
  644.         {
  645.             if (thisRoom.GetRoomMapPos() == expectedRoomPos)
  646.             {
  647.                 return thisRoom;
  648.             }
  649.         }
  650.  
  651.         /* Since each position in the roomsMap is prefilled with a new RoomClass,
  652.          * there is no scenario where we shouldn't return a room.
  653.          */
  654.  
  655.         return null;
  656.     }
  657.  
  658.     public struct RelativeNeighbors
  659.     {
  660.         public Vector2 Up, Down, Left, Right;
  661.         public Func<Vector2> GetRandomDirection;
  662.     }
  663.  
  664.     public Vector2 GetDirectionByIndex(int index)
  665.     {
  666.         switch (index)
  667.         {
  668.             case 0:
  669.                 return directions.Up;
  670.                 break;
  671.             case 1:
  672.                 return directions.Down;
  673.                 break;
  674.             case 2:
  675.                 return directions.Left;
  676.                 break;
  677.             case 3:
  678.                 return directions.Right;
  679.                 break;
  680.             default:
  681.                 break;
  682.         }
  683.         return Vector2.zero;
  684.     }
  685.  
  686.     public RoomType SetRoomType(RoomType[,] map, Vector2 roomPos, Vector2 direction)
  687.     {
  688.         RoomType currentRoomType = map[(int)roomPos.x, (int)roomPos.y];
  689.  
  690.         RoomType newRoom = RemoveWallInDirection(currentRoomType, direction);
  691.  
  692.         return newRoom;
  693.     }
  694.  
  695.     public RoomType RemoveWallInDirection(RoomType type, Vector2 direction)
  696.     {
  697.         /* Assuming the type value is the current room type, try to knock a wall down in direction and return a new room type */
  698.         switch (type)
  699.         {
  700.             case RoomType.OPEN_ALL:
  701.                 return RoomType.OPEN_ALL;
  702.                 break;
  703.             case RoomType.OPEN_N:
  704.                 switch (direction.x)
  705.                 {
  706.                     case 0:
  707.                         switch (direction.y)
  708.                         {
  709.                             case -1:
  710.                                 return RoomType.OPEN_E_W;
  711.                                 break;
  712.                             case 1:
  713.                                 return type;
  714.                                 break;
  715.                             default:
  716.                                 break;
  717.                         }
  718.                         break;
  719.                     case 1:
  720.                         return RoomType.OPEN_N_E;
  721.                         break;
  722.                     case -1:
  723.                         return RoomType.OPEN_N_W;
  724.                         break;
  725.                     default:
  726.                         break;
  727.                 }
  728.                 break;
  729.             case RoomType.OPEN_E:
  730.                 switch (direction.x)
  731.                 {
  732.                     case 0:
  733.                         switch (direction.y)
  734.                         {
  735.                             case -1:
  736.                                 return RoomType.OPEN_E_S;
  737.                                 break;
  738.                             case 1:
  739.                                 return RoomType.OPEN_N_E;
  740.                                 break;
  741.                             default:
  742.                                 break;
  743.                         }
  744.                         break;
  745.                     case 1:
  746.                         return type;
  747.                         break;
  748.                     case -1:
  749.                         return RoomType.OPEN_E_W;
  750.                         break;
  751.                     default:
  752.                         break;
  753.                 }
  754.                 break;
  755.             case RoomType.OPEN_S:
  756.                 switch (direction.x)
  757.                 {
  758.                     case 0:
  759.                         switch (direction.y)
  760.                         {
  761.                             case -1:
  762.                                 return type;
  763.                                 break;
  764.                             case 1:
  765.                                 return RoomType.OPEN_N_S;
  766.                                 break;
  767.                             default:
  768.                                 break;
  769.                         }
  770.                         break;
  771.                     case 1:
  772.                         return RoomType.OPEN_E_S;
  773.                         break;
  774.                     case -1:
  775.                         return RoomType.OPEN_S_W;
  776.                         break;
  777.                     default:
  778.                         break;
  779.                 }
  780.                 break;
  781.             case RoomType.OPEN_W:
  782.                 switch (direction.x)
  783.                 {
  784.                     case 0:
  785.                         switch (direction.y)
  786.                         {
  787.                             case -1:
  788.                                 return RoomType.OPEN_S_W;
  789.                                 break;
  790.                             case 1:
  791.                                 return RoomType.OPEN_N_W;
  792.                                 break;
  793.                             default:
  794.                                 break;
  795.                         }
  796.                         break;
  797.                     case 1:
  798.                         return RoomType.OPEN_E_W;
  799.                         break;
  800.                     case -1:
  801.                         return type;
  802.                         break;
  803.                     default:
  804.                         break;
  805.                 }
  806.                 break;
  807.             case RoomType.OPEN_N_E:
  808.                 switch (direction.x)
  809.                 {
  810.                     case 0:
  811.                         switch (direction.y)
  812.                         {
  813.                             case -1:
  814.                                 return RoomType.CLOSED_W;
  815.                                 break;
  816.                             case 1:
  817.                                 return type;
  818.                                 break;
  819.                             default:
  820.                                 break;
  821.                         }
  822.                         break;
  823.                     case 1:
  824.                         return type;
  825.                         break;
  826.                     case -1:
  827.                         return RoomType.CLOSED_S;
  828.                         break;
  829.                     default:
  830.                         break;
  831.                 }
  832.                 break;
  833.             case RoomType.OPEN_N_S:
  834.                 switch (direction.x)
  835.                 {
  836.                     case 0:
  837.                         return type;
  838.                         break;
  839.                     case 1:
  840.                         return RoomType.CLOSED_W;
  841.                         break;
  842.                     case -1:
  843.                         return RoomType.CLOSED_E;
  844.                         break;
  845.                     default:
  846.                         break;
  847.                 }
  848.                 break;
  849.             case RoomType.OPEN_N_W:
  850.                 switch (direction.x)
  851.                 {
  852.                     case 0:
  853.                         switch (direction.y)
  854.                         {
  855.                             case -1:
  856.                                 return RoomType.CLOSED_E;
  857.                                 break;
  858.                             case 1:
  859.                                 return type;
  860.                                 break;
  861.                             default:
  862.                                 break;
  863.                         }
  864.                         break;
  865.                     case 1:
  866.                         return RoomType.CLOSED_S;
  867.                         break;
  868.                     case -1:
  869.                         return type;
  870.                         break;
  871.                     default:
  872.                         break;
  873.                 }
  874.                 break;
  875.             case RoomType.OPEN_E_S:
  876.                 switch (direction.x)
  877.                 {
  878.                     case 0:
  879.                         switch (direction.y)
  880.                         {
  881.                             case -1:
  882.                                 return type;
  883.                                 break;
  884.                             case 1:
  885.                                 return RoomType.CLOSED_W;
  886.                                 break;
  887.                             default:
  888.                                 break;
  889.                         }
  890.                         break;
  891.                     case 1:
  892.                         return type;
  893.                         break;
  894.                     case -1:
  895.                         return RoomType.CLOSED_N;
  896.                         break;
  897.                     default:
  898.                         break;
  899.                 }
  900.                 break;
  901.             case RoomType.OPEN_E_W:
  902.                 if (direction.x == 0)
  903.                 {
  904.                     switch (direction.y)
  905.                     {
  906.                         case -1:
  907.                             return RoomType.CLOSED_N;
  908.                             break;
  909.                         case 1:
  910.                             return RoomType.CLOSED_S;
  911.                             break;
  912.                         default:
  913.                             break;
  914.                     }
  915.                 }else
  916.                 {
  917.                     return type;
  918.                 }
  919.                 break;
  920.             case RoomType.OPEN_S_W:
  921.                 switch (direction.x)
  922.                 {
  923.                     case 0:
  924.                         switch (direction.y)
  925.                         {
  926.                             case -1:
  927.                                 return type;
  928.                                 break;
  929.                             case 1:
  930.                                 return RoomType.CLOSED_E;
  931.                                 break;
  932.                             default:
  933.                                 break;
  934.                         }
  935.                         break;
  936.                     case 1:
  937.                         return RoomType.CLOSED_N;
  938.                         break;
  939.                     case -1:
  940.                         return type;
  941.                         break;
  942.                     default:
  943.                         break;
  944.                 }
  945.                 break;
  946.             case RoomType.CLOSED_N:
  947.                 if (direction.y == 1)
  948.                 {
  949.                     return RoomType.OPEN_ALL;
  950.                 }
  951.                 break;
  952.             case RoomType.CLOSED_S:
  953.                 if (direction.y == -1)
  954.                 {
  955.                     return RoomType.OPEN_ALL;
  956.                 }
  957.                 break;
  958.             case RoomType.CLOSED_E:
  959.                 if (direction.x == 1)
  960.                 {
  961.                     return RoomType.OPEN_ALL;
  962.                 }
  963.                 break;
  964.             case RoomType.CLOSED_W:
  965.                 if (direction.x == -1)
  966.                 {
  967.                     return RoomType.OPEN_ALL;
  968.                 }
  969.                 break;
  970.             case RoomType.CLOSED_ALL:
  971.                 switch (direction.x)
  972.                 {
  973.                     case 0:
  974.                         switch (direction.y)
  975.                         {
  976.                             case -1:
  977.                                 return RoomType.OPEN_S;
  978.                                 break;
  979.                             case 1:
  980.                                 return RoomType.OPEN_N;
  981.                                 break;
  982.                             default:
  983.                                 break;
  984.                         }
  985.                         break;
  986.                     case 1:
  987.                         return RoomType.OPEN_E;
  988.                         break;
  989.                     case -1:
  990.                         return RoomType.OPEN_W;
  991.                         break;
  992.                     default:
  993.                         break;
  994.                 }
  995.                 break;
  996.             default:
  997.                 break;
  998.         }
  999.  
  1000.         return RoomType.CLOSED_ALL;
  1001.     }
  1002.    
  1003. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top