Skip to content

Commit

Permalink
Creeper, aw man.
Browse files Browse the repository at this point in the history
  • Loading branch information
Aidenkrz committed Dec 22, 2024
1 parent 964f56b commit 167be3c
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 20 deletions.
5 changes: 5 additions & 0 deletions Content.Client/_SSS/UserInterface/SSSStatusUIController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ public void UpdateRoleDisplay(SuspicionRuleUpdateRole ev, EntitySessionEventArgs
SuspicionRole.Traitor => "roles-antag-suspicion-traitor-name",
SuspicionRole.Detective => "roles-antag-suspicion-detective-name",
SuspicionRole.Innocent => "roles-antag-suspicion-innocent-name",
SuspicionRole.Wildcard => ev.NewSubRole switch
{
SuspicionSubRole.Jester => "roles-antag-suspicion-jester-name",
_ => "roles-antag-suspicion-wildcard-unknown",
},
_ => "roles-antag-suspicion-unknown",
});
SetRoleUI(roleName, Color.FromName(ev.NewRole.GetRoleColor()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ private void InitializeCVars()
{
Subs.CVar(_cfg, CCVars.SSSTraitorPercentage, f => _traitorPercentage = f, true);
Subs.CVar(_cfg, CCVars.SSSDetectivePercentage, f => _detectivePercentage = f, true);
Subs.CVar(_cfg, CCVars.SSSWildcardPercentage, f => _wildcardPercentage = f, true);
Subs.CVar(_cfg, CCVars.SSSWildcardChance, f => _wildcardChance = f, true);
Subs.CVar(_cfg, CCVars.SSSPreparingDuration, i => _preparingDuration = i, true);
Subs.CVar(_cfg, CCVars.SSSRoundDuration, i => _roundDuration = i, true);
Subs.CVar(_cfg, CCVars.SSSTimeAddedPerKill, i => _timeAddedPerKill = i, true);
Expand All @@ -16,6 +18,8 @@ private void InitializeCVars()

private float _traitorPercentage = 0.25f;
private float _detectivePercentage = 0.25f;
private float _wildcardPercentage = 0.15f;
private float _wildcardChance = 0.3f;
private int _preparingDuration = 30;
private int _roundDuration = 480;
private int _timeAddedPerKill = 30;
Expand Down
19 changes: 16 additions & 3 deletions Content.Server/_SSS/SuspicionGameRule/SuspicionRuleSystem.Rules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ private void OnMobStateChanged(EntityUid uid, SuspicionPlayerComponent component

var allInnocents = FindAllOfType(SuspicionRole.Innocent);
var allDetectives = FindAllOfType(SuspicionRole.Detective);
var allJestersAlive = FindAllOfType(SuspicionSubRole.Jester);
var allJesters = FindAllOfType(SuspicionSubRole.Jester, false);

if (allInnocents.Count == 0 && allDetectives.Count == 0)
{
Expand All @@ -92,6 +94,15 @@ private void OnMobStateChanged(EntityUid uid, SuspicionPlayerComponent component
_roundEndSystem.EndRound(TimeSpan.FromSeconds(sus.PostRoundDuration));
return;
}

if (allJesters != allJestersAlive)
{
_chatManager.DispatchServerAnnouncement("The jesters have won the round.");
sus.GameState = SuspicionGameState.PostRound;
_roundEndSystem.EndRound(TimeSpan.FromSeconds(sus.PostRoundDuration));
return;
}

break;
}
}
Expand Down Expand Up @@ -166,7 +177,7 @@ private void OnExamine(EntityUid uid, SuspicionPlayerComponent component, ref Ex
EntityUid.Invalid,
false,
client: session.Channel,
recordReplay:true
recordReplay: true
);
}
}
Expand All @@ -176,11 +187,13 @@ private void OnExamine(EntityUid uid, SuspicionPlayerComponent component, ref Ex
}
}

var victimRole = role.Value.Comp2.SubRole?.ToString() ?? role.Value.Comp2.Role.ToString();

