]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
add limits to steal objectives (#22672)
authordeltanedas <39013340+deltanedas@users.noreply.github.com>
Mon, 25 Dec 2023 01:20:55 +0000 (01:20 +0000)
committerGitHub <noreply@github.com>
Mon, 25 Dec 2023 01:20:55 +0000 (17:20 -0800)
* add ObjectiveLimit comp/system

* give ian and disk limits

* all

* up limit

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
Content.Server/Objectives/Components/ObjectiveLimitComponent.cs [new file with mode: 0644]
Content.Server/Objectives/Systems/ObjectiveLimitSystem.cs [new file with mode: 0644]
Resources/Prototypes/Objectives/traitor.yml

diff --git a/Content.Server/Objectives/Components/ObjectiveLimitComponent.cs b/Content.Server/Objectives/Components/ObjectiveLimitComponent.cs
new file mode 100644 (file)
index 0000000..c94a60e
--- /dev/null
@@ -0,0 +1,20 @@
+using Content.Server.Objectives.Systems;
+
+namespace Content.Server.Objectives.Components;
+
+/// <summary>
+/// Limits the number of traitors that can have the same objective.
+/// Checked by the prototype id, so only considers the exact same objectives.
+/// </summary>
+/// <remarks>
+/// Only works for traitors so don't use for anything else.
+/// </remarks>
+[RegisterComponent, Access(typeof(ObjectiveLimitSystem))]
+public sealed partial class ObjectiveLimitComponent : Component
+{
+    /// <summary>
+    /// Max number of players
+    /// </summary>
+    [DataField(required: true), ViewVariables(VVAccess.ReadWrite)]
+    public uint Limit;
+}
diff --git a/Content.Server/Objectives/Systems/ObjectiveLimitSystem.cs b/Content.Server/Objectives/Systems/ObjectiveLimitSystem.cs
new file mode 100644 (file)
index 0000000..0102304
--- /dev/null
@@ -0,0 +1,64 @@
+using Content.Server.GameTicking.Rules.Components;
+using Content.Server.Objectives.Components;
+using Content.Shared.Mind;
+using Content.Shared.Objectives.Components;
+
+public sealed class ObjectiveLimitSystem : EntitySystem
+{
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<ObjectiveLimitComponent, RequirementCheckEvent>(OnCheck);
+    }
+
+    private void OnCheck(Entity<ObjectiveLimitComponent> ent, ref RequirementCheckEvent args)
+    {
+        if (args.Cancelled)
+            return;
+
+        if (Prototype(ent)?.ID is not {} proto)
+        {
+            Log.Error($"ObjectiveLimit used for non-prototyped objective {ent}");
+            return;
+        }
+
+        var remaining = ent.Comp.Limit;
+        // all traitor rules are considered
+        // maybe this would interfere with multistation stuff in the future but eh
+        foreach (var rule in EntityQuery<TraitorRuleComponent>())
+        {
+            foreach (var mindId in rule.TraitorMinds)
+            {
+                if (mindId == args.MindId || !HasObjective(mindId, proto))
+                    continue;
+
+                remaining--;
+
+                // limit has been reached, prevent adding the objective
+                if (remaining == 0)
+                {
+                    args.Cancelled = true;
+                    return;
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Returns true if the mind has an objective of a certain prototype.
+    /// </summary>
+    public bool HasObjective(EntityUid mindId, string proto, MindComponent? mind = null)
+    {
+        if (!Resolve(mindId, ref mind))
+            return false;
+
+        foreach (var objective in mind.AllObjectives)
+        {
+            if (Prototype(objective)?.ID == proto)
+                return true;
+        }
+
+        return false;
+    }
+}
index 4684e2d343d847ef04184cd20fe2a9737efde6ec..f4530e01687bda1e57d7698fbd49fbd919d908d5 100644 (file)
@@ -30,6 +30,8 @@
     verifyMapExistance: false
   - type: Objective
     difficulty: 2.75
+  - type: ObjectiveLimit
+    limit: 2 # there is usually only 1 of each steal objective, have 2 max for drama
 
 # state
 
   components:
   - type: NotJobRequirement
     job: HeadOfPersonnel
+  - type: ObjectiveLimit
+    limit: 3 # ian only has 2 slices, 3 obj for drama
   - type: StealCondition
     stealGroup: FoodMeatCorgi
     owner: objective-condition-steal-Ian