summaryrefslogtreecommitdiff
path: root/scripts/Entities/Entity.cs
blob: 76002b1cc6f0009821ad81c495415d0a0612866a (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
158
159
160
161
162
163
164
using Godot;
using Godot.Collections;
using TheLegendOfGustav.Map;
using TheLegendOfGustav.Utils;

namespace TheLegendOfGustav.Entities;

/// <summary>
/// Defino aqui que o jogo irá desenhar
/// atores em cima de itens e itens acima de corpos.
/// </summary>
public enum EntityType
{
	CORPSE,
	ITEM,
	ACTOR
};

/// <summary>
/// Classe para elementos móveis que o jogador pode interagir.
/// </summary>
public abstract partial class Entity : Sprite2D, ISaveable
{
	private Vector2I gridPosition = Vector2I.Zero;

	private EntityType type;
	private bool blocksMovement;
	private string displayName;

	/// <summary>
	/// A definição da entidade possui caracterísitcas padrões que definem
	/// a entidade em questão.
	/// </summary>
	private EntityDefinition definition;

	public Entity(Vector2I initialPosition, MapData map, EntityDefinition definition)
	{
		GridPosition = initialPosition;
		MapData = map;
		Centered = false;

		SetDefinition(definition);
	}

	/// <summary>
	/// Aqui eu confio que quem chamar este contrutor
	/// chamará SetDefinition logo depois. Este construtor existe
	/// porque tem um caso onde eu não tenho a definição logo de cara.
	/// </summary>
	/// <param name="initialPosition"></param>
	/// <param name="map"></param>
	public Entity(Vector2I initialPosition, MapData map)
	{
		GridPosition = initialPosition;
		MapData = map;
		Centered = false;
	}
	
	/// <summary>
	/// Usado para definir a camada da entidade no mapa.
	/// </summary>
	public EntityType Type
	{
		get => type;
		set
		{
			type = value;
			ZIndex = (int)type;
		}
	}

	/// <summary>
	/// É conveniente ter acesso ao mapa dentro da entidade. Isto porque ela existe dentro
	/// do mapa, então é necessário ter acesso à algumas informações.
	/// </summary>
	public MapData MapData { get; set; }

	/// <summary>
	/// Posição da entidade no mapa do jogo. Diferentemente de Position, GridPosition tem como formato 
	/// os tiles do mapa.
	/// </summary>
	public Vector2I GridPosition
	{
		set
		{
			gridPosition = value;
			// O sistema de coordenadas do Godot é em pixels, mas faz mais sentido para o jogo utilizar coordenadas em tiles.
			// Esta propriedade converte um sistema para o outro automaticamente.
			Position = Grid.GridToWorld(value);
		}
		get => gridPosition;
	}

	/// <summary>
	/// Se a entidade bloqueia movimento (não pode oculpar a mesma célula de outra entidade.)
	/// </summary>
	public bool BlocksMovement
	{
		get => blocksMovement;
		protected set
		{
			blocksMovement = value;
		}
	}

	/// <summary>
	/// Nome da entidade.
	/// </summary>
	public string DisplayName
	{
		get => displayName;
		protected set
		{
			displayName = value;
		}
	}

	public override void _Ready()
	{
		base._Ready();
		// Quando a entidade for carregada completamente, atualizamos sua posição para refletir
		// sua posição real.
		GridPosition = Grid.WorldToGrid(Position);
	}

	

	/// <summary>
	/// Aplica uma definição de NPC para o ator.
	/// Se o ator for um boneco de barro, este método é como um
	/// sopro de vida.
	/// </summary>
	/// <param name="definition">A definição do ator.</param>
	public virtual void SetDefinition(EntityDefinition definition)
	{
		this.definition = definition;
		BlocksMovement = definition.blocksMovement;
		DisplayName = definition.name;
		Type = definition.Type;
		Texture = definition.texture;
	}

	public Dictionary<string, Variant> GetSaveData()
	{
		return new()
		{
			{"position_x", GridPosition.X},
			{"position_y", GridPosition.Y},
			{"blocks_movement", BlocksMovement},
			{"name", DisplayName},
			{"layer", (int)Type},

		};
	}

	public bool LoadSaveData(Dictionary<string, Variant> saveData)
	{
		GridPosition = new((int)saveData["position_x"], (int)saveData["position_y"]);
		BlocksMovement = (bool)saveData["blocks_movement"];
		DisplayName = (string)saveData["name"];
		Type = (EntityType)(int)saveData["layer"];
		return true;
	}
}