From 0fdbb256cef665f15f59d11b65e7ac7ee6d0fc02 Mon Sep 17 00:00:00 2001 From: Adams Date: Thu, 26 Sep 2024 17:11:53 -0400 Subject: [PATCH] Adding narrative events. --- .github/workflows/unity-tests.yml | 1 + .../Conditionals/ConditionalFactory.cs | 141 ++++++++++++++++++ .../Conditionals/GenericConditional.cs | 32 ++++ .../IConditional.cs} | 2 +- Assets/Scripts/Events/GameEvent.cs | 7 +- Assets/Scripts/Events/MissionEvent.cs | 7 +- Assets/Scripts/Events/NarrativeEvent.cs | 29 ++++ Assets/Scripts/Managers/GameEventManager.cs | 4 +- Assets/Scripts/Managers/GameManager.cs | 4 +- Assets/Scripts/Managers/MissionManager.cs | 17 ++- .../Scripts/Managers/NarrativeEventManager.cs | 39 +++++ .../EditMode/Managers/GameManagerTests.cs | 5 +- .../EditMode/Managers/SaveGameManagerTests.cs | 1 - 13 files changed, 270 insertions(+), 19 deletions(-) create mode 100644 Assets/Scripts/Conditionals/ConditionalFactory.cs create mode 100644 Assets/Scripts/Conditionals/GenericConditional.cs rename Assets/Scripts/{Events/ICondition.cs => Conditionals/IConditional.cs} (93%) create mode 100644 Assets/Scripts/Events/NarrativeEvent.cs create mode 100644 Assets/Scripts/Managers/NarrativeEventManager.cs diff --git a/.github/workflows/unity-tests.yml b/.github/workflows/unity-tests.yml index acb6155..f925273 100644 --- a/.github/workflows/unity-tests.yml +++ b/.github/workflows/unity-tests.yml @@ -37,6 +37,7 @@ jobs: projectPath: . unityVersion: 2021.3.12f1 testMode: editmode + githubToken: ${{ secrets.GITHUB_TOKEN }} dockerCpuLimit: 2 dockerMemoryLimit: 8g diff --git a/Assets/Scripts/Conditionals/ConditionalFactory.cs b/Assets/Scripts/Conditionals/ConditionalFactory.cs new file mode 100644 index 0000000..74fb375 --- /dev/null +++ b/Assets/Scripts/Conditionals/ConditionalFactory.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; + +/// +/// +/// +public static class ConditionalFactory +{ + /// + /// + /// + /// + /// + private delegate IConditional ConditionalCreator(Dictionary parameters); + + /// + /// + /// + private static readonly Dictionary conditionCreators = new Dictionary + { + { "IsOnSamePlanet", CreateIsOnSamePlanet }, + { "HasFamilialRelationship", CreateHasFamilialRelationship }, + { "IsOnOpposingFactions", CreateIsOnOpposingFactions }, + { "IsOnMission", CreateIsOnMission } + // Add more condition types and their creation functions here + }; + + /// + /// + /// + /// + /// + /// + /// + public static IConditional CreateConditional(string conditionType, Dictionary parameters) + { + if (conditionCreators.TryGetValue(conditionType, out var creator)) + { + return creator(parameters); + } + else + { + throw new ArgumentException($"Invalid condition type: {conditionType}"); + } + } + + /// + /// + /// + /// + /// + private static IConditional CreateIsOnSamePlanet(Dictionary parameters) + { + return new GenericConditional(IsOnSamePlanet, parameters); + } + + /// + /// + /// + /// + /// + private static IConditional CreateHasFamilialRelationship(Dictionary parameters) + { + return new GenericConditional(HasFamilialRelationship, parameters); + } + + /// + /// + /// + /// + /// + private static IConditional CreateIsOnOpposingFactions(Dictionary parameters) + { + return new GenericConditional(IsOnOpposingFactions, parameters); + } + + /// + /// + /// + /// + /// + private static IConditional CreateIsOnMission(Dictionary parameters) + { + return new GenericConditional(IsOnMission, parameters); + } + + /// + /// + /// + /// + /// + /// + private static bool IsOnSamePlanet(Game game, Dictionary parameters) + { + string gameID1 = (string)parameters["GameID1"]; + string gameID2 = (string)parameters["GameID2"]; + // Implement the logic here + return true; // Placeholder + } + + /// + /// + /// + /// + /// + /// + private static bool HasFamilialRelationship(Game game, Dictionary parameters) + { + string gameID1 = (string)parameters["GameID1"]; + string gameID2 = (string)parameters["GameID2"]; + // Implement the logic here + return true; // Placeholder + } + + /// + /// + /// + /// + /// + /// + private static bool IsOnOpposingFactions(Game game, Dictionary parameters) + { + string gameID1 = (string)parameters["GameID1"]; + string gameID2 = (string)parameters["GameID2"]; + // Implement the logic here + return true; // Placeholder + } + + /// + /// + /// + /// + /// + /// + private static bool IsOnMission(Game game, Dictionary parameters) + { + string gameID = (string)parameters["GameID"]; + // Implement the logic here + return true; // Placeholder + } +} diff --git a/Assets/Scripts/Conditionals/GenericConditional.cs b/Assets/Scripts/Conditionals/GenericConditional.cs new file mode 100644 index 0000000..501b922 --- /dev/null +++ b/Assets/Scripts/Conditionals/GenericConditional.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +/// +/// +/// +public class GenericConditional : IConditional +{ + private readonly Func, bool> callback; + private Dictionary parameters; + + /// + /// + /// + /// + /// + public GenericConditional(Func, bool> callback, Dictionary parameters) + { + this.callback = callback; + this.parameters = parameters; + } + + /// + /// + /// + /// + /// + public bool IsMet(Game game) + { + return callback(game, parameters); + } +} diff --git a/Assets/Scripts/Events/ICondition.cs b/Assets/Scripts/Conditionals/IConditional.cs similarity index 93% rename from Assets/Scripts/Events/ICondition.cs rename to Assets/Scripts/Conditionals/IConditional.cs index a9b0293..cecf773 100644 --- a/Assets/Scripts/Events/ICondition.cs +++ b/Assets/Scripts/Conditionals/IConditional.cs @@ -1,7 +1,7 @@ /// /// Represents a condition that must be met for an event or action to proceed. /// -public interface ICondition +public interface IConditional { /// /// Evaluates the condition in the context of the provided game instance. diff --git a/Assets/Scripts/Events/GameEvent.cs b/Assets/Scripts/Events/GameEvent.cs index 8ada1b1..67ec273 100644 --- a/Assets/Scripts/Events/GameEvent.cs +++ b/Assets/Scripts/Events/GameEvent.cs @@ -20,7 +20,12 @@ public abstract class GameEvent : GameEntity public event Action OnEventTriggered; /// - /// Initializes a new instance of the class with the specified parameters. + /// Default constructor used for serialization. + /// + public GameEvent() { } + + /// + /// /// /// The tick at which the event is scheduled to occur. protected GameEvent(int scheduledTick) diff --git a/Assets/Scripts/Events/MissionEvent.cs b/Assets/Scripts/Events/MissionEvent.cs index b766c28..13c2800 100644 --- a/Assets/Scripts/Events/MissionEvent.cs +++ b/Assets/Scripts/Events/MissionEvent.cs @@ -6,7 +6,12 @@ public class MissionEvent : GameEvent public Mission Mission { get; private set; } /// - /// Initializes a new instance of the MissionEvent class. + /// Default constructor used for serialization. + /// + public MissionEvent() { } + + /// + /// Initializes a with the specified parameters. /// /// The tick at which the event is scheduled to occur. /// The mission that is being executed. diff --git a/Assets/Scripts/Events/NarrativeEvent.cs b/Assets/Scripts/Events/NarrativeEvent.cs new file mode 100644 index 0000000..3f4cda0 --- /dev/null +++ b/Assets/Scripts/Events/NarrativeEvent.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System; + +public class NarrativeEvent : GameEvent +{ + public IConditional Conditionals { get; set; } + public List> ConditionalParams { get; set; } + + /// + /// Default constructor used for serialization. + /// + public NarrativeEvent() { } + + /// + /// + /// + /// + /// + public NarrativeEvent(int scheduledTick, List conditionals) : base(scheduledTick) { } + + /// + /// + /// + /// + protected override void TriggerEvent(Game game) + { + // @TODO: Implement trigger. + } +} diff --git a/Assets/Scripts/Managers/GameEventManager.cs b/Assets/Scripts/Managers/GameEventManager.cs index 63971bc..2fbc92c 100644 --- a/Assets/Scripts/Managers/GameEventManager.cs +++ b/Assets/Scripts/Managers/GameEventManager.cs @@ -4,11 +4,11 @@ /// /// Manages game events and their scheduling. /// -public class EventManager +public class GameEventManager { private readonly Game game; - public EventManager(Game game) + public GameEventManager(Game game) { this.game = game; } diff --git a/Assets/Scripts/Managers/GameManager.cs b/Assets/Scripts/Managers/GameManager.cs index 6d25f97..bdecac6 100644 --- a/Assets/Scripts/Managers/GameManager.cs +++ b/Assets/Scripts/Managers/GameManager.cs @@ -17,7 +17,7 @@ public enum TickSpeed public class GameManager { private Game currentGame; - public EventManager EventManager { get; private set; } + public GameEventManager EventManager { get; private set; } public MissionManager MissionManager { get; private set; } private float? tickInterval; private float tickTimer; @@ -29,7 +29,7 @@ public class GameManager public GameManager(Game game) { currentGame = game; - EventManager = new EventManager(game); + EventManager = new GameEventManager(game); MissionManager = new MissionManager(EventManager); } diff --git a/Assets/Scripts/Managers/MissionManager.cs b/Assets/Scripts/Managers/MissionManager.cs index 43de2d4..ade9508 100644 --- a/Assets/Scripts/Managers/MissionManager.cs +++ b/Assets/Scripts/Managers/MissionManager.cs @@ -8,27 +8,28 @@ /// public class MissionManager { - protected EventManager eventManager; + protected GameEventManager eventManager; /// - /// Initializes a new instance of the class. + /// /// /// The event manager. - public MissionManager(EventManager eventManager) + public MissionManager(GameEventManager eventManager) { this.eventManager = eventManager; - InitializeMissions(); + + // Initialize missions (i.e. register event handlers). + initializeMissions(); } /// - /// Starts a mission by generating a random tick for the mission and scheduling a mission event. + /// Initializes the missions by registering event handlers for mission events. /// - /// The mission to start. - private void InitializeMissions() + private void initializeMissions() { // Register event handlers for mission events. List missionEvents = eventManager - .GetEventsByType() + .GetEventsByType() .OfType() .ToList(); diff --git a/Assets/Scripts/Managers/NarrativeEventManager.cs b/Assets/Scripts/Managers/NarrativeEventManager.cs new file mode 100644 index 0000000..117f5b7 --- /dev/null +++ b/Assets/Scripts/Managers/NarrativeEventManager.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using System.Linq; +using System; + +/// +/// +/// +public class NarrativeEventManager +{ + private GameEventManager eventManager; + + public NarrativeEventManager(GameEventManager eventManager) + { + this.eventManager = eventManager; + + initializeNarrativeEvents(); + } + + /// + /// + /// + private void initializeNarrativeEvents() + { + List narrativeEvents = eventManager + .GetEventsByType() + .OfType() + .ToList(); + + foreach(NarrativeEvent narrativeEvent in narrativeEvents) + { + List conditionals = narrativeEvent.ConditionalParams.Aggregate(new List(), (acc, parameters) => { + acc.Add(ConditionalFactory.CreateConditional(narrativeEvent.Conditionals, parameters)); + return acc; + }); + + } + + } +} diff --git a/Assets/Tests/EditMode/Managers/GameManagerTests.cs b/Assets/Tests/EditMode/Managers/GameManagerTests.cs index 9fd9d12..487deca 100644 --- a/Assets/Tests/EditMode/Managers/GameManagerTests.cs +++ b/Assets/Tests/EditMode/Managers/GameManagerTests.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using UnityEngine.TestTools; using System.Collections; // Mock GameEvent for testing @@ -55,12 +54,12 @@ public void TestEventExecutesAtScheduledTick() // Simulate 4 ticks (the event should not trigger yet) for (int i = 0; i < 4; i++) { - gameManager.Update(1f); // Simulate 1 second of game time (1 tick) + gameManager.Update(1f); // Simulate 1 second of game time (1 tick) Assert.IsFalse(mockEvent.WasExecuted, "Event should not have been executed yet."); } // Simulate 1 more tick (the 5th tick, where the event is scheduled) - gameManager.Update(1f); // Simulate 1 second of game time (1 tick) + gameManager.Update(1f); // Simulate 1 second of game time (1 tick) Assert.IsTrue(mockEvent.WasExecuted, "Event should have been executed at tick 5."); } diff --git a/Assets/Tests/EditMode/Managers/SaveGameManagerTests.cs b/Assets/Tests/EditMode/Managers/SaveGameManagerTests.cs index bb15b09..41804a0 100644 --- a/Assets/Tests/EditMode/Managers/SaveGameManagerTests.cs +++ b/Assets/Tests/EditMode/Managers/SaveGameManagerTests.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using UnityEngine; -using UnityEngine.TestTools; [TestFixture] public class SaveGameManagerTests