summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavoeklund01 <eklundgu@gmail.com>2025-11-10 17:25:59 -0300
committerGustavoeklund01 <eklundgu@gmail.com>2025-11-10 17:25:59 -0300
commit1a042d7303081e8bc72e9e3c341db3e528c8d998 (patch)
treecb56eafbd73ab8c7f8ba231fd512ae246b4dd64b
parentde99779d19b77d174c561cb3795538412f53bcbc (diff)
parentf46d058571d453ccf7ddf884ccb5d8694f970d7c (diff)
Merge branch 'master' of https://github.com/Simplesmente-O-Grupo/projeto-fantasiaHEADmaster
-rw-r--r--assets/Oserif-j98vR.ttfbin0 -> 88980 bytes
-rw-r--r--assets/Oserif-j98vR.ttf.import36
-rw-r--r--assets/definitions/Items/big_potion_of_heals.tres23
-rw-r--r--assets/definitions/Items/uohhh.tres21
-rw-r--r--assets/definitions/actor/toilet.tres18
-rw-r--r--assets/sprites/actors/ToiletMan.pngbin0 -> 280 bytes
-rw-r--r--assets/sprites/actors/ToiletMan.png.import40
-rw-r--r--assets/sprites/inter-face/button_texture.pngbin0 -> 156 bytes
-rw-r--r--assets/sprites/inter-face/button_texture.png.import40
-rw-r--r--assets/sprites/items/big_health_potion.pngbin0 -> 306 bytes
-rw-r--r--assets/sprites/items/big_health_potion.png.import40
-rw-r--r--assets/sprites/tiles/floor.pngbin200 -> 213 bytes
-rw-r--r--assets/sprites/tiles/wall.pngbin232 -> 215 bytes
-rw-r--r--project.godot5
-rw-r--r--scenes/GUI/Leaderboard.cs62
-rw-r--r--scenes/GUI/Leaderboard.cs.uid1
-rw-r--r--scenes/GUI/Leaderboard.tscn53
-rw-r--r--scenes/GUI/button.tres10
-rw-r--r--scenes/GUI/leaderboard_item.tscn35
-rw-r--r--scenes/GUI/main_menu.tscn20
-rw-r--r--scenes/name_thyself.tscn14
-rw-r--r--scripts/Entities/Actions/EscapeAction.cs76
-rw-r--r--scripts/Entities/Actors/Actor.cs6
-rw-r--r--scripts/GUI/LeaderboardItem.cs41
-rw-r--r--scripts/GUI/LeaderboardItem.cs.uid1
-rw-r--r--scripts/GUI/MainMenu.cs12
-rw-r--r--scripts/Game.cs2
-rw-r--r--scripts/GameManager.cs10
-rw-r--r--scripts/InputHandling/MainGameInputHandler.cs2
-rw-r--r--scripts/Map/DungeonGenerator.cs68
-rw-r--r--scripts/Utils/Stats.cs52
-rw-r--r--scripts/Utils/Stats.cs.uid1
32 files changed, 666 insertions, 23 deletions
diff --git a/assets/Oserif-j98vR.ttf b/assets/Oserif-j98vR.ttf
new file mode 100644
index 0000000..ec2b5dd
--- /dev/null
+++ b/assets/Oserif-j98vR.ttf
Binary files differ
diff --git a/assets/Oserif-j98vR.ttf.import b/assets/Oserif-j98vR.ttf.import
new file mode 100644
index 0000000..fdd9950
--- /dev/null
+++ b/assets/Oserif-j98vR.ttf.import
@@ -0,0 +1,36 @@
+[remap]
+
+importer="font_data_dynamic"
+type="FontFile"
+uid="uid://bkhmc8y1sdhb1"
+path="res://.godot/imported/Oserif-j98vR.ttf-699afbfb4c56b9ebc9e584f218277179.fontdata"
+
+[deps]
+
+source_file="res://assets/Oserif-j98vR.ttf"
+dest_files=["res://.godot/imported/Oserif-j98vR.ttf-699afbfb4c56b9ebc9e584f218277179.fontdata"]
+
+[params]
+
+Rendering=null
+antialiasing=1
+generate_mipmaps=false
+disable_embedded_bitmaps=true
+multichannel_signed_distance_field=false
+msdf_pixel_range=8
+msdf_size=48
+allow_system_fallback=true
+force_autohinter=false
+modulate_color_glyphs=false
+hinting=1
+subpixel_positioning=4
+keep_rounding_remainders=true
+oversampling=0.0
+Fallbacks=null
+fallbacks=[]
+Compress=null
+compress=true
+preload=[]
+language_support={}
+script_support={}
+opentype_features={}
diff --git a/assets/definitions/Items/big_potion_of_heals.tres b/assets/definitions/Items/big_potion_of_heals.tres
new file mode 100644
index 0000000..81c5e0b
--- /dev/null
+++ b/assets/definitions/Items/big_potion_of_heals.tres
@@ -0,0 +1,23 @@
+[gd_resource type="Resource" script_class="ItemResource" load_steps=7 format=3 uid="uid://dm0v0aoarb4dp"]
+
+[ext_resource type="Script" uid="uid://bslt4pbvwvsj1" path="res://scripts/Magic/HealEffect.cs" id="1_2x33w"]
+[ext_resource type="Script" uid="uid://bybli1lduvm3n" path="res://scripts/Entities/Items/ItemResource.cs" id="1_vsyyt"]
+[ext_resource type="Script" uid="uid://b72fwkwul1wet" path="res://scripts/Entities/Items/SpellEffectItemActivation.cs" id="2_l4xm8"]
+[ext_resource type="Texture2D" uid="uid://dftr4yuf72gg2" path="res://assets/sprites/items/big_health_potion.png" id="3_4nt2e"]
+
+[sub_resource type="Resource" id="Resource_8peth"]
+script = ExtResource("1_2x33w")
+Healing = 20
+metadata/_custom_type_script = "uid://bslt4pbvwvsj1"
+
+[sub_resource type="Resource" id="Resource_jdsxe"]
+script = ExtResource("2_l4xm8")
+effect = SubResource("Resource_8peth")
+metadata/_custom_type_script = "uid://b72fwkwul1wet"
+
+[resource]
+script = ExtResource("1_vsyyt")
+DisplayName = "Poção de cura grande"
+Icon = ExtResource("3_4nt2e")
+Activation = SubResource("Resource_jdsxe")
+metadata/_custom_type_script = "uid://bybli1lduvm3n"
diff --git a/assets/definitions/Items/uohhh.tres b/assets/definitions/Items/uohhh.tres
new file mode 100644
index 0000000..c48c07a
--- /dev/null
+++ b/assets/definitions/Items/uohhh.tres
@@ -0,0 +1,21 @@
+[gd_resource type="Resource" script_class="ItemResource" load_steps=6 format=3 uid="uid://otklq7k1tb45"]
+
+[ext_resource type="Script" uid="uid://bybli1lduvm3n" path="res://scripts/Entities/Items/ItemResource.cs" id="1_6qucm"]
+[ext_resource type="Script" uid="uid://bslt4pbvwvsj1" path="res://scripts/Magic/HealEffect.cs" id="1_uvkms"]
+[ext_resource type="Script" uid="uid://b72fwkwul1wet" path="res://scripts/Entities/Items/SpellEffectItemActivation.cs" id="2_i5wwe"]
+
+[sub_resource type="Resource" id="Resource_idx7p"]
+script = ExtResource("1_uvkms")
+Healing = 89
+metadata/_custom_type_script = "uid://bslt4pbvwvsj1"
+
+[sub_resource type="Resource" id="Resource_v7ab0"]
+script = ExtResource("2_i5wwe")
+effect = SubResource("Resource_idx7p")
+metadata/_custom_type_script = "uid://b72fwkwul1wet"
+
+[resource]
+script = ExtResource("1_6qucm")
+DisplayName = "ojo"
+Activation = SubResource("Resource_v7ab0")
+metadata/_custom_type_script = "uid://bybli1lduvm3n"
diff --git a/assets/definitions/actor/toilet.tres b/assets/definitions/actor/toilet.tres
new file mode 100644
index 0000000..f33a878
--- /dev/null
+++ b/assets/definitions/actor/toilet.tres
@@ -0,0 +1,18 @@
+[gd_resource type="Resource" script_class="EnemyDefinition" load_steps=4 format=3 uid="uid://bbj06osf7pjor"]
+
+[ext_resource type="Script" uid="uid://dkfdm2m2scyks" path="res://scripts/Entities/Actors/EnemyDefinition.cs" id="1_mh1wq"]
+[ext_resource type="Texture2D" uid="uid://w0808ug4al66" path="res://assets/sprites/actors/generic_grave.png" id="1_tv8qd"]
+[ext_resource type="Texture2D" uid="uid://j1b2vbolwsch" path="res://assets/sprites/actors/ToiletMan.png" id="3_riy75"]
+
+[resource]
+script = ExtResource("1_mh1wq")
+AI = 1
+deathTexture = ExtResource("1_tv8qd")
+Hp = 16
+Atk = 6
+Def = 2
+Men = 3
+name = "SKIBIDI"
+texture = ExtResource("3_riy75")
+Type = 2
+metadata/_custom_type_script = "uid://dkfdm2m2scyks"
diff --git a/assets/sprites/actors/ToiletMan.png b/assets/sprites/actors/ToiletMan.png
new file mode 100644
index 0000000..a257313
--- /dev/null
+++ b/assets/sprites/actors/ToiletMan.png
Binary files differ
diff --git a/assets/sprites/actors/ToiletMan.png.import b/assets/sprites/actors/ToiletMan.png.import
new file mode 100644
index 0000000..9b18b96
--- /dev/null
+++ b/assets/sprites/actors/ToiletMan.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://j1b2vbolwsch"
+path="res://.godot/imported/ToiletMan.png-f992a71b96595fd93fe0692465c52574.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/sprites/actors/ToiletMan.png"
+dest_files=["res://.godot/imported/ToiletMan.png-f992a71b96595fd93fe0692465c52574.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/assets/sprites/inter-face/button_texture.png b/assets/sprites/inter-face/button_texture.png
new file mode 100644
index 0000000..aca4745
--- /dev/null
+++ b/assets/sprites/inter-face/button_texture.png
Binary files differ
diff --git a/assets/sprites/inter-face/button_texture.png.import b/assets/sprites/inter-face/button_texture.png.import
new file mode 100644
index 0000000..00f222d
--- /dev/null
+++ b/assets/sprites/inter-face/button_texture.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dwg5pwgld1xrr"
+path="res://.godot/imported/button_texture.png-6946e2ce5b57b5b0f0334c9bd99a877f.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/sprites/inter-face/button_texture.png"
+dest_files=["res://.godot/imported/button_texture.png-6946e2ce5b57b5b0f0334c9bd99a877f.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/assets/sprites/items/big_health_potion.png b/assets/sprites/items/big_health_potion.png
new file mode 100644
index 0000000..81e8dbd
--- /dev/null
+++ b/assets/sprites/items/big_health_potion.png
Binary files differ
diff --git a/assets/sprites/items/big_health_potion.png.import b/assets/sprites/items/big_health_potion.png.import
new file mode 100644
index 0000000..6c59746
--- /dev/null
+++ b/assets/sprites/items/big_health_potion.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dftr4yuf72gg2"
+path="res://.godot/imported/big_health_potion.png-9796650ac3c4679880ae8cb9cebfbe7c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/sprites/items/big_health_potion.png"
+dest_files=["res://.godot/imported/big_health_potion.png-9796650ac3c4679880ae8cb9cebfbe7c.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/assets/sprites/tiles/floor.png b/assets/sprites/tiles/floor.png
index 2f93b12..f0e248e 100644
--- a/assets/sprites/tiles/floor.png
+++ b/assets/sprites/tiles/floor.png
Binary files differ
diff --git a/assets/sprites/tiles/wall.png b/assets/sprites/tiles/wall.png
index 3b2e058..2a94ef4 100644
--- a/assets/sprites/tiles/wall.png
+++ b/assets/sprites/tiles/wall.png
Binary files differ
diff --git a/project.godot b/project.godot
index 5ee82d7..a2bb69f 100644
--- a/project.godot
+++ b/project.godot
@@ -20,6 +20,7 @@ config/icon="res://icon.svg"
signalBus="*res://scripts/Utils/SignalBus.cs"
MessageLogData="*res://scripts/Utils/MessageLogData.cs"
+Stats="*res://scripts/Utils/Stats.cs"
[display]
@@ -29,6 +30,10 @@ window/stretch/mode="canvas_items"
project/assembly_name="projeto-fantasia"
+[gui]
+
+theme/custom_font="uid://bkhmc8y1sdhb1"
+
[input]
walk-up={
diff --git a/scenes/GUI/Leaderboard.cs b/scenes/GUI/Leaderboard.cs
new file mode 100644
index 0000000..cf126c9
--- /dev/null
+++ b/scenes/GUI/Leaderboard.cs
@@ -0,0 +1,62 @@
+using System;
+using Godot;
+using Godot.Collections;
+using TheLegendOfGustav.Utils;
+
+namespace TheLegendOfGustav.GUI;
+public partial class Leaderboard : Control
+{
+ [Signal]
+ public delegate void MenuRequestedEventHandler();
+ private static readonly PackedScene LeaderboardItemScene = GD.Load<PackedScene>("res://scenes/GUI/leaderboard_item.tscn");
+
+ private VBoxContainer leaderboard;
+ private Button BackButton;
+ // Called when the node enters the scene tree for the first time.
+ public override void _Ready()
+ {
+ leaderboard = GetNode<VBoxContainer>("VBoxContainer/VBoxContainer");
+ BackButton = GetNode<Button>("VBoxContainer/exit");
+
+ BackButton.Pressed += () => EmitSignal(SignalName.MenuRequested);
+
+ bool hasLeaderboardFile = FileAccess.FileExists("user://placar.json");
+ if (hasLeaderboardFile)
+ {
+ using var leaderboardFile = FileAccess.Open("user://placar.json", FileAccess.ModeFlags.Read);
+ string boardString = leaderboardFile.GetLine();
+
+ Dictionary<string, Variant> leaderBoardData;
+
+ try
+ {
+ var parseResult = Json.ParseString(boardString);
+ if (parseResult.VariantType == Variant.Type.Nil)
+ {
+ throw new Exception();
+ }
+ leaderBoardData = (Dictionary<string, Variant>)parseResult;
+ }
+ catch (Exception)
+ {
+ // Arquivo inválido.
+ return;
+ }
+
+ Array<Dictionary<string, Variant>> players = (Array<Dictionary<string, Variant>>)leaderBoardData["placar"];
+
+ foreach (Dictionary<string, Variant> player in players)
+ {
+ LeaderboardItem item = LeaderboardItemScene.Instantiate<LeaderboardItem>();
+
+ item.PlayerName = (string)player["jogador"];
+ item.Floor = (string)player["andar_mais_fundo"];
+ item.Kills = (string)player["inimigos_mortos"];
+ item.Damage = (string)player["dano_tomado"];
+
+ leaderboard.AddChild(item);
+ }
+
+ }
+ }
+}
diff --git a/scenes/GUI/Leaderboard.cs.uid b/scenes/GUI/Leaderboard.cs.uid
new file mode 100644
index 0000000..4681d98
--- /dev/null
+++ b/scenes/GUI/Leaderboard.cs.uid
@@ -0,0 +1 @@
+uid://bj6r5oalajbmc
diff --git a/scenes/GUI/Leaderboard.tscn b/scenes/GUI/Leaderboard.tscn
new file mode 100644
index 0000000..5724e34
--- /dev/null
+++ b/scenes/GUI/Leaderboard.tscn
@@ -0,0 +1,53 @@
+[gd_scene load_steps=7 format=3 uid="uid://ddxrecok5ctss"]
+
+[ext_resource type="Script" uid="uid://bj6r5oalajbmc" path="res://scenes/GUI/Leaderboard.cs" id="1_8w6tf"]
+[ext_resource type="Texture2D" uid="uid://bxjwbucke02gl" path="res://assets/bg.png" id="1_dlctp"]
+[ext_resource type="PackedScene" uid="uid://w4oy340d3ugn" path="res://scenes/GUI/leaderboard_item.tscn" id="2_8w6tf"]
+[ext_resource type="StyleBox" uid="uid://krfa04v10vwc" path="res://scenes/GUI/button.tres" id="4_kxih3"]
+
+[sub_resource type="InputEventKey" id="InputEventKey_8w6tf"]
+device = -1
+keycode = 86
+unicode = 118
+
+[sub_resource type="Shortcut" id="Shortcut_kxih3"]
+events = [SubResource("InputEventKey_8w6tf")]
+
+[node name="Control" type="Control"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_8w6tf")
+
+[node name="TextureRect" type="TextureRect" parent="."]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+texture = ExtResource("1_dlctp")
+expand_mode = 3
+
+[node name="VBoxContainer" type="VBoxContainer" parent="."]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer"]
+layout_mode = 2
+
+[node name="Header" parent="VBoxContainer/VBoxContainer" instance=ExtResource("2_8w6tf")]
+layout_mode = 2
+
+[node name="exit" type="Button" parent="VBoxContainer"]
+layout_mode = 2
+theme_override_styles/normal = ExtResource("4_kxih3")
+shortcut = SubResource("Shortcut_kxih3")
+text = "[V] Voltar"
diff --git a/scenes/GUI/button.tres b/scenes/GUI/button.tres
new file mode 100644
index 0000000..601c8f7
--- /dev/null
+++ b/scenes/GUI/button.tres
@@ -0,0 +1,10 @@
+[gd_resource type="StyleBoxTexture" load_steps=2 format=3 uid="uid://krfa04v10vwc"]
+
+[ext_resource type="Texture2D" uid="uid://dwg5pwgld1xrr" path="res://assets/sprites/inter-face/button_texture.png" id="1_dju77"]
+
+[resource]
+texture = ExtResource("1_dju77")
+texture_margin_left = 2.0
+texture_margin_top = 2.0
+texture_margin_right = 2.0
+texture_margin_bottom = 2.0
diff --git a/scenes/GUI/leaderboard_item.tscn b/scenes/GUI/leaderboard_item.tscn
new file mode 100644
index 0000000..4cee6d3
--- /dev/null
+++ b/scenes/GUI/leaderboard_item.tscn
@@ -0,0 +1,35 @@
+[gd_scene load_steps=2 format=3 uid="uid://w4oy340d3ugn"]
+
+[ext_resource type="Script" uid="uid://cbjltiujfsw4v" path="res://scripts/GUI/LeaderboardItem.cs" id="1_ilpit"]
+
+[node name="HBoxContainer" type="HBoxContainer"]
+script = ExtResource("1_ilpit")
+
+[node name="hdNome" type="Label" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+text = "Nome"
+
+[node name="VSeparator" type="VSeparator" parent="."]
+layout_mode = 2
+
+[node name="hdAndar" type="Label" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+text = "Maior Andar"
+
+[node name="VSeparator2" type="VSeparator" parent="."]
+layout_mode = 2
+
+[node name="hdkills" type="Label" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+text = "Inimigos Mortos"
+
+[node name="VSeparator3" type="VSeparator" parent="."]
+layout_mode = 2
+
+[node name="hddamage" type="Label" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+text = "Dano tomado"
diff --git a/scenes/GUI/main_menu.tscn b/scenes/GUI/main_menu.tscn
index 2794830..95700a0 100644
--- a/scenes/GUI/main_menu.tscn
+++ b/scenes/GUI/main_menu.tscn
@@ -1,7 +1,8 @@
-[gd_scene load_steps=10 format=3 uid="uid://cppjdsdfkkxtm"]
+[gd_scene load_steps=13 format=3 uid="uid://cppjdsdfkkxtm"]
[ext_resource type="Script" uid="uid://dx0fxht2oadb6" path="res://scripts/GUI/MainMenu.cs" id="1_b4h60"]
[ext_resource type="Texture2D" uid="uid://bxjwbucke02gl" path="res://assets/bg.png" id="1_tbt31"]
+[ext_resource type="StyleBox" uid="uid://krfa04v10vwc" path="res://scenes/GUI/button.tres" id="3_kebck"]
[sub_resource type="LabelSettings" id="LabelSettings_b4h60"]
font_size = 32
@@ -22,6 +23,14 @@ unicode = 99
[sub_resource type="Shortcut" id="Shortcut_1ei6q"]
events = [SubResource("InputEventKey_kebck")]
+[sub_resource type="InputEventKey" id="InputEventKey_b4h60"]
+device = -1
+keycode = 80
+unicode = 112
+
+[sub_resource type="Shortcut" id="Shortcut_kebck"]
+events = [SubResource("InputEventKey_b4h60")]
+
[sub_resource type="InputEventKey" id="InputEventKey_xm7ak"]
device = -1
keycode = 83
@@ -71,18 +80,27 @@ label_settings = SubResource("LabelSettings_b4h60")
[node name="neogame" type="Button" parent="VBoxContainer/CenterContainer/VBoxContainer"]
layout_mode = 2
+theme_override_styles/normal = ExtResource("3_kebck")
shortcut = SubResource("Shortcut_b4h60")
shortcut_feedback = false
text = "[N] Novo jogo"
[node name="continue" type="Button" parent="VBoxContainer/CenterContainer/VBoxContainer"]
layout_mode = 2
+theme_override_styles/normal = ExtResource("3_kebck")
shortcut = SubResource("Shortcut_1ei6q")
shortcut_feedback = false
text = "[C] Continuar"
+[node name="leaderboard" type="Button" parent="VBoxContainer/CenterContainer/VBoxContainer"]
+layout_mode = 2
+theme_override_styles/normal = ExtResource("3_kebck")
+shortcut = SubResource("Shortcut_kebck")
+text = "[P] Placar"
+
[node name="quit" type="Button" parent="VBoxContainer/CenterContainer/VBoxContainer"]
layout_mode = 2
+theme_override_styles/normal = ExtResource("3_kebck")
shortcut = SubResource("Shortcut_h03jd")
text = "[S] Sair"
diff --git a/scenes/name_thyself.tscn b/scenes/name_thyself.tscn
index d2c3650..e4f75b3 100644
--- a/scenes/name_thyself.tscn
+++ b/scenes/name_thyself.tscn
@@ -1,7 +1,17 @@
-[gd_scene load_steps=3 format=3 uid="uid://baio67tv5ifph"]
+[gd_scene load_steps=6 format=3 uid="uid://baio67tv5ifph"]
[ext_resource type="Texture2D" uid="uid://bxjwbucke02gl" path="res://assets/bg.png" id="1_c644k"]
[ext_resource type="Script" uid="uid://cmtn05tqqh0t4" path="res://scripts/GUI/PlayerName.cs" id="1_jhpgh"]
+[ext_resource type="Texture2D" uid="uid://dwg5pwgld1xrr" path="res://assets/sprites/inter-face/button_texture.png" id="3_c5fbr"]
+[ext_resource type="StyleBox" uid="uid://krfa04v10vwc" path="res://scenes/GUI/button.tres" id="4_jndhp"]
+
+[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_x2lmy"]
+texture = ExtResource("3_c5fbr")
+texture_margin_left = 2.0
+texture_margin_top = 2.0
+texture_margin_right = 2.0
+texture_margin_bottom = 2.0
+modulate_color = Color(0.39308554, 0.3930855, 0.39308548, 1)
[node name="NameThyself" type="Control"]
layout_mode = 3
@@ -42,9 +52,11 @@ text = "Quem é você?"
[node name="thename" type="LineEdit" parent="VBoxContainer"]
layout_mode = 2
+theme_override_styles/normal = SubResource("StyleBoxTexture_x2lmy")
placeholder_text = "Player"
expand_to_text_length = true
[node name="Button" type="Button" parent="VBoxContainer"]
layout_mode = 2
+theme_override_styles/normal = ExtResource("4_jndhp")
text = "Iniciar"
diff --git a/scripts/Entities/Actions/EscapeAction.cs b/scripts/Entities/Actions/EscapeAction.cs
index f0b1ed5..1b3aae2 100644
--- a/scripts/Entities/Actions/EscapeAction.cs
+++ b/scripts/Entities/Actions/EscapeAction.cs
@@ -1,13 +1,85 @@
+using System;
+using Godot;
+using Godot.Collections;
+using Microsoft.VisualBasic;
using TheLegendOfGustav.Entities.Actors;
using TheLegendOfGustav.Utils;
namespace TheLegendOfGustav.Entities.Actions;
-public partial class EscapeAction(Actor actor) : Action(actor)
+public partial class EscapeAction(Actor actor, bool should_save = false) : Action(actor)
{
+ private bool should_save = should_save;
public override bool Perform()
{
- Actor.MapData.SaveGame();
+ if (should_save) {
+ Actor.MapData.SaveGame();
+ } else {
+ // game over
+ bool hasLeaderboardFile = FileAccess.FileExists("user://placar.json");
+ if (hasLeaderboardFile) {
+ using var leaderboardFile = FileAccess.Open("user://placar.json", FileAccess.ModeFlags.ReadWrite);
+ string boardString = leaderboardFile.GetLine();
+
+ Dictionary<string, Variant> leaderBoardData;
+
+ try {
+ var parseResult = Json.ParseString(boardString);
+ if (parseResult.VariantType == Variant.Type.Nil) {
+ throw new Exception();
+ }
+ leaderBoardData = (Dictionary<string, Variant>)parseResult;
+ } catch (Exception)
+ {
+ leaderboardFile.Resize(0);
+ leaderboardFile.Seek(0);
+
+ leaderBoardData = new()
+ {
+ {"placar", new Array<Dictionary<string, Variant>>() {Stats.Instance.Serialize()}}
+ };
+ boardString = Json.Stringify(leaderBoardData);
+
+ leaderboardFile.StoreLine(boardString);
+
+ SignalBus.Instance.EmitSignal(SignalBus.SignalName.EscapeRequested);
+ return false;
+ }
+
+ Array<Dictionary<string, Variant>> players = (Array<Dictionary<string, Variant>>)leaderBoardData["placar"];
+
+ players.Add(Stats.Instance.Serialize());
+
+ for (int i = 0; i < players.Count; i++) {
+ for (int j = 0; j < players.Count - 1 - i; j++) {
+ if ((int)players[j]["andar_mais_fundo"] < (int)players[j + 1]["andar_mais_fundo"]) {
+ Dictionary<string, Variant> tmp = players[j];
+ players[j] = players[j + 1];
+ players[j + 1] = tmp;
+ }
+ }
+ }
+
+ if (players.Count > 10) {
+ players = players.GetSliceRange(0, 10);
+ }
+
+ leaderBoardData["placar"] = players;
+
+ leaderboardFile.Resize(0);
+ leaderboardFile.Seek(0);
+ leaderboardFile.StoreLine(Json.Stringify(leaderBoardData));
+ } else {
+ using var leaderboardFile = FileAccess.Open("user://placar.json", FileAccess.ModeFlags.Write);
+ Dictionary<string, Variant> leaderBoardData = new()
+ {
+ {"placar", new Array<Dictionary<string, Variant>>() {Stats.Instance.Serialize()}}
+ };
+ string boardString = Json.Stringify(leaderBoardData);
+
+ leaderboardFile.StoreLine(boardString);
+ }
+ }
SignalBus.Instance.EmitSignal(SignalBus.SignalName.EscapeRequested);
return false;
}
diff --git a/scripts/Entities/Actors/Actor.cs b/scripts/Entities/Actors/Actor.cs
index c68cc2b..e6b8867 100644
--- a/scripts/Entities/Actors/Actor.cs
+++ b/scripts/Entities/Actors/Actor.cs
@@ -101,6 +101,9 @@ public partial class Actor : Entity, ISaveable
get => hp;
set
{
+ if (MapData != null && MapData.Player == this && hp > value) {
+ Stats.Instance.DamageTaken += (hp - value);
+ }
// Esta propriedade impede que o HP seja maior que o máximo.
hp = int.Clamp(value, 0, MaxHp);
EmitSignal(SignalName.HealthChanged, Hp, MaxHp);
@@ -280,6 +283,9 @@ public partial class Actor : Entity, ISaveable
else
{
deathMessage = $"{DisplayName} morreu!";
+ if (!inLoading) {
+ Stats.Instance.EnemiesKilled++;
+ }
}
diff --git a/scripts/GUI/LeaderboardItem.cs b/scripts/GUI/LeaderboardItem.cs
new file mode 100644
index 0000000..c05bf58
--- /dev/null
+++ b/scripts/GUI/LeaderboardItem.cs
@@ -0,0 +1,41 @@
+using Godot;
+
+namespace TheLegendOfGustav.GUI;
+
+public partial class LeaderboardItem : HBoxContainer
+{
+ [Export]
+ public string PlayerName { get; set; } = "Jogador";
+ [Export]
+ public string Floor { get; set; } = "Andar Máximo";
+ [Export]
+ public string Kills { get; set; } = "Inimigos Mortos";
+ [Export]
+ public string Damage { get; set; } = "Dano tomado";
+
+ private Label nameLabel;
+ private Label floorLabel;
+ private Label killsLabel;
+ private Label damageLabel;
+
+
+ // Called when the node enters the scene tree for the first time.
+ public override void _Ready()
+ {
+ nameLabel = GetNode<Label>("hdNome");
+ floorLabel = GetNode<Label>("hdAndar");
+ killsLabel = GetNode<Label>("hdkills");
+ damageLabel = GetNode<Label>("hddamage");
+
+
+ UpdateLabels();
+ }
+
+ public void UpdateLabels()
+ {
+ nameLabel.Text = PlayerName;
+ floorLabel.Text = Floor;
+ killsLabel.Text = Kills;
+ damageLabel.Text = Damage;
+ }
+}
diff --git a/scripts/GUI/LeaderboardItem.cs.uid b/scripts/GUI/LeaderboardItem.cs.uid
new file mode 100644
index 0000000..ddac2bd
--- /dev/null
+++ b/scripts/GUI/LeaderboardItem.cs.uid
@@ -0,0 +1 @@
+uid://cbjltiujfsw4v
diff --git a/scripts/GUI/MainMenu.cs b/scripts/GUI/MainMenu.cs
index fc46cd2..0d6c8c6 100644
--- a/scripts/GUI/MainMenu.cs
+++ b/scripts/GUI/MainMenu.cs
@@ -7,9 +7,12 @@ public partial class MainMenu : Control
private Button newGameButton;
private Button loadGameButton;
private Button quitButton;
+ private Button leaderboardButton;
[Signal]
public delegate void GameRequestEventHandler(bool load);
+ [Signal]
+ public delegate void LeaderboardRequestEventHandler();
public override void _Ready()
{
@@ -18,14 +21,18 @@ public partial class MainMenu : Control
newGameButton = GetNode<Button>("VBoxContainer/CenterContainer/VBoxContainer/neogame");
loadGameButton = GetNode<Button>("VBoxContainer/CenterContainer/VBoxContainer/continue");
quitButton = GetNode<Button>("VBoxContainer/CenterContainer/VBoxContainer/quit");
+ leaderboardButton = GetNode<Button>("VBoxContainer/CenterContainer/VBoxContainer/leaderboard");
newGameButton.Pressed += OnNewGameButtonPressed;
loadGameButton.Pressed += OnLoadGameButtonPressed;
quitButton.Pressed += OnQuitButtonPressed;
+ leaderboardButton.Pressed += OnLeaderBoardRequest;
newGameButton.GrabFocus();
bool hasSaveFile = FileAccess.FileExists("user://save_game.json");
+ bool hasLeaderboard = FileAccess.FileExists("user://placar.json");
loadGameButton.Disabled = !hasSaveFile;
+ leaderboardButton.Disabled = !hasLeaderboard;
}
private void OnNewGameButtonPressed()
@@ -38,6 +45,11 @@ public partial class MainMenu : Control
EmitSignal(SignalName.GameRequest, true);
}
+ private void OnLeaderBoardRequest()
+ {
+ EmitSignal(SignalName.LeaderboardRequest);
+ }
+
private void OnQuitButtonPressed()
{
GetTree().Quit();
diff --git a/scripts/Game.cs b/scripts/Game.cs
index e55b937..cc86928 100644
--- a/scripts/Game.cs
+++ b/scripts/Game.cs
@@ -90,6 +90,8 @@ public partial class Game : Node
player.AddChild(camera);
+ Stats.Instance.PlayerName = player.DisplayName;
+
if (!map.LoadGame(player))
{
return false;
diff --git a/scripts/GameManager.cs b/scripts/GameManager.cs
index 5898744..4215475 100644
--- a/scripts/GameManager.cs
+++ b/scripts/GameManager.cs
@@ -10,6 +10,7 @@ public partial class GameManager : Node
private PackedScene mainMenuScene = GD.Load<PackedScene>("res://scenes/GUI/main_menu.tscn");
private PackedScene gameScene = GD.Load<PackedScene>("res://scenes/Game.tscn");
private PackedScene nameScene = GD.Load<PackedScene>("res://scenes/name_thyself.tscn");
+ private PackedScene leaderboardScene = GD.Load<PackedScene>("res://scenes/GUI/Leaderboard.tscn");
private Node currentScene;
@@ -42,7 +43,9 @@ public partial class GameManager : Node
private void LoadMainMenu()
{
MainMenu menu = (MainMenu)SwitchToScene(mainMenuScene);
+ Stats.Instance.Clear();
menu.GameRequest += OnGameRequest;
+ menu.LeaderboardRequest += OnLeaderboardRequest;
}
private void LoadGame()
@@ -72,6 +75,7 @@ public partial class GameManager : Node
private void OnNameSelect(string name)
{
+ Stats.Instance.PlayerName = name;
NewGame(name);
}
@@ -86,4 +90,10 @@ public partial class GameManager : Node
LoadGame();
}
}
+
+ private void OnLeaderboardRequest()
+ {
+ Leaderboard scene = (Leaderboard)SwitchToScene(leaderboardScene);
+ scene.MenuRequested += LoadMainMenu;
+ }
}
diff --git a/scripts/InputHandling/MainGameInputHandler.cs b/scripts/InputHandling/MainGameInputHandler.cs
index a18bd73..d1b5818 100644
--- a/scripts/InputHandling/MainGameInputHandler.cs
+++ b/scripts/InputHandling/MainGameInputHandler.cs
@@ -60,7 +60,7 @@ public partial class MainGameInputHandler : BaseInputHandler
if (Input.IsActionJustPressed("quit"))
{
- action = new EscapeAction(player);
+ action = new EscapeAction(player, true);
}
if (Input.IsActionJustPressed("descend"))
diff --git a/scripts/Map/DungeonGenerator.cs b/scripts/Map/DungeonGenerator.cs
index 31dcffe..cce693a 100644
--- a/scripts/Map/DungeonGenerator.cs
+++ b/scripts/Map/DungeonGenerator.cs
@@ -3,6 +3,9 @@ using TheLegendOfGustav.Entities.Actors;
using TheLegendOfGustav.Entities;
using TheLegendOfGustav.Entities.Items;
using System;
+using Godot.Collections;
+using System.Diagnostics.Metrics;
+using System.Numerics;
namespace TheLegendOfGustav.Map;
@@ -14,18 +17,41 @@ public partial class DungeonGenerator : Node
{
#region Fields
/// <summary>
+ /// Chave: Andar mínimo
+ /// Valor: Número de máximo de monstros por sala
+ /// </summary>
+ private static readonly Dictionary<int, int> maxMonstersByFloor = new()
+ {
+ {1, 2},
+ {4, 3},
+ {6, 4},
+ {10, 8}
+ };
+ /// <summary>
+ /// Chave: Andar mínimo
+ /// Valor: Número de máximo de itens por sala
+ /// </summary>
+ private static readonly Dictionary<int, int> maxItemsByFloor = new()
+ {
+ {1, 1},
+ {4, 2},
+ {6, 3},
+ };
+ /// <summary>
/// Coleção de todos os inimigos que o gerador tem acesso.
/// </summary>
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/omal.tres")
+ GD.Load<EnemyDefinition>("res://assets/definitions/actor/omal.tres"),
+ GD.Load<EnemyDefinition>("res://assets/definitions/actor/toilet.tres")
];
private static readonly Godot.Collections.Array<ItemResource> items = [
GD.Load<ItemResource>("res://assets/definitions/Items/small_healing_potion.tres"),
- GD.Load<ItemResource>("res://assets/definitions/Items/mana_bolt_grimoire.tres")
+ GD.Load<ItemResource>("res://assets/definitions/Items/mana_bolt_grimoire.tres"),
+ GD.Load<ItemResource>("res://assets/definitions/Items/big_potion_of_heals.tres")
];
/// <summary>
@@ -48,24 +74,30 @@ public partial class DungeonGenerator : Node
/// </summary>
[ExportCategory("RNG")]
private RandomNumberGenerator rng = new();
-
- /// <summary>
- /// Quantidade máxima de inimigos por sala.
- /// </summary>
- [ExportCategory("Monster RNG")]
- [Export]
- private int maxMonstersPerRoom = 2;
-
- /// <summary>
- /// Quantidade máxima de itens por sala.
- /// </summary>
- [ExportCategory("Loot RNG")]
- [Export]
- private int maxItemsPerRoom = 2;
#endregion
#region Methods
+ private int GetMaxIValueForFloor(Dictionary<int, int> valueTable, int currentFloor) {
+ int currentValue = 0;
+
+ int? key = null;
+
+ foreach (int theKey in valueTable.Keys) {
+ if (theKey > currentFloor) {
+ break;
+ } else {
+ key = theKey;
+ }
+ }
+
+ if (key.HasValue) {
+ currentValue = valueTable[key.Value];
+ }
+
+ return currentValue;
+ }
+
/// <summary>
/// Gera um andar da masmorra.
/// Inimigos são colocados conforme configurações.
@@ -230,9 +262,9 @@ 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, maxMonstersPerRoom);
+ int monsterAmount = rng.RandiRange(0, GetMaxIValueForFloor(maxMonstersByFloor, data.CurrentFloor));
// Define quantos itens serão colocados na sala.
- int itemAmount = rng.RandiRange(0, maxItemsPerRoom);
+ int itemAmount = rng.RandiRange(0, GetMaxIValueForFloor(maxItemsByFloor, data.CurrentFloor));
for (int i = 0; i < monsterAmount; i++)
{
diff --git a/scripts/Utils/Stats.cs b/scripts/Utils/Stats.cs
new file mode 100644
index 0000000..d3c4aa3
--- /dev/null
+++ b/scripts/Utils/Stats.cs
@@ -0,0 +1,52 @@
+using Godot;
+using Godot.Collections;
+using TheLegendOfGustav.Utils;
+
+namespace TheLegendOfGustav.Utils;
+
+public partial class Stats : Node
+{
+ public static Stats Instance { get; set; }
+
+ public string PlayerName { get; set; }
+ public int MaxFloor { get; set; } = 0;
+
+ public int EnemiesKilled { get; set; } = 0;
+
+ public int DamageTaken { get; set; } = 0;
+
+ public override void _Ready()
+ {
+ base._Ready();
+ Instance = this;
+
+ SignalBus.Instance.DungeonFloorChanged += OnFloorChange;
+ }
+
+ public void Clear()
+ {
+ PlayerName = "";
+ MaxFloor = 0;
+ EnemiesKilled = 0;
+ DamageTaken = 0;
+ }
+
+ void OnFloorChange(int floor)
+ {
+ if (floor > MaxFloor)
+ {
+ MaxFloor = floor;
+ }
+ }
+
+ public Dictionary<string, Variant> Serialize()
+ {
+ return new()
+ {
+ {"jogador", PlayerName},
+ {"andar_mais_fundo", MaxFloor},
+ {"inimigos_mortos", EnemiesKilled},
+ {"dano_tomado", DamageTaken}
+ };
+ }
+} \ No newline at end of file
diff --git a/scripts/Utils/Stats.cs.uid b/scripts/Utils/Stats.cs.uid
new file mode 100644
index 0000000..a93778d
--- /dev/null
+++ b/scripts/Utils/Stats.cs.uid
@@ -0,0 +1 @@
+uid://eg7t08o6wpxb