args.PushMarkup(Loc.GetString(
"suspicion-examination",
("ent", args.Examined),
("col", role.Value.Comp2.Role.GetRoleColor()),
("role", role.Value.Comp2.Role.ToString())),
("role", victimRole)),
-10);

if (!HasComp<HandsComponent>(args.Examiner))
Expand Down Expand Up @@ -211,7 +224,7 @@ private void OnExamine(EntityUid uid, SuspicionPlayerComponent component, ref Ex
("found", args.Examined),
("where", _navMapSystem.GetNearestBeaconString(loc)),
("col", role.Value.Comp2.Role.GetRoleColor()),
("role", role.Value.Comp2.Role.ToString()));
("role", victimRole));
SendAnnouncement(
msg
);
Expand Down
125 changes: 115 additions & 10 deletions Content.Server/_SSS/SuspicionGameRule/SuspicionRuleSystem.Spawning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using Content.Shared.Players;
using Content.Shared.Security.Components;
using Robust.Shared.Prototypes;
using Content.Shared.CombatMode.Pacification;

namespace Content.Server._SSS.SuspicionGameRule;

Expand All @@ -39,6 +40,11 @@ private void OnGetBriefing(Entity<SuspicionRoleComponent> role, ref GetBriefingE
SuspicionRole.Traitor => Loc.GetString("roles-antag-suspicion-traitor-objective"),
SuspicionRole.Detective => Loc.GetString("roles-antag-suspicion-detective-objective"),
SuspicionRole.Innocent => Loc.GetString("roles-antag-suspicion-innocent-objective"),
SuspicionRole.Wildcard => role.Comp.SubRole switch
{
SuspicionSubRole.Jester => Loc.GetString("roles-antag-suspicion-jester-objective"),
_ => "roles-antag-suspicion-pending-objective",
},
_ => Loc.GetString("roles-antag-suspicion-pending-objective")
};
}
Expand Down Expand Up @@ -79,29 +85,79 @@ private void StartRound(EntityUid uid, SuspicionRuleComponent component, GameRul
_rejuvenate.PerformRejuvenate(ent.Value);
}

var traitorCount = MathHelper.Clamp((int) (participatingPlayers.Count * _traitorPercentage), 1, allPlayerData.Count);
var detectiveCount = MathHelper.Clamp((int) (participatingPlayers.Count * _detectivePercentage), 1, allPlayerData.Count);
var traitorCount = MathHelper.Clamp((int)(participatingPlayers.Count * _traitorPercentage), 1, allPlayerData.Count);
var detectiveCount = MathHelper.Clamp((int)(participatingPlayers.Count * _detectivePercentage), 1, allPlayerData.Count);
var wildcardCount = 0; // Zero by default, we roll to see if wildcards will be in the next round in the next line.
if (RobustRandom.NextFloat() <= _wildcardChance)
wildcardCount = MathHelper.Clamp((int)(participatingPlayers.Count * _wildcardPercentage), 1, allPlayerData.Count);

if (traitorCount + detectiveCount > participatingPlayers.Count)
if (traitorCount + detectiveCount + wildcardCount > participatingPlayers.Count)
{
// we somehow have more picked players than valid

// what the fuck

traitorCount = participatingPlayers.Count;
detectiveCount = 0;
wildcardCount = 0;
}

/* Simyon, I think the issue is you didnt make it random enough, so I made it more random for you!
RobustRandom.Shuffle(participatingPlayers); // Shuffle the list so we can just take the first N players
RobustRandom.Shuffle(participatingPlayers);
RobustRandom.Shuffle(participatingPlayers); // I don't trust the shuffle.
RobustRandom.Shuffle(participatingPlayers);
RobustRandom.Shuffle(participatingPlayers); // I really don't trust the shuffle.
*/

int seed1 = (int)(Math.Sin(RobustRandom.Next()) * 10000);
int seed2 = (int)(Math.Cos(RobustRandom.Next()) * 10000);
int combinedSeed = seed1 ^ seed2;

