Objective Assignment Refactor (#11678)

This commit is contained in:
Rane
2022-11-16 15:58:47 -05:00
committed by GitHub
parent 2100f4dc77
commit 3184619d42
6 changed files with 72 additions and 35 deletions

View File

@@ -2,14 +2,9 @@
{
public interface IObjectivesManager
{
/// <summary>
/// Returns all objectives the provided mind is valid for.
/// </summary>
IEnumerable<ObjectivePrototype> GetAllPossibleObjectives(Mind.Mind mind);
/// <summary>
/// Returns a randomly picked objective the provided mind is valid for.
/// </summary>
ObjectivePrototype? GetRandomObjective(Mind.Mind mind);
ObjectivePrototype? GetRandomObjective(Mind.Mind mind, string objectiveGroupProto);
}
}

View File

@@ -4,6 +4,9 @@ using Robust.Shared.Prototypes;
namespace Content.Server.Objectives
{
/// <summary>
/// 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
/// </summary>
[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);

View File

@@ -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<ObjectivePrototype> GetAllPossibleObjectives(Mind.Mind mind)
public ObjectivePrototype? GetRandomObjective(Mind.Mind mind, string objectiveGroupProto)
{
return _prototypeManager.EnumeratePrototypes<ObjectivePrototype>().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<WeightedRandomPrototype>(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<WeightedRandomPrototype>(groupName, out var group))
{
Logger.Error("Couldn't index objective group prototype" + groupName);
return null;
}
if (_prototypeManager.TryIndex<ObjectivePrototype>(group.Pick(_random), out var objective)
&& objective.CanBeAssigned(mind))
return objective;
else
tries++;
}
return null;