From: deltanedas <39013340+deltanedas@users.noreply.github.com>
Date: Mon, 25 Dec 2023 01:20:55 +0000 (+0000)
Subject: add limits to steal objectives (#22672)
X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=2ca649edfa4963215919f3fc4dc621899cd8c595;p=space-station-14.git
add limits to steal objectives (#22672)
* add ObjectiveLimit comp/system
* give ian and disk limits
* all
* up limit
---------
Co-authored-by: deltanedas <@deltanedas:kde.org>
---
diff --git a/Content.Server/Objectives/Components/ObjectiveLimitComponent.cs b/Content.Server/Objectives/Components/ObjectiveLimitComponent.cs
new file mode 100644
index 0000000000..c94a60ed1b
--- /dev/null
+++ b/Content.Server/Objectives/Components/ObjectiveLimitComponent.cs
@@ -0,0 +1,20 @@
+using Content.Server.Objectives.Systems;
+
+namespace Content.Server.Objectives.Components;
+
+///
+/// Limits the number of traitors that can have the same objective.
+/// Checked by the prototype id, so only considers the exact same objectives.
+///
+///
+/// Only works for traitors so don't use for anything else.
+///
+[RegisterComponent, Access(typeof(ObjectiveLimitSystem))]
+public sealed partial class ObjectiveLimitComponent : Component
+{
+ ///
+ /// Max number of players
+ ///
+ [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
index 0000000000..0102304668
--- /dev/null
+++ b/Content.Server/Objectives/Systems/ObjectiveLimitSystem.cs
@@ -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(OnCheck);
+ }
+
+ private void OnCheck(Entity 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())
+ {
+ 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;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Returns true if the mind has an objective of a certain prototype.
+ ///
+ 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;
+ }
+}
diff --git a/Resources/Prototypes/Objectives/traitor.yml b/Resources/Prototypes/Objectives/traitor.yml
index 4684e2d343..f4530e0168 100644
--- a/Resources/Prototypes/Objectives/traitor.yml
+++ b/Resources/Prototypes/Objectives/traitor.yml
@@ -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
@@ -226,6 +228,8 @@
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