diff options
Diffstat (limited to 'scripts/map')
| -rw-r--r-- | scripts/map/DungeonGenerator.cs | 272 | ||||
| -rw-r--r-- | scripts/map/DungeonGenerator.cs.uid | 1 | ||||
| -rw-r--r-- | scripts/map/FieldOfView.cs | 96 | ||||
| -rw-r--r-- | scripts/map/FieldOfView.cs.uid | 1 | ||||
| -rw-r--r-- | scripts/map/Map.cs | 86 | ||||
| -rw-r--r-- | scripts/map/Map.cs.uid | 1 | ||||
| -rw-r--r-- | scripts/map/MapData.cs | 272 | ||||
| -rw-r--r-- | scripts/map/MapData.cs.uid | 1 | ||||
| -rw-r--r-- | scripts/map/MapDivision.cs | 98 | ||||
| -rw-r--r-- | scripts/map/MapDivision.cs.uid | 1 | ||||
| -rw-r--r-- | scripts/map/Tile.cs | 81 | ||||
| -rw-r--r-- | scripts/map/Tile.cs.uid | 1 | ||||
| -rw-r--r-- | scripts/map/TileDefinition.cs | 22 | ||||
| -rw-r--r-- | scripts/map/TileDefinition.cs.uid | 1 |
14 files changed, 0 insertions, 934 deletions
diff --git a/scripts/map/DungeonGenerator.cs b/scripts/map/DungeonGenerator.cs deleted file mode 100644 index cb89508..0000000 --- a/scripts/map/DungeonGenerator.cs +++ /dev/null @@ -1,272 +0,0 @@ -using Godot; - -/// <summary> -/// A classe dungeonGenerator cria exatamente um andar da masmorra. -/// Ela é chamada quando necessário. -/// </summary> -public partial class DungeonGenerator : Node -{ - /// <summary> - /// Coleção de todos os inimigos que o gerador tem acesso. - /// </summary> - private static readonly Godot.Collections.Array<EnemyDefinition> enemies = [ - GD.Load<EnemyDefinition>("res://assets/definitions/actor/Skeleton.tres"), - GD.Load<EnemyDefinition>("res://assets/definitions/actor/morcegao.tres"), - GD.Load<EnemyDefinition>("res://assets/definitions/actor/Shadow.tres"), - ]; - - private static readonly Godot.Collections.Array<ConsumableItemDefinition> items = [ - GD.Load<HealingConsumableDefinition>("res://assets/definitions/Items/small_healing_potion.tres") - ]; - - /// <summary> - /// Dimensões do mapa a ser criado. - /// </summary> - [ExportCategory("Dimension")] - [Export] - private int width = 80; - [Export] - private int height = 60; - - /// <summary> - /// Gerador de números aleatórios - /// </summary> - [ExportCategory("RNG")] - private RandomNumberGenerator rng = new(); - /// <summary> - /// Qual seed utilizar. - /// </summary> - [Export] - private ulong seed; - /// <summary> - /// Se será utilizada a nossa seed ou a seed padrão da classe RandomNumberGenerator. - /// </summary> - [Export] - private bool useSeed = true; - /// <summary> - /// Quantas iterações do algoritmo chamar. - /// </summary> - [Export] - private int iterations = 3; - - /// <summary> - /// Quantidade máxima de inimigos por sala. - /// </summary> - [ExportCategory("Monster RNG")] - [Export] - private int maxMonsterPerRoom = 2; - - /// <summary> - /// Quantidade máxima de itens por sala. - /// </summary> - [ExportCategory("Loot RNG")] - [Export] - private int maxItemsPerRoom = 2; - - public override void _Ready() - { - base._Ready(); - if (useSeed) { - rng.Seed = seed; - } - } - - /// <summary> - /// Transforma o tile da posição especificada em chão. - /// </summary> - /// <param name="data">o mapa</param> - /// <param name="pos">posição para colocar o chão.</param> - private static void CarveTile(MapData data, Vector2I pos) - { - Tile tile = data.GetTile(pos); - if (tile == null) return; - - tile.SetDefinition(MapData.floorDefinition); - } - - /// <summary> - /// Preenche uma área retangular com chão. - /// </summary> - /// <param name="data">O mapa</param> - /// <param name="room">Área para preencher com chão</param> - private static void CarveRoom(MapData data, Rect2I room) - { - for (int y = room.Position.Y; y < room.End.Y; y++) - { - for (int x = room.Position.X; x < room.End.X; x++) - { - CarveTile(data, new Vector2I(x, y)); - } - } - } - - /// <summary> - /// Gera um andar da masmorra. - /// Inimigos são colocados conforme configurações. - /// O jogador é colocado na primeira sala gerada. - /// </summary> - /// <param name="player">Jogador.</param> - /// <returns>O mapa gerado.</returns> - public MapData GenerateDungeon(Player player) - { - MapData data = new MapData(width, height, player); - - // Divisão mestre que engloba o mapa inteiro. - MapDivision root = new MapDivision(0, 0, width, height); - - // Chama o algoritmo para dividir o mapa. - root.Split(iterations, rng); - - bool first = true; - - // Coloca os corredores. - TunnelDivisions(data, root); - - // Cria as salas com base nas divisões geradas. - foreach(MapDivision division in root.GetLeaves()) - { - Rect2I room = new(division.Position, division.Size); - - // A sala não pode oculpar a divisão inteira, senão não haveriam paredes. - room = room.GrowIndividual( - -rng.RandiRange(1, 2), - -rng.RandiRange(1, 2), - -rng.RandiRange(1, 2), - -rng.RandiRange(1, 2) - ); - - // De fato cria a sala. - CarveRoom(data, room); - // Colocamos o jogador na primeira sala. - if (first) - { - first = false; - player.GridPosition = room.GetCenter(); - } - // Colocamos os inimigos na sala. - PlaceEntities(data, room); - } - - // Feito o mapa, inicializamos o algoritmo de pathfinding. - data.SetupPathfinding(); - return data; - } - - /// <summary> - /// Popula uma sala com inimigos. - /// </summary> - /// <param name="data">O mapa</param> - /// <param name="room">A sala.</param> - private void PlaceEntities(MapData data, Rect2I room) { - // Define quantos monstros serão colocados na sala - int monsterAmount = rng.RandiRange(0, maxMonsterPerRoom); - // Define quantos itens serão colocados na sala. - int itemAmount = rng.RandiRange(0, maxItemsPerRoom); - - for (int i = 0; i < monsterAmount; i++) { - // Escolhe um lugar aleatório na sala. - Vector2I position = new( - rng.RandiRange(room.Position.X, room.End.X - 1), - rng.RandiRange(room.Position.Y, room.End.Y - 1) - ); - - // Só podemos colocar um ator por ponto no espaço. - bool canPlace = true; - foreach (Entity entity in data.Entities) { - if (entity.GridPosition == position) { - canPlace = false; - break; - } - } - - // Se possível, criamos um inimigo aleatório na posição escolhida. - if (canPlace) { - EnemyDefinition definition = enemies.PickRandom(); - Enemy enemy = new(position, data, definition); - data.InsertEntity(enemy); - } - } - - for (int i = 0; i < itemAmount; i++) { - // Escolhe um lugar aleatório na sala. - Vector2I position = new( - rng.RandiRange(room.Position.X, room.End.X - 1), - rng.RandiRange(room.Position.Y, room.End.Y - 1) - ); - - // Só podemos colocar um ator por ponto no espaço. - bool canPlace = true; - foreach (Entity entity in data.Entities) { - if (entity.GridPosition == position) { - canPlace = false; - break; - } - } - - // Se possível, criamos um inimigo aleatório na posição escolhida. - if (canPlace) { - ConsumableItemDefinition definition = items.PickRandom(); - if (definition is HealingConsumableDefinition hcDefinition) { - HealingConsumable item = new(position, data, hcDefinition); - data.InsertEntity(item); - } - } - } - } - - /// <summary> - /// Preenche uma linha horizontal com chão. - /// </summary> - /// <param name="data">O mapa</param> - /// <param name="y">Eixo y do corredor.</param> - /// <param name="xBegin">Início do corredor</param> - /// <param name="xEnd">Final do corredor.</param> - private static void HorizontalCorridor(MapData data, int y, int xBegin, int xEnd) { - int begin = (xBegin < xEnd) ? xBegin : xEnd; - int end = (xEnd > xBegin) ? xEnd : xBegin; - for (int i = begin; i <= end; i++) { - CarveTile(data, new Vector2I(i, y)); - } - } - - /// <summary> - /// Preenche uma linha vertical com chão. - /// </summary> - /// <param name="data">O mapa.</param> - /// <param name="x">Eixo x do corredor.</param> - /// <param name="yBegin">Início do corredor</param> - /// <param name="yEnd">Final do corredor.</param> - private static void VerticalCorridor(MapData data, int x, int yBegin, int yEnd) { - int begin = (yBegin < yEnd) ? yBegin : yEnd; - int end = (yEnd > yBegin) ? yEnd : yBegin; - for (int i = begin; i <= end; i++) { - CarveTile(data, new Vector2I(x, i)); - } - } - - /// <summary> - /// Cria corredores vertical e horizontal para unir dois pontos no mapa. - /// </summary> - /// <param name="data">O mapa</param> - /// <param name="start">Ponto inicial</param> - /// <param name="end">Ponto final.</param> - private static void TunnelBetween(MapData data, Vector2I start, Vector2I end) { - HorizontalCorridor(data, start.Y, start.X, end.X); - VerticalCorridor(data, end.X, start.Y, end.Y); - } - - /// <summary> - /// Cria recursivamente corredores entre o centro de cada divisão do mapa. - /// </summary> - /// <param name="data">O mapa</param> - /// <param name="root">Divisão mestre.</param> - private static void TunnelDivisions(MapData data, MapDivision root) { - if (root.IsLeaf) { - return; - } - - TunnelBetween(data, root.Right.Center, root.Left.Center); - TunnelDivisions(data, root.Left); - TunnelDivisions(data, root.Right); - } -} diff --git a/scripts/map/DungeonGenerator.cs.uid b/scripts/map/DungeonGenerator.cs.uid deleted file mode 100644 index 15aeef6..0000000 --- a/scripts/map/DungeonGenerator.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dwyr067lwqcsj diff --git a/scripts/map/FieldOfView.cs b/scripts/map/FieldOfView.cs deleted file mode 100644 index bdcd206..0000000 --- a/scripts/map/FieldOfView.cs +++ /dev/null @@ -1,96 +0,0 @@ -using Godot; - -// Copiado e adaptado deste cara aqui: https://www.roguebasin.com/index.php?title=C%2B%2B_shadowcasting_implementation e deste também https://selinadev.github.io/08-rogueliketutorial-04/ - -// Eu não vou mentir, li como o algoritmo funciona, mas mesmo assim não entendi. - -public partial class FieldOfView : Node { - - private Godot.Collections.Array<Tile> fov = []; - - private static int[,] multipliers = new int[4,8]{ - {1, 0, 0, -1, -1, 0, 0, 1}, - {0, 1, -1, 0, 0, -1, 1, 0}, - {0, 1, 1, 0, 0, -1, -1, 0}, - {1, 0, 0, 1, -1, 0, 0, -1} - }; - private void CastLight(MapData data, Vector2I pos, int radius, int row, float startSlope, float endSlope, int xx, int xy, int yx, int yy) { - if (startSlope < endSlope) { - return; - } - - float nextStartSlope = startSlope; - for (int i = row; i <= radius; i++) - { - bool blocked = false; - for (int dx = -i, dy = -i; dx <= 0; dx++) - { - float lSlope = (float)((dx - 0.5) / (dy + 0.5)); - float rSlope = (float)((dx + 0.5) / (dy - 0.5)); - - if (startSlope < rSlope) - { - continue; - } - else if (endSlope > lSlope) - { - break; - } - - int sax = dx * xx + dy * xy; - int say = dx * yx + dy * yy; - - if ((sax < 0 && int.Abs(sax) > pos.X) || (say < 0 && int.Abs(say) > pos.Y)) { - continue; - } - int ax = pos.X + sax; - int ay = pos.Y + say; - - if (ax >= data.Width || ay >= data.Height) { - continue; - } - - Tile currentTile = data.GetTile(ax, ay); - int radius2 = radius * radius; - if ((dx * dx + dy * dy) < radius2) { - currentTile.IsInView = true; - fov.Add(currentTile); - } - - if (blocked) { - if (!currentTile.IsTransparent) { - nextStartSlope = rSlope; - continue; - } else { - blocked = false; - startSlope = nextStartSlope; - } - } else if (!currentTile.IsTransparent) { - blocked = true; - nextStartSlope = rSlope; - CastLight(data, pos, radius, i + 1, startSlope, lSlope, xx, xy, yx, yy); - } - } - if (blocked) { - break; - } - } - } - - private void ClearFOV() { - foreach (Tile tile in fov) { - tile.IsInView = false; - } - fov.Clear(); - } - - public void UpdateFOV(MapData data, Vector2I position, int radius) { - ClearFOV(); - Tile start = data.GetTile(position); - start.IsInView = true; - fov.Add(start); - for (int i = 0; i < 8; i++) { - CastLight(data, position, radius, 1, 1.0f, 0.0f, multipliers[0, i], multipliers[1, i], multipliers[2, i], multipliers[3, i]); - } - } -} diff --git a/scripts/map/FieldOfView.cs.uid b/scripts/map/FieldOfView.cs.uid deleted file mode 100644 index a173ff3..0000000 --- a/scripts/map/FieldOfView.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bereyrj1s46y5 diff --git a/scripts/map/Map.cs b/scripts/map/Map.cs deleted file mode 100644 index 148bda6..0000000 --- a/scripts/map/Map.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Godot; - -/// <summary> -/// A parte visual do mapa. -/// </summary> -public partial class Map : Node2D -{ - /// <summary> - /// Dados do mapa. - /// </summary> - public MapData Map_Data { get; private set; } - - /// <summary> - /// raio de alcance da visão do jogador. - /// </summary> - [Export] - private int fovRadius = 12; - - /// <summary> - /// Gerador de mapas. - /// </summary> - private DungeonGenerator generator; - - FieldOfView fieldOfView; - - private Node2D tilesNode; - private Node2D entitiesNode; - - public override void _Ready() - { - base._Ready(); - // Começamos obtendo nós relevantes para o mapa. - generator = GetNode<DungeonGenerator>("Generator"); - fieldOfView = GetNode<FieldOfView>("FieldOfView"); - tilesNode = GetNode<Node2D>("Tiles"); - entitiesNode = GetNode<Node2D>("Entities"); - } - - /// <summary> - /// Coloca todos os tiles do mapa no mundo do jogo. - /// </summary> - private void PlaceTiles() { - foreach (Tile tile in Map_Data.Tiles) { - tilesNode.AddChild(tile); - } - } - - /// <summary> - /// Coloca todas as entidades do mapa no mundo do jogo. - /// </summary> - private void PlaceEntities() { - foreach (Entity entity in Map_Data.Entities) { - entitiesNode.AddChild(entity); - } - } - - /// <summary> - /// Cria um andar da masmorra utilizando o gerador de mapa. - /// </summary> - /// <param name="player">O gerador de mapas precisa do jogador.</param> - public void Generate(Player player) - { - Map_Data = generator.GenerateDungeon(player); - - Map_Data.EntityPlaced += OnEntityPlaced; - - PlaceTiles(); - PlaceEntities(); - } - - /// <summary> - /// Atualiza o campo de visão do mapa com base em uma coordenada. - /// </summary> - /// <param name="pos">Centro de visão, normalmente é a posição do jogador.</param> - public void UpdateFOV(Vector2I pos) { - fieldOfView.UpdateFOV(Map_Data, pos, fovRadius); - // Esconde ou revela entidades com base no campo de visão. - foreach (Entity entity in Map_Data.Entities) { - entity.Visible = Map_Data.GetTile(entity.GridPosition).IsInView; - } - } - - private void OnEntityPlaced(Entity entity) { - entitiesNode.AddChild(entity); - } -} diff --git a/scripts/map/Map.cs.uid b/scripts/map/Map.cs.uid deleted file mode 100644 index 7306888..0000000 --- a/scripts/map/Map.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://fe2h4is11tnw diff --git a/scripts/map/MapData.cs b/scripts/map/MapData.cs deleted file mode 100644 index f3e193e..0000000 --- a/scripts/map/MapData.cs +++ /dev/null @@ -1,272 +0,0 @@ -using Godot; - -/// <summary> -/// Classe que cuida dos dados e da parte lógica do mapa. -/// O mapa é o cenário onde as ações do jogo ocorrem. -/// Mais especificamente, o mapa é um único andar da masmorra. -/// </summary> -public partial class MapData : RefCounted -{ - public static readonly TileDefinition wallDefinition = GD.Load<TileDefinition>("res://assets/definitions/tiles/wall.tres"); - public static readonly TileDefinition floorDefinition = GD.Load<TileDefinition>("res://assets/definitions/tiles/floor.tres"); - - [Signal] - public delegate void EntityPlacedEventHandler(Entity entity); - - /// <summary> - /// Largura do mapa. - /// </summary> - public int Width { get; private set; } - /// <summary> - /// Altura do mapa. - /// </summary> - public int Height { get; private set; } - - /// <summary> - /// Os tiles que compõem o mapa. - /// </summary> - public Godot.Collections.Array<Tile> Tiles { get; private set; } = []; - - /// <summary> - /// O jogador é especial e por isso o mapa faz questão de rastreá-lo. - /// </summary> - public Player Player { get; set; } - /// <summary> - /// Lista de todos os atores dentro do mapa. - /// </summary> - public Godot.Collections.Array<Entity> Entities { get; private set; } = []; - - public Godot.Collections.Array<ConsumableItem> Items { - get { - Godot.Collections.Array<ConsumableItem> list = []; - foreach (Entity entity in Entities) { - if (entity is ConsumableItem item) { - list.Add(item); - } - } - return list; - } - } - - private AStarGrid2D pathfinder; - /// <summary> - /// Objeto do Godot que utiliza do algoritmo A* para calcular - /// caminhos e rotas. - /// </summary> - public AStarGrid2D Pathfinder { get => pathfinder; } - /// <summary> - /// Peso do ator no pathfinder. - /// A IA irá evitar de passar por espaços com peso alto. - /// </summary> - private static readonly float EntityWeight = 10.0f; - - /// <summary> - /// Inicializa o pathfinder; - /// </summary> - public void SetupPathfinding() { - pathfinder = new AStarGrid2D - { - //A região é o mapa inteiro. - Region = new Rect2I(0, 0, Width, Height) - }; - - // Atualiza o pathfinder para a região definida. - pathfinder.Update(); - - // Define quais pontos do mapa são passáveis ou não. - for (int y = 0; y < Height; y++) { - for (int x = 0; x < Width; x++) { - Vector2I pos = new Vector2I(x, y); - Tile tile = GetTile(pos); - // Pontos sólidos são impossíveis de passar. - pathfinder.SetPointSolid(pos, !tile.IsWalkable); - } - } - - // Registra todos os atores em cena. - foreach (Entity entity in Entities) { - if (entity.BlocksMovement) { - RegisterBlockingEntity(entity); - } - } - - } - - /// <summary> - /// Define um peso na posição de uma entidade para que a IA evite de passar por lá. - /// Ênfase em evitar. Se o único caminho para o destino estiver bloqueado - /// por uma entidade, o jogo tentará andar mesmo assim. - /// </summary> - /// <param name="entity">A entidade em questão.</param> - public void RegisterBlockingEntity(Entity entity) { - pathfinder.SetPointWeightScale(entity.GridPosition, EntityWeight); - } - - /// <summary> - /// Remove o peso na posição de uma entidade. - /// Quando uma entidade move sua posição, devemos tirar o peso de sua posição anterior. - /// </summary> - /// <param name="entity">A entidade em questão.</param> - public void UnregisterBlockingEntity(Entity entity) { - pathfinder.SetPointWeightScale(entity.GridPosition, 0); - } - - public MapData(int width, int height, Player player) { - Width = width; - Height = height; - - Player = player; - // Como o jogador é criado antes do mapa, precisamos - // atualizá-lo com o novo mapa. - player.Map_Data = this; - InsertEntity(player); - - SetupTiles(); - } - - /// <summary> - /// Cria novos Tiles até preencher as dimensões do mapa. - /// É importante que estes tiles sejam paredes, o gerador de mapas - /// não cria paredes por conta própria. - /// </summary> - private void SetupTiles() { - for (int i = 0; i < Height; i++) - { - for (int j = 0; j < Width; j++) - { - Tiles.Add(new Tile(new Vector2I(j, i), wallDefinition)); - } - } - } - - /// <summary> - /// Registra uma entidade no mapa. A existência de uma entidade não é considerada se ela não - /// estiver registrada no mapa. - /// </summary> - /// <param name="entity">A entidade em questão</param> - public void InsertEntity(Entity entity) { - Entities.Add(entity); - } - - /// <summary> - /// Converte uma coordenada em um índice para acessar a lista de tiles. - /// </summary> - /// <param name="pos">Vetor posição</param> - /// <returns>Índice na lista de tiles. -1 se estiver fora do mapa.</returns> - private int GridToIndex(Vector2I pos) { - if (!IsInBounds(pos)) return -1; - - return pos.Y * Width + pos.X; - } - - /// <summary> - /// Se uma coordenada está dentro da área do mapa. - /// </summary> - /// <param name="pos">Vetor posição</param> - /// <returns>Se o vetor está dentro do mapa.</returns> - private bool IsInBounds(Vector2I pos) { - if (pos.X < 0 || pos.Y < 0) { - return false; - } - if (pos.X >= Width || pos.Y >= Height) { - return false; - } - - return true; - } - - /// <summary> - /// Obtém o tile na posição desejada. - /// </summary> - /// <param name="pos">Vetor posição</param> - /// <returns>O tile na posição, nulo se for fora do mapa.</returns> - public Tile GetTile(Vector2I pos) { - int index = GridToIndex(pos); - - if (index < 0) return null; - - return Tiles[index]; - } - - /// <summary> - /// Obtém o tile na posição desejada. - /// </summary> - /// <param name="x">x da coordenada</param> - /// <param name="y">y da coordenada</param> - /// <returns>O tile na posição, nulo se for fora do mapa.</returns> - public Tile GetTile(int x, int y) { - return GetTile(new Vector2I(x, y)); - } - - /// <summary> - /// Obtém a entidade na posição especificada. - /// </summary> - /// <param name="pos">Vetor posição</param> - /// <returns>A entidade na posição especificada, nulo se não houver.</returns> - public Entity GetBlockingEntityAtPosition(Vector2I pos) { - foreach (Entity entity in Entities) { - if (entity.GridPosition == pos && entity.BlocksMovement) { - return entity; - } - } - return null; - } - - /// <summary> - /// Obtém o primeiro item na posição especificada. - /// </summary> - /// <param name="pos">Posição</param> - /// <returns>O primeiro item na posição, nulo se não houver.</returns> - public ConsumableItem GetFirstItemAtPosition(Vector2I pos) { - foreach (ConsumableItem item in Items) { - if (item.GridPosition == pos) { - return item; - } - } - - return null; - } - - /// <summary> - /// Remove uma entidade do mapa sem dar free. - /// </summary> - /// <param name="entity">A entidade para remover</param> - public void RemoveEntity(Entity entity) { - // Eu removo a entidade do nó de entidades. - entity.GetParent().RemoveChild(entity); - // Eu removo a entidade da lista de entidades do mapa. - Entities.Remove(entity); - } - - /// <summary> - /// Obtém todas as entidades na posição especificada. - /// É possível haver mais de uma entidade na mesma posição se uma delas não bloquear movimento. - /// </summary> - /// <param name="pos">Vetor posição</param> - /// <returns>Lista com todas as entidades na posição especificada.</returns> - public Godot.Collections.Array<Entity> GetEntitiesAtPosition(Vector2I pos) { - Godot.Collections.Array<Entity> ZOfZero = []; - Godot.Collections.Array<Entity> ZOfOne = []; - Godot.Collections.Array<Entity> ZOfTwo = []; - - // Pego todos os atores - foreach (Entity entity in Entities) { - if (entity.GridPosition == pos) { - switch (entity.ZIndex) { - case 0: - ZOfZero.Add(entity); - break; - case 1: - ZOfOne.Add(entity); - break; - case 2: - ZOfTwo.Add(entity); - break; - } - } - } - - // Retorno os atores ordenados por ZIndex. - return ZOfZero + ZOfOne + ZOfTwo; - } -} diff --git a/scripts/map/MapData.cs.uid b/scripts/map/MapData.cs.uid deleted file mode 100644 index 6c226e7..0000000 --- a/scripts/map/MapData.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://0vbcl1etfcbg diff --git a/scripts/map/MapDivision.cs b/scripts/map/MapDivision.cs deleted file mode 100644 index 3273775..0000000 --- a/scripts/map/MapDivision.cs +++ /dev/null @@ -1,98 +0,0 @@ -using Godot; - -/// <summary> -/// Classe utilizada pelo gerador de mapas. -/// Uma divisão é uma região retangular de espaço que pode -/// conter dentro de si duas regiões menores *ou* uma sala. -/// Uma divisão é uma árvore binária que possui espaço para salas em suas folhas. -/// </summary> -public partial class MapDivision : RefCounted { - /// <summary> - /// Região retangular da divisão. - /// </summary> - public Vector2I Position { get; set; } - public Vector2I Size { get; set; } - - public Vector2I Center { - get => new(Position.X + Size.X/2, Position.Y + Size.Y/2); - } - - /// <summary> - /// Filhos da árvore - /// </summary> - private MapDivision left; - public MapDivision Left { get => this.left; } - private MapDivision right; - public MapDivision Right { get => this.right; } - - /// <summary> - /// Se a divisão atual for uma folha. - /// As folhas representam salas. - /// </summary> - public bool IsLeaf { - get => left == null && right == null; - } - - public MapDivision(Vector2I position, Vector2I size) { - Position = position; - Size = size; - } - - public MapDivision(Vector2I position, int width, int height) { - Position = position; - Size = new(width, height); - } - - public MapDivision(int x, int y, int width, int height) { - Position = new(x, y); - Size = new(width, height); - } - - /// <summary> - /// É conveniente ter acesso à todas as folhas da árvore. - /// </summary> - /// <returns>Lista com todas as folhas da árvore.</returns> - public Godot.Collections.Array<MapDivision> GetLeaves() { - if (IsLeaf) { - Godot.Collections.Array<MapDivision> list = []; - list.Add(this); - return list; - } - return left.GetLeaves() + right.GetLeaves(); - } - - /// <summary> - /// Algoritmo para gerar as divisões. - /// O mapa começa com uma única divisão que oculpa sua extensão completa. - /// Depois disso, ela se dividirá recursivamente n vezes. - /// As divisões nas folhas representam espaços onde pode gerar uma sala. - /// </summary> - /// <param name="iterations">Número de iterações</param> - /// <param name="rng">Gerador de números</param> - public void Split(int iterations, RandomNumberGenerator rng) { - float SplitRatio = rng.RandfRange(0.35f, 0.65f); - bool horizontalSplit = Size.X <= Size.Y; - - // Eu defini um limite mínimo de 4 de altura e 4 de largura para divisões. - - if (horizontalSplit) { - int leftHeight = (int) (Size.Y * SplitRatio); - if (leftHeight > 4 && Size.Y - leftHeight > 4) { - left = new MapDivision(Position, Size.X, leftHeight); - right = new MapDivision(Position.X, Position.Y + leftHeight, Size.X, Size.Y - leftHeight); - } - } else { - int leftWidth = (int) (Size.Y * SplitRatio); - - if (leftWidth > 4 && Size.Y - leftWidth > 4) { - left = new MapDivision(Position, leftWidth, Size.Y); - right = new MapDivision(Position.X + leftWidth, Position.Y, Size.X - leftWidth, Size.Y); - } - } - - if (iterations > 1) { - left?.Split(iterations - 1, rng); - right?.Split(iterations - 1, rng); - } - } -}
\ No newline at end of file diff --git a/scripts/map/MapDivision.cs.uid b/scripts/map/MapDivision.cs.uid deleted file mode 100644 index fdd53a4..0000000 --- a/scripts/map/MapDivision.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://c3niegr686acj diff --git a/scripts/map/Tile.cs b/scripts/map/Tile.cs deleted file mode 100644 index 39f7486..0000000 --- a/scripts/map/Tile.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Godot; -using System; - -/// <summary> -/// O mundo do jogo é composto por Tiles. -/// Um tile é um quadrado de 16x16 que representa uma -/// unidade discreta do cenário. Tiles podem agir como -/// parede, chão, ou outras funções. -/// </summary> -public partial class Tile : Sprite2D -{ - /// <summary> - /// A definição do tile carrega seus valores padrão. - /// </summary> - private TileDefinition definition; - - /// <summary> - /// Determina se atores podem andar em cima do Tile. - /// </summary> - public bool IsWalkable { get; private set; } - /// <summary> - /// Determina se o tile bloqueia visão. - /// </summary> - public bool IsTransparent { get; private set; } - - private bool isExplored = false; - /// <summary> - /// Se o jogador já viu este tile antes. - /// Tiles não descobertos são invisíveis. - /// </summary> - public bool IsExplored { - get => this.isExplored; - set { - isExplored = value; - if (IsExplored && !Visible) { - Visible = true; - } - } - } - - private bool isInView = false; - /// <summary> - /// Se o jogador vê o tile neste exato momento. - /// Elementos neste tile estão dentro do campo de visão do jogador. - /// </summary> - public bool IsInView { - get => isInView; - set { - isInView = value; - Modulate = isInView ? definition.LitColor : definition.DarkColor; - if (IsInView && !IsExplored) { - IsExplored = true; - } - } - } - - public Tile(Vector2I pos, TileDefinition definition) - { - // Tile herda da classe Sprite2D. - // Por padrão, a posição do Sprite2D é no centro de sua textura. - // Para o jogo, faz mais sentido que a posição seja no - // canto superior esquerdo. - Centered = false; - // Tiles começam invisíveis porque não foram vistos pelo jogador. - Visible = false; - Position = Grid.GridToWorld(pos); - SetDefinition(definition); - } - - /// <summary> - /// Define as características do tile. - /// </summary> - /// <param name="definition">Definição do tile.</param> - public void SetDefinition(TileDefinition definition) { - this.definition = definition; - Modulate = definition.DarkColor; - Texture = definition.Texture; - IsWalkable = definition.IsWalkable; - IsTransparent = definition.IsTransparent; - } -} diff --git a/scripts/map/Tile.cs.uid b/scripts/map/Tile.cs.uid deleted file mode 100644 index 9fa3c81..0000000 --- a/scripts/map/Tile.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://b2dkecc01tqc0 diff --git a/scripts/map/TileDefinition.cs b/scripts/map/TileDefinition.cs deleted file mode 100644 index 84e5cc1..0000000 --- a/scripts/map/TileDefinition.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Godot; - -/// <summary> -/// Define as características de um tile. -/// </summary> -[GlobalClass] -public partial class TileDefinition : Resource -{ - [ExportCategory("Visuals")] - [Export] - public Texture2D Texture { get; set; } - [Export(PropertyHint.ColorNoAlpha)] - public Color LitColor { get; set; } = Colors.White; - [Export(PropertyHint.ColorNoAlpha)] - public Color DarkColor { get; set; } = Colors.White; - - [ExportCategory("Mechanics")] - [Export] - public bool IsWalkable { get; set; } - [Export] - public bool IsTransparent { get; set; } -} diff --git a/scripts/map/TileDefinition.cs.uid b/scripts/map/TileDefinition.cs.uid deleted file mode 100644 index 14f2903..0000000 --- a/scripts/map/TileDefinition.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ba82a33ov6uuo |