RobustRandom.SetSeed(combinedSeed);

int depth = 5;
while (depth > 0)
{
int chaoticSeed = (int)Math.Pow(RobustRandom.Next(), 3) ^ (RobustRandom.Next() % 10000);
RobustRandom.SetSeed(chaoticSeed);

int halfCount = participatingPlayers.Count / 2;
var shuffledSubset = participatingPlayers.Take(halfCount).ToList();
RobustRandom.Shuffle(shuffledSubset);
participatingPlayers.RemoveRange(0, halfCount);
participatingPlayers.AddRange(shuffledSubset);

depth--;
}

RobustRandom.SetSeed(RobustRandom.Next());
RobustRandom.Shuffle(participatingPlayers);

RobustRandom.SetSeed(RobustRandom.Next());
RobustRandom.Shuffle(participatingPlayers);

var shuffledIndices = participatingPlayers
.Select((_, i) => (Index: i, Value: RobustRandom.Next()))
.OrderBy(tuple => tuple.Value)
.Select(tuple => tuple.Index)
.ToList();

var reorderedPlayers = shuffledIndices.Select(i => participatingPlayers[i]).ToList();
participatingPlayers.Clear();
participatingPlayers.AddRange(reorderedPlayers);

for (int i = 0; i < 3; i++)
{
RobustRandom.SetSeed(RobustRandom.Next());
RobustRandom.Shuffle(participatingPlayers);
}

// I hope thats random enough!

