summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/definitions/actor/Player.tres2
-rw-r--r--assets/definitions/tiles/downstairs.tres12
-rw-r--r--assets/definitions/tiles/floor.tres1
-rw-r--r--assets/sprites/tiles/downstairs.pngbin0 -> 168 bytes
-rw-r--r--assets/sprites/tiles/downstairs.png.import40
-rw-r--r--project.godot5
-rw-r--r--scenes/Game.tscn3
-rw-r--r--scripts/Entities/Actions/TakeStairsAction.cs28
-rw-r--r--scripts/Entities/Actions/TakeStairsAction.cs.uid1
-rw-r--r--scripts/InputHandling/MainGameInputHandler.cs5
-rw-r--r--scripts/Map/DungeonGenerator.cs32
-rw-r--r--scripts/Map/FieldOfView.cs11
-rw-r--r--scripts/Map/Map.cs50
-rw-r--r--scripts/Map/MapData.cs10
-rw-r--r--scripts/Map/Tile.cs6
-rw-r--r--scripts/Utils/SignalBus.cs3
16 files changed, 182 insertions, 27 deletions
diff --git a/assets/definitions/actor/Player.tres b/assets/definitions/actor/Player.tres
index 4eba7f7..8a4e2c1 100644
--- a/assets/definitions/actor/Player.tres
+++ b/assets/definitions/actor/Player.tres
@@ -11,7 +11,7 @@ deathTexture = ExtResource("1_m72ac")
Hp = 36
Mp = 12
Atk = 8
-Def = 2
+Def = 10
Men = 3
name = "Jogador"
texture = ExtResource("3_m72ac")
diff --git a/assets/definitions/tiles/downstairs.tres b/assets/definitions/tiles/downstairs.tres
new file mode 100644
index 0000000..5b6c23a
--- /dev/null
+++ b/assets/definitions/tiles/downstairs.tres
@@ -0,0 +1,12 @@
+[gd_resource type="Resource" script_class="TileDefinition" load_steps=3 format=3 uid="uid://ch688yvi87hl5"]
+
+[ext_resource type="Script" uid="uid://ba82a33ov6uuo" path="res://scripts/Map/TileDefinition.cs" id="1_pedoq"]
+[ext_resource type="Texture2D" uid="uid://c6d3vikw7v8d7" path="res://assets/sprites/tiles/downstairs.png" id="1_voylm"]
+
+[resource]
+script = ExtResource("1_pedoq")
+Texture = ExtResource("1_voylm")
+DarkColor = Color(0.27450982, 0.27450982, 0.27450982, 1)
+IsWalkable = true
+IsTransparent = true
+metadata/_custom_type_script = "uid://ba82a33ov6uuo"
diff --git a/assets/definitions/tiles/floor.tres b/assets/definitions/tiles/floor.tres
index 44b0097..70bbb68 100644
--- a/assets/definitions/tiles/floor.tres
+++ b/assets/definitions/tiles/floor.tres
@@ -6,7 +6,6 @@
[resource]
script = ExtResource("1_snxyj")
Texture = ExtResource("1_vvyfi")
-LitColor = Color(1, 1, 1, 1)
DarkColor = Color(0.272655, 0.272655, 0.272655, 1)
IsWalkable = true
IsTransparent = true
diff --git a/assets/sprites/tiles/downstairs.png b/assets/sprites/tiles/downstairs.png
new file mode 100644
index 0000000..34cb872
--- /dev/null
+++ b/assets/sprites/tiles/downstairs.png
Binary files differ
diff --git a/assets/sprites/tiles/downstairs.png.import b/assets/sprites/tiles/downstairs.png.import
new file mode 100644
index 0000000..b2240cb
--- /dev/null
+++ b/assets/sprites/tiles/downstairs.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c6d3vikw7v8d7"
+path="res://.godot/imported/downstairs.png-426496fa50b43c52de7237b978e7f7d9.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/sprites/tiles/downstairs.png"
+dest_files=["res://.godot/imported/downstairs.png-426496fa50b43c52de7237b978e7f7d9.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/project.godot b/project.godot
index 30b0f6f..5ee82d7 100644
--- a/project.godot
+++ b/project.godot
@@ -114,6 +114,11 @@ open-spellbook={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":90,"physical_keycode":0,"key_label":0,"unicode":122,"location":0,"echo":false,"script":null)
]
}
+descend={
+"deadzone": 0.2,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":46,"physical_keycode":0,"key_label":0,"unicode":62,"location":0,"echo":false,"script":null)
+]
+}
[rendering]
diff --git a/scenes/Game.tscn b/scenes/Game.tscn
index 90bf37a..e9bd9d2 100644
--- a/scenes/Game.tscn
+++ b/scenes/Game.tscn
@@ -23,8 +23,9 @@ script = ExtResource("3_cpr0p")
[node name="Generator" type="Node" parent="Map"]
script = ExtResource("4_78awf")
+width = 30
+height = 20
useSeed = false
-iterations = 6
[node name="FieldOfView" type="Node" parent="Map"]
script = ExtResource("5_s0nni")
diff --git a/scripts/Entities/Actions/TakeStairsAction.cs b/scripts/Entities/Actions/TakeStairsAction.cs
new file mode 100644
index 0000000..17fa7e5
--- /dev/null
+++ b/scripts/Entities/Actions/TakeStairsAction.cs
@@ -0,0 +1,28 @@
+using Godot;
+using TheLegendOfGustav.Entities.Actors;
+using TheLegendOfGustav.Utils;
+
+namespace TheLegendOfGustav.Entities.Actions;
+
+public partial class TakeStairsAction : Action
+{
+ public TakeStairsAction(Actor actor) : base(actor)
+ {
+ cost = 0;
+ }
+
+ public override bool Perform()
+ {
+ if (Actor.GridPosition == MapData.DownstairsLocation)
+ {
+ SignalBus.Instance.EmitSignal(SignalBus.SignalName.PlayerDescent);
+ MessageLogData.Instance.AddMessage("Você desce as escadas...");
+ return true;
+ }
+ else
+ {
+ MessageLogData.Instance.AddMessage("Não tem escadas aqui...");
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/scripts/Entities/Actions/TakeStairsAction.cs.uid b/scripts/Entities/Actions/TakeStairsAction.cs.uid
new file mode 100644
index 0000000..03b2448
--- /dev/null
+++ b/scripts/Entities/Actions/TakeStairsAction.cs.uid
@@ -0,0 +1 @@
+uid://c0adtd8ynoh4q
diff --git a/scripts/InputHandling/MainGameInputHandler.cs b/scripts/InputHandling/MainGameInputHandler.cs
index bbfb9ca..a18bd73 100644
--- a/scripts/InputHandling/MainGameInputHandler.cs
+++ b/scripts/InputHandling/MainGameInputHandler.cs
@@ -63,6 +63,11 @@ public partial class MainGameInputHandler : BaseInputHandler
action = new EscapeAction(player);
}
+ if (Input.IsActionJustPressed("descend"))
+ {
+ action = new TakeStairsAction(player);
+ }
+
return action;
}
}
diff --git a/scripts/Map/DungeonGenerator.cs b/scripts/Map/DungeonGenerator.cs
index 2d5ef8d..2b24e8a 100644
--- a/scripts/Map/DungeonGenerator.cs
+++ b/scripts/Map/DungeonGenerator.cs
@@ -2,6 +2,7 @@ using Godot;
using TheLegendOfGustav.Entities.Actors;
using TheLegendOfGustav.Entities;
using TheLegendOfGustav.Entities.Items;
+using System;
namespace TheLegendOfGustav.Map;
@@ -36,16 +37,6 @@ public partial class DungeonGenerator : Node
private int height = 60;
/// <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]
@@ -73,14 +64,6 @@ public partial class DungeonGenerator : Node
#endregion
#region Methods
- public override void _Ready()
- {
- base._Ready();
- if (useSeed)
- {
- rng.Seed = seed;
- }
- }
/// <summary>
/// Gera um andar da masmorra.
@@ -89,9 +72,12 @@ public partial class DungeonGenerator : Node
/// </summary>
/// <param name="player">Jogador.</param>
/// <returns>O mapa gerado.</returns>
- public MapData GenerateDungeon(Player player)
+ public MapData GenerateDungeon(Player player, int currentFloor)
{
+ rng.Seed = (ulong)DateTimeOffset.Now.ToUnixTimeMilliseconds();
+
MapData data = new MapData(width, height, player);
+ data.CurrentFloor = currentFloor;
// Divisão mestre que engloba o mapa inteiro.
MapDivision root = new MapDivision(0, 0, width, height);
@@ -104,6 +90,8 @@ public partial class DungeonGenerator : Node
// Coloca os corredores.
TunnelDivisions(data, root);
+ Rect2I lastRoom = new(0, 0, 0, 0);
+
// Cria as salas com base nas divisões geradas.
foreach (MapDivision division in root.GetLeaves())
{
@@ -127,8 +115,14 @@ public partial class DungeonGenerator : Node
}
// Colocamos os inimigos na sala.
PlaceEntities(data, room);
+
+ lastRoom = room;
}
+ data.DownstairsLocation = lastRoom!.GetCenter();
+ Tile downTile = data.GetTile(data.DownstairsLocation);
+ downTile.Key = TileType.DOWN_STAIRS;
+
// Feito o mapa, inicializamos o algoritmo de pathfinding.
data.SetupPathfinding();
return data;
diff --git a/scripts/Map/FieldOfView.cs b/scripts/Map/FieldOfView.cs
index 40df320..474c1ca 100644
--- a/scripts/Map/FieldOfView.cs
+++ b/scripts/Map/FieldOfView.cs
@@ -101,6 +101,17 @@ public partial class FieldOfView : Node
fov.Clear();
}
+ /// <summary>
+ /// Diferença de ClearFOV: não referencia tiles.
+ /// No contexto onde ResetFOV é chamado, os tiles não
+ /// podem ser referenciados porque já foram liberados da
+ /// memória.
+ /// </summary>
+ public void ResetFOV()
+ {
+ fov.Clear();
+ }
+
public void UpdateFOV(MapData data, Vector2I position, int radius)
{
ClearFOV();
diff --git a/scripts/Map/Map.cs b/scripts/Map/Map.cs
index 04ccabd..2913c1f 100644
--- a/scripts/Map/Map.cs
+++ b/scripts/Map/Map.cs
@@ -2,6 +2,7 @@ using System.Net.Http.Headers;
using Godot;
using TheLegendOfGustav.Entities;
using TheLegendOfGustav.Entities.Actors;
+using TheLegendOfGustav.Utils;
namespace TheLegendOfGustav.Map;
@@ -30,7 +31,11 @@ public partial class Map : Node2D
/// Dados do mapa.
/// </summary>
public MapData MapData { get; private set; }
-
+
+ [Signal]
+ public delegate void DungeonFloorChangedEventHandler(int floor);
+
+ private SignalBus.PlayerDescentEventHandler joinSignal;
public override void _Ready()
{
base._Ready();
@@ -39,20 +44,46 @@ public partial class Map : Node2D
fieldOfView = GetNode<FieldOfView>("FieldOfView");
tilesNode = GetNode<Node2D>("Tiles");
entitiesNode = GetNode<Node2D>("Entities");
+
+ joinSignal = () => NextFloor();
+ SignalBus.Instance.PlayerDescent += joinSignal;
+ }
+
+ void NextFloor()
+ {
+ Player player = MapData.Player;
+ entitiesNode.RemoveChild(player);
+
+ foreach (var entity in entitiesNode.GetChildren())
+ {
+ entity.QueueFree();
+ }
+
+ foreach (var tile in tilesNode.GetChildren())
+ {
+ tile.QueueFree();
+ }
+
+ Generate(player, MapData.CurrentFloor + 1);
+ player.GetNode<Camera2D>("Camera2D").MakeCurrent();
+ fieldOfView.ResetFOV();
+ UpdateFOV(player.GridPosition);
}
/// <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)
+ public void Generate(Player player, int currentFloor = 1)
{
- MapData = generator.GenerateDungeon(player);
+ MapData = generator.GenerateDungeon(player, currentFloor);
MapData.EntityPlaced += OnEntityPlaced;
PlaceTiles();
PlaceEntities();
+
+ EmitSignal(SignalName.DungeonFloorChanged, currentFloor);
}
/// <summary>
@@ -111,6 +142,19 @@ public partial class Map : Node2D
PlaceEntities();
MapData.EntityPlaced += OnEntityPlaced;
+ EmitSignal(SignalName.DungeonFloorChanged, MapData.CurrentFloor);
return true;
}
+
+ public override void _Notification(int what)
+ {
+ if (what == NotificationPredelete)
+ {
+ if (joinSignal != null)
+ {
+ SignalBus.Instance.PlayerDescent -= joinSignal;
+ }
+ }
+ base._Notification(what);
+ }
}
diff --git a/scripts/Map/MapData.cs b/scripts/Map/MapData.cs
index 5f96743..907e8d0 100644
--- a/scripts/Map/MapData.cs
+++ b/scripts/Map/MapData.cs
@@ -84,6 +84,10 @@ public partial class MapData : RefCounted, ISaveable
return list;
}
}
+
+ public int CurrentFloor { get; set; } = 0;
+
+ public Vector2I DownstairsLocation { get; set; }
/// <summary>
/// Objeto do Godot que utiliza do algoritmo A* para calcular
/// caminhos e rotas.
@@ -349,6 +353,9 @@ public partial class MapData : RefCounted, ISaveable
{"player", Player.GetSaveData()},
{"width", Width},
{"height", Height},
+ {"current_floor", CurrentFloor},
+ {"down_stairs_location_x", DownstairsLocation.X},
+ {"down_stairs_location_y", DownstairsLocation.Y}
};
}
@@ -357,6 +364,9 @@ public partial class MapData : RefCounted, ISaveable
Width = (int)saveData["width"];
Height = (int)saveData["height"];
+ CurrentFloor = (int)saveData["current_floor"];
+ DownstairsLocation = new((int)saveData["down_stairs_location_x"], (int)saveData["down_stairs_location_y"]);
+
SetupTiles();
Array<Dictionary<string, Variant>> serializedTiles = (Array<Dictionary<string, Variant>>)saveData["tiles"];
diff --git a/scripts/Map/Tile.cs b/scripts/Map/Tile.cs
index 6790f3e..03039e0 100644
--- a/scripts/Map/Tile.cs
+++ b/scripts/Map/Tile.cs
@@ -8,7 +8,8 @@ namespace TheLegendOfGustav.Map;
public enum TileType
{
WALL,
- FLOOR
+ FLOOR,
+ DOWN_STAIRS
}
/// <summary>
@@ -22,7 +23,8 @@ public partial class Tile : Sprite2D, ISaveable
private static readonly Godot.Collections.Dictionary<TileType, TileDefinition> Types = new()
{
{TileType.WALL, GD.Load<TileDefinition>("res://assets/definitions/tiles/wall.tres")},
- {TileType.FLOOR, GD.Load<TileDefinition>("res://assets/definitions/tiles/floor.tres")}
+ {TileType.FLOOR, GD.Load<TileDefinition>("res://assets/definitions/tiles/floor.tres")},
+ {TileType.DOWN_STAIRS, GD.Load<TileDefinition>("res://assets/definitions/tiles/downstairs.tres")}
};
TileType key;
diff --git a/scripts/Utils/SignalBus.cs b/scripts/Utils/SignalBus.cs
index 291ffcd..a7eccf8 100644
--- a/scripts/Utils/SignalBus.cs
+++ b/scripts/Utils/SignalBus.cs
@@ -34,6 +34,9 @@ public partial class SignalBus : Node
[Signal]
public delegate void EscapeRequestedEventHandler();
+ [Signal]
+ public delegate void PlayerDescentEventHandler();
+
public override void _Ready()
{
base._Ready();