diff --git a/Content.Server/Objectives/Conditions/RandomTraitorAliveCondition.cs b/Content.Server/Objectives/Conditions/RandomTraitorAliveCondition.cs index c20c203b7c..787dfcdd52 100644 --- a/Content.Server/Objectives/Conditions/RandomTraitorAliveCondition.cs +++ b/Content.Server/Objectives/Conditions/RandomTraitorAliveCondition.cs @@ -1,9 +1,6 @@ -using Content.Server.Mind.Components; using Content.Server.Objectives.Interfaces; using Robust.Shared.Random; using Robust.Shared.Utility; -using Content.Server.Traitor; -using Content.Server.Mind; using Content.Server.GameTicking.Rules; namespace Content.Server.Objectives.Conditions @@ -17,8 +14,28 @@ namespace Content.Server.Objectives.Conditions { var entityMgr = IoCManager.Resolve(); var traitors = EntitySystem.Get().Traitors; + List removeList = new(); - if (traitors.Count == 0) return new RandomTraitorAliveCondition { _target = mind }; //You were made a traitor by admins, and are the first/only. + foreach (var traitor in traitors) + { + if (traitor.Mind == null) + { + removeList.Add(traitor); + continue; + } + if (traitor.Mind == mind) // we have different objectives for defending ourselves. + { + removeList.Add(traitor); + continue; + } + } + + foreach (var traitor in removeList) + { + traitors.Remove(traitor); + } + + if (traitors.Count == 0) return new EscapeShuttleCondition{}; //You were made a traitor by admins, and are the first/only. return new RandomTraitorAliveCondition { _target = IoCManager.Resolve().Pick(traitors).Mind }; } diff --git a/Content.Server/Objectives/Conditions/RandomTraitorProgressCondition.cs b/Content.Server/Objectives/Conditions/RandomTraitorProgressCondition.cs new file mode 100644 index 0000000000..95a9d11726 --- /dev/null +++ b/Content.Server/Objectives/Conditions/RandomTraitorProgressCondition.cs @@ -0,0 +1,132 @@ +using Content.Server.Objectives.Interfaces; +using Robust.Shared.Random; +using Robust.Shared.Utility; +using Content.Server.GameTicking.Rules; + +namespace Content.Server.Objectives.Conditions +{ + [DataDefinition] + public sealed class RandomTraitorProgressCondition : IObjectiveCondition + { + private Mind.Mind? _target; + + public IObjectiveCondition GetAssigned(Mind.Mind mind) + { + var entityMgr = IoCManager.Resolve(); + var traitors = EntitySystem.Get().Traitors; + List removeList = new(); + + foreach (var traitor in traitors) + { + if (traitor.Mind == null) + { + removeList.Add(traitor); + continue; + } + if (traitor.Mind == mind) + { + removeList.Add(traitor); + continue; + } + foreach (var objective in traitor.Mind.AllObjectives) + { + foreach (var condition in objective.Conditions) + { + if (condition.GetType() == typeof(RandomTraitorProgressCondition)) + { + removeList.Add(traitor); + } + } + } + } + + foreach (var traitor in removeList) + { + traitors.Remove(traitor); + } + + if (traitors.Count == 0) return new EscapeShuttleCondition{}; //You were made a traitor by admins, and are the first/only. + return new RandomTraitorProgressCondition { _target = IoCManager.Resolve().Pick(traitors).Mind }; + } + + public string Title + { + get + { + var targetName = string.Empty; + var jobName = _target?.CurrentJob?.Name ?? "Unknown"; + + if (_target == null) + return Loc.GetString("objective-condition-other-traitor-progress-title", ("targetName", targetName), ("job", jobName)); + + if (_target.CharacterName != null) + targetName = _target.CharacterName; + else if (_target.OwnedEntity is {Valid: true} owned) + targetName = IoCManager.Resolve().GetComponent(owned).EntityName; + + return Loc.GetString("objective-condition-other-traitor-progress-title", ("targetName", targetName), ("job", jobName)); + } + } + + public string Description => Loc.GetString("objective-condition-other-traitor-progress-description"); + + public SpriteSpecifier Icon => new SpriteSpecifier.Rsi(new ResourcePath("Objects/Misc/bureaucracy.rsi"), "folder-white"); + + public float Progress + { + get { + var entMan = IoCManager.Resolve(); + + float total = 0f; // how much progress they have + float max = 0f; // how much progress is needed for 100% + + if (_target == null) + { + Logger.Error("Null target on RandomTraitorProgressCondition."); + return 1f; + } + + foreach (var objective in _target.AllObjectives) + { + foreach (var condition in objective.Conditions) + { + max++; // things can only be up to 100% complete yeah + total += condition.Progress; + } + } + + if (max == 0f) + { + Logger.Error("RandomTraitorProgressCondition assigned someone with no objectives to be helped."); + return 1f; + } + + var completion = total / max; + + if (completion >= 0.5f) + return 1f; + else + return completion / 0.5f; + } + } + + public float Difficulty => 2.5f; + + public bool Equals(IObjectiveCondition? other) + { + return other is RandomTraitorProgressCondition kpc && Equals(_target, kpc._target); + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + return obj is RandomTraitorProgressCondition alive && alive.Equals(this); + } + + public override int GetHashCode() + { + return _target?.GetHashCode() ?? 0; + } + } +} diff --git a/Resources/Locale/en-US/objectives/conditions/other-traitor-progress-condition.ftl b/Resources/Locale/en-US/objectives/conditions/other-traitor-progress-condition.ftl new file mode 100644 index 0000000000..883e61ce4f --- /dev/null +++ b/Resources/Locale/en-US/objectives/conditions/other-traitor-progress-condition.ftl @@ -0,0 +1,2 @@ +objective-condition-other-traitor-progress-title = Ensure fellow traitor {$targetName}, {CAPITALIZE($job)} achieves at least half their objectives. +objective-condition-other-traitor-progress-description = Identify yourself at your own risk. We just need them to succeed. diff --git a/Resources/Prototypes/Objectives/traitorObjectives.yml b/Resources/Prototypes/Objectives/traitorObjectives.yml index d79ff1c8f8..1258d12047 100644 --- a/Resources/Prototypes/Objectives/traitorObjectives.yml +++ b/Resources/Prototypes/Objectives/traitorObjectives.yml @@ -221,3 +221,13 @@ - DieCondition conditions: - !type:EscapeShuttleCondition {} + +- type: objective + id: RandomTraitorProgressObjective + issuer: syndicate + requirements: + - !type:TraitorRequirement {} + - !type:MultipleTraitorsRequirement + conditions: + - !type:RandomTraitorProgressCondition {} + canBeDuplicate: true