From f4ed469fc9eaeebf39093fbf6601581cc10c6e2f Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 26 Oct 2025 20:02:15 -0300 Subject: feat:save AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit O vazio dentro de mim é como uma xícara de café esquecida no canto da mesa. --- scripts/Map/MapData.cs | 120 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 4 deletions(-) (limited to 'scripts/Map/MapData.cs') diff --git a/scripts/Map/MapData.cs b/scripts/Map/MapData.cs index 49e4ca0..5f96743 100644 --- a/scripts/Map/MapData.cs +++ b/scripts/Map/MapData.cs @@ -1,4 +1,5 @@ using Godot; +using Godot.Collections; using TheLegendOfGustav.Entities; using TheLegendOfGustav.Entities.Actors; using TheLegendOfGustav.Entities.Items; @@ -10,11 +11,9 @@ namespace TheLegendOfGustav.Map; /// O mapa é o cenário onde as ações do jogo ocorrem. /// Mais especificamente, o mapa é um único andar da masmorra. /// -public partial class MapData : RefCounted +public partial class MapData : RefCounted, ISaveable { #region Fields - public static readonly TileDefinition wallDefinition = GD.Load("res://assets/definitions/tiles/wall.tres"); - public static readonly TileDefinition floorDefinition = GD.Load("res://assets/definitions/tiles/floor.tres"); /// /// Peso do ator no pathfinder. /// A IA irá evitar de passar por espaços com peso alto. @@ -275,11 +274,16 @@ public partial class MapData : RefCounted /// private void SetupTiles() { + if (Tiles.Count > 1) + { + Tiles.Clear(); + } + for (int i = 0; i < Height; i++) { for (int j = 0; j < Width; j++) { - Tiles.Add(new Tile(new Vector2I(j, i), wallDefinition)); + Tiles.Add(new Tile(new Vector2I(j, i), TileType.WALL)); } } } @@ -314,5 +318,113 @@ public partial class MapData : RefCounted return true; } + + public Dictionary GetSaveData() + { + Array> serializedTiles = []; + Array> serializedItemEntities = []; + Array> serializedEnemies = []; + foreach (Tile tile in Tiles) + { + serializedTiles.Add(tile.GetSaveData()); + } + + foreach (Entity ent in Entities) + { + if (ent is Enemy enemy) + { + serializedEnemies.Add(enemy.GetSaveData()); + } + else if (ent is ItemEntity it) + { + serializedItemEntities.Add(it.GetSaveData()); + } + } + + return new() + { + {"tiles", serializedTiles}, + {"enemies", serializedEnemies}, + {"items", serializedItemEntities}, + {"player", Player.GetSaveData()}, + {"width", Width}, + {"height", Height}, + }; + } + + public bool LoadSaveData(Dictionary saveData) + { + Width = (int)saveData["width"]; + Height = (int)saveData["height"]; + + SetupTiles(); + + Array> serializedTiles = (Array>)saveData["tiles"]; + Array> serializedItemEntities = (Array>)saveData["items"]; + Array> serializedEnemies = (Array>)saveData["enemies"]; + + for (int i = 0; i < serializedTiles.Count; i++) + { + if (!Tiles[i].LoadSaveData(serializedTiles[i])) + { + return false; + } + } + SetupPathfinding(); + if (!Player.LoadSaveData((Dictionary)saveData["player"])) + { + return false; + } + + Player.MapData = this; + + foreach(Dictionary enemy in serializedEnemies) + { + Enemy en = new(Vector2I.Zero, this); + if (!en.LoadSaveData(enemy)) + { + return false; + } + + InsertEntity(en); + } + + foreach(Dictionary item in serializedItemEntities) + { + ItemEntity en = new(Vector2I.Zero, this); + + if (!en.LoadSaveData(item)) + { + return false; + } + + InsertEntity(en); + } + + return true; + } + + public void SaveGame() + { + using var saveFile = FileAccess.Open("user://save_game.json", FileAccess.ModeFlags.Write); + var saveData = GetSaveData(); + string saveString = Json.Stringify(saveData); + + saveFile.StoreLine(saveString); + } + + public bool LoadGame() + { + using var saveFile = FileAccess.Open("user://save_game.json", FileAccess.ModeFlags.Read); + string saveString = saveFile.GetLine(); + var saveData = (Dictionary)Json.ParseString(saveString); + + if (!LoadSaveData(saveData)) + { + return false; + } + + return true; + } #endregion } -- cgit v1.2.3