Skip to content

Commit

Permalink
Jester Role (#49)
Browse files Browse the repository at this point in the history
* Creeper, aw man.

* Good enough

* Update Resources/Locale/en-US/_SSS/suspicion.ftl

Co-authored-by: Simon <[email protected]>

* millions must var

* Update Resources/Locale/en-US/_SSS/suspicion.ftl

Co-authored-by: Simon <[email protected]>

* idk

---------

Co-authored-by: Simon <[email protected]>
  • Loading branch information
Aidenkrz and Simyon264 authored Dec 22, 2024
1 parent e481cf9 commit 7479f79
Show file tree
Hide file tree
Showing 10 changed files with 298 additions and 25 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
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.");
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);
}

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

0 comments on commit 7479f79

Please sign in to comment.