1
0

ObjectiveLimitSystem.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. using Content.Server.GameTicking.Rules.Components;
  2. using Content.Server.Objectives.Components;
  3. using Content.Shared.Mind;
  4. using Content.Shared.Objectives.Components;
  5. public sealed class ObjectiveLimitSystem : EntitySystem
  6. {
  7. public override void Initialize()
  8. {
  9. base.Initialize();
  10. SubscribeLocalEvent<ObjectiveLimitComponent, RequirementCheckEvent>(OnCheck);
  11. }
  12. private void OnCheck(Entity<ObjectiveLimitComponent> ent, ref RequirementCheckEvent args)
  13. {
  14. if (args.Cancelled)
  15. return;
  16. if (Prototype(ent)?.ID is not {} proto)
  17. {
  18. Log.Error($"ObjectiveLimit used for non-prototyped objective {ent}");
  19. return;
  20. }
  21. var remaining = ent.Comp.Limit;
  22. // all traitor rules are considered
  23. // maybe this would interfere with multistation stuff in the future but eh
  24. foreach (var rule in EntityQuery<TraitorRuleComponent>())
  25. {
  26. foreach (var mindId in rule.TraitorMinds)
  27. {
  28. if (mindId == args.MindId || !HasObjective(mindId, proto))
  29. continue;
  30. remaining--;
  31. // limit has been reached, prevent adding the objective
  32. if (remaining == 0)
  33. {
  34. args.Cancelled = true;
  35. return;
  36. }
  37. }
  38. }
  39. }
  40. /// <summary>
  41. /// Returns true if the mind has an objective of a certain prototype.
  42. /// </summary>
  43. public bool HasObjective(EntityUid mindId, string proto, MindComponent? mind = null)
  44. {
  45. if (!Resolve(mindId, ref mind))
  46. return false;
  47. foreach (var objective in mind.Objectives)
  48. {
  49. if (Prototype(objective)?.ID == proto)
  50. return true;
  51. }
  52. return false;
  53. }
  54. }