Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jester Role #49

Merged
merged 8 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
30 changes: 25 additions & 5 deletions Content.Server/_SSS/SuspicionGameRule/SuspicionRuleSystem.Rules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Content.Shared.Mobs.Components;
using Content.Shared.Overlays;
using Content.Shared.Popups;
using Content.Server.KillTracking;

namespace Content.Server._SSS.SuspicionGameRule;

Expand Down Expand Up @@ -53,6 +54,10 @@ private void OnMobStateChanged(EntityUid uid, SuspicionPlayerComponent component

DropAllItemsOnEntity(args.Target);

}

private void OnKillReported(ref KillReportedEvent ev)
{
var query = EntityQueryEnumerator<SuspicionRuleComponent, GameRuleComponent>();
while (query.MoveNext(out var ruleId, out var sus, out var gameRule))
{
Expand All @@ -76,8 +81,9 @@ private void OnMobStateChanged(EntityUid uid, SuspicionPlayerComponent component

var allInnocents = FindAllOfType(SuspicionRole.Innocent);
var allDetectives = FindAllOfType(SuspicionRole.Detective);
var allWildcards = FindAllOfType(SuspicionRole.Wildcard);

if (allInnocents.Count == 0 && allDetectives.Count == 0)
if (allInnocents.Count == 0 && allDetectives.Count == 0 && allWildcards.Count == 0)
{
_chatManager.DispatchServerAnnouncement("The traitors have won the round.");
sus.GameState = SuspicionGameState.PostRound;
Expand All @@ -92,6 +98,19 @@ private void OnMobStateChanged(EntityUid uid, SuspicionPlayerComponent component
_roundEndSystem.EndRound(TimeSpan.FromSeconds(sus.PostRoundDuration));
return;
}

if (ev.Primary is KillPlayerSource player && !ev.Suicide)
if (TrySusRole(ev.Entity, out var roleComp))
if (roleComp.SubRole == SuspicionSubRole.Jester)
if (TrySusRole(player.PlayerId, out var attackerRoleComp))
if (attackerRoleComp.Role == SuspicionRole.Innocent || attackerRoleComp.Role == SuspicionRole.Detective)
{
_chatManager.DispatchServerAnnouncement("The jesters have won the round.");
Aidenkrz marked this conversation as resolved.
Show resolved Hide resolved
sus.GameState = SuspicionGameState.PostRound;
_roundEndSystem.EndRound(TimeSpan.FromSeconds(sus.PostRoundDuration));
return;
}

break;
}
}
Expand Down Expand Up @@ -166,7 +185,7 @@ private void OnExamine(EntityUid uid, SuspicionPlayerComponent component, ref Ex
EntityUid.Invalid,
false,
client: session.Channel,
recordReplay:true
recordReplay: true
);
}
}
Expand All @@ -176,11 +195,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,12 +232,11 @@ 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
);
}

private void UpdateSpaceWalkDamage(ref SuspicionRuleComponent sus, float frameTime)
{
var query = EntityQueryEnumerator<SuspicionPlayerComponent>();
Expand Down
132 changes: 122 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,8 @@
using Content.Shared.Players;
using Content.Shared.Security.Components;
using Robust.Shared.Prototypes;
using Content.Shared.CombatMode.Pacification;
using Robust.Shared.Audio;

namespace Content.Server._SSS.SuspicionGameRule;

Expand All @@ -39,6 +41,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 +86,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.
*/

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

RobustRandom.SetSeed(combinedSeed);

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

var 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 (var 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 +175,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 +184,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 +202,68 @@ 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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we should probably pull out some of the systems here (such as the briefing and shit) so we don't duplicated code like crazy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really should, but like I said, I'm not trying to refactor everything with this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah thats fine

}

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")
};

SoundPathSpecifier? briefingSound = selectedSubRole switch
{
SuspicionSubRole.Jester => new SoundPathSpecifier("/Audio/Voice/Cluwne/cluwnelaugh1.ogg"),
_ => null
};

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: briefingSound);

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 +281,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
Loading
Loading