From 6cf0f966aab7097ccc1626346da7f591d18abfe3 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Tue, 22 Aug 2017 21:06:04 +0300 Subject: [PATCH] Refactored event/task logic: - Instead of configuring a commonness value and difficulty for an event and creating new random events until the maximum difficulty of the selected level is reached, the number of events per level can be configured directly (and overridden for specific level types). - Removed task logic. The initial idea was to display the unfinished tasks to the player somehow and to use them as objectives for the AI crew, but those were scrapped and the tasks only ended up controlling which type of music to play. TODO: implement some kind of logic to determine when to play repair/monster music clips. --- .../GameModes/Tutorials/TutorialType.cs | 2 +- .../Source/Sounds/SoundPlayer.cs | 36 +-- .../BarotraumaShared.projitems | 6 +- .../BarotraumaShared/Content/randomevents.xml | 128 +++++--- .../Source/Events/EventManager.cs | 54 ++++ .../Source/Events/PropertyTask.cs | 28 -- .../Source/Events/RepairTask.cs | 20 -- .../Source/Events/ScriptedEvent.cs | 294 +++++++++++------- .../Source/Events/ScriptedTask.cs | 32 -- .../BarotraumaShared/Source/Events/Task.cs | 64 ---- .../Source/Events/TaskManager.cs | 86 ----- .../Source/GameSession/GameSession.cs | 4 +- .../Components/Machines/OxygenGenerator.cs | 8 +- .../Items/Components/Machines/Reactor.cs | 10 - 14 files changed, 324 insertions(+), 448 deletions(-) create mode 100644 Barotrauma/BarotraumaShared/Source/Events/EventManager.cs delete mode 100644 Barotrauma/BarotraumaShared/Source/Events/PropertyTask.cs delete mode 100644 Barotrauma/BarotraumaShared/Source/Events/RepairTask.cs delete mode 100644 Barotrauma/BarotraumaShared/Source/Events/ScriptedTask.cs delete mode 100644 Barotrauma/BarotraumaShared/Source/Events/Task.cs delete mode 100644 Barotrauma/BarotraumaShared/Source/Events/TaskManager.cs diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/TutorialType.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/TutorialType.cs index 3d403bfe0..9997caa28 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/TutorialType.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/TutorialType.cs @@ -41,7 +41,7 @@ namespace Barotrauma.Tutorials GameMain.GameSession.StartShift("tuto"); - GameMain.GameSession.TaskManager.Tasks.Clear(); + GameMain.GameSession.TaskManager.Events.Clear(); GameMain.GameScreen.Select(); } diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs b/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs index d46c64c3d..b30ba86e0 100644 --- a/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs +++ b/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs @@ -344,6 +344,13 @@ namespace Barotrauma private static List GetSuitableMusicClips() { + + Submarine targetSubmarine = null; + if (Character.Controlled != null) + { + targetSubmarine = Character.Controlled.Submarine; + } + string musicType = "default"; if (OverrideMusicType != null) { @@ -355,37 +362,14 @@ namespace Barotrauma { musicType = "ruins"; } - else if ((Character.Controlled != null && Character.Controlled.Submarine != null && Character.Controlled.Submarine.AtDamageDepth) || + else if ((targetSubmarine != null && targetSubmarine.AtDamageDepth) || (Screen.Selected == GameMain.GameScreen && GameMain.GameScreen.Cam.Position.Y < SubmarineBody.DamageDepth)) { musicType = "deep"; } - else + else if (targetSubmarine != null) { - Task criticalTask = null; - if (GameMain.GameSession != null && GameMain.GameSession.TaskManager != null) - { - foreach (Task task in GameMain.GameSession.TaskManager.Tasks) - { - if (!task.IsStarted) continue; - if (criticalTask == null || task.Priority > criticalTask.Priority) - { - criticalTask = task; - } - } - } - - if (criticalTask != null) - { - var suitableClips = - musicClips.Where(music => - music != null && - music.type == criticalTask.MusicType && - music.priorityRange.X < criticalTask.Priority && - music.priorityRange.Y > criticalTask.Priority).ToList(); - - if (suitableClips.Count > 0) return suitableClips; - } + //TODO: determine whether to switch to monster or repair musictype } return musicClips.Where(music => music != null && music.type == musicType).ToList(); diff --git a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems index e44727471..947714b5f 100644 --- a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems +++ b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems @@ -1350,18 +1350,14 @@ + - - - - - diff --git a/Barotrauma/BarotraumaShared/Content/randomevents.xml b/Barotrauma/BarotraumaShared/Content/randomevents.xml index 6bb1c18b7..20f7eceba 100644 --- a/Barotrauma/BarotraumaShared/Content/randomevents.xml +++ b/Barotrauma/BarotraumaShared/Content/randomevents.xml @@ -1,110 +1,142 @@  - + musictype="monster"> + + + + + musictype="monster"> + + + + musictype="monster"> + + + + musictype="monster"> + + + + + musictype="monster"> + + musictype="monster"> + + + + + + + musictype="deep"> + + + + + + + minamount="1" maxamount="3"> + + + + musictype="monster"> + + + musictype="monster"> + + musictype="monster"> + + mineventcount="0" maxeventcount="5" + itemname="Skyholder Artifact"/> + mineventcount="0" maxeventcount="5" + itemname="Thermal Artifact"/> + mineventcount="0" maxeventcount="8" + itemname="Faraday Artifact"/> + + \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/Source/Events/EventManager.cs b/Barotrauma/BarotraumaShared/Source/Events/EventManager.cs new file mode 100644 index 000000000..f43754fc6 --- /dev/null +++ b/Barotrauma/BarotraumaShared/Source/Events/EventManager.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Barotrauma +{ + class EventManager + { + const float CriticalPriority = 50.0f; + + private List events; + + public List Events + { + get { return events; } + } + + public EventManager(GameSession session) + { + events = new List(); + } + + public void StartShift(Level level) + { + CreateScriptedEvents(level); + foreach (ScriptedEvent ev in events) + { + ev.Init(); + } + } + + public void EndShift() + { + events.Clear(); + } + + private void CreateScriptedEvents(Level level) + { + MTRandom rand = new MTRandom(ToolBox.StringToInt(level.Seed)); + events.AddRange(ScriptedEvent.GenerateLevelEvents(rand, level)); + } + + public void Update(float deltaTime) + { + events.RemoveAll(t => t.IsFinished); + foreach (ScriptedEvent ev in events) + { + if (!ev.IsFinished) + { + ev.Update(deltaTime); + } + } + } + } +} diff --git a/Barotrauma/BarotraumaShared/Source/Events/PropertyTask.cs b/Barotrauma/BarotraumaShared/Source/Events/PropertyTask.cs deleted file mode 100644 index acb9e7591..000000000 --- a/Barotrauma/BarotraumaShared/Source/Events/PropertyTask.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace Barotrauma -{ - class PropertyTask : Task - { - Item item; - - - public delegate bool IsFinishedHandler(); - private IsFinishedHandler IsFinishedChecker; - - public PropertyTask(Item item, IsFinishedHandler isFinished, float priority, string name) - : base(priority, name) - { - if (taskManager == null) return; - - this.item = item; - IsFinishedChecker = isFinished; - } - - public override void Update(float deltaTime) - { - if (IsFinishedChecker()) - { - Finished(); - } - } - } -} diff --git a/Barotrauma/BarotraumaShared/Source/Events/RepairTask.cs b/Barotrauma/BarotraumaShared/Source/Events/RepairTask.cs deleted file mode 100644 index 1afd36582..000000000 --- a/Barotrauma/BarotraumaShared/Source/Events/RepairTask.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Barotrauma -{ - class RepairTask : Task - { - Item item; - - public RepairTask(Item item, float priority, string name) - : base(priority, name) - { - if (taskManager == null) return; - - this.item = item; - } - - public override void Update(float deltaTime) - { - if (item.Condition > item.Prefab.Health * 0.5f) Finished(); - } - } -} diff --git a/Barotrauma/BarotraumaShared/Source/Events/ScriptedEvent.cs b/Barotrauma/BarotraumaShared/Source/Events/ScriptedEvent.cs index 20cd73150..8bb726479 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/ScriptedEvent.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/ScriptedEvent.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Reflection; using System.Xml.Linq; @@ -8,15 +7,19 @@ namespace Barotrauma { class ScriptedEvent { - protected string name; - protected string description; + private static List prefabs; - protected int commonness; - protected int difficulty; + protected readonly string name; + protected readonly string description; + + private readonly int minEventCount, maxEventCount; protected bool isFinished; - public Dictionary OverrideCommonness; + private readonly XElement configElement; + + private readonly Dictionary overrideMinEventCount; + private readonly Dictionary overrideMaxEventCount; public string Name { @@ -27,12 +30,7 @@ namespace Barotrauma { get { return description; } } - - public int Commonness - { - get { return commonness; } - } - + public string MusicType { get; @@ -48,136 +46,43 @@ namespace Barotrauma { get { return isFinished; } } - - public int Difficulty - { - get { return difficulty; } - } - + public override string ToString() { - return "ScriptedEvent ("+name+")"; + return "ScriptedEvent (" + name + ")"; } - public ScriptedEvent(XElement element) + protected ScriptedEvent(XElement element) { + configElement = element; + name = ToolBox.GetAttributeString(element, "name", ""); description = ToolBox.GetAttributeString(element, "description", ""); - - difficulty = ToolBox.GetAttributeInt(element, "difficulty", 1); - commonness = ToolBox.GetAttributeInt(element, "commonness", 1); + + minEventCount = ToolBox.GetAttributeInt(element, "mineventcount", 0); + maxEventCount = ToolBox.GetAttributeInt(element, "maxeventcount", 0); MusicType = ToolBox.GetAttributeString(element, "musictype", "default"); - OverrideCommonness = new Dictionary(); + overrideMinEventCount = new Dictionary(); + overrideMaxEventCount = new Dictionary(); foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { - case "overridecommonness": + case "overrideeventcount": string levelType = ToolBox.GetAttributeString(subElement, "leveltype", ""); - if (!OverrideCommonness.ContainsKey(levelType)) + if (!overrideMinEventCount.ContainsKey(levelType)) { - OverrideCommonness.Add(levelType, ToolBox.GetAttributeInt(subElement, "commonness", 1)); + overrideMinEventCount.Add(levelType, ToolBox.GetAttributeInt(subElement, "min", 0)); + overrideMaxEventCount.Add(levelType, ToolBox.GetAttributeInt(subElement, "max", 0)); } break; } } } - - public static ScriptedEvent LoadRandom(Random rand) - { - var configFiles = GameMain.Config.SelectedContentPackage.GetFilesOfType(ContentType.RandomEvents); - - if (!configFiles.Any()) - { - DebugConsole.ThrowError("No config files for random events found in the selected content package"); - return null; - } - - string configFile = configFiles[0]; - - XDocument doc = ToolBox.TryLoadXml(configFile); - if (doc == null) return null; - - int eventCount = doc.Root.Elements().Count(); - //int[] commonness = new int[eventCount]; - float[] eventProbability = new float[eventCount]; - - float probabilitySum = 0.0f; - - int i = 0; - foreach (XElement element in doc.Root.Elements()) - { - eventProbability[i] = ToolBox.GetAttributeInt(element, "commonness", 1); - - //if the event has been previously selected, it's less likely to be selected now - //int previousEventIndex = previousEvents.FindIndex(x => x == i); - //if (previousEventIndex >= 0) - //{ - // //how many shifts ago was the event last selected - // int eventDist = eventCount - previousEventIndex; - - // float weighting = (1.0f / eventDist) * PreviouslyUsedWeight; - - // eventProbability[i] *= weighting; - //} - - probabilitySum += eventProbability[i]; - - i++; - } - - float randomNumber = (float)rand.NextDouble() * probabilitySum; - - i = 0; - foreach (XElement element in doc.Root.Elements()) - { - if (randomNumber <= eventProbability[i]) - { - Type t; - string type = element.Name.ToString(); - - try - { - t = Type.GetType("Barotrauma." + type, true, true); - if (t == null) - { - DebugConsole.ThrowError("Error in " + configFile + "! Could not find an event class of the type \"" + type + "\"."); - continue; - } - } - catch - { - DebugConsole.ThrowError("Error in " + configFile + "! Could not find an event class of the type \"" + type + "\"."); - continue; - } - - ConstructorInfo constructor = t.GetConstructor(new[] { typeof(XElement) }); - object instance = null; - try - { - instance = constructor.Invoke(new object[] { element }); - } - catch (Exception ex) - { - DebugConsole.ThrowError(ex.InnerException!=null ? ex.InnerException.ToString() : ex.ToString()); - } - - //previousEvents.Add(i); - - return (ScriptedEvent)instance; - } - - randomNumber -= eventProbability[i]; - i++; - } - - return null; - } - public virtual void Init() { isFinished = false; @@ -191,5 +96,156 @@ namespace Barotrauma { isFinished = true; } + + + private static void LoadPrefabs() + { + prefabs = new List(); + var configFiles = GameMain.Config.SelectedContentPackage.GetFilesOfType(ContentType.RandomEvents); + + if (configFiles.Count == 0) + { + DebugConsole.ThrowError("No config files for random events found in the selected content package"); + return; + } + + foreach (string configFile in configFiles) + { + XDocument doc = ToolBox.TryLoadXml(configFile); + if (doc == null) continue; + + foreach (XElement element in doc.Root.Elements()) + { + prefabs.Add(new ScriptedEvent(element)); + } + } + } + + public static List GenerateLevelEvents(Random random, Level level) + { + if (prefabs == null) + { + LoadPrefabs(); + } + + List events = new List(); + foreach (ScriptedEvent scriptedEvent in prefabs) + { + int minCount = scriptedEvent.overrideMinEventCount.ContainsKey(level.GenerationParams.Name) ? + scriptedEvent.overrideMinEventCount[level.GenerationParams.Name] : scriptedEvent.minEventCount; + int maxCount = scriptedEvent.overrideMaxEventCount.ContainsKey(level.GenerationParams.Name) ? + scriptedEvent.overrideMaxEventCount[level.GenerationParams.Name] : scriptedEvent.maxEventCount; + + minCount = Math.Min(minCount, maxCount); + + int count = random.Next(maxCount - minCount) + minCount; + + for (int i = 0; i tasks; - - public List Tasks - { - get { return tasks; } - } - - public bool CriticalTasks - { - get - { - return tasks.Any(task => task.Priority >= CriticalPriority); - } - } - - public TaskManager(GameSession session) - { - tasks = new List(); - } - - public void AddTask(Task newTask) - { - if (tasks.Contains(newTask)) return; - - tasks.Add(newTask); - } - - public void StartShift(Level level) - { - CreateScriptedEvents(level); - } - - - public void EndShift() - { - tasks.Clear(); - } - - private void CreateScriptedEvents(Level level) - { - MTRandom rand = new MTRandom(ToolBox.StringToInt(level.Seed)); - - float totalDifficulty = level.Difficulty; - - int tries = 0; - while (tries < 5) - { - ScriptedEvent scriptedEvent = ScriptedEvent.LoadRandom(rand); - if (scriptedEvent==null || scriptedEvent.Difficulty > totalDifficulty) - { - tries++; - continue; - } - DebugConsole.Log("Created scripted event " + scriptedEvent.ToString()); - - AddTask(new ScriptedTask(scriptedEvent)); - totalDifficulty -= scriptedEvent.Difficulty; - tries = 0; - } - - } - - public void Update(float deltaTime) - { - foreach (Task task in tasks) - { - if (!task.IsFinished) - { - task.Update(deltaTime); - } - } - - tasks.RemoveAll(t => t.IsFinished); - } - - } -} diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs index 264e5f456..c47f79fd1 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs @@ -7,7 +7,7 @@ namespace Barotrauma { public enum InfoFrameTab { Crew, Mission, ManagePlayers }; - public readonly TaskManager TaskManager; + public readonly EventManager TaskManager; public readonly GameMode gameMode; @@ -86,7 +86,7 @@ namespace Barotrauma GameMain.GameSession = this; - TaskManager = new TaskManager(this); + TaskManager = new EventManager(this); this.saveFile = saveFile; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/OxygenGenerator.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/OxygenGenerator.cs index 4fb394973..f63f66027 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/OxygenGenerator.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/OxygenGenerator.cs @@ -8,8 +8,6 @@ namespace Barotrauma.Items.Components { class OxygenGenerator : Powered { - PropertyTask powerUpTask; - float powerDownTimer; bool running; @@ -59,11 +57,7 @@ namespace Barotrauma.Items.Components { powerDownTimer += deltaTime; running = false; - if ((powerUpTask==null || powerUpTask.IsFinished) && powerDownTimer>5.0f) - { - powerUpTask = new PropertyTask(item, IsRunning, 50.0f, "Turn on the oxygen generator"); - } - return; + return; } else { diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs index fccaf60f9..62a09f944 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs @@ -47,8 +47,6 @@ namespace Barotrauma.Items.Components private float load; - private PropertyTask powerUpTask; - private bool unsentChanges; private float sendUpdateTimer; @@ -218,13 +216,6 @@ namespace Barotrauma.Items.Components MeltDown(); return; } - else if (temperature == 0.0f) - { - if (powerUpTask == null || powerUpTask.IsFinished) - { - powerUpTask = new PropertyTask(item, IsRunning, 50.0f, "Power up the reactor"); - } - } load = 0.0f; @@ -325,7 +316,6 @@ namespace Barotrauma.Items.Components GameServer.Log("Reactor meltdown!", ServerLog.MessageType.ItemInteraction); - new RepairTask(item, 60.0f, "Reactor meltdown!"); item.Condition = 0.0f; var containedItems = item.ContainedItems;