ShowFactionIconsSystem.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using Content.Shared.StatusIcon.Components; // For JobIconPrototype if you use it directly
  2. using Robust.Shared.Prototypes;
  3. using System.Linq; // For LINQ queries if needed for checking existing squad members
  4. namespace Content.Shared.Overlays;
  5. public abstract class SharedFactionIconsSystem : EntitySystem
  6. {
  7. [Dependency] protected readonly IPrototypeManager PrototypeManager = default!;
  8. [Dependency] private readonly IEntityManager _entityManager = default!;
  9. // Example: Define your squad configurations. This could be more dynamic.
  10. // You'd likely have prototypes for squads themselves eventually.
  11. protected static readonly Dictionary<string, SquadConfig> Squads = new()
  12. {
  13. { "Alpha", new SquadConfig("JobIconSquad1", "JobIconSquad1", 20) },
  14. { "Bravo", new SquadConfig("JobIconSquad2", "JobIconSquad2", 20) },
  15. { "Charlie", new SquadConfig("JobIconSquad3", "JobIconSquad3", 20) },
  16. // Add more squads here: "SquadName", "MemberIconId", "SergeantIconId", MaxSize
  17. };
  18. protected record SquadConfig(string MemberIconId, string SergeantIconId, int MaxSize);
  19. /// <summary>
  20. /// Call this on the SERVER to attempt to assign an entity to a squad.
  21. /// </summary>
  22. public virtual bool TryAssignToSquad(EntityUid uid, string squadName, bool assignAsSergeant, ShowFactionIconsComponent? component = null)
  23. {
  24. if (!Resolve(uid, ref component, logMissing: false))
  25. return false; // Only run on server and if component exists
  26. if (!Squads.TryGetValue(squadName, out var config))
  27. return false; // Squad doesn't exist
  28. // --- Server-Side Logic to check rules based on new explicit fields ---
  29. int currentOccupantsInSquad = 0;
  30. bool sergeantRoleFilledInSquad = false;
  31. EntityUid? existingSergeantUid = null;
  32. ShowFactionIconsComponent? oldSergeantComp = null; // For demotion
  33. var query = AllEntityQuery<ShowFactionIconsComponent>();
  34. while (query.MoveNext(out var otherUid, out var otherComp))
  35. {
  36. if (otherComp.AssignSquad && otherComp.AssignedSquadNameKey == squadName)
  37. {
  38. currentOccupantsInSquad++;
  39. if (otherComp.IsSergeantInSquad)
  40. {
  41. sergeantRoleFilledInSquad = true;
  42. existingSergeantUid = otherUid;
  43. }
  44. }
  45. }
  46. // Current state of the entity 'uid' being assigned
  47. bool entityIsAlreadyInThisSquad = component.AssignSquad && component.AssignedSquadNameKey == squadName;
  48. bool entityIsAlreadySergeantOfThisSquad = entityIsAlreadyInThisSquad && component.IsSergeantInSquad;
  49. if (assignAsSergeant)
  50. {
  51. // Trying to make 'uid' the sergeant.
  52. // If another sergeant exists and it's not 'uid', 'uid' will replace them (demotion handled later).
  53. // Check if adding 'uid' (if not already in squad) would exceed MaxSize.
  54. if (!entityIsAlreadyInThisSquad && currentOccupantsInSquad >= config.MaxSize)
  55. {
  56. Log.Debug($"Cannot assign {ToPrettyString(uid)} as Sergeant to squad {squadName}. Squad is full ({currentOccupantsInSquad}/{config.MaxSize}) and entity is not already in squad.");
  57. return false; // Squad is full, cannot add a new person as sergeant.
  58. }
  59. }
  60. else // Assigning as member
  61. {
  62. // Trying to make 'uid' a member.
  63. if (entityIsAlreadySergeantOfThisSquad)
  64. {
  65. // 'uid' is demoting itself. Count doesn't change. Fine.
  66. }
  67. else if (entityIsAlreadyInThisSquad && !component.IsSergeantInSquad) // Already a member
  68. {
  69. // 'uid' is re-affirming member status. Count doesn't change. Fine.
  70. }
  71. else // 'uid' is not in this squad (or in another squad, or not assigned).
  72. {
  73. if (currentOccupantsInSquad >= config.MaxSize)
  74. {
  75. Log.Debug($"Cannot assign {ToPrettyString(uid)} as Member to squad {squadName}. Squad is full ({currentOccupantsInSquad}/{config.MaxSize}).");
  76. return false; // Squad is full, cannot add a new member.
  77. }
  78. }
  79. }
  80. // --- Update component ---
  81. component.AssignSquad = true;
  82. component.AssignedSquadNameKey = squadName;
  83. component.IsSergeantInSquad = assignAsSergeant;
  84. component.SquadIcon = assignAsSergeant ? config.SergeantIconId : config.MemberIconId;
  85. Dirty(uid, component); // Mark component as dirty to ensure state is synced
  86. // If 'uid' became sergeant, and there was a *different* existing sergeant in this squad, demote the old one.
  87. if (assignAsSergeant && sergeantRoleFilledInSquad && existingSergeantUid.HasValue && existingSergeantUid.Value != uid)
  88. {
  89. if (Resolve(existingSergeantUid.Value, ref oldSergeantComp, logMissing: false))
  90. {
  91. // Ensure this old sergeant was indeed for *this* squad before demoting.
  92. if (oldSergeantComp.AssignSquad && oldSergeantComp.AssignedSquadNameKey == squadName && oldSergeantComp.IsSergeantInSquad)
  93. {
  94. oldSergeantComp.IsSergeantInSquad = false;
  95. oldSergeantComp.SquadIcon = config.MemberIconId; // Demote to member icon
  96. // oldSergeantComp.AssignedSquadNameKey remains squadName
  97. Dirty(existingSergeantUid.Value, oldSergeantComp);
  98. Log.Info($"Demoted {ToPrettyString(existingSergeantUid.Value)} from sergeant in squad {squadName} as {ToPrettyString(uid)} took the role.");
  99. }
  100. }
  101. }
  102. Log.Info($"Assigned {ToPrettyString(uid)} to squad {squadName} as {(assignAsSergeant ? "Sergeant" : "Member")}. Icon: {component.SquadIcon}");
  103. return true;
  104. }
  105. public virtual void RemoveFromSquad(EntityUid uid, ShowFactionIconsComponent? component = null)
  106. {
  107. if (!Resolve(uid, ref component, logMissing: false))
  108. return;
  109. component.AssignSquad = false;
  110. component.SquadIcon = null;
  111. component.AssignedSquadNameKey = null;
  112. component.IsSergeantInSquad = false;
  113. Dirty(uid, component);
  114. Log.Info($"Removed {ToPrettyString(uid)} from squad.");
  115. }
  116. }