summaryrefslogtreecommitdiff
path: root/scripts/Map/Map.cs
blob: 104d6580c527f5b4eae846fb92b6aac7f34bf6c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
using System.Net.Http.Headers;
using Godot;
using TheLegendOfGustav.Entities;
using TheLegendOfGustav.Entities.Actors;
using TheLegendOfGustav.Utils;

namespace TheLegendOfGustav.Map;

/// <summary>
/// A parte visual do mapa.
/// </summary>
public partial class Map : Node2D
{
	/// <summary>
	/// raio de alcance da visão do jogador.
	/// </summary>
	[Export]
	private int fovRadius = 12;

	private FieldOfView fieldOfView;

	private Node2D tilesNode;
	private Node2D entitiesNode;

	/// <summary>
	/// Gerador de mapas.
	/// </summary>
	private DungeonGenerator generator;

	/// <summary>
	/// Dados do mapa.
	/// </summary>
	public MapData MapData { get; private set; }

	private SignalBus.PlayerDescentEventHandler joinSignal;
	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");

		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, int currentFloor = 1)
	{
		MapData = generator.GenerateDungeon(player, currentFloor);

		MapData.EntityPlaced += OnEntityPlaced;

		PlaceTiles();
		PlaceEntities();

		SignalBus.Instance.EmitSignal(SignalBus.SignalName.DungeonFloorChanged, currentFloor);
	}

	/// <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(MapData, pos, fovRadius);
		// Esconde ou revela entidades com base no campo de visão.
		foreach (Entity entity in MapData.Entities)
		{
			entity.Visible = MapData.GetTile(entity.GridPosition).IsInView;
		}
	}


	/// <summary>
	/// Coloca todos os tiles do mapa no mundo do jogo.
	/// </summary>
	private void PlaceTiles()
	{
		foreach (Tile tile in MapData.Tiles)
		{
			tilesNode.AddChild(tile);
		}
	}

	/// <summary>
	/// Coloca todas as entidades do mapa no mundo do jogo.
	/// </summary>
	private void PlaceEntities()
	{
		foreach (Entity entity in MapData.Entities)
		{
			entitiesNode.AddChild(entity);
		}
	}

	private void OnEntityPlaced(Entity entity)
	{
		entitiesNode.AddChild(entity);
	}

	public bool LoadGame(Player player)
	{

		MapData = new(0, 0, player);

		if (!MapData.LoadGame())
		{
			return false;
		}

		PlaceTiles();
		PlaceEntities();

		MapData.EntityPlaced += OnEntityPlaced;
		SignalBus.Instance.EmitSignal(SignalBus.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);
	}
}