From 3184619d42e9fcbbd39872864218a0ff7fe1c95d Mon Sep 17 00:00:00 2001 From: Rane <60792108+Elijahrane@users.noreply.github.com> Date: Wed, 16 Nov 2022 15:58:47 -0500 Subject: [PATCH] Objective Assignment Refactor (#11678) --- .../GameTicking/Rules/TraitorRuleSystem.cs | 2 +- .../Interfaces/IObjectivesManager.cs | 7 +--- .../Objectives/ObjectivePrototype.cs | 5 ++- .../Objectives/ObjectivesManager.cs | 41 ++++++++++++------- .../Prototypes/Objectives/objectiveGroups.yml | 41 +++++++++++++++++++ .../Objectives/traitorObjectives.yml | 11 ----- 6 files changed, 72 insertions(+), 35 deletions(-) create mode 100644 Resources/Prototypes/Objectives/objectiveGroups.yml diff --git a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs index 2dbe908ea4..d563fe2b1d 100644 --- a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs @@ -193,7 +193,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem var difficulty = 0f; for (var pick = 0; pick < maxPicks && maxDifficulty > difficulty; pick++) { - var objective = _objectivesManager.GetRandomObjective(traitorRole.Mind); + var objective = _objectivesManager.GetRandomObjective(traitorRole.Mind, "TraitorObjectiveGroups"); if (objective == null) continue; if (traitorRole.Mind.TryAddObjective(objective)) difficulty += objective.Difficulty; diff --git a/Content.Server/Objectives/Interfaces/IObjectivesManager.cs b/Content.Server/Objectives/Interfaces/IObjectivesManager.cs index 57b36675c1..bee98bc80b 100644 --- a/Content.Server/Objectives/Interfaces/IObjectivesManager.cs +++ b/Content.Server/Objectives/Interfaces/IObjectivesManager.cs @@ -2,14 +2,9 @@ { public interface IObjectivesManager { - /// - /// Returns all objectives the provided mind is valid for. - /// - IEnumerable GetAllPossibleObjectives(Mind.Mind mind); - /// /// Returns a randomly picked objective the provided mind is valid for. /// - ObjectivePrototype? GetRandomObjective(Mind.Mind mind); + ObjectivePrototype? GetRandomObjective(Mind.Mind mind, string objectiveGroupProto); } } diff --git a/Content.Server/Objectives/ObjectivePrototype.cs b/Content.Server/Objectives/ObjectivePrototype.cs index 5cc7aa6f10..d9ee76c207 100644 --- a/Content.Server/Objectives/ObjectivePrototype.cs +++ b/Content.Server/Objectives/ObjectivePrototype.cs @@ -4,6 +4,9 @@ using Robust.Shared.Prototypes; namespace Content.Server.Objectives { + /// + /// Prototype for objectives. Remember that to be assigned, it should be added to one or more objective groups in prototype. E.g. crew, traitor, wizard + /// [Prototype("objective")] public sealed class ObjectivePrototype : IPrototype { @@ -13,8 +16,6 @@ namespace Content.Server.Objectives [DataField("issuer")] public string Issuer { get; private set; } = "Unknown"; - [DataField("prob")] public float Probability { get; private set; } = 0.3f; - [ViewVariables] public float Difficulty => _difficultyOverride ?? _conditions.Sum(c => c.Difficulty); diff --git a/Content.Server/Objectives/ObjectivesManager.cs b/Content.Server/Objectives/ObjectivesManager.cs index ff3e72ad2a..11563f9934 100644 --- a/Content.Server/Objectives/ObjectivesManager.cs +++ b/Content.Server/Objectives/ObjectivesManager.cs @@ -1,5 +1,6 @@ -using System.Linq; -using Content.Server.Objectives.Interfaces; +using Content.Server.Objectives.Interfaces; +using Content.Shared.Random.Helpers; +using Content.Shared.Random; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -10,21 +11,31 @@ namespace Content.Server.Objectives [Dependency] private IPrototypeManager _prototypeManager = default!; [Dependency] private IRobustRandom _random = default!; - public IEnumerable GetAllPossibleObjectives(Mind.Mind mind) + public ObjectivePrototype? GetRandomObjective(Mind.Mind mind, string objectiveGroupProto) { - return _prototypeManager.EnumeratePrototypes().Where(objectivePrototype => objectivePrototype.CanBeAssigned(mind)); - } - - public ObjectivePrototype? GetRandomObjective(Mind.Mind mind) - { - var objectives = GetAllPossibleObjectives(mind).ToList(); - _random.Shuffle(objectives); - - //to prevent endless loops - foreach (var objective in objectives) + if (!_prototypeManager.TryIndex(objectiveGroupProto, out var groups)) { - if (!_random.Prob(objective.Probability)) continue; - return objective; + Logger.Error("Tried to get a random objective, but can't index WeightedRandomPrototype " + objectiveGroupProto); + return null; + } + + // yeah the old 'preventing infinite loops' thing wasn't super elegant either and it mislead people on what exactly it did + var tries = 0; + while (tries < 20) + { + var groupName = groups.Pick(_random); + + if (!_prototypeManager.TryIndex(groupName, out var group)) + { + Logger.Error("Couldn't index objective group prototype" + groupName); + return null; + } + + if (_prototypeManager.TryIndex(group.Pick(_random), out var objective) + && objective.CanBeAssigned(mind)) + return objective; + else + tries++; } return null; diff --git a/Resources/Prototypes/Objectives/objectiveGroups.yml b/Resources/Prototypes/Objectives/objectiveGroups.yml new file mode 100644 index 0000000000..e4a6b0907d --- /dev/null +++ b/Resources/Prototypes/Objectives/objectiveGroups.yml @@ -0,0 +1,41 @@ +# Traitor +- type: weightedRandom + id: TraitorObjectiveGroups + weights: + TraitorObjectiveGroupSteal: 1 + TraitorObjectiveGroupKill: 1 + TraitorObjectiveGroupState: 1 #As in, something about your character. Alive, dead, arrested, gained an ability... + TraitorObjectiveGroupSocial: 1 #Involves helping/harming others without killing them or stealing their stuff + +- type: weightedRandom + id: TraitorObjectiveGroupSteal + weights: + CaptainIDStealObjective: 1 + CMOHyposprayStealObjective: 1 + RDHardsuitStealObjective: 1 + NukeDiskStealObjective: 1 + IDComputerBoardStealObjective: 1 + MagbootsStealObjective: 1 + SupplyConsoleBoardStealObjective: 1 + CorgiMeatStealObjective: 1 + CaptainGunStealObjective: 0.5 + CaptainJetpackStealObjective: 0.5 + +- type: weightedRandom + id: TraitorObjectiveGroupKill + weights: + KillRandomObjective: 1 + +- type: weightedRandom + id: TraitorObjectiveGroupState + weights: + EscapeShuttleObjective: 1 + DieObjective: 0.05 + +- type: weightedRandom + id: TraitorObjectiveGroupSocial + weights: + RandomTraitorAliveObjective: 1 + RandomTraitorProgressObjective: 1 + +#Changeling, crew, wizard, when you code it... diff --git a/Resources/Prototypes/Objectives/traitorObjectives.yml b/Resources/Prototypes/Objectives/traitorObjectives.yml index 1258d12047..9946a2e2ac 100644 --- a/Resources/Prototypes/Objectives/traitorObjectives.yml +++ b/Resources/Prototypes/Objectives/traitorObjectives.yml @@ -2,7 +2,6 @@ id: CaptainIDStealObjective issuer: syndicate difficultyOverride: 2.75 - prob: 0.2 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement @@ -42,7 +41,6 @@ - type: objective id: DieObjective issuer: syndicate - prob: 0.03 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement @@ -56,7 +54,6 @@ id: CMOHyposprayStealObjective issuer: syndicate difficultyOverride: 2.75 - prob: 0.2 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement @@ -73,7 +70,6 @@ id: RDHardsuitStealObjective issuer: syndicate difficultyOverride: 2.75 - prob: 0.2 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement @@ -89,7 +85,6 @@ - type: objective id: NukeDiskStealObjective issuer: syndicate - prob: 0.2 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement @@ -116,7 +111,6 @@ - type: objective id: IDComputerBoardStealObjective issuer: syndicate - prob: 0.2 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement @@ -133,7 +127,6 @@ id: MagbootsStealObjective issuer: syndicate difficultyOverride: 2.75 - prob: 0.2 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement @@ -149,7 +142,6 @@ - type: objective id: SupplyConsoleBoardStealObjective issuer: syndicate - prob: 0.2 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement @@ -165,7 +157,6 @@ - type: objective id: CorgiMeatStealObjective issuer: syndicate - prob: 0.2 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement @@ -182,7 +173,6 @@ id: CaptainGunStealObjective issuer: syndicate difficultyOverride: 2.75 - prob: 0.1 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement @@ -199,7 +189,6 @@ id: CaptainJetpackStealObjective issuer: syndicate difficultyOverride: 2.75 - prob: 0.1 requirements: - !type:TraitorRequirement {} - !type:IncompatibleConditionsRequirement