summaryrefslogtreecommitdiff
path: root/scripts/Map/Tile.cs
blob: 03039e0561d21da42480780e4c02143f7683d6ec (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
using System.Threading;
using Godot;
using Godot.Collections;
using TheLegendOfGustav.Utils;

namespace TheLegendOfGustav.Map;

public enum TileType
{
	WALL,
	FLOOR,
	DOWN_STAIRS
}

/// <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, 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.DOWN_STAIRS, GD.Load<TileDefinition>("res://assets/definitions/tiles/downstairs.tres")}
	};

	TileType key;
	public TileType Key
	{
		get => key;
		set
		{
			key = value;
			SetDefinition(Types[value]);
		}
	}

	private bool isExplored = false;
	private bool isInView = false;

	/// <summary>
	/// A definição do tile carrega seus valores padrão.
	/// </summary>
	private TileDefinition definition;

	public Tile(Vector2I pos, TileType type)
	{
		// 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);
		Key = type;
	}

	/// <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; }

	
	/// <summary>
	/// Se o jogador já viu este tile antes.
	/// Tiles não descobertos são invisíveis.
	/// </summary>
	public bool IsExplored
	{
		get => isExplored;
		set
		{
			isExplored = value;
			if (IsExplored && !Visible)
			{
				Visible = true;
			}
		}
	}

	/// <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;
			}
		}
	}

	/// <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;
	}

	public Dictionary<string, Variant> GetSaveData()
	{
		return new()
		{
			{"key", (int)Key},
			{"is_explored", IsExplored}
		};
	}

	public bool LoadSaveData(Dictionary<string, Variant> saveData)
	{
		// É o seguinte, não tenho tempo, não vou verificar se a entrada está correta.
		Key = (TileType)(int)saveData["key"];

		IsExplored = (bool)saveData["is_explored"];
		return true;
	}
}