Skip to content

Commit 1e0d46b

Browse files
Merge branch 'starlight-dev' of github.com:ss14Starlight/space-station-14 into upstream/solutions-rebirth
2 parents 53d1124 + 3637d90 commit 1e0d46b

12 files changed

Lines changed: 32629 additions & 32496 deletions

File tree

Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public void Initialize()
6060

6161
// NullLink start
6262
_net.RegisterNetMessage<MsgUpdatePlayerPlayTime>(Update);
63-
_achievements.AchievementsUpdated += OnAchievementsUpdated;
63+
_achievements.AchievementUnlocked += OnAchievementsUnlocked;
6464
_cfg.OnValueChanged(NullLinkCCVars.Project, OnProjectChanged, true);
6565
_cfg.OnValueChanged(NullLinkCCVars.Server, OnServerChanged, true);
6666
// NullLink end
@@ -121,7 +121,7 @@ private void MergePlayTime()
121121
Updated?.Invoke();
122122
}
123123

124-
private void OnAchievementsUpdated()
124+
private void OnAchievementsUnlocked(string achievement)
125125
=> Updated?.Invoke();
126126
// Nulllink end
127127

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using Content.Server.Antag.Components;
2+
using Content.Shared.Antag;
3+
using Content.Shared.Humanoid;
4+
using Content.Shared.Preferences;
5+
using JetBrains.Annotations;
6+
using Robust.Shared.Player;
7+
using Robust.Shared.Prototypes;
8+
9+
using static Content.Server.Antag.Components.AntagSelectionTime;
10+
11+
namespace Content.Server.Antag;
12+
13+
public sealed partial class AntagSelectionSystem
14+
{
15+
/// <summary>
16+
/// Checks if a player has already been pre-selected for a different antag within the same game rule.
17+
/// </summary>
18+
private bool HasConflictingPreSelection(
19+
Entity<AntagSelectionComponent> gameRule,
20+
ProtoId<AntagSpecifierPrototype> definition,
21+
ICommonSession player)
22+
{
23+
foreach (var (proto, sessions) in gameRule.Comp.PreSelectedSessions)
24+
{
25+
if (proto != definition && sessions.Contains(player))
26+
return true;
27+
}
28+
29+
return false;
30+
}
31+
32+
/// <summary>
33+
/// Checks if a given player is valid for a given antag definition, checking the player's selected profile if it exists.
34+
/// </summary>
35+
/// <param name="player">The player session to check.</param>
36+
/// <param name="antagEntity">The entity representing the antag.</param>
37+
/// <param name="selectedProfile">The player's selected character profile, if any.</param>
38+
/// <param name="definition">The antag definition to check against.</param>
39+
/// <returns>True if the player is valid for the antag, false otherwise.</returns>
40+
private bool IsSelectedProfileValidForAntag(
41+
ICommonSession player,
42+
EntityUid antagEntity,
43+
HumanoidCharacterProfile? selectedProfile,
44+
AntagSpecifierPrototype definition)
45+
{
46+
if (selectedProfile != null)
47+
return IsProfileValidForAntag(player, selectedProfile, definition);
48+
49+
// Bodies without HumanoidAppearanceComponent have no character profile to
50+
// validate and are allowed through here. Humanoid bodies must have a recoverable
51+
// profile so profile-specific antag requirements, including species restrictions
52+
// and preferences, cannot be bypassed.
53+
if (!TryComp<HumanoidAppearanceComponent>(antagEntity, out var humanoid))
54+
return true;
55+
56+
var profile = _humanoidAppearance.GetBaseProfile((antagEntity, humanoid));
57+
return profile != null && IsProfileValidForAntag(player, profile, definition);
58+
}
59+
60+
/// <summary>
61+
/// Returns whether a player may claim an antagonist ghost role.
62+
/// This intentionally does not require the antag preference to be enabled.
63+
/// </summary>
64+
[PublicAPI]
65+
public bool CanTakeAntagGhostRole(ICommonSession session, ProtoId<AntagSpecifierPrototype> definition)
66+
{
67+
return Proto.Resolve(definition, out var antag) && CanTakeAntagGhostRole(session, antag);
68+
}
69+
70+
/// <summary>
71+
/// Returns whether a player may claim an antagonist ghost role.
72+
/// </summary>
73+
[PublicAPI]
74+
public bool CanTakeAntagGhostRole(ICommonSession session, AntagSpecifierPrototype definition)
75+
{
76+
return !IsAntagBanned(session, definition) && _playTime.IsAllowedNonSpawning(session, definition.PrefRoles);
77+
}
78+
}

Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs

