Mega Antag Refactor (#25786)

* Mega Antag Refactor

* last minute delta save

* more workshopping

* more shit

* ok tested this for once

* okkkkk sure

* generic delays for starting rules

* well darn

* nukies partially

* ouagh

* ballin' faded and smonkin wed

* obliterated the diff

* Spread my arms and soak up congratulations

* I've got plenty of love, but nothing to show for it

* but there’s too much sunlight
Shining on my laptop monitor, so I
Can’t see anything with any amount of clarity

* ok this junk

* OOK!

* fubar

* most of sloth's review

* oh boy

* eek

* hell yea!

* ASDFJASDJFvsakcvjkzjnhhhyh
This commit is contained in:
Nemanja
2024-04-24 21:31:45 -04:00
committed by GitHub
parent 771661f478
commit 161fd6c83c
99 changed files with 1931 additions and 2310 deletions

View File

@@ -14,7 +14,6 @@ using Content.Server.Station.Systems;
using Content.Shared.Database;
using Content.Shared.Humanoid;
using Content.Shared.IdentityManagement;
using Content.Shared.Inventory;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Mindshield.Components;
@@ -24,12 +23,11 @@ using Content.Shared.Mobs.Systems;
using Content.Shared.NPC.Prototypes;
using Content.Shared.NPC.Systems;
using Content.Shared.Revolutionary.Components;
using Content.Shared.Roles;
using Content.Shared.Stunnable;
using Content.Shared.Zombies;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using System.Linq;
using Content.Server.GameTicking.Components;
namespace Content.Server.GameTicking.Rules;
@@ -40,7 +38,7 @@ public sealed class RevolutionaryRuleSystem : GameRuleSystem<RevolutionaryRuleCo
{
[Dependency] private readonly IAdminLogManager _adminLogManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly AntagSelectionSystem _antagSelection = default!;
[Dependency] private readonly AntagSelectionSystem _antag = default!;
[Dependency] private readonly EuiManager _euiMan = default!;
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
@@ -51,7 +49,6 @@ public sealed class RevolutionaryRuleSystem : GameRuleSystem<RevolutionaryRuleCo
[Dependency] private readonly RoundEndSystem _roundEnd = default!;
[Dependency] private readonly StationSystem _stationSystem = default!;
[Dependency] private readonly EmergencyShuttleSystem _emergencyShuttle = default!;
[Dependency] private readonly InventorySystem _inventory = default!;
//Used in OnPostFlash, no reference to the rule component is available
public readonly ProtoId<NpcFactionPrototype> RevolutionaryNpcFaction = "Revolutionary";
@@ -60,23 +57,12 @@ public sealed class RevolutionaryRuleSystem : GameRuleSystem<RevolutionaryRuleCo
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RoundStartAttemptEvent>(OnStartAttempt);
SubscribeLocalEvent<RulePlayerJobsAssignedEvent>(OnPlayerJobAssigned);
SubscribeLocalEvent<CommandStaffComponent, MobStateChangedEvent>(OnCommandMobStateChanged);
SubscribeLocalEvent<HeadRevolutionaryComponent, MobStateChangedEvent>(OnHeadRevMobStateChanged);
SubscribeLocalEvent<RoundEndTextAppendEvent>(OnRoundEndText);
SubscribeLocalEvent<RevolutionaryRoleComponent, GetBriefingEvent>(OnGetBriefing);
SubscribeLocalEvent<HeadRevolutionaryComponent, AfterFlashedEvent>(OnPostFlash);
}
//Set miniumum players
protected override void Added(EntityUid uid, RevolutionaryRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
{
base.Added(uid, component, gameRule, args);
gameRule.MinPlayers = component.MinPlayers;
}
protected override void Started(EntityUid uid, RevolutionaryRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);
@@ -98,40 +84,29 @@ public sealed class RevolutionaryRuleSystem : GameRuleSystem<RevolutionaryRuleCo
}
}
private void OnRoundEndText(RoundEndTextAppendEvent ev)
protected override void AppendRoundEndText(EntityUid uid, RevolutionaryRuleComponent component, GameRuleComponent gameRule,
ref RoundEndTextAppendEvent args)
{
base.AppendRoundEndText(uid, component, gameRule, ref args);
var revsLost = CheckRevsLose();
var commandLost = CheckCommandLose();
var query = AllEntityQuery<RevolutionaryRuleComponent>();
while (query.MoveNext(out var headrev))
// This is (revsLost, commandsLost) concatted together
// (moony wrote this comment idk what it means)
var index = (commandLost ? 1 : 0) | (revsLost ? 2 : 0);
args.AddLine(Loc.GetString(Outcomes[index]));
var sessionData = _antag.GetAntagIdentifiers(uid);
args.AddLine(Loc.GetString("rev-headrev-count", ("initialCount", sessionData.Count)));
foreach (var (mind, data, name) in sessionData)
{
// This is (revsLost, commandsLost) concatted together
// (moony wrote this comment idk what it means)
var index = (commandLost ? 1 : 0) | (revsLost ? 2 : 0);
ev.AddLine(Loc.GetString(Outcomes[index]));
var count = CompOrNull<RevolutionaryRoleComponent>(mind)?.ConvertedCount ?? 0;
args.AddLine(Loc.GetString("rev-headrev-name-user",
("name", name),
("username", data.UserName),
("count", count)));
ev.AddLine(Loc.GetString("rev-headrev-count", ("initialCount", headrev.HeadRevs.Count)));
foreach (var player in headrev.HeadRevs)
{
// TODO: when role entities are a thing this has to change
var count = CompOrNull<RevolutionaryRoleComponent>(player.Value)?.ConvertedCount ?? 0;
_mind.TryGetSession(player.Value, out var session);
var username = session?.Name;
if (username != null)
{
ev.AddLine(Loc.GetString("rev-headrev-name-user",
("name", player.Key),
("username", username), ("count", count)));
}
else
{
ev.AddLine(Loc.GetString("rev-headrev-name",
("name", player.Key), ("count", count)));
}
// TODO: someone suggested listing all alive? revs maybe implement at some point
}
// TODO: someone suggested listing all alive? revs maybe implement at some point
}
}
@@ -144,57 +119,6 @@ public sealed class RevolutionaryRuleSystem : GameRuleSystem<RevolutionaryRuleCo
args.Append(Loc.GetString(head ? "head-rev-briefing" : "rev-briefing"));
}
//Check for enough players to start rule
private void OnStartAttempt(RoundStartAttemptEvent ev)
{
TryRoundStartAttempt(ev, Loc.GetString("roles-antag-rev-name"));
}
private void OnPlayerJobAssigned(RulePlayerJobsAssignedEvent ev)
{
var query = QueryActiveRules();
while (query.MoveNext(out var uid, out var activeGameRule, out var comp, out var gameRule))
{
var eligiblePlayers = _antagSelection.GetEligiblePlayers(ev.Players, comp.HeadRevPrototypeId);
if (eligiblePlayers.Count == 0)
continue;
var headRevCount = _antagSelection.CalculateAntagCount(ev.Players.Length, comp.PlayersPerHeadRev, comp.MaxHeadRevs);
var headRevs = _antagSelection.ChooseAntags(headRevCount, eligiblePlayers);
GiveHeadRev(headRevs, comp.HeadRevPrototypeId, comp);
}
}
private void GiveHeadRev(IEnumerable<EntityUid> chosen, ProtoId<AntagPrototype> antagProto, RevolutionaryRuleComponent comp)
{
foreach (var headRev in chosen)
GiveHeadRev(headRev, antagProto, comp);
}
private void GiveHeadRev(EntityUid chosen, ProtoId<AntagPrototype> antagProto, RevolutionaryRuleComponent comp)
{
RemComp<CommandStaffComponent>(chosen);
var inCharacterName = MetaData(chosen).EntityName;
if (!_mind.TryGetMind(chosen, out var mind, out _))
return;
if (!_role.MindHasRole<RevolutionaryRoleComponent>(mind))
{
_role.MindAddRole(mind, new RevolutionaryRoleComponent { PrototypeId = antagProto }, silent: true);
}
comp.HeadRevs.Add(inCharacterName, mind);
_inventory.SpawnItemsOnEntity(chosen, comp.StartingGear);
var revComp = EnsureComp<RevolutionaryComponent>(chosen);
EnsureComp<HeadRevolutionaryComponent>(chosen);
_antagSelection.SendBriefing(chosen, Loc.GetString("head-rev-role-greeting"), Color.CornflowerBlue, revComp.RevStartSound);
}
/// <summary>
/// Called when a Head Rev uses a flash in melee to convert somebody else.
/// </summary>
@@ -232,22 +156,7 @@ public sealed class RevolutionaryRuleSystem : GameRuleSystem<RevolutionaryRuleCo
}
if (mind?.Session != null)
_antagSelection.SendBriefing(mind.Session, Loc.GetString("rev-role-greeting"), Color.Red, revComp.RevStartSound);
}
public void OnHeadRevAdmin(EntityUid entity)
{
if (HasComp<HeadRevolutionaryComponent>(entity))
return;
var revRule = EntityQuery<RevolutionaryRuleComponent>().FirstOrDefault();
if (revRule == null)
{
GameTicker.StartGameRule("Revolutionary", out var ruleEnt);
revRule = Comp<RevolutionaryRuleComponent>(ruleEnt);
}
GiveHeadRev(entity, revRule.HeadRevPrototypeId, revRule);
_antag.SendBriefing(mind.Session, Loc.GetString("rev-role-greeting"), Color.Red, revComp.RevStartSound);
}
//TODO: Enemies of the revolution
@@ -308,7 +217,7 @@ public sealed class RevolutionaryRuleSystem : GameRuleSystem<RevolutionaryRuleCo
_popup.PopupEntity(Loc.GetString("rev-break-control", ("name", Identity.Entity(uid, EntityManager))), uid);
_adminLogManager.Add(LogType.Mind, LogImpact.Medium, $"{ToPrettyString(uid)} was deconverted due to all Head Revolutionaries dying.");
if (!_mind.TryGetMind(uid, out var mindId, out var mind, mc))
if (!_mind.TryGetMind(uid, out var mindId, out _, mc))
continue;
// remove their antag role