Refactor minds to be entities with components, make roles components (#19591)
Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
This commit is contained in:
@@ -6,7 +6,7 @@ namespace Content.Server.GameTicking.Rules.Components;
|
||||
public sealed partial class PiratesRuleComponent : Component
|
||||
{
|
||||
[ViewVariables]
|
||||
public List<Mind.Mind> Pirates = new();
|
||||
public List<EntityUid> Pirates = new();
|
||||
[ViewVariables]
|
||||
public EntityUid PirateShip = EntityUid.Invalid;
|
||||
[ViewVariables]
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Server.Roles;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Audio;
|
||||
@@ -10,12 +9,12 @@ namespace Content.Server.GameTicking.Rules.Components;
|
||||
[RegisterComponent, Access(typeof(TraitorRuleSystem))]
|
||||
public sealed partial class TraitorRuleComponent : Component
|
||||
{
|
||||
public List<TraitorRole> Traitors = new();
|
||||
public readonly List<EntityUid> TraitorMinds = new();
|
||||
|
||||
[DataField("traitorPrototypeId", customTypeSerializer: typeof(PrototypeIdSerializer<AntagPrototype>))]
|
||||
public string TraitorPrototypeId = "Traitor";
|
||||
|
||||
public int TotalTraitors => Traitors.Count;
|
||||
public int TotalTraitors => TraitorMinds.Count;
|
||||
public string[] Codewords = new string[3];
|
||||
|
||||
public enum SelectionState
|
||||
|
||||
@@ -6,7 +6,6 @@ using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Ghost.Roles.Components;
|
||||
using Content.Server.Ghost.Roles.Events;
|
||||
using Content.Server.Humanoid;
|
||||
using Content.Server.Humanoid.Systems;
|
||||
using Content.Server.Mind;
|
||||
using Content.Server.Mind.Components;
|
||||
using Content.Server.NPC.Components;
|
||||
@@ -20,7 +19,6 @@ using Content.Server.Shuttles.Systems;
|
||||
using Content.Server.Spawners.Components;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.Traitor;
|
||||
using Content.Shared.Dataset;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
@@ -58,8 +56,12 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
[Dependency] private readonly MapLoaderSystem _map = default!;
|
||||
[Dependency] private readonly ShuttleSystem _shuttle = default!;
|
||||
[Dependency] private readonly MindSystem _mindSystem = default!;
|
||||
[Dependency] private readonly RoleSystem _roles = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
|
||||
[ValidatePrototypeId<AntagPrototype>]
|
||||
public const string NukeopsId = "Nukeops";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -87,10 +89,10 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
continue;
|
||||
|
||||
// If entity has a prior mind attached, add them to the players list.
|
||||
if (!TryComp<MindContainerComponent>(uid, out var mindComponent))
|
||||
if (!_mindSystem.TryGetMind(uid, out _, out var mind))
|
||||
continue;
|
||||
|
||||
var session = mindComponent.Mind?.Session;
|
||||
var session = mind?.Session;
|
||||
var name = MetaData(uid).EntityName;
|
||||
if (session != null)
|
||||
nukeops.OperativePlayers.Add(name, session);
|
||||
@@ -592,22 +594,21 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
|
||||
private void OnMindAdded(EntityUid uid, NukeOperativeComponent component, MindAddedMessage args)
|
||||
{
|
||||
if (!TryComp<MindContainerComponent>(uid, out var mindContainerComponent) || mindContainerComponent.Mind == null)
|
||||
if (!_mindSystem.TryGetMind(uid, out var mindId, out var mind))
|
||||
return;
|
||||
|
||||
var mind = mindContainerComponent.Mind;
|
||||
|
||||
foreach (var nukeops in EntityQuery<NukeopsRuleComponent>())
|
||||
{
|
||||
if (nukeops.OperativeMindPendingData.TryGetValue(uid, out var role) || !nukeops.SpawnOutpost || !nukeops.EndsRound)
|
||||
{
|
||||
role ??= nukeops.OperativeRoleProto;
|
||||
_mindSystem.AddRole(mind, new NukeopsRole(mind, _prototypeManager.Index<AntagPrototype>(role)));
|
||||
_roles.MindAddRole(mindId, new NukeopsRoleComponent { PrototypeId = role });
|
||||
nukeops.OperativeMindPendingData.Remove(uid);
|
||||
}
|
||||
|
||||
if (!_mindSystem.TryGetSession(mind, out var playerSession))
|
||||
if (mind.Session is not { } playerSession)
|
||||
return;
|
||||
|
||||
if (nukeops.OperativePlayers.ContainsValue(playerSession))
|
||||
return;
|
||||
|
||||
@@ -778,7 +779,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
SetupOperativeEntity(mob, spawnDetails.Name, spawnDetails.Gear, profile, component);
|
||||
var newMind = _mindSystem.CreateMind(session.UserId, spawnDetails.Name);
|
||||
_mindSystem.SetUserId(newMind, session.UserId);
|
||||
_mindSystem.AddRole(newMind, new NukeopsRole(newMind, nukeOpsAntag));
|
||||
_roles.MindAddRole(newMind, new NukeopsRoleComponent { PrototypeId = spawnDetails.Role });
|
||||
|
||||
_mindSystem.TransferTo(newMind, mob);
|
||||
}
|
||||
@@ -820,13 +821,13 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
}
|
||||
|
||||
//For admins forcing someone to nukeOps.
|
||||
public void MakeLoneNukie(Mind.Mind mind)
|
||||
public void MakeLoneNukie(EntityUid mindId, MindComponent mind)
|
||||
{
|
||||
if (!mind.OwnedEntity.HasValue)
|
||||
return;
|
||||
|
||||
//ok hardcoded value bad but so is everything else here
|
||||
_mindSystem.AddRole(mind, new NukeopsRole(mind, _prototypeManager.Index<AntagPrototype>("Nukeops")));
|
||||
_roles.MindAddRole(mindId, new NukeopsRoleComponent { PrototypeId = NukeopsId }, mind);
|
||||
SetOutfitCommand.SetOutfit(mind.OwnedEntity.Value, "SyndicateOperativeGearFull", EntityManager);
|
||||
}
|
||||
|
||||
@@ -878,7 +879,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
var query = EntityQuery<NukeOperativeComponent, MindContainerComponent, MetaDataComponent>(true);
|
||||
foreach (var (_, mindComp, metaData) in query)
|
||||
{
|
||||
if (!mindComp.HasMind || !_mindSystem.TryGetSession(mindComp.Mind, out var session))
|
||||
if (!mindComp.HasMind || !_mindSystem.TryGetSession(mindComp.Mind.Value, out var session))
|
||||
continue;
|
||||
component.OperativePlayers.Add(metaData.EntityName, session);
|
||||
}
|
||||
|
||||
@@ -16,14 +16,12 @@ using Content.Shared.Roles;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Maps;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
@@ -68,15 +66,14 @@ public sealed class PiratesRuleSystem : GameRuleSystem<PiratesRuleComponent>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
List<(double, EntityUid)> mostValuableThefts = new();
|
||||
|
||||
var comp1 = pirates;
|
||||
var finalValue = _pricingSystem.AppraiseGrid(pirates.PirateShip, uid =>
|
||||
{
|
||||
foreach (var mind in comp1.Pirates)
|
||||
foreach (var mindId in comp1.Pirates)
|
||||
{
|
||||
if (mind.CurrentEntity == uid)
|
||||
if (TryComp(mindId, out MindComponent? mind) && mind.CurrentEntity == uid)
|
||||
return false; // Don't appraise the pirates twice, we count them in separately.
|
||||
}
|
||||
|
||||
@@ -92,9 +89,9 @@ public sealed class PiratesRuleSystem : GameRuleSystem<PiratesRuleComponent>
|
||||
mostValuableThefts.Pop();
|
||||
});
|
||||
|
||||
foreach (var mind in pirates.Pirates)
|
||||
foreach (var mindId in pirates.Pirates)
|
||||
{
|
||||
if (mind.CurrentEntity is not null)
|
||||
if (TryComp(mindId, out MindComponent? mind) && mind.CurrentEntity is not null)
|
||||
finalValue += _pricingSystem.GetPrice(mind.CurrentEntity.Value);
|
||||
}
|
||||
|
||||
@@ -119,7 +116,10 @@ public sealed class PiratesRuleSystem : GameRuleSystem<PiratesRuleComponent>
|
||||
ev.AddLine(Loc.GetString("pirates-list-start"));
|
||||
foreach (var pirate in pirates.Pirates)
|
||||
{
|
||||
ev.AddLine($"- {pirate.CharacterName} ({pirate.Session?.Name})");
|
||||
if (TryComp(pirate, out MindComponent? mind))
|
||||
{
|
||||
ev.AddLine($"- {mind.CharacterName} ({mind.Session?.Name})");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,7 +239,7 @@ public sealed class PiratesRuleSystem : GameRuleSystem<PiratesRuleComponent>
|
||||
}
|
||||
|
||||
//Forcing one player to be a pirate.
|
||||
public void MakePirate(Mind.Mind mind)
|
||||
public void MakePirate(EntityUid mindId, MindComponent mind)
|
||||
{
|
||||
if (!mind.OwnedEntity.HasValue)
|
||||
return;
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.NPC.Systems;
|
||||
using Content.Server.Mind;
|
||||
using Content.Server.Objectives.Interfaces;
|
||||
using Content.Server.NPC.Systems;
|
||||
using Content.Server.Objectives;
|
||||
using Content.Server.PDA.Ringer;
|
||||
using Content.Server.Players;
|
||||
using Content.Server.Roles;
|
||||
using Content.Server.Roles.Jobs;
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Content.Server.Traitor.Uplink;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Dataset;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.PDA;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Configuration;
|
||||
@@ -28,16 +28,17 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly IObjectivesManager _objectivesManager = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IComponentFactory _component = default!;
|
||||
[Dependency] private readonly NpcFactionSystem _npcFaction = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
||||
[Dependency] private readonly UplinkSystem _uplink = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
[Dependency] private readonly MindSystem _mindSystem = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
[Dependency] private readonly RoleSystem _roleSystem = default!;
|
||||
[Dependency] private readonly JobSystem _jobs = default!;
|
||||
[Dependency] private readonly ObjectivesSystem _objectives = default!;
|
||||
|
||||
private int PlayersPerTraitor => _cfg.GetCVar(CCVars.TraitorPlayersPerTraitor);
|
||||
private int MaxTraitors => _cfg.GetCVar(CCVars.TraitorMaxTraitors);
|
||||
@@ -46,8 +47,6 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_sawmill = Logger.GetSawmill("preset");
|
||||
|
||||
SubscribeLocalEvent<RoundStartAttemptEvent>(OnStartAttempt);
|
||||
SubscribeLocalEvent<RulePlayerJobsAssignedEvent>(OnPlayersSpawned);
|
||||
SubscribeLocalEvent<PlayerSpawnCompleteEvent>(HandleLatejoin);
|
||||
@@ -107,7 +106,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
{
|
||||
if (!component.StartCandidates.Any())
|
||||
{
|
||||
_sawmill.Error("Tried to start Traitor mode without any candidates.");
|
||||
Log.Error("Tried to start Traitor mode without any candidates.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -156,7 +155,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
foreach (var player in candidates.Keys)
|
||||
{
|
||||
// Role prevents antag.
|
||||
if (!(player.Data.ContentData()?.Mind?.AllRoles.All(role => role is not Job { CanBeAntag: false }) ?? false))
|
||||
if (!_jobs.CanBeAntag(player))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -180,7 +179,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
}
|
||||
if (prefList.Count == 0)
|
||||
{
|
||||
_sawmill.Info("Insufficient preferred traitors, picking at random.");
|
||||
Log.Info("Insufficient preferred traitors, picking at random.");
|
||||
prefList = list;
|
||||
}
|
||||
return prefList;
|
||||
@@ -191,14 +190,14 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
var results = new List<IPlayerSession>(traitorCount);
|
||||
if (prefList.Count == 0)
|
||||
{
|
||||
_sawmill.Info("Insufficient ready players to fill up with traitors, stopping the selection.");
|
||||
Log.Info("Insufficient ready players to fill up with traitors, stopping the selection.");
|
||||
return results;
|
||||
}
|
||||
|
||||
for (var i = 0; i < traitorCount; i++)
|
||||
{
|
||||
results.Add(_random.PickAndTake(prefList));
|
||||
_sawmill.Info("Selected a preferred traitor.");
|
||||
Log.Info("Selected a preferred traitor.");
|
||||
}
|
||||
return results;
|
||||
}
|
||||
@@ -215,22 +214,28 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
MakeCodewords(traitorRule);
|
||||
}
|
||||
|
||||
var mind = traitor.Data.ContentData()?.Mind;
|
||||
if (mind == null)
|
||||
if (!_mindSystem.TryGetMind(traitor, out var mindId, out var mind))
|
||||
{
|
||||
_sawmill.Info("Failed getting mind for picked traitor.");
|
||||
Log.Info("Failed getting mind for picked traitor.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HasComp<TraitorRoleComponent>(mindId))
|
||||
{
|
||||
Log.Error($"Player {traitor.Name} is already a traitor.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mind.OwnedEntity is not { } entity)
|
||||
{
|
||||
Logger.ErrorS("preset", "Mind picked for traitor did not have an attached entity.");
|
||||
Log.Error("Mind picked for traitor did not have an attached entity.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculate the amount of currency on the uplink.
|
||||
var startingBalance = _cfg.GetCVar(CCVars.TraitorStartingBalance);
|
||||
if (mind.CurrentJob != null)
|
||||
startingBalance = Math.Max(startingBalance - mind.CurrentJob.Prototype.AntagAdvantage, 0);
|
||||
if (_jobs.MindTryGetJob(mindId, out _, out var prototype))
|
||||
startingBalance = Math.Max(startingBalance - prototype.AntagAdvantage, 0);
|
||||
|
||||
// creadth: we need to create uplink for the antag.
|
||||
// PDA should be in place already
|
||||
@@ -241,22 +246,22 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
// Add the ringtone uplink and get its code for greeting
|
||||
var code = EnsureComp<RingerUplinkComponent>(pda.Value).Code;
|
||||
|
||||
// Prepare antagonist role
|
||||
var antagPrototype = _prototypeManager.Index<AntagPrototype>(traitorRule.TraitorPrototypeId);
|
||||
var traitorRole = new TraitorRole(mind, antagPrototype);
|
||||
|
||||
// Prepare traitor role
|
||||
// Give traitors their codewords and uplink code to keep in their character info menu
|
||||
traitorRole.Mind.Briefing = string.Format(
|
||||
"{0}\n{1}",
|
||||
Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", traitorRule.Codewords))),
|
||||
Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", code).Replace("sharp","#"))));
|
||||
var briefing =
|
||||
$"{Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", traitorRule.Codewords)))}\n{Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", code).Replace("sharp", "#")))}";
|
||||
var traitorRole = new TraitorRoleComponent
|
||||
{
|
||||
PrototypeId = traitorRule.TraitorPrototypeId,
|
||||
Briefing = briefing
|
||||
};
|
||||
|
||||
// Assign traitor roles
|
||||
_mindSystem.AddRole(mind, traitorRole);
|
||||
SendTraitorBriefing(mind, traitorRule.Codewords, code);
|
||||
traitorRule.Traitors.Add(traitorRole);
|
||||
_roleSystem.MindAddRole(mindId, traitorRole);
|
||||
SendTraitorBriefing(mindId, traitorRule.Codewords, code);
|
||||
traitorRule.TraitorMinds.Add(mindId);
|
||||
|
||||
if (_mindSystem.TryGetSession(mind, out var session))
|
||||
if (_mindSystem.TryGetSession(mindId, out var session))
|
||||
{
|
||||
// Notificate player about new role assignment
|
||||
_audioSystem.PlayGlobal(traitorRule.GreetSoundNotification, session);
|
||||
@@ -272,11 +277,11 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
var difficulty = 0f;
|
||||
for (var pick = 0; pick < maxPicks && maxDifficulty > difficulty; pick++)
|
||||
{
|
||||
var objective = _objectivesManager.GetRandomObjective(traitorRole.Mind, "TraitorObjectiveGroups");
|
||||
var objective = _objectives.GetRandomObjective(mindId, mind, "TraitorObjectiveGroups");
|
||||
|
||||
if (objective == null)
|
||||
continue;
|
||||
if (_mindSystem.TryAddObjective(traitorRole.Mind, objective))
|
||||
if (_mindSystem.TryAddObjective(mindId, mind, objective))
|
||||
difficulty += objective.Difficulty;
|
||||
}
|
||||
|
||||
@@ -289,7 +294,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
/// <param name="mind">A mind (player)</param>
|
||||
/// <param name="codewords">Codewords</param>
|
||||
/// <param name="code">Uplink codes</param>
|
||||
private void SendTraitorBriefing(Mind.Mind mind, string[] codewords, Note[] code)
|
||||
private void SendTraitorBriefing(EntityUid mind, string[] codewords, Note[] code)
|
||||
{
|
||||
if (_mindSystem.TryGetSession(mind, out var session))
|
||||
{
|
||||
@@ -362,18 +367,21 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
if (!GameTicker.IsGameRuleAdded(uid, gameRule))
|
||||
continue;
|
||||
|
||||
var result = Loc.GetString("traitor-round-end-result", ("traitorCount", traitor.Traitors.Count));
|
||||
var result = Loc.GetString("traitor-round-end-result", ("traitorCount", traitor.TraitorMinds.Count));
|
||||
|
||||
result += "\n" + Loc.GetString("traitor-round-end-codewords", ("codewords", string.Join(", ", traitor.Codewords))) +
|
||||
"\n";
|
||||
|
||||
foreach (var t in traitor.Traitors)
|
||||
foreach (var mindId in traitor.TraitorMinds)
|
||||
{
|
||||
var name = t.Mind.CharacterName;
|
||||
_mindSystem.TryGetSession(t.Mind, out var session);
|
||||
if (!TryComp(mindId, out MindComponent? mind))
|
||||
continue;
|
||||
|
||||
var name = mind.CharacterName;
|
||||
_mindSystem.TryGetSession(mindId, out var session);
|
||||
var username = session?.Name;
|
||||
|
||||
var objectives = t.Mind.AllObjectives.ToArray();
|
||||
var objectives = mind.AllObjectives.ToArray();
|
||||
if (objectives.Length == 0)
|
||||
{
|
||||
if (username != null)
|
||||
@@ -437,12 +445,12 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
}
|
||||
}
|
||||
|
||||
public List<TraitorRole> GetOtherTraitorsAliveAndConnected(Mind.Mind ourMind)
|
||||
public List<(EntityUid Id, MindComponent Mind)> GetOtherTraitorMindsAliveAndConnected(MindComponent ourMind)
|
||||
{
|
||||
List<TraitorRole> allTraitors = new();
|
||||
List<(EntityUid Id, MindComponent Mind)> allTraitors = new();
|
||||
foreach (var traitor in EntityQuery<TraitorRuleComponent>())
|
||||
{
|
||||
foreach (var role in GetOtherTraitorsAliveAndConnected(ourMind, traitor))
|
||||
foreach (var role in GetOtherTraitorMindsAliveAndConnected(ourMind, traitor))
|
||||
{
|
||||
if (!allTraitors.Contains(role))
|
||||
allTraitors.Add(role);
|
||||
@@ -452,13 +460,22 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
return allTraitors;
|
||||
}
|
||||
|
||||
private List<TraitorRole> GetOtherTraitorsAliveAndConnected(Mind.Mind ourMind, TraitorRuleComponent component)
|
||||
private List<(EntityUid Id, MindComponent Mind)> GetOtherTraitorMindsAliveAndConnected(MindComponent ourMind, TraitorRuleComponent component)
|
||||
{
|
||||
return component.Traitors // don't want
|
||||
.Where(t => t.Mind.OwnedEntity is not null) // no entity
|
||||
.Where(t => t.Mind.Session is not null) // player disconnected
|
||||
.Where(t => t.Mind != ourMind) // ourselves
|
||||
.Where(t => _mobStateSystem.IsAlive((EntityUid) t.Mind.OwnedEntity!)) // dead
|
||||
.Where(t => t.Mind.CurrentEntity == t.Mind.OwnedEntity).ToList(); // not in original body
|
||||
var traitors = new List<(EntityUid Id, MindComponent Mind)>();
|
||||
foreach (var traitor in component.TraitorMinds)
|
||||
{
|
||||
if (TryComp(traitor, out MindComponent? mind) &&
|
||||
mind.OwnedEntity != null &&
|
||||
mind.Session != null &&
|
||||
mind != ourMind &&
|
||||
_mobStateSystem.IsAlive(mind.OwnedEntity.Value) &&
|
||||
mind.CurrentEntity == mind.OwnedEntity)
|
||||
{
|
||||
traitors.Add((traitor, mind));
|
||||
}
|
||||
}
|
||||
|
||||
return traitors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ using Content.Server.Chat.Managers;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Mind;
|
||||
using Content.Server.Mind.Components;
|
||||
using Content.Server.Players;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Preferences.Managers;
|
||||
using Content.Server.Roles;
|
||||
@@ -21,7 +19,6 @@ using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Zombies;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Player;
|
||||
@@ -48,6 +45,7 @@ public sealed class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponent>
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly ZombieSystem _zombie = default!;
|
||||
[Dependency] private readonly MindSystem _mindSystem = default!;
|
||||
[Dependency] private readonly RoleSystem _roles = default!;
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
|
||||
@@ -97,10 +95,9 @@ public sealed class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponent>
|
||||
{
|
||||
var meta = MetaData(survivor);
|
||||
var username = string.Empty;
|
||||
if (TryComp<MindContainerComponent>(survivor, out var mindcomp))
|
||||
if (_mindSystem.TryGetMind(survivor, out _, out var mind) && mind.Session != null)
|
||||
{
|
||||
if (mindcomp.Mind != null && mindcomp.Mind.Session != null)
|
||||
username = mindcomp.Mind.Session.Name;
|
||||
username = mind.Session.Name;
|
||||
}
|
||||
|
||||
ev.AddLine(Loc.GetString("zombie-round-end-user-was-survivor",
|
||||
@@ -312,12 +309,15 @@ public sealed class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponent>
|
||||
|
||||
prefList.Remove(zombie);
|
||||
playerList.Remove(zombie);
|
||||
if (zombie.Data.ContentData()?.Mind is not { } mind || mind.OwnedEntity is not { } ownedEntity)
|
||||
if (!_mindSystem.TryGetMind(zombie, out var mindId, out var mind) ||
|
||||
mind.OwnedEntity is not { } ownedEntity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
totalInfected++;
|
||||
|
||||
_mindSystem.AddRole(mind, new ZombieRole(mind, _prototypeManager.Index<AntagPrototype>(component.PatientZeroPrototypeId)));
|
||||
_roles.MindAddRole(mindId, new ZombieRoleComponent { PrototypeId = component.PatientZeroPrototypeId });
|
||||
|
||||
var pending = EnsureComp<PendingZombieComponent>(ownedEntity);
|
||||
pending.GracePeriod = _random.Next(component.MinInitialInfectedGrace, component.MaxInitialInfectedGrace);
|
||||
|
||||
Reference in New Issue
Block a user