From 59d313d97d9f6ab794580e67bae33519e00ccccf Mon Sep 17 00:00:00 2001 From: jonathan Date: Thu, 18 Dec 2025 14:27:27 +0100 Subject: [PATCH] Added basic entity scripts --- Babushka.csproj | 3 + scripts/CSharp/GameEntity/Entities/Entity.cs | 23 ++++++++ .../CSharp/GameEntity/Entities/Entity.cs.uid | 1 + .../GameEntity/Entities/PositionalEntity.cs | 27 +++++++++ .../Entities/PositionalEntity.cs.uid | 1 + .../GameEntity/LoadSave/EntityLoadSaveUtil.cs | 32 ++++++++++ .../LoadSave/EntityLoadSaveUtil.cs.uid | 1 + .../LoadSave/MalformedJsonException.cs | 12 ++++ .../LoadSave/MalformedJsonException.cs.uid | 1 + .../GameEntity/Management/EntityManager.cs | 59 +++++++++++++++++++ .../Management/EntityManager.cs.uid | 1 + .../Management/EntityManagerUtil.cs | 14 +++++ .../Management/EntityManagerUtil.cs.uid | 1 + .../Management/EntityNodeCreator.cs | 16 +++++ .../Management/EntityNodeCreator.cs.uid | 1 + .../Management/EntitySceneManager.cs | 25 ++++++++ .../Management/EntitySceneManager.cs.uid | 1 + scripts/CSharp/GameEntity/Types/EntityType.cs | 7 +++ .../CSharp/GameEntity/Types/EntityType.cs.uid | 1 + 19 files changed, 227 insertions(+) create mode 100644 scripts/CSharp/GameEntity/Entities/Entity.cs create mode 100644 scripts/CSharp/GameEntity/Entities/Entity.cs.uid create mode 100644 scripts/CSharp/GameEntity/Entities/PositionalEntity.cs create mode 100644 scripts/CSharp/GameEntity/Entities/PositionalEntity.cs.uid create mode 100644 scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs create mode 100644 scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs.uid create mode 100644 scripts/CSharp/GameEntity/LoadSave/MalformedJsonException.cs create mode 100644 scripts/CSharp/GameEntity/LoadSave/MalformedJsonException.cs.uid create mode 100644 scripts/CSharp/GameEntity/Management/EntityManager.cs create mode 100644 scripts/CSharp/GameEntity/Management/EntityManager.cs.uid create mode 100644 scripts/CSharp/GameEntity/Management/EntityManagerUtil.cs create mode 100644 scripts/CSharp/GameEntity/Management/EntityManagerUtil.cs.uid create mode 100644 scripts/CSharp/GameEntity/Management/EntityNodeCreator.cs create mode 100644 scripts/CSharp/GameEntity/Management/EntityNodeCreator.cs.uid create mode 100644 scripts/CSharp/GameEntity/Management/EntitySceneManager.cs create mode 100644 scripts/CSharp/GameEntity/Management/EntitySceneManager.cs.uid create mode 100644 scripts/CSharp/GameEntity/Types/EntityType.cs create mode 100644 scripts/CSharp/GameEntity/Types/EntityType.cs.uid diff --git a/Babushka.csproj b/Babushka.csproj index e6eea3b..8ad7a50 100644 --- a/Babushka.csproj +++ b/Babushka.csproj @@ -8,4 +8,7 @@ + + + \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/Entities/Entity.cs b/scripts/CSharp/GameEntity/Entities/Entity.cs new file mode 100644 index 0000000..1661fe4 --- /dev/null +++ b/scripts/CSharp/GameEntity/Entities/Entity.cs @@ -0,0 +1,23 @@ +using Babushka.scripts.CSharp.GameEntity.LoadSave; +using Babushka.scripts.CSharp.GameEntity.Types; +using Godot; +using Newtonsoft.Json.Linq; + +namespace Babushka.scripts.CSharp.GameEntity.Entities; + +public partial class Entity : Node2D +{ + private long _id; + protected virtual EntityType Type => EntityType.None; + + protected virtual void SaveEntity(JObject json) + { + json["id"] = _id; + json["type"] = (int)Type; + } + + protected virtual void LoadEntity(JObject json) + { + _id = json.GetLongValue("id"); + } +} \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/Entities/Entity.cs.uid b/scripts/CSharp/GameEntity/Entities/Entity.cs.uid new file mode 100644 index 0000000..ba72fbb --- /dev/null +++ b/scripts/CSharp/GameEntity/Entities/Entity.cs.uid @@ -0,0 +1 @@ +uid://hnmpt23ovfgl diff --git a/scripts/CSharp/GameEntity/Entities/PositionalEntity.cs b/scripts/CSharp/GameEntity/Entities/PositionalEntity.cs new file mode 100644 index 0000000..232f1b6 --- /dev/null +++ b/scripts/CSharp/GameEntity/Entities/PositionalEntity.cs @@ -0,0 +1,27 @@ +using Babushka.scripts.CSharp.GameEntity.LoadSave; +using Godot; +using Newtonsoft.Json.Linq; + +namespace Babushka.scripts.CSharp.GameEntity.Entities; + +public partial class PositionalEntity : Entity +{ + public string sceneName = "none"; + + protected override void SaveEntity(JObject json) + { + base.SaveEntity(json); + json["posx"] = Position.X; + json["posy"] = Position.Y; + json["scene"] = sceneName; + } + + protected override void LoadEntity(JObject json) + { + base.LoadEntity(json); + Position = new Vector2( + json.GetFloatValue("posx"), + json.GetFloatValue("posy")); + sceneName = json.GetStringValue("scene"); + } +} \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/Entities/PositionalEntity.cs.uid b/scripts/CSharp/GameEntity/Entities/PositionalEntity.cs.uid new file mode 100644 index 0000000..3e9ed4a --- /dev/null +++ b/scripts/CSharp/GameEntity/Entities/PositionalEntity.cs.uid @@ -0,0 +1 @@ +uid://bs38dulqv7sop diff --git a/scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs b/scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs new file mode 100644 index 0000000..04750b7 --- /dev/null +++ b/scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs @@ -0,0 +1,32 @@ +using Newtonsoft.Json.Linq; + +namespace Babushka.scripts.CSharp.GameEntity.LoadSave; + +public static class EntityLoadSaveUtil +{ + private static void AssertTokenType(this JObject json, string key, JTokenType type) + { + 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.Type != type) throw new MalformedJsonException(json, key, $"is not of type {type}"); + } + + public static long GetLongValue(this JObject json, string key) + { + AssertTokenType(json, key, JTokenType.Integer); + return json.Value(key); + } + + public static float GetFloatValue(this JObject json, string key) + { + AssertTokenType(json, key, JTokenType.Float); + return json.Value(key); + } + + public static string GetStringValue(this JObject json, string key) + { + AssertTokenType(json, key, JTokenType.String); + return json.Value(key)!; + } +} \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs.uid b/scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs.uid new file mode 100644 index 0000000..350cb0f --- /dev/null +++ b/scripts/CSharp/GameEntity/LoadSave/EntityLoadSaveUtil.cs.uid @@ -0,0 +1 @@ +uid://ccu6p418viliu diff --git a/scripts/CSharp/GameEntity/LoadSave/MalformedJsonException.cs b/scripts/CSharp/GameEntity/LoadSave/MalformedJsonException.cs new file mode 100644 index 0000000..d04f379 --- /dev/null +++ b/scripts/CSharp/GameEntity/LoadSave/MalformedJsonException.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Newtonsoft.Json.Linq; + +namespace Babushka.scripts.CSharp.GameEntity.LoadSave; + +public class MalformedJsonException(JObject actualJson, string key, string problem) : Exception +{ + public override string Message => $"JsonObject was malformed: {key} {problem}"; + public override IDictionary Data => new Dictionary { { "json", actualJson } }; +} \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/LoadSave/MalformedJsonException.cs.uid b/scripts/CSharp/GameEntity/LoadSave/MalformedJsonException.cs.uid new file mode 100644 index 0000000..76f73aa --- /dev/null +++ b/scripts/CSharp/GameEntity/LoadSave/MalformedJsonException.cs.uid @@ -0,0 +1 @@ +uid://d1o066hh84ow diff --git a/scripts/CSharp/GameEntity/Management/EntityManager.cs b/scripts/CSharp/GameEntity/Management/EntityManager.cs new file mode 100644 index 0000000..7525268 --- /dev/null +++ b/scripts/CSharp/GameEntity/Management/EntityManager.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Babushka.scripts.CSharp.GameEntity.Types; +using Godot; +using Entity = Babushka.scripts.CSharp.GameEntity.Entities.Entity; +using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity; + +namespace Babushka.scripts.CSharp.GameEntity.Management; + +public partial class EntityManager : Node +{ + [Export] private EntityNodeCreator _nodeCreator = null!; + + private EntitySceneManager? _currentEntitySceneManager; + + + private readonly List _allEntities = new(); + + public IEnumerable AllEntities => _allEntities; + + public IEnumerable AllPositionalEntities => _allEntities.OfType(); + + public T NewPositionalEntity(EntityType type, Vector2 position, string? scene = null) where T : PositionalEntity + { + if (scene == null) + { + if (_currentEntitySceneManager == null) + throw new Exception("No current scene. Specify scene to spawn an entity"); + + scene = _currentEntitySceneManager.sceneName; + } + + var newEntity = _nodeCreator.Create(type); + newEntity.Position = position; + newEntity.sceneName = scene; + _allEntities.Add(newEntity); + + _currentEntitySceneManager.AddIfNeeded(newEntity); + + return newEntity; + } + + public void UnloadScene() + { + if (_currentEntitySceneManager == null) return; + _currentEntitySceneManager.RemoveAllEntities(); + _currentEntitySceneManager = null; + } + + public void LoadScene(EntitySceneManager sceneManager) + { + _currentEntitySceneManager = sceneManager; + foreach (var entity in AllPositionalEntities) + { + _currentEntitySceneManager.AddIfNeeded(entity); + } + } +} \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/Management/EntityManager.cs.uid b/scripts/CSharp/GameEntity/Management/EntityManager.cs.uid new file mode 100644 index 0000000..4f201fd --- /dev/null +++ b/scripts/CSharp/GameEntity/Management/EntityManager.cs.uid @@ -0,0 +1 @@ +uid://umop2b1m1qm8 diff --git a/scripts/CSharp/GameEntity/Management/EntityManagerUtil.cs b/scripts/CSharp/GameEntity/Management/EntityManagerUtil.cs new file mode 100644 index 0000000..4b58348 --- /dev/null +++ b/scripts/CSharp/GameEntity/Management/EntityManagerUtil.cs @@ -0,0 +1,14 @@ +using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity; + +namespace Babushka.scripts.CSharp.GameEntity.Management; + +public static class EntityManagerUtil +{ + public static void AddIfNeeded(this EntitySceneManager? self, PositionalEntity entity) + { + if(self == null) return; + if(self.sceneName != entity.sceneName) return; + + self.AddEntity(entity); + } +} \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/Management/EntityManagerUtil.cs.uid b/scripts/CSharp/GameEntity/Management/EntityManagerUtil.cs.uid new file mode 100644 index 0000000..1fbbf02 --- /dev/null +++ b/scripts/CSharp/GameEntity/Management/EntityManagerUtil.cs.uid @@ -0,0 +1 @@ +uid://dc3283h7sx4cl diff --git a/scripts/CSharp/GameEntity/Management/EntityNodeCreator.cs b/scripts/CSharp/GameEntity/Management/EntityNodeCreator.cs new file mode 100644 index 0000000..f763b15 --- /dev/null +++ b/scripts/CSharp/GameEntity/Management/EntityNodeCreator.cs @@ -0,0 +1,16 @@ +using Babushka.scripts.CSharp.GameEntity.Types; +using Godot; +using Godot.Collections; +using Entity = Babushka.scripts.CSharp.GameEntity.Entities.Entity; + +namespace Babushka.scripts.CSharp.GameEntity.Management; + +public partial class EntityNodeCreator : Node +{ + [Export] private Dictionary _entityPrefabs; + + public T Create(EntityType type) where T:Entity + { + return _entityPrefabs[type].Instantiate(); + } +} \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/Management/EntityNodeCreator.cs.uid b/scripts/CSharp/GameEntity/Management/EntityNodeCreator.cs.uid new file mode 100644 index 0000000..dec3ecb --- /dev/null +++ b/scripts/CSharp/GameEntity/Management/EntityNodeCreator.cs.uid @@ -0,0 +1 @@ +uid://bogqp274y1pgr diff --git a/scripts/CSharp/GameEntity/Management/EntitySceneManager.cs b/scripts/CSharp/GameEntity/Management/EntitySceneManager.cs new file mode 100644 index 0000000..2d7e838 --- /dev/null +++ b/scripts/CSharp/GameEntity/Management/EntitySceneManager.cs @@ -0,0 +1,25 @@ +using Godot; +using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity; + +namespace Babushka.scripts.CSharp.GameEntity.Management; + +public partial class EntitySceneManager : Node2D +{ + [Export] public string sceneName = "none"; + + public void AddEntity(PositionalEntity entity) + { + AddChild(entity); + } + + public void RemoveAllEntities() + { + foreach (var entity in GetChildren()) + { + if (entity is PositionalEntity positionalEntity) + { + RemoveChild(entity); + } + } + } +} \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/Management/EntitySceneManager.cs.uid b/scripts/CSharp/GameEntity/Management/EntitySceneManager.cs.uid new file mode 100644 index 0000000..12921a3 --- /dev/null +++ b/scripts/CSharp/GameEntity/Management/EntitySceneManager.cs.uid @@ -0,0 +1 @@ +uid://ca1pg6k3gn47y diff --git a/scripts/CSharp/GameEntity/Types/EntityType.cs b/scripts/CSharp/GameEntity/Types/EntityType.cs new file mode 100644 index 0000000..92be4a5 --- /dev/null +++ b/scripts/CSharp/GameEntity/Types/EntityType.cs @@ -0,0 +1,7 @@ +namespace Babushka.scripts.CSharp.GameEntity.Types; + +public enum EntityType +{ + None = 0, + Yeli = 1, +} \ No newline at end of file diff --git a/scripts/CSharp/GameEntity/Types/EntityType.cs.uid b/scripts/CSharp/GameEntity/Types/EntityType.cs.uid new file mode 100644 index 0000000..f548051 --- /dev/null +++ b/scripts/CSharp/GameEntity/Types/EntityType.cs.uid @@ -0,0 +1 @@ +uid://cjygyr4lc224m