Lines changed: 31 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
using Content.Shared.Hands.Components;
1010
using Content.Shared.Humanoid;
1111
using Content.Shared.Players;
12-
using Content.Shared.Preferences;
12+
using Content.Shared.Silicons.Borgs.Components;
13+
using Content.Shared.Xenoborgs.Components;
1314
using JetBrains.Annotations;
1415
using Robust.Shared.Player;
1516
using Robust.Shared.Prototypes;
@@ -72,53 +73,6 @@ public bool CanBeAntag(ICommonSession player,
7273
return true;
7374
}
7475

75-
#region Starlight
76-
/// <summary>
77-
/// Checks if a player has already been pre-selected for a different antag within the same game rule.
78-
/// </summary>
79-
private bool HasConflictingPreSelection(
80-
Entity<AntagSelectionComponent> gameRule,
81-
ProtoId<AntagSpecifierPrototype> definition,
82-
ICommonSession player)
83-
{
84-
foreach (var (proto, sessions) in gameRule.Comp.PreSelectedSessions)
85-
{
86-
if (proto != definition && sessions.Contains(player))
87-
return true;
88-
}
89-
90-
return false;
91-
}
92-
93-
/// <summary>
94-
/// Checks if a given player is valid for a given antag definition, checking the player's selected profile if it exists.
95-
/// </summary>
96-
/// <param name="player">The player session to check.</param>
97-
/// <param name="antagEntity">The entity representing the antag.</param>
98-
/// <param name="selectedProfile">The player's selected character profile, if any.</param>
99-
/// <param name="definition">The antag definition to check against.</param>
100-
/// <returns>True if the player is valid for the antag, false otherwise.</returns>
101-
private bool IsSelectedProfileValidForAntag(
102-
ICommonSession player,
103-
EntityUid antagEntity,
104-
HumanoidCharacterProfile? selectedProfile,
105-
AntagSpecifierPrototype definition)
106-
{
107-
if (selectedProfile != null)
108-
return IsProfileValidForAntag(player, selectedProfile, definition);
109-
110-
// Bodies without HumanoidAppearanceComponent have no character profile to
111-
// validate and are allowed through here. Humanoid bodies must have a recoverable
112-
// profile so profile-specific antag requirements, including species restrictions
113-
// and preferences, cannot be bypassed.
114-
if (!TryComp<HumanoidAppearanceComponent>(antagEntity, out var humanoid))
115-
return true;
116-
117-
var profile = _humanoidAppearance.GetBaseProfile((antagEntity, humanoid));
118-
return profile != null && IsProfileValidForAntag(player, profile, definition);
119-
}
120-
#endregion
121-
12276
/// <inhereitdoc cref="IsSessionValid(ICommonSession,Entity{AntagSelectionComponent},ProtoId{AntagSpecifierPrototype})"/>
12377
public bool IsSessionValid(ICommonSession player,
12478
Entity<AntagSelectionComponent> gameRule,
@@ -239,6 +193,9 @@ public bool IsEntityValid(EntityUid? uid, AntagSpecifierPrototype def) // Starli
239193
if (HasComp<GhostComponent>(uid))
240194
return false;
241195

196+
if (HasComp<BorgChassisComponent>(uid) && !HasComp<XenoborgComponent>(uid)) // Starlight, we should really make this look better in the future if we add more borg antags
197+
return false; // Starlight
198+
242199
if (!HasComp<HumanoidAppearanceComponent>(uid) && (!def.AllowNonHumans || !HasComp<HandsComponent>(uid))) // Starlight, Cheese, you have sent me down the path of the hell trying to get this working reliably
243200
return false;
244201

@@ -268,27 +225,6 @@ public bool IsAntagBanned(ICommonSession session, AntagSpecifierPrototype defini
268225
return false;
269226
}
270227

271-
#region Starlight
272-
/// <summary>
273-
/// Returns whether a player may claim an antagonist ghost role.
274-
/// This intentionally does not require the antag preference to be enabled.
275-
/// </summary>
276-
[PublicAPI]
277-
public bool CanTakeAntagGhostRole(ICommonSession session, ProtoId<AntagSpecifierPrototype> definition)
278-
{
279-
return Proto.Resolve(definition, out var antag) && CanTakeAntagGhostRole(session, antag);
280-
}
281-
282-
/// <summary>
283-
/// Returns whether a player may claim an antagonist ghost role.
284-
/// </summary>
285-
[PublicAPI]
286-
public bool CanTakeAntagGhostRole(ICommonSession session, AntagSpecifierPrototype definition)
287-
{
288-
return !IsAntagBanned(session, definition) && _playTime.IsAllowedNonSpawning(session, definition.PrefRoles);
289-
}
290-
#endregion
291-
292228
/// <inheritdoc cref="TryMakeAntag(Entity{AntagSelectionComponent},AntagSpecifierPrototype,ICommonSession,bool)"/>
293229
[PublicAPI]
294230
public bool TryMakeAntag(Entity<AntagSelectionComponent> gameRule,
@@ -338,6 +274,18 @@ public bool TryAssignNextAvailableAntag(Entity<AntagSelectionComponent> gameRule
338274
ICommonSession session,
339275
int players)
340276
{
277+
#region Starlight
278+
return TryAssignNextAvailableAntag(gameRule, session, players, out _);
279+
}
280+
281+
/// <summary>
282+
/// Tries to find an open antag slot for a given player and returns the definition that was assigned.
283+
/// </summary>
284+
private bool TryAssignNextAvailableAntag(Entity<AntagSelectionComponent> gameRule, ICommonSession session, int players, [NotNullWhen(true)] out AntagSpecifierPrototype? assignedAntag)
285+
{
286+
assignedAntag = null;
287+
#endregion
288+
341289
foreach (var selector in gameRule.Comp.Antags)
342290
{
343291
if (!Proto.Resolve(selector.Proto, out var antag))
@@ -348,8 +296,13 @@ public bool TryAssignNextAvailableAntag(Entity<AntagSelectionComponent> gameRule
348296
continue;
349297

350298
// Try and assign this antag, if we fail, then try the next definition!
351-
if (TryMakeAntag(gameRule, antag, session))
352-
return true;
299+
#region Starlight
300+
if (!TryMakeAntag(gameRule, antag, session))
301+
continue;
302+
303+
assignedAntag = antag;
304+
return true;
305+
#endregion
353306
}
354307

355308
return false;
@@ -385,8 +338,13 @@ public bool TryMakeLateJoinAntag(ICommonSession session)
385338

386339
foreach (var (uid, antag) in rules)
387340
{
388-
if (TryAssignNextAvailableAntag((uid, antag), session, players))
389-
return true;
341+
#region Starlight
342+
if (!TryAssignNextAvailableAntag((uid, antag), session, players, out var assignedAntag))
343+
continue;
344+
345+
RecordLateJoinAntagAssignment((uid, antag), assignedAntag); // logging
346+
return true;
347+
#endregion
390348
}
391349

392350
return false;

0 commit comments

Comments
 (0)