summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatheus <matheus.guedes.mg.m@gmail.com>2025-09-04 18:31:40 -0300
committerMatheus <matheus.guedes.mg.m@gmail.com>2025-09-04 18:31:40 -0300
commit1e248d3dd18f7c6bfaf8066c4662facbbb89e8f9 (patch)
tree8250335d5ad8176da05f7243052b9af85802c7ed
parent147bb12b5d48c5432aa1bd1cbe60b8435294445b (diff)
Itens na masmorra
-rw-r--r--assets/definitions/Items/small_healing_potion.tres13
-rw-r--r--assets/definitions/actor/Player.tres7
-rw-r--r--assets/definitions/actor/Shadow.tres7
-rw-r--r--assets/definitions/actor/Skeleton.tres8
-rw-r--r--assets/definitions/actor/morcegao.tres7
-rw-r--r--assets/sprites/items/small_health_potion.pngbin0 -> 269 bytes
-rw-r--r--assets/sprites/items/small_health_potion.png.import34
-rw-r--r--assets/sprites/small_health_potion.pxobin0 -> 1207 bytes
-rw-r--r--scripts/entities/Entity.cs34
-rw-r--r--scripts/entities/EntityDefinition.cs7
-rw-r--r--scripts/entities/actions/Action.cs3
-rw-r--r--scripts/entities/actions/ItemAction.cs15
-rw-r--r--scripts/entities/actions/ItemAction.cs.uid1
-rw-r--r--scripts/entities/actors/Actor.cs4
-rw-r--r--scripts/entities/items/ConsumableItem.cs31
-rw-r--r--scripts/entities/items/ConsumableItem.cs.uid1
-rw-r--r--scripts/entities/items/ConsumableItemDefinition.cs7
-rw-r--r--scripts/entities/items/ConsumableItemDefinition.cs.uid1
-rw-r--r--scripts/entities/items/HealingConsumable.cs27
-rw-r--r--scripts/entities/items/HealingConsumable.cs.uid1
-rw-r--r--scripts/entities/items/HealingConsumableDefinition.cs11
-rw-r--r--scripts/entities/items/HealingConsumableDefinition.cs.uid1
-rw-r--r--scripts/map/DungeonGenerator.cs45
-rw-r--r--scripts/map/Map.cs12
24 files changed, 247 insertions, 30 deletions
diff --git a/assets/definitions/Items/small_healing_potion.tres b/assets/definitions/Items/small_healing_potion.tres
new file mode 100644
index 0000000..56d1294
--- /dev/null
+++ b/assets/definitions/Items/small_healing_potion.tres
@@ -0,0 +1,13 @@
+[gd_resource type="Resource" script_class="HealingConsumableDefinition" load_steps=3 format=3 uid="uid://bm6yx6rwh8bds"]
+
+[ext_resource type="Script" uid="uid://b3qy4gtjfci14" path="res://scripts/entities/items/HealingConsumableDefinition.cs" id="1_4dl2g"]
+[ext_resource type="Texture2D" uid="uid://b7drpdbk4lggb" path="res://assets/sprites/items/small_health_potion.png" id="2_esrbk"]
+
+[resource]
+script = ExtResource("1_4dl2g")
+healingPercentage = 10.0
+name = "Poção de vida pequena"
+texture = ExtResource("2_esrbk")
+Type = 1
+blocksMovement = false
+metadata/_custom_type_script = "uid://b3qy4gtjfci14"
diff --git a/assets/definitions/actor/Player.tres b/assets/definitions/actor/Player.tres
index 0b3ec76..f465740 100644
--- a/assets/definitions/actor/Player.tres
+++ b/assets/definitions/actor/Player.tres
@@ -6,14 +6,15 @@
[resource]
script = ExtResource("1_2k33r")
-name = "Jogador"
-texture = ExtResource("2_2xyvf")
deathTexture = ExtResource("1_m72ac")
-blocksMovement = true
Speed = 10
Hp = 36
Mp = 12
Atk = 8
Def = 2
Men = 3
+name = "Jogador"
+texture = ExtResource("2_2xyvf")
+Type = 2
+blocksMovement = true
metadata/_custom_type_script = "uid://crxw1e37xlrrt"
diff --git a/assets/definitions/actor/Shadow.tres b/assets/definitions/actor/Shadow.tres
index a82a5f7..cfa0995 100644
--- a/assets/definitions/actor/Shadow.tres
+++ b/assets/definitions/actor/Shadow.tres
@@ -7,14 +7,15 @@
[resource]
script = ExtResource("1_4jpld")
AI = 1
-name = "Shadow"
-texture = ExtResource("3_kvxyn")
deathTexture = ExtResource("1_3bs08")
-blocksMovement = true
Speed = 10
Hp = 15
Mp = 23
Atk = 5
Def = 2
Men = 8
+name = "Shadow"
+texture = ExtResource("3_kvxyn")
+Type = 2
+blocksMovement = true
metadata/_custom_type_script = "uid://dkfdm2m2scyks"
diff --git a/assets/definitions/actor/Skeleton.tres b/assets/definitions/actor/Skeleton.tres
index 1ec7c6d..f67bf56 100644
--- a/assets/definitions/actor/Skeleton.tres
+++ b/assets/definitions/actor/Skeleton.tres
@@ -7,13 +7,15 @@
[resource]
script = ExtResource("1_m5x88")
AI = 1
-name = "Eis que leto"
-texture = ExtResource("2_hhidw")
deathTexture = ExtResource("1_7fof3")
-blocksMovement = true
+Speed = 10
Hp = 12
Mp = 2
Atk = 3
Def = 2
Men = 2
+name = "Eis que leto"
+texture = ExtResource("2_hhidw")
+Type = 2
+blocksMovement = true
metadata/_custom_type_script = "uid://dkfdm2m2scyks"
diff --git a/assets/definitions/actor/morcegao.tres b/assets/definitions/actor/morcegao.tres
index 8d0cf80..937679f 100644
--- a/assets/definitions/actor/morcegao.tres
+++ b/assets/definitions/actor/morcegao.tres
@@ -7,14 +7,15 @@
[resource]
script = ExtResource("1_m2lyk")
AI = 1
-name = "Morcegão"
-texture = ExtResource("3_601km")
deathTexture = ExtResource("1_hdleo")
-blocksMovement = true
Speed = 10
Hp = 10
Mp = 0
Atk = 5
Def = 1
Men = 0
+name = "Morcegão"
+texture = ExtResource("3_601km")
+Type = 2
+blocksMovement = true
metadata/_custom_type_script = "uid://dkfdm2m2scyks"
diff --git a/assets/sprites/items/small_health_potion.png b/assets/sprites/items/small_health_potion.png
new file mode 100644
index 0000000..a72eabe
--- /dev/null
+++ b/assets/sprites/items/small_health_potion.png
Binary files differ
diff --git a/assets/sprites/items/small_health_potion.png.import b/assets/sprites/items/small_health_potion.png.import
new file mode 100644
index 0000000..68df3be
--- /dev/null
+++ b/assets/sprites/items/small_health_potion.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b7drpdbk4lggb"
+path="res://.godot/imported/small_health_potion.png-ac7c73317b9ed7f3138a57fb088ebb00.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/sprites/items/small_health_potion.png"
+dest_files=["res://.godot/imported/small_health_potion.png-ac7c73317b9ed7f3138a57fb088ebb00.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+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/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/assets/sprites/small_health_potion.pxo b/assets/sprites/small_health_potion.pxo
new file mode 100644
index 0000000..bd4df9b
--- /dev/null
+++ b/assets/sprites/small_health_potion.pxo
Binary files differ
diff --git a/scripts/entities/Entity.cs b/scripts/entities/Entity.cs
index fb83f90..85a3156 100644
--- a/scripts/entities/Entity.cs
+++ b/scripts/entities/Entity.cs
@@ -1,16 +1,42 @@
using Godot;
-public partial class Entity : Sprite2D {
+/// <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 {
/// <summary>
/// A definição da entidade possui caracterísitcas padrões que definem
/// a entidade em questão.
/// </summary>
private EntityDefinition definition;
+ private EntityType 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.
+ /// 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 Map_Data { get; set; }
private Vector2I gridPosition = Vector2I.Zero;
@@ -76,7 +102,7 @@ public partial class Entity : Sprite2D {
this.definition = definition;
BlocksMovement = definition.blocksMovement;
DisplayName = definition.name;
- ZIndex = 1;
+ Type = definition.Type;
Texture = definition.texture;
}
} \ No newline at end of file
diff --git a/scripts/entities/EntityDefinition.cs b/scripts/entities/EntityDefinition.cs
index 19693db..ba7236a 100644
--- a/scripts/entities/EntityDefinition.cs
+++ b/scripts/entities/EntityDefinition.cs
@@ -2,15 +2,18 @@ using Godot;
[GlobalClass]
public partial class EntityDefinition : Resource{
- [ExportCategory("Visuals")]
+ [ExportCategory("Entity Visuals")]
// Nome da entidade.
[Export]
public string name = "unnamed";
// Seu sprite.
[Export]
public Texture2D texture;
+ // A camada da entidade.
+ [Export]
+ public EntityType Type;
- [ExportCategory("Mechanics")]
+ [ExportCategory("Entity Mechanics")]
// Se a entidade bloqueia movimento.
[Export]
public bool blocksMovement = true;
diff --git a/scripts/entities/actions/Action.cs b/scripts/entities/actions/Action.cs
index 3f15105..9dab5a4 100644
--- a/scripts/entities/actions/Action.cs
+++ b/scripts/entities/actions/Action.cs
@@ -10,8 +10,9 @@ public abstract partial class Action : RefCounted {
/// O ator que realiza a ação.
/// </summary>
protected Actor actor;
+ public Actor ThisActor { get => actor; }
- // O custo da ação.
+ // O custo da ação.
protected int cost;
public Action(Actor actor) {
diff --git a/scripts/entities/actions/ItemAction.cs b/scripts/entities/actions/ItemAction.cs
new file mode 100644
index 0000000..54ff207
--- /dev/null
+++ b/scripts/entities/actions/ItemAction.cs
@@ -0,0 +1,15 @@
+using Godot;
+
+public partial class ItemAction : Action
+{
+ private ConsumableItem item;
+ public ItemAction(Actor actor, ConsumableItem item) : base(actor)
+ {
+ this.item = item;
+ }
+
+ public override bool Perform()
+ {
+ return item.Activate(this);
+ }
+} \ No newline at end of file
diff --git a/scripts/entities/actions/ItemAction.cs.uid b/scripts/entities/actions/ItemAction.cs.uid
new file mode 100644
index 0000000..c8c8e23
--- /dev/null
+++ b/scripts/entities/actions/ItemAction.cs.uid
@@ -0,0 +1 @@
+uid://f7ep4u4fwsyl
diff --git a/scripts/entities/actors/Actor.cs b/scripts/entities/actors/Actor.cs
index dc8ba53..1717cfa 100644
--- a/scripts/entities/actors/Actor.cs
+++ b/scripts/entities/actors/Actor.cs
@@ -156,7 +156,7 @@ public partial class Actor : Entity
base.SetDefinition(definition);
this.definition = definition;
- ZIndex = 1;
+ Type = definition.Type;
MaxHp = definition.Hp;
Hp = definition.Hp;
@@ -207,7 +207,7 @@ public partial class Actor : Entity
Texture = definition.deathTexture;
BlocksMovement = false;
- ZIndex = 0;
+ Type = EntityType.CORPSE;
DisplayName= $"Restos mortais de {DisplayName}";
Map_Data.UnregisterBlockingEntity(this);
EmitSignal(SignalName.Died);
diff --git a/scripts/entities/items/ConsumableItem.cs b/scripts/entities/items/ConsumableItem.cs
new file mode 100644
index 0000000..8c862da
--- /dev/null
+++ b/scripts/entities/items/ConsumableItem.cs
@@ -0,0 +1,31 @@
+using Godot;
+
+/// <summary>
+/// Classe para itens consumíveis.
+/// Itens consumíveis são itens de uso limitado.
+/// </summary>
+public abstract partial class ConsumableItem : Entity
+{
+ public ConsumableItem(Vector2I initialPosition, MapData map, EntityDefinition definition) : base(initialPosition, map, definition)
+ {
+ }
+
+ /// <summary>
+ /// Gera uma ação onde o ator consome o item.
+ /// </summary>
+ /// <param name="consumer"></param>
+ /// <returns></returns>
+ public Action GetAction(Actor consumer)
+ {
+ return new ItemAction(consumer, this);
+ }
+
+ /// <summary>
+ /// Ativa a função deste item.
+ /// Este método é chamado pela ação gerada por ele mesmo.
+ /// Este método permite definir condições para a sua ativação.
+ /// </summary>
+ /// <param name="action">Ação gerada pelo item.</param>
+ /// <returns>Se a ação foi realizada ou não.</returns>
+ public abstract bool Activate(ItemAction action);
+} \ No newline at end of file
diff --git a/scripts/entities/items/ConsumableItem.cs.uid b/scripts/entities/items/ConsumableItem.cs.uid
new file mode 100644
index 0000000..e6c452a
--- /dev/null
+++ b/scripts/entities/items/ConsumableItem.cs.uid
@@ -0,0 +1 @@
+uid://hpppt5k743x
diff --git a/scripts/entities/items/ConsumableItemDefinition.cs b/scripts/entities/items/ConsumableItemDefinition.cs
new file mode 100644
index 0000000..74340d2
--- /dev/null
+++ b/scripts/entities/items/ConsumableItemDefinition.cs
@@ -0,0 +1,7 @@
+using Godot;
+
+/// <summary>
+/// Esta classe só existe para agrupar seus descendentes.
+/// </summary>
+[GlobalClass]
+public abstract partial class ConsumableItemDefinition : EntityDefinition; \ No newline at end of file
diff --git a/scripts/entities/items/ConsumableItemDefinition.cs.uid b/scripts/entities/items/ConsumableItemDefinition.cs.uid
new file mode 100644
index 0000000..9ddc0f6
--- /dev/null
+++ b/scripts/entities/items/ConsumableItemDefinition.cs.uid
@@ -0,0 +1 @@
+uid://dpdju2ucehsb0
diff --git a/scripts/entities/items/HealingConsumable.cs b/scripts/entities/items/HealingConsumable.cs
new file mode 100644
index 0000000..3d8df51
--- /dev/null
+++ b/scripts/entities/items/HealingConsumable.cs
@@ -0,0 +1,27 @@
+using Godot;
+
+public partial class HealingConsumable : ConsumableItem
+{
+ private HealingConsumableDefinition definition;
+ public float HealingPercentage { get; private set; }
+ public HealingConsumable(Vector2I initialPosition, MapData map, HealingConsumableDefinition definition) : base(initialPosition, map, definition)
+ {
+ this.definition = definition;
+ HealingPercentage = definition.healingPercentage;
+ }
+
+ public override bool Activate(ItemAction action)
+ {
+ Actor consumer = action.ThisActor;
+ int intendedAmount = (int)(HealingPercentage / 100 * consumer.MaxHp);
+ int recovered = consumer.Heal(intendedAmount);
+
+ // Se não tinha o que curar, a ativação falhou.
+ if (recovered == 0) {
+ MessageLogData.Instance.AddMessage("Você já está saudável.");
+ return false;
+ }
+ MessageLogData.Instance.AddMessage($"Você consome {DisplayName} e recupera {recovered} de HP");
+ return true;
+ }
+} \ No newline at end of file
diff --git a/scripts/entities/items/HealingConsumable.cs.uid b/scripts/entities/items/HealingConsumable.cs.uid
new file mode 100644
index 0000000..8f8f942
--- /dev/null
+++ b/scripts/entities/items/HealingConsumable.cs.uid
@@ -0,0 +1 @@
+uid://ct20rmjhaukge
diff --git a/scripts/entities/items/HealingConsumableDefinition.cs b/scripts/entities/items/HealingConsumableDefinition.cs
new file mode 100644
index 0000000..2562e9e
--- /dev/null
+++ b/scripts/entities/items/HealingConsumableDefinition.cs
@@ -0,0 +1,11 @@
+using Godot;
+
+[GlobalClass]
+public partial class HealingConsumableDefinition : ConsumableItemDefinition {
+ ///<summary>
+ /// Porcentagem da vida do ator para restaurar.
+ ///</summary>
+ [ExportCategory("Item Mechanics")]
+ [Export]
+ public float healingPercentage = 10;
+} \ No newline at end of file
diff --git a/scripts/entities/items/HealingConsumableDefinition.cs.uid b/scripts/entities/items/HealingConsumableDefinition.cs.uid
new file mode 100644
index 0000000..2fd311d
--- /dev/null
+++ b/scripts/entities/items/HealingConsumableDefinition.cs.uid
@@ -0,0 +1 @@
+uid://b3qy4gtjfci14
diff --git a/scripts/map/DungeonGenerator.cs b/scripts/map/DungeonGenerator.cs
index f016dd2..cb89508 100644
--- a/scripts/map/DungeonGenerator.cs
+++ b/scripts/map/DungeonGenerator.cs
@@ -12,12 +12,16 @@ public partial class DungeonGenerator : Node
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")
+ 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>
+ /// Dimensões do mapa a ser criado.
+ /// </summary>
[ExportCategory("Dimension")]
[Export]
private int width = 80;
@@ -52,6 +56,13 @@ public partial class DungeonGenerator : Node
[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();
@@ -149,6 +160,8 @@ public partial class DungeonGenerator : Node
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.
@@ -173,6 +186,32 @@ public partial class DungeonGenerator : Node
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>
diff --git a/scripts/map/Map.cs b/scripts/map/Map.cs
index c14880a..f4f0783 100644
--- a/scripts/map/Map.cs
+++ b/scripts/map/Map.cs
@@ -46,11 +46,11 @@ public partial class Map : Node2D
}
/// <summary>
- /// Coloca todos os tiles do mapa no mundo do jogo.
+ /// Coloca todas as entidades do mapa no mundo do jogo.
/// </summary>
private void PlaceEntities() {
- foreach (Actor actor in Map_Data.Entities) {
- entitiesNode.AddChild(actor);
+ foreach (Entity entity in Map_Data.Entities) {
+ entitiesNode.AddChild(entity);
}
}
@@ -72,9 +72,9 @@ public partial class Map : Node2D
/// <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 atores com base no campo de visão.
- foreach (Actor actor in Map_Data.Entities) {
- actor.Visible = Map_Data.GetTile(actor.GridPosition).IsInView;
+ // 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;
}
}
}