for (var i = 0; i < traitorCount; i++)
{
var role = participatingPlayers[i];
var role = participatingPlayers[RobustRandom.Next(participatingPlayers.Count)];
role.comp.Role = SuspicionRole.Traitor;
var ownedEntity = Comp<MindComponent>(role.mind).OwnedEntity;
if (!ownedEntity.HasValue)
Expand All @@ -118,7 +174,7 @@ private void StartRound(EntityUid uid, SuspicionRuleComponent component, GameRul

_npcFactionSystem.AddFaction(ownedEntity.Value, component.TraitorFaction);

_subdermalImplant.AddImplants(ownedEntity.Value, new List<string> {component.UplinkImplant}); // Why does this method only take in a list???
_subdermalImplant.AddImplants(ownedEntity.Value, new List<string> { component.UplinkImplant }); // Why does this method only take in a list???

_antagSelectionSystem.SendBriefing(
ownedEntity.Value,
Expand All @@ -127,11 +183,12 @@ private void StartRound(EntityUid uid, SuspicionRuleComponent component, GameRul
_traitorStartSound);

RaiseNetworkEvent(new SuspicionRuleUpdateRole(SuspicionRole.Traitor), ownedEntity.Value);
participatingPlayers.Remove(role);
}

for (var i = traitorCount; i < traitorCount + detectiveCount; i++)
for (var i = 0; i < detectiveCount; i++)
{
var role = participatingPlayers[i];
var role = participatingPlayers[RobustRandom.Next(participatingPlayers.Count)];
role.comp.Role = SuspicionRole.Detective;
var ownedEntity = Comp<MindComponent>(role.mind).OwnedEntity;
if (!ownedEntity.HasValue)
Expand All @@ -144,14 +201,62 @@ private void StartRound(EntityUid uid, SuspicionRuleComponent component, GameRul

AddKeyToRadio(ownedEntity.Value, component.DetectiveRadio);

_subdermalImplant.AddImplants(ownedEntity.Value, new List<string> {component.DetectiveImplant});
_subdermalImplant.AddImplants(ownedEntity.Value, new List<string> { component.DetectiveImplant });

_antagSelectionSystem.SendBriefing(
ownedEntity.Value,
Loc.GetString("detective-briefing"),
Color.LightBlue,
briefingSound:null);
briefingSound: null);
RaiseNetworkEvent(new SuspicionRuleUpdateRole(SuspicionRole.Detective), ownedEntity.Value);
participatingPlayers.Remove(role);
}

var wildcardRoles = new List<SuspicionSubRole>
{
SuspicionSubRole.Jester
};

for (var i = 0; i < wildcardCount; i++)
{
var role = participatingPlayers[RobustRandom.Next(participatingPlayers.Count)];

var selectedSubRole = wildcardRoles[RobustRandom.Next(wildcardRoles.Count)];

role.comp.Role = SuspicionRole.Wildcard;
role.comp.SubRole = selectedSubRole;

string briefingText = selectedSubRole switch
{
SuspicionSubRole.Jester => Loc.GetString("jester-briefing"),
_ => Loc.GetString("wildcard-briefing")
};

var ownedEntity = Comp<MindComponent>(role.mind).OwnedEntity;
if (!ownedEntity.HasValue)
{
Log.Error("Player mind has no entity.");
continue;
}

switch (selectedSubRole)
{
case SuspicionSubRole.Jester:
{
EnsureComp<PacifiedComponent>(ownedEntity.Value);
break;
}
}

_antagSelectionSystem.SendBriefing(
ownedEntity.Value,
briefingText,
Color.LightPink,
briefingSound: null);

RaiseNetworkEvent(new SuspicionRuleUpdateRole(SuspicionRole.Wildcard, selectedSubRole), ownedEntity.Value);

participatingPlayers.Remove(role);
}

// Anyone who isn't a traitor will get the innocent role.
Expand All @@ -169,7 +274,7 @@ private void StartRound(EntityUid uid, SuspicionRuleComponent component, GameRul
ownedEntity.Value,
Loc.GetString("innocent-briefing"),
briefingColor: Color.Green,
briefingSound:null);
briefingSound: null);

RaiseNetworkEvent(new SuspicionRuleUpdateRole(SuspicionRole.Innocent), ownedEntity.Value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private void AddTcToPlayer(EntityUid player, int amount, bool displayMessage = t
/// </summary>
private List<(EntityUid body, Entity<MindRoleComponent, SuspicionRoleComponent> sus)> FindAllOfType(SuspicionRole role, bool filterDead = true)
{
var allMinds = new HashSet<Entity<MindComponent>>();
var allMinds = new HashSet<Entity<MindComponent>>();
if (filterDead)
{
allMinds = _mindSystem.GetAliveHumans();
Expand Down Expand Up @@ -123,6 +123,49 @@ private void AddTcToPlayer(EntityUid player, int amount, bool displayMessage = t
return result;
}

/// <summary>
/// Finds all players with a specific sub-role.
/// </summary>
private List<(EntityUid body, Entity<MindRoleComponent, SuspicionRoleComponent> sus)> FindAllOfType(SuspicionSubRole subRole, bool filterDead = true)
{
var allMinds = new HashSet<Entity<MindComponent>>();
if (filterDead)
{
allMinds = _mindSystem.GetAliveHumans();
}
else
{
var query = EntityQueryEnumerator<HumanoidAppearanceComponent>();
while (query.MoveNext(out var uid, out _))
{
if (!_mindSystem.TryGetMind(uid, out var mind, out var mindComp))
continue;

allMinds.Add(new Entity<MindComponent>(mind, mindComp));
}
}

var result = new List<(EntityUid body, Entity<MindRoleComponent, SuspicionRoleComponent>)>();
foreach (var mind in allMinds)
{
var nullableMind = new Entity<MindComponent?>(mind.Owner, mind.Comp); // Following the pattern from the original method.

if (!_roleSystem.MindHasRole<SuspicionRoleComponent>(nullableMind, out var roleComp))
continue;

if (roleComp.Value.Comp2.SubRole != subRole)
continue;

var entity = Comp<MindComponent>(mind).OwnedEntity;
if (!entity.HasValue)
continue;

result.Add((entity.Value, roleComp.Value));
}

return result;
}

public void DropAllItemsOnEntity(EntityUid entity)
{
if (!TryComp(entity, out InventoryComponent? inventory))
Expand Down
Loading

0 comments on commit 167be3c

Please sign in to comment.