diff --git a/project.godot b/project.godot index 2083935..300980d 100644 --- a/project.godot +++ b/project.godot @@ -317,6 +317,11 @@ DebugEntities={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":66,"key_label":0,"unicode":98,"location":0,"echo":false,"script":null) ] } +SaveGame={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194336,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} [internationalization] diff --git a/scripts/CSharp/GameEntity/Entities/Entity.cs b/scripts/CSharp/GameEntity/Entities/Entity.cs index 0227929..fee522f 100644 --- a/scripts/CSharp/GameEntity/Entities/Entity.cs +++ b/scripts/CSharp/GameEntity/Entities/Entity.cs @@ -14,13 +14,13 @@ public class Entity id = new Random().NextInt64(); } - protected virtual void SaveEntity(JObject json) + public virtual void SaveEntity(JObject json) { json["id"] = id; json["type"] = EntityType; } - protected virtual void LoadEntity(JObject json) + public virtual void LoadEntity(JObject json) { id = json.GetLongValue("id"); } diff --git a/scripts/CSharp/GameEntity/Entities/LoadedScenesEntity.cs b/scripts/CSharp/GameEntity/Entities/LoadedScenesEntity.cs index 88a94a9..95241c3 100644 --- a/scripts/CSharp/GameEntity/Entities/LoadedScenesEntity.cs +++ b/scripts/CSharp/GameEntity/Entities/LoadedScenesEntity.cs @@ -1,13 +1,32 @@ +using System; using System.Collections.Generic; +using System.Linq; +using System.Transactions; +using Newtonsoft.Json.Linq; namespace Babushka.scripts.CSharp.GameEntity.Entities; public class LoadedScenesEntity : Entity { private HashSet _loadedScenes = new(); - public override string EntityType => "LoadedScenesEntity"; + public override string EntityType => OWN_TYPE_NAME; + public const string OWN_TYPE_NAME = "LoadedScenesEntity"; public void AddScene(string sceneName) => _loadedScenes.Add(sceneName); public bool WasSceneLoaded(string sceneName) => _loadedScenes.Contains(sceneName); + + public override void SaveEntity(JObject json) + { + base.SaveEntity(json); + json["scenes"] = new JArray(_loadedScenes); + } + + public override void LoadEntity(JObject json) + { + base.LoadEntity(json); + JArray array = (JArray?) json["scenes"] ?? throw new Exception("No scenes found in LoadedScenesEntity."); + + _loadedScenes = array.ToObject>()!; + } } \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/Entities/PositionalEntity.cs b/scripts/CSharp/GameEntity/Entities/PositionalEntity.cs index f8b6e79..98bc6b8 100644 --- a/scripts/CSharp/GameEntity/Entities/PositionalEntity.cs +++ b/scripts/CSharp/GameEntity/Entities/PositionalEntity.cs @@ -6,22 +6,21 @@ namespace Babushka.scripts.CSharp.GameEntity.Entities; public abstract class PositionalEntity : Entity { - private Node2D _positionalNodeRef; public Vector2 position; public string sceneName = "none"; - protected override void SaveEntity(JObject json) + public override void SaveEntity(JObject json) { base.SaveEntity(json); - json["posx"] = _positionalNodeRef.Position.X; - json["posy"] = _positionalNodeRef.Position.Y; + json["posx"] = position.X; + json["posy"] = position.Y; json["scene"] = sceneName; } - protected override void LoadEntity(JObject json) + public override void LoadEntity(JObject json) { base.LoadEntity(json); - _positionalNodeRef.Position = new Vector2( + position = new Vector2( json.GetFloatValue("posx"), json.GetFloatValue("posy")); sceneName = json.GetStringValue("scene"); diff --git a/scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs b/scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs index ca7ed40..39d1cd0 100644 --- a/scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs +++ b/scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs @@ -8,7 +8,7 @@ public static class EntityLoadSaveUtil { var token = json[key]; if (token == null) throw new MalformedJsonException(json, key, "does not exist"); - if (!token.HasValues) throw new MalformedJsonException(json, key, "has no value"); + //if (!token.HasValues) throw new MalformedJsonException(json, key, "has no value"); if (token.Type != type) throw new MalformedJsonException(json, key, $"is not of type {type}"); } diff --git a/scripts/CSharp/GameEntity/Management/EntityManager.cs b/scripts/CSharp/GameEntity/Management/EntityManager.cs index fdf8834..3e14b1a 100644 --- a/scripts/CSharp/GameEntity/Management/EntityManager.cs +++ b/scripts/CSharp/GameEntity/Management/EntityManager.cs @@ -1,6 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using Babushka.scripts.CSharp.GameEntity.Entities; using Godot; +using Newtonsoft.Json.Linq; using Entity = Babushka.scripts.CSharp.GameEntity.Entities.Entity; using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity; @@ -15,6 +18,7 @@ public partial class EntityManager : Node public static EntityManager Instance; [Export] private EntityNodeCreator _nodeCreator = null!; + [Export] private string saveDirectory = "user://save_data/"; private EntitySceneContainer? _currentEntitySceneContainer; private readonly List _allEntities = new(); @@ -27,6 +31,7 @@ public partial class EntityManager : Node public override void _EnterTree() { Instance = this; + Load(); } public override void _Input(InputEvent @event) @@ -40,6 +45,58 @@ public partial class EntityManager : Node GD.Print(entity.EntityType + " " + entity.id); } } + + if(@event.IsActionPressed("SaveGame")) Save(); + } + + public void Save() + { + JArray array = new JArray(); + foreach (var entity in AllEntities) + { + JObject saveData = new JObject(); + entity.SaveEntity(saveData); + array.Add(saveData); + } + + using var SaveFile = FileAccess.Open(saveDirectory + "save.json", FileAccess.ModeFlags.Write); + SaveFile.StoreString(array.ToString()); + } + + public void Load() + { + using var saveFile = FileAccess.Open(saveDirectory + "save.json", FileAccess.ModeFlags.Read); + if (saveFile == null) return; + + JArray array = JArray.Parse(saveFile.GetAsText()); + + foreach (var token in array) + { + var jobj = (JObject)token; + + if (jobj == null) continue; + + if (jobj.TryGetValue("type", out var entityType)) + { + string entityTypeString = (string) entityType!; + Entity entity = InitializeEntity(entityTypeString); + entity.LoadEntity(jobj); + AddEntity(entity); + + } + } + } + + private Entity InitializeEntity(string type) + { + Entity entity = type switch + { + TrashEntity.OWN_TYPE_NAME => new TrashEntity(), + LoadedScenesEntity.OWN_TYPE_NAME => new LoadedScenesEntity(), + _ => throw new Exception($"Trying to load unknown entity type: {type}") + }; + + return entity; } #region ENTITY MANAGEMENT diff --git a/scripts/CSharp/GameEntity/Management/EntitySceneContainer.cs b/scripts/CSharp/GameEntity/Management/EntitySceneContainer.cs index 2979cf4..e052fcd 100644 --- a/scripts/CSharp/GameEntity/Management/EntitySceneContainer.cs +++ b/scripts/CSharp/GameEntity/Management/EntitySceneContainer.cs @@ -16,14 +16,20 @@ public partial class EntitySceneContainer : Node2D public override void _ExitTree() { + EntityManager.Instance.Save(); EntityManager.Instance.UnsetSceneContainer(); - var loadedScenesEntity = EntityManager.Instance.GetUniqueEntity(); - loadedScenesEntity.AddScene(sceneName); } public override void _Ready() { AddAllEntities(); + CallDeferred(nameof(RegisterWithScenesEntity)); + } + + private void RegisterWithScenesEntity() + { + var loadedScenesEntity = EntityManager.Instance.GetUniqueEntity(); + loadedScenesEntity.AddScene(sceneName); } public void AddAllEntities()