Untitled

 avatar
unknown
plain_text
10 months ago
16 kB
5
Indexable
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.Mathematics;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;

public enum RoomTypes
{
    RoomStarting,
    RoomDefault,
    RoomHallway,
    RoomTreasure,
    RoomBoss
}

public class GridManager : MonoBehaviour
{
    private int _roomWidth;
    private int _roomHeight;
    [SerializeField] private int _defaultRoomWidth = 11;
    [SerializeField] private int _defaultRoomHeight = 11;
    [SerializeField] private Player _player; 
    [SerializeField] private GameObject _groupTiles;
    [SerializeField] private GameObject _groupWalls;

    public EnemieSpawner enemieSpawner;
    public RoomTypes roomTypes;
    private bool spawnedPlayerBool = false;

    private Dictionary<Vector2Int, Tile> _tiles;
    private Dictionary<Vector3, Wall> _walls;

    [SerializeField] private GameObject _hitBoxs;
    [SerializeField] private Tile[] _tilePrefabs; //tilePrefabs added like this instead
    [SerializeField] private Wall[] _wallPrefabs;

    public void OnStart(int _roomCount)
    {
        roomTypes = RoomTypes.RoomDefault;
        _tiles = new Dictionary<Vector2Int, Tile>();
        _walls = new Dictionary<Vector3, Wall>();
        GenerateDungeon(_roomCount, 0);
    }
    private void GenerateDungeon(int _roomCount, int level)
    {
    BiomeRegion[] biomeRegions = {
        BiomeRegion.Grey,
        BiomeRegion.Red,
        BiomeRegion.Purple,
        BiomeRegion.Blue,
        BiomeRegion.Green,
        BiomeRegion.Yellow,
        BiomeRegion.White

        };
        Vector2Int tempRoom = new Vector2Int(0, 0);
        BiomeRegion region = (level >= 0 && level < biomeRegions.Length) ? biomeRegions[level] : BiomeRegion.White;
        GenerateDungeonRoom(0, 0, region, RoomTypes.RoomStarting);
        enemieSpawner.OnStart(_roomWidth, _roomHeight);

        for (int i = 1; i < _roomCount; i++)
        {
            if (i >= 1 && i < _roomCount - 1) { roomTypes = RoomTypes.RoomDefault; }
            if (i == _roomCount - 1) { roomTypes = RoomTypes.RoomBoss; }

            int randomX = 0; int randomY = 0;
            if (UnityEngine.Random.Range(0, 2) == 0)
            {
                randomX = UnityEngine.Random.Range(0, 2) == 0 ? -1 : 1;
                randomY = 0;
            }
            else
            {
                randomX = 0;
                randomY = UnityEngine.Random.Range(0, 2) == 0 ? -1 : 1;
            }
            for (int t = 0; t < 100 && GetWallAtPosition(new Vector2Int((tempRoom.x + randomX) * (_roomWidth + 1), (tempRoom.y + randomY) * (_roomHeight + 1))) != null; t++)
            {
                if (UnityEngine.Random.Range(0, 2) == 0)
                {
                    randomX = UnityEngine.Random.Range(0, 2) == 0 ? -1 : 1;
                    randomY = 0;
                }
                else
                {
                    randomX = 0;
                    randomY = UnityEngine.Random.Range(0, 2) == 0 ? -1 : 1;
                }
                for (int x = 0; x <= _roomWidth; x++)
                {
                    for (int y = 0; y <= _roomWidth; y++)
                    {
                        if(GetWallAtPosition(new Vector2Int((tempRoom.x + randomX) * x, (tempRoom.y + randomY) * y)) != null){
                            if (UnityEngine.Random.Range(0, 2) == 0)
                            {
                                randomX = UnityEngine.Random.Range(0, 2) == 0 ? -1 : 1;
                                randomY = 0;
                            }
                            else
                            {
                                randomX = 0;
                                randomY = UnityEngine.Random.Range(0, 2) == 0 ? -1 : 1;
                            }
                        }
                    }
                }
            }
            tempRoom = new Vector2Int(tempRoom.x + randomX, tempRoom.y + randomY);
            if(roomTypes == RoomTypes.RoomBoss){
                Debug.Log(_walls);
                if(randomX == -1){
                    GenerateDungeonRoom(tempRoom.x * (_roomWidth + 1) - 9, tempRoom.y * (_roomHeight + 1) -2, region, roomTypes);
                }
                else if(randomY == -1){
                    GenerateDungeonRoom(tempRoom.x * (_roomWidth + 1) -2, tempRoom.y * (_roomHeight + 1) - 9, region, roomTypes);
                }
                else {
                    Debug.LogError("Couldnt spawn bossroom, retrying"); 
                    Debug.ClearDeveloperConsole();
                    ClearLevel();
                    GenerateDungeon(_roomCount, level);
                }
            }
            else {
            GenerateDungeonRoom(tempRoom.x * (_roomWidth + 1), tempRoom.y * (_roomHeight + 1), region, roomTypes);
            }
        }
    }
    private void GenerateDungeonRoom(int offSetX, int offSetY, BiomeRegion region, RoomTypes RoomType) //Remade:
    {
    
        switch (RoomType)
        {
            case RoomTypes.RoomDefault:
                _roomWidth = _defaultRoomWidth;
                _roomHeight = _defaultRoomHeight;
                break;
            case RoomTypes.RoomStarting:
                _roomWidth = 11;
                _roomHeight = 11;
                break;
            case RoomTypes.RoomHallway:
                _roomWidth = 11;
                _roomHeight = 11;
                break;
            case RoomTypes.RoomTreasure:
                _roomWidth = 9;
                _roomHeight = 9;
                break;
            case RoomTypes.RoomBoss:
                _roomWidth = 20;
                _roomHeight = 20;
                break;
        }
        //enemieSpawner.OnStart(offSetX, offSetY);
        for (int x = offSetX; x < _roomWidth + offSetX; x++)
        {
            for (int y = offSetY; y < _roomHeight + offSetY; y++)
            {
                Quaternion rotation = GetRandomRotation();

                Tile selectedTilePrefab = _tilePrefabs[UnityEngine.Random.Range(0, _tilePrefabs.Length)];
                Wall selectedWallPrefab = _wallPrefabs[UnityEngine.Random.Range(0, _wallPrefabs.Length)];

                Vector3 positionTile = new Vector3(x, y, 0);
                Vector3 positionWall = new Vector3(x, y, (float)-.5);
                bool isOffset = (x + y) % 2 != 0;
                if (x == Math.Round((double)_roomWidth / 2) - 1 && y == Math.Round((double)_roomHeight / 2) - 1 && !spawnedPlayerBool)
                { // player spawn, inneficient because it checks every square if its  4,4 will make it better
                    Vector3 spawnPosition = new Vector3(x, y, 0);
                    Player spawnedPlayer = Instantiate(_player, spawnPosition, Quaternion.identity);
                    spawnedPlayerBool = true;
                }
                if ((x >= offSetX && y == offSetY)
                        || (x >= offSetX && y == _roomHeight + offSetY - 1)
                        || (x == offSetX && y >= offSetY)
                        || (x == _roomWidth + offSetX - 1 && y >= offSetY))
                { // Bad code but works.
                    Wall spawnedWall = Instantiate(selectedWallPrefab, positionWall, rotation, _groupWalls.transform);
                    Instantiate(_hitBoxs, new Vector3(positionWall.x, positionWall.y, 0), rotation, spawnedWall.transform);
                    spawnedWall.name = $"Wall {x}:{y}";
                    spawnedWall.Init(isOffset, region);
                    _walls[new Vector3(x, y, (int)-.5)] = spawnedWall;

                }
                else
                {
                    Tile spawnedTile = Instantiate(selectedTilePrefab, positionTile, rotation, _groupTiles.transform);
                    spawnedTile.name = $"Tile {x}:{y}";
                    spawnedTile.Init(isOffset, region);
                    _tiles[new Vector2Int(x, y)] = spawnedTile;
                }
                CreateCoridors(offSetX, offSetY, region);
            }
        }
    }
    private Quaternion GetRandomRotation()
    {
        int randomAngle = UnityEngine.Random.Range(0, 2) * 180; //Rotation of tiles, (0, 4) * 90 will do either 0 90 180 270 
        return Quaternion.Euler(0, 0, randomAngle);
    }
    private void CreateCoridors(int offSetX, int offSetY, BiomeRegion region)
    {
        int halfRoomH = (int)System.Math.Floor(_roomHeight / 2.0);   // Below +1 is the void (and +0 or just the value is the room your in)
        int halfRoomW = (int)System.Math.Floor(_roomWidth / 2.0);    // And +2 is the rooms thats not the one your on but the one your checking.

        var directions = new Dictionary<string, (Vector2Int checkOffset, Vector2Int removeOffset1, Vector2Int removeOffset2, Vector2Int removeOffset3, Vector2Int placeOffset1, Vector2Int placeOffset2)>
        {
            {"LEFT", (new Vector2Int(halfRoomW + 2, 1), new Vector2Int(halfRoomW, 0), new Vector2Int(halfRoomW + 2, 0), new Vector2Int(halfRoomW + 1, 0), new Vector2Int(halfRoomW + 1, 1), new Vector2Int(halfRoomW + 1, -1))},
            {"RIGHT", (new Vector2Int(-(halfRoomW + 2), 1), new Vector2Int(-halfRoomW, 0), new Vector2Int(-(halfRoomW + 2), 0), new Vector2Int(-(halfRoomW + 1), 0), new Vector2Int(-(halfRoomW + 1), 1), new Vector2Int(-(halfRoomW + 1), -1))},
            {"UP", (new Vector2Int(1, halfRoomH + 2), new Vector2Int(0, halfRoomH), new Vector2Int(0, halfRoomH + 2), new Vector2Int(0, halfRoomH + 1), new Vector2Int(1, halfRoomH + 1), new Vector2Int(-1, halfRoomH + 1))},
            {"DOWN", (new Vector2Int(1, -(halfRoomH + 2)), new Vector2Int(0, -halfRoomH), new Vector2Int(0, -(halfRoomH + 2)), new Vector2Int(0, -(halfRoomH + 1)), new Vector2Int(1, -(halfRoomH + 1)), new Vector2Int(-1, -(halfRoomH + 1)))}
        };

        foreach (var direction in directions)
        {
            var (checkOffset, removeOffset1, removeOffset2, removeOffset3, placeOffset1, placeOffset2) = direction.Value;

            Vector2Int checkPos = CalculateReturnVec2(offSetX, offSetY, checkOffset.x, checkOffset.y);
            if (GetWallAtPosition(checkPos) != null)
            {
                Vector3 removePos1 = CalculateReturnVec3(offSetX, offSetY, removeOffset1.x, removeOffset1.y);
                Vector3 removePos2 = CalculateReturnVec3(offSetX, offSetY, removeOffset2.x, removeOffset2.y);

                RemoveWallIfExists(removePos1);
                RemoveWallIfExists(removePos2);

                PlaceWallIfNotExists(CalculateReturnVec2(offSetX, offSetY, placeOffset1.x, placeOffset1.y), region); //Walls in the void 1
                PlaceWallIfNotExists(CalculateReturnVec2(offSetX, offSetY, placeOffset2.x, placeOffset2.y), region); //Walls in the void 2

                PlaceTileIfNotExists(CalculateReturnVec2(offSetX, offSetY, removeOffset1.x, removeOffset1.y), region);                                 // Spawns the tile closest to Room
                PlaceTileIfNotExists(CalculateReturnVec2(offSetX, offSetY, removeOffset3.x, removeOffset3.y), region);                                 // Spawns tile inbetween Rooms
                PlaceTileIfNotExists(CalculateReturnVec2(offSetX, offSetY, removeOffset2.x, removeOffset2.y), GetWallAtPosition(checkPos).biomeRegion);// Spawns tile on the other room, using its region
            }
        }
    }
    private Vector2Int CalculateReturnVec2(double offSetX, double offSetY, int MultiX, int MultiY)
    {
        double x = offSetX + _roomWidth - 1 - _roomWidth / 2.0 + MultiX;
        double y = offSetY + _roomHeight - 1 - _roomHeight / 2.0 + MultiY;
        int roundedX = (int)System.Math.Ceiling(x);
        int roundedY = (int)System.Math.Ceiling(y);

        return new Vector2Int(roundedX, roundedY);
    }
    private Vector3 CalculateReturnVec3(int offSetX, int offSetY, int MultiX, int MultiY)
    {
        double x = offSetX + _roomWidth - 1 - _roomWidth / 2.0 + MultiX;
        double y = offSetY + _roomHeight - 1 - _roomHeight / 2.0 + MultiY;
        int roundedX = (int)System.Math.Ceiling(x);
        int roundedY = (int)System.Math.Ceiling(y);

        return new Vector3(roundedX, roundedY, (int)-0.5);
    }
    private void PlaceWallAtPosition(Vector2 position, BiomeRegion region)
    {
        Quaternion rotation = GetRandomRotation();
        Wall spawnedWallPrefab = _wallPrefabs[UnityEngine.Random.Range(0, _wallPrefabs.Length)];
        bool isOffset = ((int)position.x + (int)position.y) % 2 != 0;

        if (!_tiles.ContainsKey(new Vector2Int((int)position.x, (int)position.y)))
        {
            Wall spawnedWall = Instantiate(spawnedWallPrefab, new Vector3(position.x, position.y, (float)-0.5), rotation, _groupTiles.transform);
            Instantiate(_hitBoxs, new Vector3(position.x, position.y, (float)-0.5), rotation, spawnedWall.transform);
            spawnedWall.name = $"Wall {position.x}:{position.y}";
            spawnedWall.Init(isOffset, region);
            _walls[new Vector3((int)position.x, (int)position.y, (int)-.5)] = spawnedWall;
        }
    }
    private void PlaceTileAtPosition(Vector2Int position, BiomeRegion region)
    {
        Quaternion rotation = GetRandomRotation();
        Tile selectedTilePrefab = _tilePrefabs[UnityEngine.Random.Range(0, _tilePrefabs.Length)];
        bool isOffset = ((int)position.x + (int)position.y) % 2 != 0;

        if (!_tiles.ContainsKey(new Vector2Int((int)position.x, (int)position.y)))
        {
            Tile spawnedTile = Instantiate(selectedTilePrefab, new Vector3(position.x, position.y, 0), rotation, _groupTiles.transform);
            spawnedTile.name = $"Tile {position.x}:{position.y}";
            spawnedTile.Init(isOffset, region);
            _tiles[new Vector2Int((int)position.x, (int)position.y)] = spawnedTile;
        }
    }
    private void PlaceWallIfNotExists(Vector2 position, BiomeRegion region)
    {
        if (!_walls.ContainsKey(new Vector3(position.x, position.y, (int)-.5)))
        {
            PlaceWallAtPosition(position, region);
        }
    }
    private void PlaceTileIfNotExists(Vector2Int position, BiomeRegion region)
    {
        if (!_tiles.ContainsKey(position))
        {
            PlaceTileAtPosition(position, region);
        }
    }
    private void RemoveWallIfExists(Vector3 pos)
    {
        if (_walls.TryGetValue(pos, out Wall wall))
        {
            Destroy(wall.gameObject);
            _walls.Remove(pos);
        }
    }
    public Wall GetWallAtPosition(Vector2Int pos)
    { // Wracked my brain over this
        if (_walls.TryGetValue(new Vector3(pos.x, pos.y, (int)-.5), out var wall))
            return wall;
        return null;
    }
    public Tile GetTileAtPosition(Vector2Int pos)
    {
        if (_tiles.TryGetValue(pos, out var tile))
            return tile;
        return null;
    }
    public void ClearLevel()
    {
        foreach (var tile in _tiles.Values)
        {
            Destroy(tile.gameObject);
        }
        foreach (var wall in _walls.Values)
        {
            Destroy(wall.gameObject);
        }
        foreach (Transform child in _groupTiles.transform)
        {
            Destroy(child.gameObject);
        }
        foreach (Transform child in _groupWalls.transform)
        {
            Destroy(child.gameObject);
        }
        _walls.Clear();
        _tiles.Clear();
    }
}
Editor is loading...
Leave a Comment