diff --git a/Content.Client/Mind/MindSystem.cs b/Content.Client/Mind/MindSystem.cs new file mode 100644 index 0000000000..87d9e9ddbe --- /dev/null +++ b/Content.Client/Mind/MindSystem.cs @@ -0,0 +1,7 @@ +using Content.Shared.Mind; + +namespace Content.Client.Mind; + +public sealed class MindSystem : SharedMindSystem +{ +} diff --git a/Content.Client/Players/PlayerSystem.cs b/Content.Client/Players/PlayerSystem.cs new file mode 100644 index 0000000000..d5ce4ec197 --- /dev/null +++ b/Content.Client/Players/PlayerSystem.cs @@ -0,0 +1,12 @@ +using Content.Shared.Players; +using Robust.Shared.Players; + +namespace Content.Client.Players; + +public sealed class PlayerSystem : SharedPlayerSystem +{ + public override PlayerData? ContentData(ICommonSession? session) + { + return null; + } +} diff --git a/Content.Client/Roles/Jobs/JobSystem.cs b/Content.Client/Roles/Jobs/JobSystem.cs new file mode 100644 index 0000000000..7e7c4ccc3e --- /dev/null +++ b/Content.Client/Roles/Jobs/JobSystem.cs @@ -0,0 +1,7 @@ +using Content.Shared.Roles.Jobs; + +namespace Content.Client.Roles.Jobs; + +public sealed class JobSystem : SharedJobSystem +{ +} diff --git a/Content.Client/Roles/RoleSystem.cs b/Content.Client/Roles/RoleSystem.cs new file mode 100644 index 0000000000..6a98320af4 --- /dev/null +++ b/Content.Client/Roles/RoleSystem.cs @@ -0,0 +1,5 @@ +namespace Content.Client.Roles; + +public sealed class RoleSystem : EntitySystem +{ +} diff --git a/Content.IntegrationTests/Pair/TestPair.Recycle.cs b/Content.IntegrationTests/Pair/TestPair.Recycle.cs index 8de7149043..c9796c0079 100644 --- a/Content.IntegrationTests/Pair/TestPair.Recycle.cs +++ b/Content.IntegrationTests/Pair/TestPair.Recycle.cs @@ -2,10 +2,10 @@ using System.IO; using System.Linq; using Content.Server.GameTicking; -using Content.Server.Mind; -using Content.Server.Mind.Components; using Content.Shared.CCVar; using Content.Shared.GameTicking; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Robust.Client; using Robust.Server.Player; using Robust.Shared.Exceptions; diff --git a/Content.IntegrationTests/PoolManager.cs b/Content.IntegrationTests/PoolManager.cs index e1f0a4b5a4..3f8d261e8d 100644 --- a/Content.IntegrationTests/PoolManager.cs +++ b/Content.IntegrationTests/PoolManager.cs @@ -12,22 +12,13 @@ using Content.IntegrationTests.Tests; using Content.IntegrationTests.Tests.Destructible; using Content.IntegrationTests.Tests.DeviceNetwork; using Content.IntegrationTests.Tests.Interaction.Click; -using Content.Server.GameTicking; -using Content.Server.Mind.Components; -using Content.Shared.CCVar; -using Content.Shared.GameTicking; using Robust.Client; -using Robust.Client.State; using Robust.Server; -using Robust.Server.Player; -using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.ContentPack; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Log; -using Robust.Shared.Map; -using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.UnitTesting; diff --git a/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs b/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs index bf8c77e066..ce2c4b6981 100644 --- a/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs +++ b/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs @@ -5,7 +5,6 @@ using Content.Client.Construction; using Content.Client.Examine; using Content.IntegrationTests.Pair; using Content.Server.Body.Systems; -using Content.Server.Mind; using Content.Server.Players; using Content.Server.Stack; using Content.Server.Tools; @@ -14,6 +13,7 @@ using Content.Shared.DoAfter; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; +using Content.Shared.Mind; using Robust.Client.Input; using Robust.Client.UserInterface; using Robust.Server.GameObjects; @@ -192,7 +192,7 @@ public abstract partial class InteractionTest { // Fuck you mind system I want an hour of my life back // Mind system is a time vampire - SEntMan.System().WipeMind(ServerSession.ContentData()?.Mind); + SEntMan.System().WipeMind(ServerSession.ContentData()?.Mind); old = cPlayerMan.LocalPlayer.ControlledEntity; Player = SEntMan.SpawnEntity(PlayerPrototype, PlayerCoords); diff --git a/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs b/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs index 5eecfd01ec..28e49645c9 100644 --- a/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs +++ b/Content.IntegrationTests/Tests/Minds/GhostRoleTests.cs @@ -2,9 +2,9 @@ using System.Linq; using Content.Server.Ghost.Roles; using Content.Server.Ghost.Roles.Components; -using Content.Server.Mind; using Content.Server.Players; using Content.Shared.Ghost; +using Content.Shared.Mind; using Robust.Shared.Console; using Robust.Shared.GameObjects; using Robust.Shared.Map; @@ -42,7 +42,7 @@ public sealed class GhostRoleTests var entMan = server.ResolveDependency(); var sPlayerMan = server.ResolveDependency(); var conHost = client.ResolveDependency(); - var mindSystem = entMan.System(); + var mindSystem = entMan.System(); var session = sPlayerMan.ServerSessions.Single(); var originalMindId = session.ContentData()!.Mind!.Value; diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs b/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs index 019d887842..9fc68ef93d 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.EntityDeletion.cs @@ -1,7 +1,7 @@ using System.Linq; -using Content.Server.Mind; using Content.Server.Players; using Content.Shared.Ghost; +using Content.Shared.Mind; using Robust.Server.Console; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -27,7 +27,7 @@ public sealed partial class MindTests var entMan = server.ResolveDependency(); var playerMan = server.ResolveDependency(); - var mindSystem = entMan.EntitySysManager.GetEntitySystem(); + var mindSystem = entMan.EntitySysManager.GetEntitySystem(); EntityUid playerEnt = default; EntityUid visitEnt = default; @@ -83,7 +83,7 @@ public sealed partial class MindTests var playerMan = server.ResolveDependency(); var player = playerMan.ServerSessions.Single(); - var mindSystem = entMan.EntitySysManager.GetEntitySystem(); + var mindSystem = entMan.EntitySysManager.GetEntitySystem(); EntityUid playerEnt = default; EntityUid mindId = default!; @@ -159,7 +159,7 @@ public sealed partial class MindTests var entMan = server.ResolveDependency(); var playerMan = server.ResolveDependency(); - var mindSystem = entMan.EntitySysManager.GetEntitySystem(); + var mindSystem = entMan.EntitySysManager.GetEntitySystem(); var mind = GetMind(pair); var player = playerMan.ServerSessions.Single(); diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs b/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs index 1eab9cd6c6..f71a6ad5f9 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.Helpers.cs @@ -1,8 +1,8 @@ using System.Linq; using Content.IntegrationTests.Pair; -using Content.Server.Mind; using Content.Server.Players; using Content.Shared.Ghost; +using Content.Shared.Mind; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Enums; @@ -34,7 +34,7 @@ public sealed partial class MindTests var entMan = pair.Server.ResolveDependency(); var playerMan = pair.Server.ResolveDependency(); - var mindSys = entMan.System(); + var mindSys = entMan.System(); var player = playerMan.ServerSessions.Single(); @@ -66,7 +66,7 @@ public sealed partial class MindTests { var entMan = pair.Server.ResolveDependency(); var playerMan = pair.Server.ResolveDependency(); - var mindSys = entMan.System(); + var mindSys = entMan.System(); EntityUid ghostUid = default; EntityUid mindId = default!; MindComponent mind = default!; diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs b/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs index 8d957bf197..ea2110c03a 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.ReconnectTests.cs @@ -1,6 +1,6 @@ using System.Linq; -using Content.Server.Mind; using Content.Shared.Ghost; +using Content.Shared.Mind; using Robust.Server.Player; using Robust.Shared.GameObjects; using Robust.Shared.Map; @@ -124,7 +124,7 @@ public sealed partial class MindTests { await using var pair = await SetupPair(); var entMan = pair.Server.ResolveDependency(); - var mindSys = entMan.System(); + var mindSys = entMan.System(); var mind = GetMind(pair); // Make player visit a new mob diff --git a/Content.IntegrationTests/Tests/Minds/MindTests.cs b/Content.IntegrationTests/Tests/Minds/MindTests.cs index 7928f4368f..fb2fef43ed 100644 --- a/Content.IntegrationTests/Tests/Minds/MindTests.cs +++ b/Content.IntegrationTests/Tests/Minds/MindTests.cs @@ -3,15 +3,16 @@ using System.Linq; using Content.Server.Ghost; using Content.Server.Ghost.Roles; using Content.Server.Ghost.Roles.Components; -using Content.Server.Mind; using Content.Server.Mind.Commands; -using Content.Server.Mind.Components; using Content.Server.Players; using Content.Server.Roles; -using Content.Server.Roles.Jobs; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; using Content.Shared.FixedPoint; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; +using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; using Robust.Server.Console; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -61,7 +62,7 @@ public sealed partial class MindTests await server.WaitAssertion(() => { - var mindSystem = entMan.EntitySysManager.GetEntitySystem(); + var mindSystem = entMan.EntitySysManager.GetEntitySystem(); var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); @@ -88,7 +89,7 @@ public sealed partial class MindTests await server.WaitAssertion(() => { - var mindSystem = entMan.EntitySysManager.GetEntitySystem(); + var mindSystem = entMan.EntitySysManager.GetEntitySystem(); var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); @@ -122,7 +123,7 @@ public sealed partial class MindTests EntityUid entity = default!; MindContainerComponent mindContainerComp = default!; EntityUid mindId = default!; - var mindSystem = entMan.EntitySysManager.GetEntitySystem(); + var mindSystem = entMan.EntitySysManager.GetEntitySystem(); var damageableSystem = entMan.EntitySysManager.GetEntitySystem(); await server.WaitAssertion(() => @@ -176,7 +177,7 @@ public sealed partial class MindTests await server.WaitAssertion(() => { - var mindSystem = entMan.EntitySysManager.GetEntitySystem(); + var mindSystem = entMan.EntitySysManager.GetEntitySystem(); var entity = entMan.SpawnEntity(null, new MapCoordinates()); var targetEntity = entMan.SpawnEntity(null, new MapCoordinates()); @@ -213,7 +214,7 @@ public sealed partial class MindTests var entMan = server.ResolveDependency(); await pair.RunTicksSync(5); - var mindSystem = entMan.EntitySysManager.GetEntitySystem(); + var mindSystem = entMan.EntitySysManager.GetEntitySystem(); var originalMind = GetMind(pair); var userId = originalMind.Comp.UserId; @@ -269,8 +270,8 @@ public sealed partial class MindTests await server.WaitAssertion(() => { - var mindSystem = entMan.EntitySysManager.GetEntitySystem(); - var roleSystem = entMan.EntitySysManager.GetEntitySystem(); + var mindSystem = entMan.EntitySysManager.GetEntitySystem(); + var roleSystem = entMan.EntitySysManager.GetEntitySystem(); var entity = entMan.SpawnEntity(null, new MapCoordinates()); var mindComp = entMan.EnsureComponent(entity); @@ -339,7 +340,7 @@ public sealed partial class MindTests var entMan = server.ResolveDependency(); var playerMan = server.ResolveDependency(); - var mindSystem = entMan.EntitySysManager.GetEntitySystem(); + var mindSystem = entMan.EntitySysManager.GetEntitySystem(); var ghostSystem = entMan.EntitySysManager.GetEntitySystem(); EntityUid entity = default!; diff --git a/Content.Server/Administration/Commands/AGhost.cs b/Content.Server/Administration/Commands/AGhost.cs index 21ae9f246a..a8217c5556 100644 --- a/Content.Server/Administration/Commands/AGhost.cs +++ b/Content.Server/Administration/Commands/AGhost.cs @@ -1,7 +1,7 @@ using Content.Server.GameTicking; -using Content.Server.Mind; using Content.Shared.Administration; using Content.Shared.Ghost; +using Content.Shared.Mind; using Robust.Server.Player; using Robust.Shared.Console; @@ -25,7 +25,7 @@ namespace Content.Server.Administration.Commands return; } - var mindSystem = _entities.System(); + var mindSystem = _entities.System(); if (!mindSystem.TryGetMind(player, out var mindId, out var mind)) { shell.WriteLine("You can't ghost here!"); diff --git a/Content.Server/Administration/Commands/ControlMob.cs b/Content.Server/Administration/Commands/ControlMob.cs index b0f7237429..2d205e44d3 100644 --- a/Content.Server/Administration/Commands/ControlMob.cs +++ b/Content.Server/Administration/Commands/ControlMob.cs @@ -1,5 +1,5 @@ -using Content.Server.Mind; using Content.Shared.Administration; +using Content.Shared.Mind; using Robust.Server.Player; using Robust.Shared.Console; @@ -42,7 +42,7 @@ namespace Content.Server.Administration.Commands return; } - var mindSystem = _entities.System(); + var mindSystem = _entities.System(); if (!mindSystem.TryGetMind(target, out var mindId, out var mind)) { shell.WriteLine(Loc.GetString("shell-entity-is-not-mob")); diff --git a/Content.Server/Administration/Commands/SetMindCommand.cs b/Content.Server/Administration/Commands/SetMindCommand.cs index 5fcb7ac8b2..b9ff329ed2 100644 --- a/Content.Server/Administration/Commands/SetMindCommand.cs +++ b/Content.Server/Administration/Commands/SetMindCommand.cs @@ -1,7 +1,7 @@ -using Content.Server.Mind; -using Content.Server.Mind.Components; using Content.Server.Players; using Content.Shared.Administration; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Robust.Server.Player; using Robust.Shared.Console; @@ -67,7 +67,7 @@ namespace Content.Server.Administration.Commands return; } - var mindSystem = entityManager.System(); + var mindSystem = entityManager.System(); var metadata = entityManager.GetComponent(eUid); var mind = playerCData.Mind ?? mindSystem.CreateMind(session.UserId, metadata.EntityName); diff --git a/Content.Server/Administration/Notes/AdminNotesManager.cs b/Content.Server/Administration/Notes/AdminNotesManager.cs index c83a103606..8a7846663f 100644 --- a/Content.Server/Administration/Notes/AdminNotesManager.cs +++ b/Content.Server/Administration/Notes/AdminNotesManager.cs @@ -9,10 +9,9 @@ using Content.Shared.Administration.Notes; using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.Players.PlayTimeTracking; -using Robust.Server.Player; -using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Network; +using Robust.Shared.Players; namespace Content.Server.Administration.Notes; @@ -33,27 +32,27 @@ public sealed class AdminNotesManager : IAdminNotesManager, IPostInjectInit private ISawmill _sawmill = default!; - public bool CanCreate(IPlayerSession admin) + public bool CanCreate(ICommonSession admin) { return CanEdit(admin); } - public bool CanDelete(IPlayerSession admin) + public bool CanDelete(ICommonSession admin) { return CanEdit(admin); } - public bool CanEdit(IPlayerSession admin) + public bool CanEdit(ICommonSession admin) { return _admins.HasAdminFlag(admin, AdminFlags.EditNotes); } - public bool CanView(IPlayerSession admin) + public bool CanView(ICommonSession admin) { return _admins.HasAdminFlag(admin, AdminFlags.ViewNotes); } - public async Task OpenEui(IPlayerSession admin, Guid notedPlayer) + public async Task OpenEui(ICommonSession admin, Guid notedPlayer) { var ui = new AdminNotesEui(); _euis.OpenEui(ui, admin); @@ -61,7 +60,7 @@ public sealed class AdminNotesManager : IAdminNotesManager, IPostInjectInit await ui.ChangeNotedPlayer(notedPlayer); } - public async Task OpenUserNotesEui(IPlayerSession player) + public async Task OpenUserNotesEui(ICommonSession player) { var ui = new UserNotesEui(); _euis.OpenEui(ui, player); @@ -69,7 +68,7 @@ public sealed class AdminNotesManager : IAdminNotesManager, IPostInjectInit await ui.UpdateNotes(); } - public async Task AddAdminRemark(IPlayerSession createdBy, Guid player, NoteType type, string message, NoteSeverity? severity, bool secret, DateTime? expiryTime) + public async Task AddAdminRemark(ICommonSession createdBy, Guid player, NoteType type, string message, NoteSeverity? severity, bool secret, DateTime? expiryTime) { message = message.Trim(); @@ -179,7 +178,7 @@ public sealed class AdminNotesManager : IAdminNotesManager, IPostInjectInit }; } - public async Task DeleteAdminRemark(int noteId, NoteType type, IPlayerSession deletedBy) + public async Task DeleteAdminRemark(int noteId, NoteType type, ICommonSession deletedBy) { var note = await GetAdminRemark(noteId, type); if (note == null) @@ -215,7 +214,7 @@ public sealed class AdminNotesManager : IAdminNotesManager, IPostInjectInit NoteDeleted?.Invoke(note); } - public async Task ModifyAdminRemark(int noteId, NoteType type, IPlayerSession editedBy, string message, NoteSeverity? severity, bool secret, DateTime? expiryTime) + public async Task ModifyAdminRemark(int noteId, NoteType type, ICommonSession editedBy, string message, NoteSeverity? severity, bool secret, DateTime? expiryTime) { message = message.Trim(); diff --git a/Content.Server/Administration/Notes/IAdminNotesManager.cs b/Content.Server/Administration/Notes/IAdminNotesManager.cs index b92f0c1148..ae7133c56d 100644 --- a/Content.Server/Administration/Notes/IAdminNotesManager.cs +++ b/Content.Server/Administration/Notes/IAdminNotesManager.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Content.Server.Database; using Content.Shared.Administration.Notes; using Content.Shared.Database; -using Robust.Server.Player; +using Robust.Shared.Players; namespace Content.Server.Administration.Notes; @@ -12,15 +12,15 @@ public interface IAdminNotesManager event Action? NoteModified; event Action? NoteDeleted; - bool CanCreate(IPlayerSession admin); - bool CanDelete(IPlayerSession admin); - bool CanEdit(IPlayerSession admin); - bool CanView(IPlayerSession admin); - Task OpenEui(IPlayerSession admin, Guid notedPlayer); - Task OpenUserNotesEui(IPlayerSession player); - Task AddAdminRemark(IPlayerSession createdBy, Guid player, NoteType type, string message, NoteSeverity? severity, bool secret, DateTime? expiryTime); - Task DeleteAdminRemark(int noteId, NoteType type, IPlayerSession deletedBy); - Task ModifyAdminRemark(int noteId, NoteType type, IPlayerSession editedBy, string message, NoteSeverity? severity, bool secret, DateTime? expiryTime); + bool CanCreate(ICommonSession admin); + bool CanDelete(ICommonSession admin); + bool CanEdit(ICommonSession admin); + bool CanView(ICommonSession admin); + Task OpenEui(ICommonSession admin, Guid notedPlayer); + Task OpenUserNotesEui(ICommonSession player); + Task AddAdminRemark(ICommonSession createdBy, Guid player, NoteType type, string message, NoteSeverity? severity, bool secret, DateTime? expiryTime); + Task DeleteAdminRemark(int noteId, NoteType type, ICommonSession deletedBy); + Task ModifyAdminRemark(int noteId, NoteType type, ICommonSession editedBy, string message, NoteSeverity? severity, bool secret, DateTime? expiryTime); /// /// Queries the database and retrieves all notes, secret and visible /// diff --git a/Content.Server/Administration/Systems/AdminSystem.cs b/Content.Server/Administration/Systems/AdminSystem.cs index eab4bba78e..03cf10206a 100644 --- a/Content.Server/Administration/Systems/AdminSystem.cs +++ b/Content.Server/Administration/Systems/AdminSystem.cs @@ -2,16 +2,17 @@ using System.Linq; using Content.Server.Administration.Managers; using Content.Server.IdentityManagement; using Content.Server.Mind; -using Content.Server.Roles; -using Content.Server.Roles.Jobs; using Content.Shared.Administration; using Content.Shared.Administration.Events; using Content.Shared.GameTicking; using Content.Shared.IdentityManagement; +using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Network; +using Robust.Shared.Player; namespace Content.Server.Administration.Systems { @@ -19,9 +20,9 @@ namespace Content.Server.Administration.Systems { [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IAdminManager _adminManager = default!; - [Dependency] private readonly JobSystem _jobs = default!; + [Dependency] private readonly SharedJobSystem _jobs = default!; [Dependency] private readonly MindSystem _minds = default!; - [Dependency] private readonly RoleSystem _role = default!; + [Dependency] private readonly SharedRoleSystem _role = default!; private readonly Dictionary _playerList = new(); @@ -104,10 +105,11 @@ namespace Content.Server.Administration.Systems private void OnRoleEvent(RoleEvent ev) { - if (!ev.Antagonist || ev.Mind.Session == null) + var session = _minds.GetSession(ev.Mind); + if (!ev.Antagonist || session == null) return; - UpdatePlayerList(ev.Mind.Session); + UpdatePlayerList(session); } private void OnAdminPermsChanged(AdminPermsChangedEventArgs obj) diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Antags.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Antags.cs index a1e1c7a45d..6aebd60e2e 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Antags.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Antags.cs @@ -1,9 +1,9 @@ using Content.Server.GameTicking.Rules; -using Content.Server.Mind; -using Content.Server.Mind.Components; using Content.Server.Zombies; using Content.Shared.Administration; using Content.Shared.Database; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Verbs; using Robust.Server.GameObjects; using Robust.Shared.Utility; @@ -16,7 +16,7 @@ public sealed partial class AdminVerbSystem [Dependency] private readonly TraitorRuleSystem _traitorRule = default!; [Dependency] private readonly NukeopsRuleSystem _nukeopsRule = default!; [Dependency] private readonly PiratesRuleSystem _piratesRule = default!; - [Dependency] private readonly MindSystem _minds = default!; + [Dependency] private readonly SharedMindSystem _minds = default!; // All antag verbs have names so invokeverb works. private void AddAntagVerbs(GetVerbsEvent args) diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.cs b/Content.Server/Administration/Systems/AdminVerbSystem.cs index 5667f990c2..8b792b0892 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.cs @@ -8,9 +8,7 @@ using Content.Server.Disposal.Tube; using Content.Server.Disposal.Tube.Components; using Content.Server.EUI; using Content.Server.Ghost.Roles; -using Content.Server.Mind; using Content.Server.Mind.Commands; -using Content.Server.Mind.Components; using Content.Server.Prayer; using Content.Server.Xenoarchaeology.XenoArtifacts; using Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components; @@ -20,6 +18,8 @@ using Content.Shared.Database; using Content.Shared.GameTicking; using Content.Shared.Interaction.Helpers; using Content.Shared.Inventory; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Server.Console; @@ -28,6 +28,7 @@ using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.Shared.Toolshed; @@ -54,11 +55,11 @@ namespace Content.Server.Administration.Systems [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly PrayerSystem _prayerSystem = default!; [Dependency] private readonly EuiManager _eui = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; [Dependency] private readonly ToolshedManager _toolshed = default!; [Dependency] private readonly RejuvenateSystem _rejuvenate = default!; - private readonly Dictionary _openSolutionUis = new(); + private readonly Dictionary _openSolutionUis = new(); public override void Initialize() { @@ -425,7 +426,7 @@ namespace Content.Server.Administration.Systems eui.StateDirty(); } - public void OnEditSolutionsEuiClosed(IPlayerSession session) + public void OnEditSolutionsEuiClosed(ICommonSession session) { _openSolutionUis.Remove(session, out var eui); } diff --git a/Content.Server/Administration/Systems/BwoinkSystem.cs b/Content.Server/Administration/Systems/BwoinkSystem.cs index c970ea2096..98e5af1126 100644 --- a/Content.Server/Administration/Systems/BwoinkSystem.cs +++ b/Content.Server/Administration/Systems/BwoinkSystem.cs @@ -8,9 +8,9 @@ using System.Threading.Tasks; using Content.Server.Administration.Managers; using Content.Server.Discord; using Content.Server.GameTicking; -using Content.Server.Mind; using Content.Shared.Administration; using Content.Shared.CCVar; +using Content.Shared.Mind; using JetBrains.Annotations; using Robust.Server.Player; using Robust.Shared; @@ -31,7 +31,7 @@ namespace Content.Server.Administration.Systems [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IPlayerLocator _playerLocator = default!; [Dependency] private readonly GameTicker _gameTicker = default!; - [Dependency] private readonly MindSystem _minds = default!; + [Dependency] private readonly SharedMindSystem _minds = default!; private ISawmill _sawmill = default!; private readonly HttpClient _httpClient = new(); diff --git a/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs b/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs index a76e56c604..b1ea16be7f 100644 --- a/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs +++ b/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs @@ -3,7 +3,6 @@ using System.Linq; using Content.Server.Administration.Logs; using Content.Server.Ame.Components; using Content.Server.Chat.Managers; -using Content.Server.Mind.Components; using Content.Server.NodeContainer; using Content.Server.Power.Components; using Content.Shared.Ame; @@ -11,6 +10,7 @@ using Content.Shared.Database; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; +using Content.Shared.Mind.Components; using Content.Shared.Popups; using Robust.Server.Containers; using Robust.Server.GameObjects; diff --git a/Content.Server/Body/Systems/BodySystem.cs b/Content.Server/Body/Systems/BodySystem.cs index b51dfd46b7..471daea79a 100644 --- a/Content.Server/Body/Systems/BodySystem.cs +++ b/Content.Server/Body/Systems/BodySystem.cs @@ -4,12 +4,12 @@ using Content.Server.Body.Components; using Content.Server.GameTicking; using Content.Server.Humanoid; using Content.Server.Kitchen.Components; -using Content.Server.Mind; using Content.Shared.Body.Components; using Content.Shared.Body.Organ; using Content.Shared.Body.Part; using Content.Shared.Body.Systems; using Content.Shared.Humanoid; +using Content.Shared.Mind; using Content.Shared.Mobs.Systems; using Content.Shared.Movement.Events; using Content.Shared.Random.Helpers; @@ -28,7 +28,7 @@ public sealed class BodySystem : SharedBodySystem [Dependency] private readonly HumanoidAppearanceSystem _humanoidSystem = default!; [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; public override void Initialize() diff --git a/Content.Server/Body/Systems/BrainSystem.cs b/Content.Server/Body/Systems/BrainSystem.cs index 5598226142..9b5da508dd 100644 --- a/Content.Server/Body/Systems/BrainSystem.cs +++ b/Content.Server/Body/Systems/BrainSystem.cs @@ -1,10 +1,10 @@ using Content.Server.Body.Components; using Content.Server.Ghost.Components; -using Content.Server.Mind; -using Content.Server.Mind.Components; using Content.Shared.Body.Components; using Content.Shared.Body.Events; using Content.Shared.Body.Organ; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; @@ -13,7 +13,7 @@ namespace Content.Server.Body.Systems public sealed class BrainSystem : EntitySystem { [Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; public override void Initialize() { diff --git a/Content.Server/Chat/Commands/SuicideCommand.cs b/Content.Server/Chat/Commands/SuicideCommand.cs index df3cd67f63..389ff039bf 100644 --- a/Content.Server/Chat/Commands/SuicideCommand.cs +++ b/Content.Server/Chat/Commands/SuicideCommand.cs @@ -1,6 +1,6 @@ using Content.Server.GameTicking; -using Content.Server.Mind; using Content.Shared.Administration; +using Content.Shared.Mind; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; @@ -27,7 +27,7 @@ namespace Content.Server.Chat.Commands if (player.Status != SessionStatus.InGame || player.AttachedEntity == null) return; - var minds = IoCManager.Resolve().System(); + var minds = IoCManager.Resolve().System(); // This check also proves mind not-null for at the end when the mob is ghosted. if (!minds.TryGetMind(player, out var mindId, out var mind) || mind.OwnedEntity is not { Valid: true } victim) diff --git a/Content.Server/Chat/Managers/ChatManager.cs b/Content.Server/Chat/Managers/ChatManager.cs index b92771c369..cecd08a7c6 100644 --- a/Content.Server/Chat/Managers/ChatManager.cs +++ b/Content.Server/Chat/Managers/ChatManager.cs @@ -2,17 +2,18 @@ using System.Linq; using Content.Server.Administration.Logs; using Content.Server.Administration.Managers; using Content.Server.Administration.Systems; -using Content.Server.Mind; using Content.Server.MoMMI; using Content.Server.Preferences.Managers; using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.Chat; using Content.Shared.Database; +using Content.Shared.Mind; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; using Robust.Shared.Player; +using Robust.Shared.Players; using Robust.Shared.Replays; using Robust.Shared.Utility; @@ -84,7 +85,7 @@ namespace Content.Server.Chat.Managers _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Server announcement: {message}"); } - public void DispatchServerMessage(IPlayerSession player, string message, bool suppressLog = false) + public void DispatchServerMessage(ICommonSession player, string message, bool suppressLog = false) { var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", FormattedMessage.EscapeText(message))); ChatMessageToOne(ChatChannel.Server, message, wrappedMessage, default, false, player.ConnectedClient); @@ -116,7 +117,7 @@ namespace Content.Server.Chat.Managers public void SendAdminAlert(EntityUid player, string message) { - var mindSystem = _entityManager.System(); + var mindSystem = _entityManager.System(); if (!mindSystem.TryGetMind(player, out var mindId, out var mind)) { SendAdminAlert(message); diff --git a/Content.Server/Chat/Managers/IChatManager.cs b/Content.Server/Chat/Managers/IChatManager.cs index 6d81848f7e..a398be74fd 100644 --- a/Content.Server/Chat/Managers/IChatManager.cs +++ b/Content.Server/Chat/Managers/IChatManager.cs @@ -2,6 +2,7 @@ using Content.Shared.Chat; using Robust.Server.Player; using Robust.Shared.Network; using Robust.Shared.Player; +using Robust.Shared.Players; namespace Content.Server.Chat.Managers { @@ -16,7 +17,7 @@ namespace Content.Server.Chat.Managers /// Override the color of the message being sent. void DispatchServerAnnouncement(string message, Color? colorOverride = null); - void DispatchServerMessage(IPlayerSession player, string message, bool suppressLog = false); + void DispatchServerMessage(ICommonSession player, string message, bool suppressLog = false); void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type); diff --git a/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs b/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs index 242e7aa760..2e5529fbd2 100644 --- a/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs +++ b/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs @@ -1,8 +1,7 @@ using Content.Server.Ghost.Roles.Components; -using Content.Server.Mind.Components; using Content.Server.Speech.Components; using Content.Shared.Chemistry.Reagent; -using Content.Server.Ghost.Roles.Components; +using Content.Shared.Mind.Components; using Robust.Shared.Prototypes; namespace Content.Server.Chemistry.ReagentEffects; diff --git a/Content.Server/Chemistry/ReagentEffects/Polymorph.cs b/Content.Server/Chemistry/ReagentEffects/Polymorph.cs index bf7d8b7099..569da51e39 100644 --- a/Content.Server/Chemistry/ReagentEffects/Polymorph.cs +++ b/Content.Server/Chemistry/ReagentEffects/Polymorph.cs @@ -1,8 +1,6 @@ -using Content.Server.Mind.Components; using Content.Server.Polymorph.Components; using Content.Server.Polymorph.Systems; using Content.Shared.Chemistry.Reagent; -using Content.Shared.Item; using Content.Shared.Polymorph; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; diff --git a/Content.Server/Cloning/AcceptCloningEui.cs b/Content.Server/Cloning/AcceptCloningEui.cs index e1b463aaee..3d4356f8ca 100644 --- a/Content.Server/Cloning/AcceptCloningEui.cs +++ b/Content.Server/Cloning/AcceptCloningEui.cs @@ -1,7 +1,7 @@ using Content.Server.EUI; -using Content.Server.Mind; using Content.Shared.Cloning; using Content.Shared.Eui; +using Content.Shared.Mind; namespace Content.Server.Cloning { diff --git a/Content.Server/Cloning/CloningConsoleSystem.cs b/Content.Server/Cloning/CloningConsoleSystem.cs index 665d1ac70e..aea0532bfc 100644 --- a/Content.Server/Cloning/CloningConsoleSystem.cs +++ b/Content.Server/Cloning/CloningConsoleSystem.cs @@ -3,7 +3,6 @@ using Content.Server.Administration.Logs; using Content.Server.Cloning.Components; using Content.Server.DeviceLinking.Systems; using Content.Server.Medical.Components; -using Content.Server.Mind; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Server.UserInterface; @@ -13,6 +12,7 @@ using Content.Shared.Database; using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking.Events; using Content.Shared.IdentityManagement; +using Content.Shared.Mind; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using JetBrains.Annotations; @@ -31,7 +31,7 @@ namespace Content.Server.Cloning [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly MobStateSystem _mobStateSystem = default!; [Dependency] private readonly PowerReceiverSystem _powerReceiverSystem = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; public override void Initialize() { diff --git a/Content.Server/Cloning/CloningSystem.cs b/Content.Server/Cloning/CloningSystem.cs index 1eb9f01ced..e94f0d1183 100644 --- a/Content.Server/Cloning/CloningSystem.cs +++ b/Content.Server/Cloning/CloningSystem.cs @@ -8,11 +8,8 @@ using Content.Server.Fluids.EntitySystems; using Content.Server.Humanoid; using Content.Server.Jobs; using Content.Server.Materials; -using Content.Server.Mind; -using Content.Server.Mind.Components; using Content.Server.Popups; using Content.Server.Power.EntitySystems; -using Content.Server.Roles.Jobs; using Content.Server.Traits.Assorted; using Content.Shared.Atmos; using Content.Shared.CCVar; @@ -26,7 +23,10 @@ using Content.Shared.Examine; using Content.Shared.GameTicking; using Content.Shared.Humanoid; using Content.Shared.Humanoid.Prototypes; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Mobs.Systems; +using Content.Shared.Roles.Jobs; using Robust.Server.Containers; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -59,9 +59,9 @@ namespace Content.Server.Cloning [Dependency] private readonly IConfigurationManager _configManager = default!; [Dependency] private readonly MaterialStorageSystem _material = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; [Dependency] private readonly MetaDataSystem _metaSystem = default!; - [Dependency] private readonly JobSystem _jobs = default!; + [Dependency] private readonly SharedJobSystem _jobs = default!; public readonly Dictionary ClonesWaitingForMind = new(); public const float EasyModeCloningCost = 0.7f; diff --git a/Content.Server/Cloning/Components/BeingClonedComponent.cs b/Content.Server/Cloning/Components/BeingClonedComponent.cs index c3a4f80002..769f8b4d12 100644 --- a/Content.Server/Cloning/Components/BeingClonedComponent.cs +++ b/Content.Server/Cloning/Components/BeingClonedComponent.cs @@ -1,4 +1,4 @@ -using Content.Server.Mind; +using Content.Shared.Mind; namespace Content.Server.Cloning.Components { diff --git a/Content.Server/Content.Server.csproj b/Content.Server/Content.Server.csproj index fa3ee60eb9..a2ccc769c9 100644 --- a/Content.Server/Content.Server.csproj +++ b/Content.Server/Content.Server.csproj @@ -25,5 +25,8 @@ + + + diff --git a/Content.Server/CrewManifest/CrewManifestSystem.cs b/Content.Server/CrewManifest/CrewManifestSystem.cs index 7fffc33627..23cd9c88ea 100644 --- a/Content.Server/CrewManifest/CrewManifestSystem.cs +++ b/Content.Server/CrewManifest/CrewManifestSystem.cs @@ -13,6 +13,7 @@ using Content.Shared.StationRecords; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Console; +using Robust.Shared.Players; namespace Content.Server.CrewManifest; @@ -30,7 +31,7 @@ public sealed class CrewManifestSystem : EntitySystem /// private readonly Dictionary _cachedEntries = new(); - private readonly Dictionary> _openEuis = new(); + private readonly Dictionary> _openEuis = new(); public override void Initialize() { @@ -168,7 +169,7 @@ public sealed class CrewManifestSystem : EntitySystem /// Station that we're displaying the crew manifest for. /// The player's session. /// The owner of this EUI, if there was one. - public void CloseEui(EntityUid station, IPlayerSession session, EntityUid? owner = null) + public void CloseEui(EntityUid station, ICommonSession session, EntityUid? owner = null) { if (!HasComp(station)) { diff --git a/Content.Server/Drone/DroneSystem.cs b/Content.Server/Drone/DroneSystem.cs index 4cf047c95c..7e1199bb4d 100644 --- a/Content.Server/Drone/DroneSystem.cs +++ b/Content.Server/Drone/DroneSystem.cs @@ -1,7 +1,6 @@ using Content.Server.Body.Systems; using Content.Server.Drone.Components; using Content.Server.Ghost.Roles.Components; -using Content.Server.Mind.Components; using Content.Server.Popups; using Content.Server.Tools.Innate; using Content.Server.UserInterface; @@ -14,14 +13,13 @@ using Content.Shared.IdentityManagement; using Content.Shared.Interaction.Components; using Content.Shared.Interaction.Events; using Content.Shared.Item; +using Content.Shared.Mind.Components; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Popups; using Content.Shared.Tag; using Content.Shared.Throwing; -using Robust.Server.GameObjects; -using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Drone diff --git a/Content.Server/EUI/BaseEui.cs b/Content.Server/EUI/BaseEui.cs index b569f9e87c..4a41ad40a5 100644 --- a/Content.Server/EUI/BaseEui.cs +++ b/Content.Server/EUI/BaseEui.cs @@ -1,7 +1,6 @@ using Content.Shared.Eui; -using Robust.Server.Player; using Robust.Shared.Network; - +using Robust.Shared.Players; namespace Content.Server.EUI { @@ -23,7 +22,7 @@ namespace Content.Server.EUI /// /// The player that this EUI is open for. /// - public IPlayerSession Player { get; private set; } = default!; + public ICommonSession Player { get; private set; } = default!; public bool IsShutDown { get; private set; } public EuiManager Manager { get; private set; } = default!; public uint Id { get; private set; } @@ -118,7 +117,7 @@ namespace Content.Server.EUI netMgr.ServerSendMessage(msg, Player.ConnectedClient); } - internal void Initialize(EuiManager manager, IPlayerSession player, uint id) + internal void Initialize(EuiManager manager, ICommonSession player, uint id) { Manager = manager; Player = player; diff --git a/Content.Server/EUI/EuiManager.cs b/Content.Server/EUI/EuiManager.cs index ab4b8bd18b..4d99719525 100644 --- a/Content.Server/EUI/EuiManager.cs +++ b/Content.Server/EUI/EuiManager.cs @@ -2,9 +2,9 @@ using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Network; +using Robust.Shared.Players; using Robust.Shared.Utility; - namespace Content.Server.EUI { public sealed class EuiManager : IPostInjectInit @@ -12,11 +12,11 @@ namespace Content.Server.EUI [Dependency] private readonly IPlayerManager _players = default!; [Dependency] private readonly IServerNetManager _net = default!; - private readonly Dictionary _playerData = + private readonly Dictionary _playerData = new(); - private readonly Queue<(IPlayerSession player, uint id)> _stateUpdateQueue = - new Queue<(IPlayerSession, uint id)>(); + private readonly Queue<(ICommonSession player, uint id)> _stateUpdateQueue = + new Queue<(ICommonSession, uint id)>(); private sealed class PlayerEuiData { @@ -53,7 +53,7 @@ namespace Content.Server.EUI } } - public void OpenEui(BaseEui eui, IPlayerSession player) + public void OpenEui(BaseEui eui, ICommonSession player) { if (eui.Id != 0) { diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs index 8e9cb6651f..e9efe639f2 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs @@ -1,13 +1,12 @@ using System.Linq; using System.Numerics; using Content.Server.Explosion.Components; -using Content.Server.Mind.Components; using Content.Shared.CCVar; using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.Explosion; -using Content.Shared.FixedPoint; using Content.Shared.Maps; +using Content.Shared.Mind.Components; using Content.Shared.Physics; using Content.Shared.Projectiles; using Content.Shared.Spawners.Components; diff --git a/Content.Server/GameTicking/Commands/RespawnCommand.cs b/Content.Server/GameTicking/Commands/RespawnCommand.cs index 9c887dbf17..057572297f 100644 --- a/Content.Server/GameTicking/Commands/RespawnCommand.cs +++ b/Content.Server/GameTicking/Commands/RespawnCommand.cs @@ -1,5 +1,5 @@ -using Content.Server.Mind; -using Content.Server.Players; +using Content.Shared.Mind; +using Content.Shared.Players; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Network; @@ -24,7 +24,7 @@ namespace Content.Server.GameTicking.Commands var playerMgr = IoCManager.Resolve(); var sysMan = IoCManager.Resolve(); var ticker = sysMan.GetEntitySystem(); - var mind = sysMan.GetEntitySystem(); + var mind = sysMan.GetEntitySystem(); NetUserId userId; if (args.Length == 0) diff --git a/Content.Server/GameTicking/GameTicker.GamePreset.cs b/Content.Server/GameTicking/GameTicker.GamePreset.cs index 8ce1003b02..a5e6d7a605 100644 --- a/Content.Server/GameTicking/GameTicker.GamePreset.cs +++ b/Content.Server/GameTicking/GameTicker.GamePreset.cs @@ -3,12 +3,12 @@ using System.Linq; using System.Threading.Tasks; using Content.Server.GameTicking.Presets; using Content.Server.Maps; -using Content.Server.Mind; using Content.Shared.CCVar; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; using Content.Shared.Database; using Content.Shared.Ghost; +using Content.Shared.Mind; using Content.Shared.Mobs.Components; using JetBrains.Annotations; using Robust.Server.Player; @@ -214,7 +214,7 @@ namespace Content.Server.GameTicking { if (mind.Session != null) // Logging is suppressed to prevent spam from ghost attempts caused by movement attempts { - _chatManager.DispatchServerMessage(mind.Session, Loc.GetString("comp-mind-ghosting-prevented"), + _chatManager.DispatchServerMessage((IPlayerSession) mind.Session, Loc.GetString("comp-mind-ghosting-prevented"), true); } diff --git a/Content.Server/GameTicking/GameTicker.Player.cs b/Content.Server/GameTicking/GameTicker.Player.cs index 837410db42..f6402589b2 100644 --- a/Content.Server/GameTicking/GameTicker.Player.cs +++ b/Content.Server/GameTicking/GameTicker.Player.cs @@ -2,6 +2,7 @@ using Content.Server.Database; using Content.Server.Players; using Content.Shared.GameTicking; using Content.Shared.GameWindow; +using Content.Shared.Players; using Content.Shared.Preferences; using JetBrains.Annotations; using Robust.Server.Player; diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index 83df72d2a0..7643a28961 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -4,10 +4,10 @@ using Content.Server.Discord; using Content.Server.GameTicking.Events; using Content.Server.Ghost; using Content.Server.Maps; -using Content.Server.Mind; -using Content.Server.Players; using Content.Shared.Database; using Content.Shared.GameTicking; +using Content.Shared.Mind; +using Content.Shared.Players; using Content.Shared.Preferences; using JetBrains.Annotations; using Prometheus; diff --git a/Content.Server/GameTicking/GameTicker.Spawning.cs b/Content.Server/GameTicking/GameTicker.Spawning.cs index db4d12ada9..7fe11fad0f 100644 --- a/Content.Server/GameTicking/GameTicker.Spawning.cs +++ b/Content.Server/GameTicking/GameTicker.Spawning.cs @@ -4,7 +4,6 @@ using System.Numerics; using Content.Server.Administration.Managers; using Content.Server.Ghost; using Content.Server.Players; -using Content.Server.Roles.Jobs; using Content.Server.Spawners.Components; using Content.Server.Speech.Components; using Content.Server.Station.Components; @@ -12,6 +11,7 @@ using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.Preferences; using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; using JetBrains.Annotations; using Robust.Server.Player; using Robust.Shared.Map; @@ -25,7 +25,7 @@ namespace Content.Server.GameTicking public sealed partial class GameTicker { [Dependency] private readonly IAdminManager _adminManager = default!; - [Dependency] private readonly JobSystem _jobs = default!; + [Dependency] private readonly SharedJobSystem _jobs = default!; [ValidatePrototypeId] private const string ObserverPrototypeName = "MobObserver"; diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index 88e1427572..14819fb0ac 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -5,16 +5,15 @@ using Content.Server.Chat.Systems; using Content.Server.Database; using Content.Server.Ghost; using Content.Server.Maps; -using Content.Server.Mind; using Content.Server.Players.PlayTimeTracking; using Content.Server.Preferences.Managers; -using Content.Server.Roles; using Content.Server.ServerUpdates; using Content.Server.Shuttles.Systems; using Content.Server.Station.Systems; using Content.Shared.Chat; using Content.Shared.Damage; using Content.Shared.GameTicking; +using Content.Shared.Mind; using Content.Shared.Mobs.Systems; using Content.Shared.Roles; using Robust.Server; @@ -57,7 +56,7 @@ namespace Content.Server.GameTicking [Dependency] private readonly DamageableSystem _damageable = default!; [Dependency] private readonly MapLoaderSystem _map = default!; [Dependency] private readonly GhostSystem _ghost = default!; - [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly PlayTimeTrackingSystem _playTimeTrackings = default!; [Dependency] private readonly PvsOverrideSystem _pvsOverride = default!; @@ -67,7 +66,7 @@ namespace Content.Server.GameTicking [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly UserDbDataManager _userDb = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; - [Dependency] private readonly RoleSystem _roles = default!; + [Dependency] private readonly SharedRoleSystem _roles = default!; [ViewVariables] private bool _initialized; [ViewVariables] private bool _postInitialized; diff --git a/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs index 33f4663988..8795bf1950 100644 --- a/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs @@ -2,8 +2,8 @@ using Content.Server.NPC.Components; using Content.Server.StationEvents.Events; using Content.Shared.Dataset; using Content.Shared.Roles; -using Robust.Server.Player; using Robust.Shared.Map; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; @@ -158,7 +158,7 @@ public sealed partial class NukeopsRuleComponent : Component /// /// todo: don't store sessions, dingus [DataField("operativePlayers")] - public Dictionary OperativePlayers = new(); + public Dictionary OperativePlayers = new(); [DataField("faction", customTypeSerializer: typeof(PrototypeIdSerializer), required: true)] public string Faction = default!; diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index ab23fb07fc..20d0871448 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -10,7 +10,6 @@ using Content.Server.Ghost.Roles.Components; using Content.Server.Ghost.Roles.Events; using Content.Server.Humanoid; using Content.Server.Mind; -using Content.Server.Mind.Components; using Content.Server.NPC.Components; using Content.Server.NPC.Systems; using Content.Server.Nuke; @@ -30,6 +29,8 @@ using Content.Server.Store.Systems; using Content.Shared.Dataset; using Content.Shared.Humanoid; using Content.Shared.Humanoid.Prototypes; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Nuke; @@ -69,7 +70,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem [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 SharedRoleSystem _roles = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly ChatSystem _chatSystem = default!; diff --git a/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs b/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs index 0410e0ff57..b223161c10 100644 --- a/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/PiratesRuleSystem.cs @@ -4,13 +4,13 @@ using Content.Server.Administration.Commands; using Content.Server.Cargo.Systems; using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; -using Content.Server.Mind; using Content.Server.Preferences.Managers; using Content.Server.Spawners.Components; using Content.Server.Station.Components; using Content.Server.Station.Systems; using Content.Shared.CCVar; using Content.Shared.Humanoid; +using Content.Shared.Mind; using Content.Shared.Preferences; using Content.Shared.Roles; using Robust.Server.GameObjects; @@ -40,7 +40,7 @@ public sealed class PiratesRuleSystem : GameRuleSystem [Dependency] private readonly PricingSystem _pricingSystem = default!; [Dependency] private readonly MapLoaderSystem _map = default!; [Dependency] private readonly NamingSystem _namingSystem = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; diff --git a/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs b/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs index 5f36dcd7d1..7c54bcddfa 100644 --- a/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RespawnRuleSystem.cs @@ -1,12 +1,10 @@ using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; -using Content.Server.Mind; -using Content.Server.Mind.Components; -using Content.Server.Mind.Toolshed; using Content.Server.Players; using Content.Server.Station.Systems; using Content.Shared.Chat; using Content.Shared.Interaction.Events; +using Content.Shared.Mind; using Content.Shared.Mobs; using Robust.Server.GameObjects; using Robust.Server.Player; diff --git a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs index 9446e2ad8c..81a4fad7c5 100644 --- a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs @@ -6,17 +6,19 @@ using Content.Server.NPC.Systems; using Content.Server.Objectives; using Content.Server.PDA.Ringer; 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.Mind; using Content.Shared.Mobs.Systems; using Content.Shared.PDA; using Content.Shared.Preferences; using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; using Robust.Server.Player; using Robust.Shared.Configuration; +using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -30,14 +32,13 @@ public sealed class TraitorRuleSystem : GameRuleSystem [Dependency] private readonly IConfigurationManager _cfg = 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!; - [Dependency] private readonly RoleSystem _roleSystem = default!; - [Dependency] private readonly JobSystem _jobs = default!; + [Dependency] private readonly SharedRoleSystem _roleSystem = default!; + [Dependency] private readonly SharedJobSystem _jobs = default!; [Dependency] private readonly ObjectivesSystem _objectives = default!; private int PlayersPerTraitor => _cfg.GetCVar(CCVars.TraitorPlayersPerTraitor); @@ -202,7 +203,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem return results; } - public bool MakeTraitor(IPlayerSession traitor) + public bool MakeTraitor(ICommonSession traitor) { var traitorRule = EntityQuery().FirstOrDefault(); if (traitorRule == null) diff --git a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs index f281f14d54..164c5148a2 100644 --- a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs @@ -4,7 +4,6 @@ using Content.Server.Actions; using Content.Server.Chat.Managers; using Content.Server.Chat.Systems; using Content.Server.GameTicking.Rules.Components; -using Content.Server.Mind; using Content.Server.Popups; using Content.Server.Preferences.Managers; using Content.Server.Roles; @@ -15,10 +14,12 @@ using Content.Server.Zombies; using Content.Shared.Actions.ActionTypes; using Content.Shared.CCVar; using Content.Shared.Humanoid; +using Content.Shared.Mind; 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; @@ -44,8 +45,8 @@ public sealed class ZombieRuleSystem : GameRuleSystem [Dependency] private readonly ActionsSystem _action = default!; [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 SharedMindSystem _mindSystem = default!; + [Dependency] private readonly SharedRoleSystem _roles = default!; [Dependency] private readonly StationSystem _station = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; diff --git a/Content.Server/Ghost/Ghost.cs b/Content.Server/Ghost/Ghost.cs index 9204b107dd..0462d1bc94 100644 --- a/Content.Server/Ghost/Ghost.cs +++ b/Content.Server/Ghost/Ghost.cs @@ -1,6 +1,6 @@ using Content.Server.GameTicking; -using Content.Server.Mind; using Content.Shared.Administration; +using Content.Shared.Mind; using Robust.Server.Player; using Robust.Shared.Console; @@ -24,7 +24,7 @@ namespace Content.Server.Ghost return; } - var minds = _entities.System(); + var minds = _entities.System(); if (!minds.TryGetMind(player, out var mindId, out var mind)) { shell.WriteLine("You have no Mind, you can't ghost."); diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index 0ee7592608..657b6848f3 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -2,9 +2,6 @@ using System.Linq; using System.Numerics; using Content.Server.GameTicking; using Content.Server.Ghost.Components; -using Content.Server.Mind; -using Content.Server.Mind.Components; -using Content.Server.Roles.Jobs; using Content.Server.Visible; using Content.Server.Warps; using Content.Shared.Actions; @@ -12,9 +9,12 @@ using Content.Shared.Administration; using Content.Shared.Examine; using Content.Shared.Follower; using Content.Shared.Ghost; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Movement.Events; +using Content.Shared.Roles.Jobs; using Content.Shared.Storage.Components; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -30,15 +30,15 @@ namespace Content.Server.Ghost [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly GameTicker _ticker = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly VisibilitySystem _visibilitySystem = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly FollowerSystem _followerSystem = default!; [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; - [Dependency] private readonly MindSystem _minds = default!; - [Dependency] private readonly JobSystem _jobs = default!; + [Dependency] private readonly SharedMindSystem _minds = default!; + [Dependency] private readonly SharedJobSystem _jobs = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; public override void Initialize() diff --git a/Content.Server/Ghost/ReturnToBodyEui.cs b/Content.Server/Ghost/ReturnToBodyEui.cs index 164d65f0f1..77b143f7df 100644 --- a/Content.Server/Ghost/ReturnToBodyEui.cs +++ b/Content.Server/Ghost/ReturnToBodyEui.cs @@ -1,17 +1,17 @@ using Content.Server.EUI; -using Content.Server.Mind; using Content.Shared.Eui; using Content.Shared.Ghost; +using Content.Shared.Mind; namespace Content.Server.Ghost; public sealed class ReturnToBodyEui : BaseEui { - private readonly MindSystem _mindSystem; + private readonly SharedMindSystem _mindSystem; private readonly MindComponent _mind; - public ReturnToBodyEui(MindComponent mind, MindSystem mindSystem) + public ReturnToBodyEui(MindComponent mind, SharedMindSystem mindSystem) { _mind = mind; _mindSystem = mindSystem; diff --git a/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs b/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs index a76ea95579..c97e3be9dc 100644 --- a/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs +++ b/Content.Server/Ghost/Roles/Components/TakeGhostRoleEvent.cs @@ -1,9 +1,9 @@ -using Robust.Server.Player; +using Robust.Shared.Players; namespace Content.Server.Ghost.Roles.Components; [ByRefEvent] -public record struct TakeGhostRoleEvent(IPlayerSession Player) +public record struct TakeGhostRoleEvent(ICommonSession Player) { public bool TookRole { get; set; } } diff --git a/Content.Server/Ghost/Roles/GhostRoleSystem.cs b/Content.Server/Ghost/Roles/GhostRoleSystem.cs index 361c99dda2..90bcc1a584 100644 --- a/Content.Server/Ghost/Roles/GhostRoleSystem.cs +++ b/Content.Server/Ghost/Roles/GhostRoleSystem.cs @@ -3,23 +3,24 @@ using Content.Server.EUI; using Content.Server.Ghost.Roles.Components; using Content.Server.Ghost.Roles.Events; using Content.Server.Ghost.Roles.UI; -using Content.Server.Mind; using Content.Server.Mind.Commands; -using Content.Server.Mind.Components; using Content.Server.Players; -using Content.Server.Roles; using Content.Shared.Administration; using Content.Shared.Database; using Content.Shared.Follower; using Content.Shared.GameTicking; using Content.Shared.Ghost; using Content.Shared.Ghost.Roles; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Mobs; +using Content.Shared.Roles; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; +using Robust.Shared.Players; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -34,14 +35,14 @@ namespace Content.Server.Ghost.Roles [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly FollowerSystem _followerSystem = default!; [Dependency] private readonly TransformSystem _transform = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; - [Dependency] private readonly RoleSystem _roleSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; + [Dependency] private readonly SharedRoleSystem _roleSystem = default!; private uint _nextRoleIdentifier; private bool _needsUpdateGhostRoleCount = true; private readonly Dictionary _ghostRoles = new(); - private readonly Dictionary _openUis = new(); - private readonly Dictionary _openMakeGhostRoleUis = new(); + private readonly Dictionary _openUis = new(); + private readonly Dictionary _openMakeGhostRoleUis = new(); [ViewVariables] public IReadOnlyCollection GhostRoles => _ghostRoles.Values; @@ -123,7 +124,7 @@ namespace Content.Server.Ghost.Roles eui.StateDirty(); } - public void CloseEui(IPlayerSession session) + public void CloseEui(ICommonSession session) { if (!_openUis.ContainsKey(session)) return; @@ -132,7 +133,7 @@ namespace Content.Server.Ghost.Roles eui?.Close(); } - public void CloseMakeGhostRoleEui(IPlayerSession session) + public void CloseMakeGhostRoleEui(ICommonSession session) { if (_openMakeGhostRoleUis.Remove(session, out var eui)) { @@ -190,7 +191,7 @@ namespace Content.Server.Ghost.Roles UpdateAllEui(); } - public void Takeover(IPlayerSession player, uint identifier) + public void Takeover(ICommonSession player, uint identifier) { if (!_ghostRoles.TryGetValue(identifier, out var role)) return; @@ -205,7 +206,7 @@ namespace Content.Server.Ghost.Roles CloseEui(player); } - public void Follow(IPlayerSession player, uint identifier) + public void Follow(ICommonSession player, uint identifier) { if (!_ghostRoles.TryGetValue(identifier, out var role)) return; if (player.AttachedEntity == null) return; @@ -213,7 +214,7 @@ namespace Content.Server.Ghost.Roles _followerSystem.StartFollowingEntity(player.AttachedEntity.Value, role.Owner); } - public void GhostRoleInternalCreateMindAndTransfer(IPlayerSession player, EntityUid roleUid, EntityUid mob, GhostRoleComponent? role = null) + public void GhostRoleInternalCreateMindAndTransfer(ICommonSession player, EntityUid roleUid, EntityUid mob, GhostRoleComponent? role = null) { if (!Resolve(roleUid, ref role)) return; diff --git a/Content.Server/Ghost/Roles/MakeGhostRoleCommand.cs b/Content.Server/Ghost/Roles/MakeGhostRoleCommand.cs index cbbec64f11..b26738d976 100644 --- a/Content.Server/Ghost/Roles/MakeGhostRoleCommand.cs +++ b/Content.Server/Ghost/Roles/MakeGhostRoleCommand.cs @@ -1,7 +1,7 @@ using Content.Server.Administration; using Content.Server.Ghost.Roles.Components; -using Content.Server.Mind.Components; using Content.Shared.Administration; +using Content.Shared.Mind.Components; using Robust.Shared.Console; namespace Content.Server.Ghost.Roles diff --git a/Content.Server/Ghost/Roles/ToggleableGhostRoleSystem.cs b/Content.Server/Ghost/Roles/ToggleableGhostRoleSystem.cs index a1f3eb68b6..d78df4f2a2 100644 --- a/Content.Server/Ghost/Roles/ToggleableGhostRoleSystem.cs +++ b/Content.Server/Ghost/Roles/ToggleableGhostRoleSystem.cs @@ -1,10 +1,9 @@ using Content.Server.Ghost.Roles.Components; -using Content.Server.Mind; -using Content.Server.Mind.Components; using Content.Server.PAI; using Content.Shared.Examine; using Content.Shared.Interaction.Events; using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Popups; using Content.Shared.Verbs; @@ -17,7 +16,7 @@ public sealed class ToggleableGhostRoleSystem : EntitySystem { [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; - [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; //todo this really shouldn't be in here but this system was converted from PAIs [Dependency] private readonly PAISystem _pai = default!; diff --git a/Content.Server/Holiday/Christmas/LimitedItemGiverSystem.cs b/Content.Server/Holiday/Christmas/LimitedItemGiverSystem.cs index d0790dd1a6..58cf415a25 100644 --- a/Content.Server/Holiday/Christmas/LimitedItemGiverSystem.cs +++ b/Content.Server/Holiday/Christmas/LimitedItemGiverSystem.cs @@ -1,5 +1,4 @@ using Content.Server.Hands.Systems; -using Content.Server.Mind.Components; using Content.Server.Popups; using Content.Shared.Interaction; using Content.Shared.Storage; diff --git a/Content.Server/Light/EntitySystems/UnpoweredFlashlightSystem.cs b/Content.Server/Light/EntitySystems/UnpoweredFlashlightSystem.cs index bd6c0d5dba..1cc7f50268 100644 --- a/Content.Server/Light/EntitySystems/UnpoweredFlashlightSystem.cs +++ b/Content.Server/Light/EntitySystems/UnpoweredFlashlightSystem.cs @@ -1,10 +1,10 @@ using Content.Server.Light.Events; -using Content.Server.Mind.Components; using Content.Shared.Actions; using Content.Shared.Decals; using Content.Shared.Emag.Systems; using Content.Shared.Light; using Content.Shared.Light.Component; +using Content.Shared.Mind.Components; using Content.Shared.Toggleable; using Content.Shared.Verbs; using Robust.Server.GameObjects; diff --git a/Content.Server/Materials/MaterialReclaimerSystem.cs b/Content.Server/Materials/MaterialReclaimerSystem.cs index 9a2a5cb391..caac0ae577 100644 --- a/Content.Server/Materials/MaterialReclaimerSystem.cs +++ b/Content.Server/Materials/MaterialReclaimerSystem.cs @@ -4,7 +4,6 @@ using Content.Server.Chemistry.EntitySystems; using Content.Server.Construction; using Content.Server.Fluids.EntitySystems; using Content.Server.GameTicking; -using Content.Server.Mind; using Content.Server.Nutrition.Components; using Content.Server.Popups; using Content.Server.Power.Components; @@ -17,6 +16,7 @@ using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; using Content.Shared.Materials; +using Content.Shared.Mind; using Robust.Server.GameObjects; using Robust.Shared.Player; using Robust.Shared.Utility; @@ -34,7 +34,7 @@ public sealed class MaterialReclaimerSystem : SharedMaterialReclaimerSystem [Dependency] private readonly SharedBodySystem _body = default!; //bobby [Dependency] private readonly PuddleSystem _puddle = default!; [Dependency] private readonly StackSystem _stack = default!; - [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; /// public override void Initialize() diff --git a/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs b/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs index 5b88b94fcf..880f702d1c 100644 --- a/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs +++ b/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs @@ -4,7 +4,6 @@ using Content.Server.Climbing; using Content.Server.Construction; using Content.Server.Fluids.EntitySystems; using Content.Server.Materials; -using Content.Server.Mind; using Content.Server.Power.Components; using Content.Shared.Administration.Logs; using Content.Shared.Audio; @@ -18,6 +17,7 @@ using Content.Shared.Interaction; using Content.Shared.Interaction.Events; using Content.Shared.Jittering; using Content.Shared.Medical; +using Content.Shared.Mind; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Nutrition.Components; @@ -45,7 +45,7 @@ namespace Content.Server.Medical.BiomassReclaimer [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly MaterialStorageSystem _material = default!; - [Dependency] private readonly MindSystem _minds = default!; + [Dependency] private readonly SharedMindSystem _minds = default!; public override void Update(float frameTime) { diff --git a/Content.Server/Medical/DefibrillatorSystem.cs b/Content.Server/Medical/DefibrillatorSystem.cs index 35b019257a..f86f6b24b3 100644 --- a/Content.Server/Medical/DefibrillatorSystem.cs +++ b/Content.Server/Medical/DefibrillatorSystem.cs @@ -4,7 +4,6 @@ using Content.Server.DoAfter; using Content.Server.Electrocution; using Content.Server.EUI; using Content.Server.Ghost; -using Content.Server.Mind; using Content.Server.Popups; using Content.Server.PowerCell; using Content.Shared.Damage; @@ -13,12 +12,13 @@ using Content.Shared.Interaction; using Content.Shared.Interaction.Components; using Content.Shared.Interaction.Events; using Content.Shared.Medical; +using Content.Shared.Mind; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Timing; using Content.Shared.Toggleable; -using Robust.Server.Player; +using Robust.Shared.Players; using Robust.Shared.Timing; namespace Content.Server.Medical; @@ -42,7 +42,7 @@ public sealed class DefibrillatorSystem : EntitySystem [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly UseDelaySystem _useDelay = default!; - [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; /// public override void Initialize() @@ -208,7 +208,7 @@ public sealed class DefibrillatorSystem : EntitySystem component.NextZapTime = _timing.CurTime + component.ZapDelay; _appearance.SetData(uid, DefibrillatorVisuals.Ready, false); - IPlayerSession? session = null; + ICommonSession? session = null; if (_rotting.IsRotten(target)) { diff --git a/Content.Server/Mind/Commands/MakeSentientCommand.cs b/Content.Server/Mind/Commands/MakeSentientCommand.cs index 22ca8ebde0..04907962a0 100644 --- a/Content.Server/Mind/Commands/MakeSentientCommand.cs +++ b/Content.Server/Mind/Commands/MakeSentientCommand.cs @@ -1,9 +1,8 @@ using Content.Server.Administration; -using Content.Server.Mind.Components; -using Content.Server.NPC.Components; using Content.Shared.Administration; using Content.Shared.Emoting; using Content.Shared.Examine; +using Content.Shared.Mind.Components; using Content.Shared.Movement.Components; using Content.Shared.Speech; using Robust.Shared.Console; diff --git a/Content.Server/Mind/Commands/MindInfoCommand.cs b/Content.Server/Mind/Commands/MindInfoCommand.cs index 0327657d97..d4961b82db 100644 --- a/Content.Server/Mind/Commands/MindInfoCommand.cs +++ b/Content.Server/Mind/Commands/MindInfoCommand.cs @@ -1,7 +1,8 @@ using System.Text; using Content.Server.Administration; -using Content.Server.Roles; using Content.Shared.Administration; +using Content.Shared.Mind; +using Content.Shared.Roles; using Robust.Server.Player; using Robust.Shared.Console; @@ -31,7 +32,7 @@ namespace Content.Server.Mind.Commands return; } - var minds = _entities.System(); + var minds = _entities.System(); if (!minds.TryGetMind(session, out var mindId, out var mind)) { shell.WriteLine("Can't find that mind"); @@ -41,7 +42,7 @@ namespace Content.Server.Mind.Commands var builder = new StringBuilder(); builder.AppendFormat("player: {0}, mob: {1}\nroles: ", mind.UserId, mind.OwnedEntity); - var roles = _entities.System(); + var roles = _entities.System(); foreach (var role in roles.MindGetAllRoles(mindId)) { builder.AppendFormat("{0} ", role.Name); diff --git a/Content.Server/Mind/Commands/RenameCommand.cs b/Content.Server/Mind/Commands/RenameCommand.cs index b4e26cb6c2..cbe8be239d 100644 --- a/Content.Server/Mind/Commands/RenameCommand.cs +++ b/Content.Server/Mind/Commands/RenameCommand.cs @@ -5,6 +5,7 @@ using Content.Server.PDA; using Content.Server.StationRecords.Systems; using Content.Shared.Access.Components; using Content.Shared.Administration; +using Content.Shared.Mind; using Content.Shared.PDA; using Content.Shared.StationRecords; using Robust.Server.GameObjects; @@ -45,7 +46,7 @@ public sealed class RenameCommand : IConsoleCommand var oldName = metadata.EntityName; entMan.System().SetEntityName(entityUid, name, metadata); - var minds = entMan.System(); + var minds = entMan.System(); if (minds.TryGetMind(entityUid, out var mindId, out var mind)) { diff --git a/Content.Server/Mind/MindSystem.cs b/Content.Server/Mind/MindSystem.cs index f170d337f9..797e8a273b 100644 --- a/Content.Server/Mind/MindSystem.cs +++ b/Content.Server/Mind/MindSystem.cs @@ -1,17 +1,11 @@ -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using Content.Server.Administration.Logs; using Content.Server.GameTicking; -using Content.Server.Ghost; -using Content.Server.Mind.Components; -using Content.Server.Objectives; -using Content.Server.Players; using Content.Shared.Database; -using Content.Shared.Examine; -using Content.Shared.GameTicking; using Content.Shared.Ghost; -using Content.Shared.Interaction.Events; -using Content.Shared.Mobs.Components; -using Content.Shared.Mobs.Systems; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; +using Content.Shared.Players; using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Map; @@ -21,90 +15,22 @@ using Robust.Shared.Utility; namespace Content.Server.Mind; -public sealed class MindSystem : EntitySystem +public sealed class MindSystem : SharedMindSystem { - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly GameTicker _gameTicker = default!; [Dependency] private readonly ActorSystem _actor = default!; - [Dependency] private readonly MobStateSystem _mobStateSystem = default!; - [Dependency] private readonly GhostSystem _ghostSystem = default!; - [Dependency] private readonly TransformSystem _transform = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; - [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly GameTicker _gameTicker = default!; + [Dependency] private readonly SharedGhostSystem _ghosts = default!; + [Dependency] private readonly IMapManager _maps = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; - - // This is dictionary is required to track the minds of disconnected players that may have had their entity deleted. - private readonly Dictionary _userMinds = new(); + [Dependency] private readonly IPlayerManager _players = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnExamined); - SubscribeLocalEvent(OnSuicide); SubscribeLocalEvent(OnMindContainerTerminating); - SubscribeLocalEvent(OnVisitingTerminating); - SubscribeLocalEvent(OnReset); - } - - public override void Shutdown() - { - base.Shutdown(); - WipeAllMinds(); - } - - private void OnReset(RoundRestartCleanupEvent ev) - { - WipeAllMinds(); - } - - public void WipeAllMinds() - { - foreach (var mind in _userMinds.Values) - { - WipeMind(mind); - } - DebugTools.Assert(_userMinds.Count == 0); - - foreach (var unCastData in _playerManager.GetAllPlayerData()) - { - if (unCastData.ContentData()?.Mind is not { } mind) - continue; - - Log.Error("Player mind was missing from MindSystem dictionary."); - WipeMind(mind); - } - } - - public EntityUid? GetMind(NetUserId user) - { - TryGetMind(user, out var mind, out _); - return mind; - } - - public bool TryGetMind(NetUserId user, [NotNullWhen(true)] out EntityUid? mindId, [NotNullWhen(true)] out MindComponent? mind) - { - if (_userMinds.TryGetValue(user, out var mindIdValue) && - TryComp(mindIdValue, out mind)) - { - DebugTools.Assert(mind.UserId == user); - DebugTools.Assert(_playerManager.GetPlayerData(user).ContentData() is not {} data - || data.Mind == mindIdValue); - - mindId = mindIdValue; - return true; - } - - DebugTools.Assert(_playerManager.GetPlayerData(user).ContentData()?.Mind == null); - mindId = null; - mind = null; - return false; - } - - private void OnVisitingTerminating(EntityUid uid, VisitingMindComponent component, ref EntityTerminatingEvent args) - { - if (component.MindId != null) - UnVisit(component.MindId.Value); } private void OnMindContainerTerminating(EntityUid uid, MindContainerComponent component, ref EntityTerminatingEvent args) @@ -124,7 +50,7 @@ public sealed class MindSystem : EntitySystem { TransferTo(mindId, visiting, mind: mind); if (TryComp(visiting, out GhostComponent? ghost)) - _ghostSystem.SetCanReturnToBody(ghost, false); + _ghosts.SetCanReturnToBody(ghost, false); return; } @@ -144,7 +70,7 @@ public sealed class MindSystem : EntitySystem return; // Async this so that we don't throw if the grid we're on is being deleted. - if (!_mapManager.GridExists(gridId)) + if (!_maps.GridExists(gridId)) spawnPosition = _gameTicker.GetObserverSpawnPoint(); // TODO refactor observer spawning. @@ -159,7 +85,7 @@ public sealed class MindSystem : EntitySystem var ghost = Spawn("MobObserver", spawnPosition); var ghostComponent = Comp(ghost); - _ghostSystem.SetCanReturnToBody(ghostComponent, false); + _ghosts.SetCanReturnToBody(ghostComponent, false); // Log these to make sure they're not causing the GameTicker round restart bugs... Log.Debug($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, spawned \"{ToPrettyString(ghost)}\"."); @@ -171,92 +97,52 @@ public sealed class MindSystem : EntitySystem } } - private void OnExamined(EntityUid uid, MindContainerComponent mindContainer, ExaminedEvent args) + public override bool TryGetMind(NetUserId user, [NotNullWhen(true)] out EntityUid? mindId, [NotNullWhen(true)] out MindComponent? mind) { - if (!mindContainer.ShowExamineInfo || !args.IsInDetailsRange) - return; + if (base.TryGetMind(user, out mindId, out mind)) + { + DebugTools.Assert(_players.GetPlayerData(user).ContentData() is not { } data || data.Mind == mindId); + return true; + } - var dead = _mobStateSystem.IsDead(uid); - var hasSession = CompOrNull(mindContainer.Mind)?.Session; - - if (dead && !mindContainer.HasMind) - args.PushMarkup($"[color=mediumpurple]{Loc.GetString("comp-mind-examined-dead-and-irrecoverable", ("ent", uid))}[/color]"); - else if (dead && hasSession == null) - args.PushMarkup($"[color=yellow]{Loc.GetString("comp-mind-examined-dead-and-ssd", ("ent", uid))}[/color]"); - else if (dead) - args.PushMarkup($"[color=red]{Loc.GetString("comp-mind-examined-dead", ("ent", uid))}[/color]"); - else if (!mindContainer.HasMind) - args.PushMarkup($"[color=mediumpurple]{Loc.GetString("comp-mind-examined-catatonic", ("ent", uid))}[/color]"); - else if (hasSession == null) - args.PushMarkup($"[color=yellow]{Loc.GetString("comp-mind-examined-ssd", ("ent", uid))}[/color]"); + DebugTools.Assert(_players.GetPlayerData(user).ContentData()?.Mind == null); + return false; } - private void OnSuicide(EntityUid uid, MindContainerComponent component, SuicideEvent args) + public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out IPlayerSession? session) { - if (args.Handled) - return; + session = null; + return TryComp(mindId, out MindComponent? mind) && (session = (IPlayerSession?) mind.Session) != null; + } - if (TryComp(component.Mind, out MindComponent? mind) && mind.PreventSuicide) + public IPlayerSession? GetSession(MindComponent mind) + { + return (IPlayerSession?) mind.Session; + } + + public bool TryGetSession(MindComponent mind, [NotNullWhen(true)] out IPlayerSession? session) + { + return (session = GetSession(mind)) != null; + } + + public override void WipeAllMinds() + { + base.WipeAllMinds(); + + foreach (var unCastData in _players.GetAllPlayerData()) { - args.BlockSuicideAttempt(true); + if (unCastData.ContentData()?.Mind is not { } mind) + continue; + + Log.Error("Player mind was missing from MindSystem dictionary."); + WipeMind(mind); } } - public EntityUid? GetMind(EntityUid uid, MindContainerComponent? mind = null) + public override void Visit(EntityUid mindId, EntityUid entity, MindComponent? mind = null) { - if (!Resolve(uid, ref mind)) - return null; + base.Visit(mindId, entity, mind); - if (mind.HasMind) - return mind.Mind; - - return null; - } - - public EntityUid CreateMind(NetUserId? userId, string? name = null) - { - var mindId = Spawn(null, MapCoordinates.Nullspace); - var mind = EnsureComp(mindId); - mind.CharacterName = name; - SetUserId(mindId, userId, mind); - - Dirty(mindId, MetaData(mindId)); - - return mindId; - } - - /// - /// True if the OwnedEntity of this mind is physically dead. - /// This specific definition, as opposed to CharacterDeadIC, is used to determine if ghosting should allow return. - /// - public bool IsCharacterDeadPhysically(MindComponent mind) - { - // This is written explicitly so that the logic can be understood. - // But it's also weird and potentially situational. - // Specific considerations when updating this: - // + Does being turned into a borg (if/when implemented) count as dead? - // *If not, add specific conditions to users of this property where applicable.* - // + Is being transformed into a donut 'dead'? - // TODO: Consider changing the way ghost roles work. - // Mind is an *IC* mind, therefore ghost takeover is IC revival right now. - // + Is it necessary to have a reference to a specific 'mind iteration' to cycle when certain events happen? - // (If being a borg or AI counts as dead, then this is highly likely, as it's still the same Mind for practical purposes.) - - if (mind.OwnedEntity == null) - return true; - - // This can be null if they're deleted (spike / brain nom) - var targetMobState = EntityManager.GetComponentOrNull(mind.OwnedEntity); - // This can be null if it's a brain (this happens very often) - // Brains are the result of gibbing so should definitely count as dead - if (targetMobState == null) - return true; - // They might actually be alive. - return _mobStateSystem.IsDead(mind.OwnedEntity.Value, targetMobState); - } - - public void Visit(EntityUid mindId, EntityUid entity, MindComponent? mind = null) - { if (!Resolve(mindId, ref mind)) return; @@ -272,7 +158,7 @@ public sealed class MindSystem : EntitySystem return; } - mind.Session?.AttachToEntity(entity); + GetSession(mind)?.AttachToEntity(entity); mind.VisitingEntity = entity; // EnsureComp instead of AddComp to deal with deferred deletions. @@ -281,11 +167,10 @@ public sealed class MindSystem : EntitySystem Log.Info($"Session {mind.Session?.Name} visiting entity {entity}."); } - /// - /// Returns the mind to its original entity. - /// - public void UnVisit(EntityUid mindId, MindComponent? mind = null) + public override void UnVisit(EntityUid mindId, MindComponent? mind = null) { + base.UnVisit(mindId, mind); + if (!Resolve(mindId, ref mind)) return; @@ -298,7 +183,7 @@ public sealed class MindSystem : EntitySystem return; var owned = mind.OwnedEntity; - mind.Session.AttachToEntity(owned); + GetSession(mind)?.AttachToEntity(owned); if (owned.HasValue) { @@ -307,74 +192,11 @@ public sealed class MindSystem : EntitySystem } } - /// - /// Returns the mind to its original entity. - /// - public void UnVisit(IPlayerSession? player) + public override void TransferTo(EntityUid mindId, EntityUid? entity, bool ghostCheckOverride = false, bool createGhost = true, + MindComponent? mind = null) { - if (player == null || !TryGetMind(player, out var mindId, out var mind)) - return; + base.TransferTo(mindId, entity, ghostCheckOverride, createGhost, mind); - UnVisit(mindId, mind); - } - - /// - /// Cleans up the VisitingEntity. - /// - /// - private void RemoveVisitingEntity(MindComponent mind) - { - if (mind.VisitingEntity == null) - return; - - var oldVisitingEnt = mind.VisitingEntity.Value; - // Null this before removing the component to avoid any infinite loops. - mind.VisitingEntity = null; - - if (TryComp(oldVisitingEnt, out VisitingMindComponent? visitComp)) - { - visitComp.MindId = null; - RemCompDeferred(oldVisitingEnt, visitComp); - } - - RaiseLocalEvent(oldVisitingEnt, new MindUnvisitedMessage(), true); - } - - public void WipeMind(IPlayerSession player) - { - var mind = player.ContentData()?.Mind; - DebugTools.Assert(GetMind(player.UserId) == mind); - WipeMind(mind); - } - - /// - /// Detaches a mind from all entities and clears the user ID. - /// - public void WipeMind(EntityUid? mindId, MindComponent? mind = null) - { - if (mindId == null || !Resolve(mindId.Value, ref mind, false)) - return; - - TransferTo(mindId.Value, null, mind: mind); - SetUserId(mindId.Value, null, mind: mind); - } - - /// - /// Transfer this mind's control over to a new entity. - /// - /// The mind to transfer - /// - /// The entity to control. - /// Can be null, in which case it will simply detach the mind from any entity. - /// - /// - /// If true, skips ghost check for Visiting Entity - /// - /// - /// Thrown if is already controlled by another player. - /// - public void TransferTo(EntityUid mindId, EntityUid? entity, bool ghostCheckOverride = false, bool createGhost = true, MindComponent? mind = null) - { if (!Resolve(mindId, ref mind)) return; @@ -410,7 +232,7 @@ public sealed class MindSystem : EntitySystem entity = Spawn("MobObserver", position); var ghostComponent = Comp(entity.Value); - _ghostSystem.SetCanReturnToBody(ghostComponent, false); + _ghosts.SetCanReturnToBody(ghostComponent, false); } var oldComp = mind.OwnedComponent; @@ -440,10 +262,11 @@ public sealed class MindSystem : EntitySystem } // Player is CURRENTLY connected. - if (mind.Session != null && !alreadyAttached && mind.VisitingEntity == null) + var session = GetSession(mind); + if (session != null && !alreadyAttached && mind.VisitingEntity == null) { - _actor.Attach(entity, mind.Session, true); - Log.Info($"Session {mind.Session.Name} transferred to entity {entity}."); + _actor.Attach(entity, session, true); + Log.Info($"Session {session.Name} transferred to entity {entity}."); } if (mind.OwnedComponent != null) @@ -454,127 +277,17 @@ public sealed class MindSystem : EntitySystem } } - /// - /// Adds an objective to this mind. - /// - public bool TryAddObjective(EntityUid mindId, MindComponent mind, ObjectivePrototype objectivePrototype) + public override void SetUserId(EntityUid mindId, NetUserId? userId, MindComponent? mind = null) { - if (!objectivePrototype.CanBeAssigned(mindId, mind)) - return false; - var objective = objectivePrototype.GetObjective(mindId, mind); - if (mind.Objectives.Contains(objective)) - return false; + base.SetUserId(mindId, userId, mind); - foreach (var condition in objective.Conditions) - { - _adminLogger.Add(LogType.Mind, LogImpact.Low, $"'{condition.Title}' added to mind of {MindOwnerLoggingString(mind)}"); - } - - mind.Objectives.Add(objective); - return true; - } - - /// - /// Removes an objective to this mind. - /// - /// Returns true if the removal succeeded. - public bool TryRemoveObjective(MindComponent mind, int index) - { - if (index < 0 || index >= mind.Objectives.Count) - return false; - - var objective = mind.Objectives[index]; - - foreach (var condition in objective.Conditions) - { - _adminLogger.Add(LogType.Mind, LogImpact.Low, $"'{condition.Title}' removed from the mind of {MindOwnerLoggingString(mind)}"); - } - - mind.Objectives.Remove(objective); - return true; - } - - public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out IPlayerSession? session) - { - session = null; - return TryComp(mindId, out MindComponent? mind) && (session = mind.Session) != null; - } - - /// - /// Gets a mind from uid and/or MindContainerComponent. Used for null checks. - /// - /// Entity UID that owns the mind. - /// The mind id. - /// The returned mind. - /// Mind component on to get the mind from. - /// True if mind found. False if not. - public bool TryGetMind( - EntityUid uid, - out EntityUid mindId, - [NotNullWhen(true)] out MindComponent? mind, - MindContainerComponent? container = null) - { - mindId = default; - mind = null; - - if (!Resolve(uid, ref container, false)) - return false; - - if (!container.HasMind) - return false; - - mindId = container.Mind ?? default; - return TryComp(mindId, out mind); - } - - public bool TryGetMind( - PlayerData player, - out EntityUid mindId, - [NotNullWhen(true)] out MindComponent? mind) - { - mindId = player.Mind ?? default; - return TryComp(mindId, out mind); - } - - public bool TryGetMind( - IPlayerSession? player, - out EntityUid mindId, - [NotNullWhen(true)] out MindComponent? mind) - { - mindId = default; - mind = null; - return player?.ContentData() is { } data && TryGetMind(data, out mindId, out mind); - } - - /// - /// Sets the Mind's OwnedComponent and OwnedEntity - /// - /// Mind to set OwnedComponent and OwnedEntity on - /// Entity owned by - /// MindContainerComponent owned by - private void SetOwnedEntity(MindComponent mind, EntityUid? uid, MindContainerComponent? mindContainerComponent) - { - if (uid != null) - Resolve(uid.Value, ref mindContainerComponent); - - mind.OwnedEntity = uid; - mind.OwnedComponent = mindContainerComponent; - } - - /// - /// Sets the Mind's UserId, Session, and updates the player's PlayerData. This should have no direct effect on the - /// entity that any mind is connected to, except as a side effect of the fact that it may change a player's - /// attached entity. E.g., ghosts get deleted. - /// - public void SetUserId(EntityUid mindId, NetUserId? userId, MindComponent? mind = null) - { if (!Resolve(mindId, ref mind)) return; if (mind.UserId == userId) return; - if (userId != null && !_playerManager.TryGetPlayerData(userId.Value, out _)) + if (userId != null && !_players.TryGetPlayerData(userId.Value, out _)) { Log.Error($"Attempted to set mind user to invalid value {userId}"); return; @@ -582,14 +295,14 @@ public sealed class MindSystem : EntitySystem if (mind.Session != null) { - _actor.Attach(null, mind.Session); + _actor.Attach(null, GetSession(mind)!); mind.Session = null; } if (mind.UserId != null) { - _userMinds.Remove(mind.UserId.Value); - if (_playerManager.GetPlayerData(mind.UserId.Value).ContentData() is { } oldData) + UserMinds.Remove(mind.UserId.Value); + if (_players.GetPlayerData(mind.UserId.Value).ContentData() is { } oldData) oldData.Mind = null; mind.UserId = null; } @@ -600,71 +313,26 @@ public sealed class MindSystem : EntitySystem return; } - if (_userMinds.TryGetValue(userId.Value, out var oldMindId) && + if (UserMinds.TryGetValue(userId.Value, out var oldMindId) && TryComp(oldMindId, out MindComponent? oldMind)) { SetUserId(oldMindId, null, oldMind); } - DebugTools.AssertNull(_playerManager.GetPlayerData(userId.Value).ContentData()?.Mind); + DebugTools.AssertNull(_players.GetPlayerData(userId.Value).ContentData()?.Mind); - _userMinds[userId.Value] = mindId; + UserMinds[userId.Value] = mindId; mind.UserId = userId; mind.OriginalOwnerUserId ??= userId; - if (_playerManager.TryGetSessionById(userId.Value, out var ret)) + if (_players.TryGetSessionById(userId.Value, out var ret)) { mind.Session = ret; - _actor.Attach(mind.CurrentEntity, mind.Session); + _actor.Attach(mind.CurrentEntity, ret); } // session may be null, but user data may still exist for disconnected players. - if (_playerManager.GetPlayerData(userId.Value).ContentData() is { } data) + if (_players.GetPlayerData(userId.Value).ContentData() is { } data) data.Mind = mindId; } - - /// - /// True if this Mind is 'sufficiently dead' IC (Objectives, EndText). - /// Note that this is *IC logic*, it's not necessarily tied to any specific truth. - /// "If administrators decide that zombies are dead, this returns true for zombies." - /// (Maybe you were looking for the action blocker system?) - /// - public bool IsCharacterDeadIc(MindComponent mind) - { - if (mind.OwnedEntity is { } owned) - { - var ev = new GetCharactedDeadIcEvent(null); - RaiseLocalEvent(owned, ref ev); - - if (ev.Dead != null) - return ev.Dead.Value; - } - - return IsCharacterDeadPhysically(mind); - } - - /// - /// A string to represent the mind for logging - /// - public string MindOwnerLoggingString(MindComponent mind) - { - if (mind.OwnedEntity != null) - return ToPrettyString(mind.OwnedEntity.Value); - if (mind.UserId != null) - return mind.UserId.Value.ToString(); - return "(originally " + mind.OriginalOwnerUserId + ")"; - } - - public string? GetCharacterName(NetUserId userId) - { - return TryGetMind(userId, out _, out var mind) ? mind.CharacterName : null; - } } - -/// -/// Raised on an entity to determine whether or not they are "dead" in IC-logic. -/// If not handled, then it will simply check if they are dead physically. -/// -/// -[ByRefEvent] -public record struct GetCharactedDeadIcEvent(bool? Dead); diff --git a/Content.Server/Mind/Toolshed/MindCommand.cs b/Content.Server/Mind/Toolshed/MindCommand.cs index 3d8ffe8629..b53f9a6a9c 100644 --- a/Content.Server/Mind/Toolshed/MindCommand.cs +++ b/Content.Server/Mind/Toolshed/MindCommand.cs @@ -1,4 +1,5 @@ -using Robust.Server.Player; +using Content.Shared.Mind; +using Robust.Server.Player; using Robust.Shared.Toolshed; using Robust.Shared.Toolshed.Errors; using Robust.Shared.Toolshed.Syntax; @@ -11,19 +12,19 @@ namespace Content.Server.Mind.Toolshed; [ToolshedCommand] public sealed class MindCommand : ToolshedCommand { - private MindSystem? _mind; + private SharedMindSystem? _mind; [CommandImplementation("get")] public MindComponent? Get([PipedArgument] IPlayerSession session) { - _mind ??= GetSys(); + _mind ??= GetSys(); return _mind.TryGetMind(session, out _, out var mind) ? mind : null; } [CommandImplementation("get")] public MindComponent? Get([PipedArgument] EntityUid ent) { - _mind ??= GetSys(); + _mind ??= GetSys(); return _mind.TryGetMind(ent, out _, out var mind) ? mind : null; } @@ -33,7 +34,7 @@ public sealed class MindCommand : ToolshedCommand [PipedArgument] EntityUid target, [CommandArgument] ValueRef playerRef) { - _mind ??= GetSys(); + _mind ??= GetSys(); var player = playerRef.Evaluate(ctx); if (player is null) diff --git a/Content.Server/Mind/TransferMindOnGibSystem.cs b/Content.Server/Mind/TransferMindOnGibSystem.cs index c1d4d82341..758a23c868 100644 --- a/Content.Server/Mind/TransferMindOnGibSystem.cs +++ b/Content.Server/Mind/TransferMindOnGibSystem.cs @@ -1,6 +1,7 @@ using System.Linq; using Content.Server.Body.Components; -using Content.Server.Mind.Components; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Tag; using Robust.Shared.Random; @@ -15,7 +16,7 @@ public sealed class TransferMindOnGibSystem : EntitySystem { [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly TagSystem _tag = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; /// public override void Initialize() diff --git a/Content.Server/Mobs/CritMobActionsSystem.cs b/Content.Server/Mobs/CritMobActionsSystem.cs index 26788ddf6b..7babea79ab 100644 --- a/Content.Server/Mobs/CritMobActionsSystem.cs +++ b/Content.Server/Mobs/CritMobActionsSystem.cs @@ -1,16 +1,12 @@ using Content.Server.Administration; using Content.Server.Chat.Systems; -using Content.Server.GameTicking; -using Content.Server.Mind.Components; using Content.Server.Popups; using Content.Server.Speech.Muting; -using Content.Shared.ActionBlocker; using Content.Shared.Actions; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Robust.Server.Console; using Robust.Server.GameObjects; -using System; namespace Content.Server.Mobs; diff --git a/Content.Server/Morgue/CrematoriumSystem.cs b/Content.Server/Morgue/CrematoriumSystem.cs index f285dd424b..5ef42ea00e 100644 --- a/Content.Server/Morgue/CrematoriumSystem.cs +++ b/Content.Server/Morgue/CrematoriumSystem.cs @@ -1,5 +1,4 @@ using Content.Server.GameTicking; -using Content.Server.Mind; using Content.Server.Morgue.Components; using Content.Server.Storage.Components; using Content.Server.Storage.EntitySystems; @@ -7,6 +6,7 @@ using Content.Shared.Database; using Content.Shared.Examine; using Content.Shared.IdentityManagement; using Content.Shared.Interaction.Events; +using Content.Shared.Mind; using Content.Shared.Morgue; using Content.Shared.Popups; using Content.Shared.Standing; @@ -26,7 +26,7 @@ public sealed class CrematoriumSystem : EntitySystem [Dependency] private readonly EntityStorageSystem _entityStorage = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly StandingStateSystem _standing = default!; - [Dependency] private readonly MindSystem _minds = default!; + [Dependency] private readonly SharedMindSystem _minds = default!; public override void Initialize() { diff --git a/Content.Server/Nutrition/EntitySystems/AnimalHusbandrySystem.cs b/Content.Server/Nutrition/EntitySystems/AnimalHusbandrySystem.cs index b5779bfe0a..94a80c4bd5 100644 --- a/Content.Server/Nutrition/EntitySystems/AnimalHusbandrySystem.cs +++ b/Content.Server/Nutrition/EntitySystems/AnimalHusbandrySystem.cs @@ -1,17 +1,16 @@ using Content.Server.Administration.Logs; using Content.Server.Interaction.Components; -using Content.Server.Mind.Components; using Content.Server.Nutrition.Components; using Content.Server.Popups; using Content.Shared.Database; using Content.Shared.IdentityManagement; +using Content.Shared.Mind.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Nutrition.AnimalHusbandry; using Content.Shared.Nutrition.Components; using Content.Shared.Nutrition.EntitySystems; using Content.Shared.Storage; using Robust.Server.GameObjects; -using Robust.Shared.Collections; using Robust.Shared.Random; using Robust.Shared.Timing; diff --git a/Content.Server/Objectives/Commands/AddObjectiveCommand.cs b/Content.Server/Objectives/Commands/AddObjectiveCommand.cs index 7ee0d8b38e..f5519e5095 100644 --- a/Content.Server/Objectives/Commands/AddObjectiveCommand.cs +++ b/Content.Server/Objectives/Commands/AddObjectiveCommand.cs @@ -1,6 +1,7 @@ using Content.Server.Administration; -using Content.Server.Mind; using Content.Shared.Administration; +using Content.Shared.Mind; +using Content.Shared.Objectives; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -30,7 +31,7 @@ namespace Content.Server.Objectives.Commands return; } - var minds = _entityManager.System(); + var minds = _entityManager.System(); if (!minds.TryGetMind(data, out var mindId, out var mind)) { shell.WriteLine("Can't find the mind."); @@ -44,7 +45,7 @@ namespace Content.Server.Objectives.Commands return; } - var mindSystem = _entityManager.System(); + var mindSystem = _entityManager.System(); if (!mindSystem.TryAddObjective(mindId, mind, objectivePrototype)) { shell.WriteLine("Objective requirements dont allow that objective to be added."); diff --git a/Content.Server/Objectives/Commands/ListObjectivesCommand.cs b/Content.Server/Objectives/Commands/ListObjectivesCommand.cs index 0351bf291c..d1a7feb0ca 100644 --- a/Content.Server/Objectives/Commands/ListObjectivesCommand.cs +++ b/Content.Server/Objectives/Commands/ListObjectivesCommand.cs @@ -1,7 +1,7 @@ using System.Linq; using Content.Server.Administration; -using Content.Server.Mind; using Content.Shared.Administration; +using Content.Shared.Mind; using Robust.Server.Player; using Robust.Shared.Console; @@ -24,7 +24,7 @@ namespace Content.Server.Objectives.Commands return; } - var minds = _entities.System(); + var minds = _entities.System(); if (!minds.TryGetMind(player, out _, out var mind)) { shell.WriteError(LocalizationManager.GetString("shell-target-entity-does-not-have-message", ("missing", "mind"))); diff --git a/Content.Server/Objectives/Commands/RemoveObjectiveCommand.cs b/Content.Server/Objectives/Commands/RemoveObjectiveCommand.cs index 68af65fd1d..26369822fd 100644 --- a/Content.Server/Objectives/Commands/RemoveObjectiveCommand.cs +++ b/Content.Server/Objectives/Commands/RemoveObjectiveCommand.cs @@ -1,6 +1,6 @@ using Content.Server.Administration; -using Content.Server.Mind; using Content.Shared.Administration; +using Content.Shared.Mind; using Robust.Server.Player; using Robust.Shared.Console; @@ -23,7 +23,7 @@ namespace Content.Server.Objectives.Commands } var mgr = IoCManager.Resolve(); - var minds = _entityManager.System(); + var minds = _entityManager.System(); if (!mgr.TryGetSessionByUsername(args[0], out var session)) { shell.WriteLine("Can't find the playerdata."); @@ -38,7 +38,7 @@ namespace Content.Server.Objectives.Commands if (int.TryParse(args[1], out var i)) { - var mindSystem = _entityManager.System(); + var mindSystem = _entityManager.System(); shell.WriteLine(mindSystem.TryRemoveObjective(mind, i) ? "Objective successfully removed!" : "Objective removing failed. Maybe the index is out of bounds? Check lsobjectives!"); diff --git a/Content.Server/Objectives/Conditions/DieCondition.cs b/Content.Server/Objectives/Conditions/DieCondition.cs index 48fc9fc8b3..d5e9e1aef6 100644 --- a/Content.Server/Objectives/Conditions/DieCondition.cs +++ b/Content.Server/Objectives/Conditions/DieCondition.cs @@ -1,5 +1,5 @@ -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; using JetBrains.Annotations; using Robust.Shared.Utility; @@ -27,7 +27,7 @@ namespace Content.Server.Objectives.Conditions get { var entityManager = IoCManager.Resolve(); - var mindSystem = entityManager.System(); + var mindSystem = entityManager.System(); return _mind == null || mindSystem.IsCharacterDeadIc(_mind) ? 1f : 0f; } } diff --git a/Content.Server/Objectives/Conditions/EscapeShuttleCondition.cs b/Content.Server/Objectives/Conditions/EscapeShuttleCondition.cs index 8848a15085..27d7975c24 100644 --- a/Content.Server/Objectives/Conditions/EscapeShuttleCondition.cs +++ b/Content.Server/Objectives/Conditions/EscapeShuttleCondition.cs @@ -1,7 +1,7 @@ -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; using Content.Server.Shuttles.Systems; using Content.Shared.Cuffs.Components; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; using JetBrains.Annotations; using Robust.Shared.Utility; @@ -32,7 +32,7 @@ namespace Content.Server.Objectives.Conditions { get { var entMan = IoCManager.Resolve(); - var mindSystem = entMan.System(); + var mindSystem = entMan.System(); if (_mind?.OwnedEntity == null || !entMan.TryGetComponent(_mind.OwnedEntity, out var xform)) diff --git a/Content.Server/Objectives/Conditions/KillPersonCondition.cs b/Content.Server/Objectives/Conditions/KillPersonCondition.cs index e8568f0534..b5f16a62a2 100644 --- a/Content.Server/Objectives/Conditions/KillPersonCondition.cs +++ b/Content.Server/Objectives/Conditions/KillPersonCondition.cs @@ -1,9 +1,9 @@ -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; -using Content.Server.Roles.Jobs; using Content.Server.Shuttles.Systems; using Content.Shared.CCVar; +using Content.Shared.Mind; using Content.Shared.Mobs.Systems; +using Content.Shared.Objectives.Interfaces; +using Content.Shared.Roles.Jobs; using Robust.Shared.Configuration; using Robust.Shared.Utility; @@ -13,8 +13,8 @@ namespace Content.Server.Objectives.Conditions { // TODO refactor all of this to be ecs protected IEntityManager EntityManager => IoCManager.Resolve(); - protected MindSystem Minds => EntityManager.System(); - protected JobSystem Jobs => EntityManager.System(); + protected SharedMindSystem Minds => EntityManager.System(); + protected SharedJobSystem Jobs => EntityManager.System(); protected MobStateSystem MobStateSystem => EntityManager.System(); protected EntityUid? TargetMindId; protected MindComponent? TargetMind => EntityManager.GetComponentOrNull(TargetMindId); @@ -52,7 +52,7 @@ namespace Content.Server.Objectives.Conditions return 1f; var entMan = IoCManager.Resolve(); - var mindSystem = entMan.System(); + var mindSystem = entMan.System(); if (mindSystem.IsCharacterDeadIc(TargetMind)) return 1f; diff --git a/Content.Server/Objectives/Conditions/KillRandomHeadCondition.cs b/Content.Server/Objectives/Conditions/KillRandomHeadCondition.cs index b5e7f5c8cc..2703a37bc1 100644 --- a/Content.Server/Objectives/Conditions/KillRandomHeadCondition.cs +++ b/Content.Server/Objectives/Conditions/KillRandomHeadCondition.cs @@ -1,8 +1,8 @@ using System.Linq; -using Content.Server.Mind; -using Content.Server.Mind.Components; -using Content.Server.Objectives.Interfaces; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Mobs.Components; +using Content.Shared.Objectives.Interfaces; using Robust.Shared.Random; namespace Content.Server.Objectives.Conditions; @@ -17,7 +17,7 @@ public sealed partial class KillRandomHeadCondition : KillPersonCondition var allHumans = EntityManager.EntityQuery(true).Where(mc => { - var entity = EntityManager.GetComponentOrNull(mc.Mind)?.OwnedEntity; + var entity = EntityManagerExt.GetComponentOrNull(EntityManager, (EntityUid?) mc.Mind)?.OwnedEntity; if (entity == default) return false; diff --git a/Content.Server/Objectives/Conditions/KillRandomPersonCondition.cs b/Content.Server/Objectives/Conditions/KillRandomPersonCondition.cs index 1d27e72b27..74eb6422b2 100644 --- a/Content.Server/Objectives/Conditions/KillRandomPersonCondition.cs +++ b/Content.Server/Objectives/Conditions/KillRandomPersonCondition.cs @@ -1,8 +1,8 @@ -using Content.Server.Mind; -using Content.Server.Mind.Components; -using Content.Server.Objectives.Interfaces; using Content.Shared.Humanoid; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Mobs.Components; +using Content.Shared.Objectives.Interfaces; using Robust.Shared.Random; namespace Content.Server.Objectives.Conditions; diff --git a/Content.Server/Objectives/Conditions/RandomTraitorAliveCondition.cs b/Content.Server/Objectives/Conditions/RandomTraitorAliveCondition.cs index 9aa063e3f9..8f914f0896 100644 --- a/Content.Server/Objectives/Conditions/RandomTraitorAliveCondition.cs +++ b/Content.Server/Objectives/Conditions/RandomTraitorAliveCondition.cs @@ -1,8 +1,8 @@ using System.Linq; using Content.Server.GameTicking.Rules; -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; -using Content.Server.Roles.Jobs; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; +using Content.Shared.Roles.Jobs; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -17,7 +17,7 @@ namespace Content.Server.Objectives.Conditions { var entityMgr = IoCManager.Resolve(); - var traitors = entityMgr.System().GetOtherTraitorMindsAliveAndConnected(mind).ToList(); + var traitors = Enumerable.ToList<(EntityUid Id, MindComponent Mind)>(entityMgr.System().GetOtherTraitorMindsAliveAndConnected(mind)); if (traitors.Count == 0) return new EscapeShuttleCondition(); //You were made a traitor by admins, and are the first/only. @@ -30,7 +30,7 @@ namespace Content.Server.Objectives.Conditions { var targetName = string.Empty; var ents = IoCManager.Resolve(); - var jobs = ents.System(); + var jobs = ents.System(); var jobName = jobs.MindTryGetJobName(_targetMind); if (_targetMind == null) @@ -55,7 +55,7 @@ namespace Content.Server.Objectives.Conditions get { var entityManager = IoCManager.Resolve(); - var mindSystem = entityManager.System(); + var mindSystem = entityManager.System(); return !entityManager.TryGetComponent(_targetMind, out MindComponent? mind) || !mindSystem.IsCharacterDeadIc(mind) ? 1f diff --git a/Content.Server/Objectives/Conditions/RandomTraitorProgressCondition.cs b/Content.Server/Objectives/Conditions/RandomTraitorProgressCondition.cs index d2f6a13baf..4b0dc018aa 100644 --- a/Content.Server/Objectives/Conditions/RandomTraitorProgressCondition.cs +++ b/Content.Server/Objectives/Conditions/RandomTraitorProgressCondition.cs @@ -1,8 +1,8 @@ using System.Linq; using Content.Server.GameTicking.Rules; -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; -using Content.Server.Roles.Jobs; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; +using Content.Shared.Roles.Jobs; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -51,7 +51,7 @@ namespace Content.Server.Objectives.Conditions { var targetName = string.Empty; var entities = IoCManager.Resolve(); - var jobs = entities.System(); + var jobs = entities.System(); var jobName = jobs.MindTryGetJobName(_targetMind); if (_targetMind == null) diff --git a/Content.Server/Objectives/Conditions/StealCondition.cs b/Content.Server/Objectives/Conditions/StealCondition.cs index 77f8852ddb..5ca36a7784 100644 --- a/Content.Server/Objectives/Conditions/StealCondition.cs +++ b/Content.Server/Objectives/Conditions/StealCondition.cs @@ -1,5 +1,5 @@ -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; using JetBrains.Annotations; using Robust.Shared.Containers; using Robust.Shared.Prototypes; diff --git a/Content.Server/Objectives/ObjectivesSystem.cs b/Content.Server/Objectives/ObjectivesSystem.cs index 9536578f9a..ce6cb9a1f6 100644 --- a/Content.Server/Objectives/ObjectivesSystem.cs +++ b/Content.Server/Objectives/ObjectivesSystem.cs @@ -1,4 +1,5 @@ -using Content.Server.Mind; +using Content.Shared.Mind; +using Content.Shared.Objectives; using Content.Shared.Random; using Content.Shared.Random.Helpers; using Robust.Shared.Prototypes; diff --git a/Content.Server/Objectives/Requirements/IncompatibleConditionsRequirement.cs b/Content.Server/Objectives/Requirements/IncompatibleConditionsRequirement.cs index ad4f2f768b..9a235e53ad 100644 --- a/Content.Server/Objectives/Requirements/IncompatibleConditionsRequirement.cs +++ b/Content.Server/Objectives/Requirements/IncompatibleConditionsRequirement.cs @@ -1,5 +1,5 @@ -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; namespace Content.Server.Objectives.Requirements { diff --git a/Content.Server/Objectives/Requirements/IncompatibleObjectivesRequirement.cs b/Content.Server/Objectives/Requirements/IncompatibleObjectivesRequirement.cs index ab71366708..57209dcdbf 100644 --- a/Content.Server/Objectives/Requirements/IncompatibleObjectivesRequirement.cs +++ b/Content.Server/Objectives/Requirements/IncompatibleObjectivesRequirement.cs @@ -1,5 +1,5 @@ -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; namespace Content.Server.Objectives.Requirements { diff --git a/Content.Server/Objectives/Requirements/MultipleTraitorsRequirement.cs b/Content.Server/Objectives/Requirements/MultipleTraitorsRequirement.cs index 0797d95b35..826894104c 100644 --- a/Content.Server/Objectives/Requirements/MultipleTraitorsRequirement.cs +++ b/Content.Server/Objectives/Requirements/MultipleTraitorsRequirement.cs @@ -1,6 +1,6 @@ using Content.Server.GameTicking.Rules; -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; namespace Content.Server.Objectives.Requirements { diff --git a/Content.Server/Objectives/Requirements/NotRoleRequirement.cs b/Content.Server/Objectives/Requirements/NotRoleRequirement.cs index 5043d3dc80..f0b06f3b82 100644 --- a/Content.Server/Objectives/Requirements/NotRoleRequirement.cs +++ b/Content.Server/Objectives/Requirements/NotRoleRequirement.cs @@ -1,7 +1,7 @@ -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; -using Content.Server.Roles.Jobs; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Server.Objectives.Requirements diff --git a/Content.Server/Objectives/Requirements/TraitorRequirement.cs b/Content.Server/Objectives/Requirements/TraitorRequirement.cs index d4dec52a2e..e2bab8f471 100644 --- a/Content.Server/Objectives/Requirements/TraitorRequirement.cs +++ b/Content.Server/Objectives/Requirements/TraitorRequirement.cs @@ -1,6 +1,7 @@ -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; -using Content.Server.Roles; +using Content.Server.Roles; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; +using Content.Shared.Roles; using JetBrains.Annotations; namespace Content.Server.Objectives.Requirements @@ -11,7 +12,7 @@ namespace Content.Server.Objectives.Requirements { public bool CanBeAssigned(EntityUid mindId, MindComponent mind) { - var roleSystem = IoCManager.Resolve().System(); + var roleSystem = IoCManager.Resolve().System(); return roleSystem.MindHasRole(mindId); } } diff --git a/Content.Server/PAI/PAISystem.cs b/Content.Server/PAI/PAISystem.cs index 27ab1ba165..a601bdea8b 100644 --- a/Content.Server/PAI/PAISystem.cs +++ b/Content.Server/PAI/PAISystem.cs @@ -1,6 +1,6 @@ using Content.Server.Instruments; -using Content.Server.Mind.Components; using Content.Shared.Interaction.Events; +using Content.Shared.Mind.Components; using Content.Shared.PAI; using Robust.Server.GameObjects; diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs index 1a8314011d..3902b8e1b9 100644 --- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs +++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs @@ -2,11 +2,12 @@ using System.Linq; using Content.Server.Afk; using Content.Server.Afk.Events; using Content.Server.GameTicking; -using Content.Server.Roles; +using Content.Server.Mind; using Content.Shared.CCVar; using Content.Shared.GameTicking; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; +using Content.Shared.Players; using Content.Shared.Players.PlayTimeTracking; using Content.Shared.Roles; using Robust.Server.GameObjects; @@ -27,6 +28,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPrototypeManager _prototypes = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private readonly MindSystem _minds = default!; [Dependency] private readonly PlayTimeTrackingManager _tracking = default!; public override void Initialize() @@ -103,18 +105,14 @@ public sealed class PlayTimeTrackingSystem : EntitySystem private void OnRoleRemove(RoleRemovedEvent ev) { - if (ev.Mind.Session == null) - return; - - _tracking.QueueRefreshTrackers(ev.Mind.Session); + if (_minds.TryGetSession(ev.Mind, out var session)) + _tracking.QueueRefreshTrackers(session); } private void OnRoleAdd(RoleAddedEvent ev) { - if (ev.Mind.Session == null) - return; - - _tracking.QueueRefreshTrackers(ev.Mind.Session); + if (_minds.TryGetSession(ev.Mind, out var session)) + _tracking.QueueRefreshTrackers(session); } private void OnRoundEnd(RoundRestartCleanupEvent ev) diff --git a/Content.Server/Players/PlayerData.cs b/Content.Server/Players/PlayerData.cs index aadaeb225c..b0ca6f3c18 100644 --- a/Content.Server/Players/PlayerData.cs +++ b/Content.Server/Players/PlayerData.cs @@ -1,59 +1,11 @@ -using Content.Server.GameTicking; -using Content.Server.Mind; +using Content.Shared.Players; using Robust.Server.Player; -using Robust.Shared.Network; +using Robust.Shared.Players; namespace Content.Server.Players { - /// - /// Content side for all data that tracks a player session. - /// Use to retrieve this from an . - /// - public sealed class PlayerData - { - /// - /// The session ID of the player owning this data. - /// - [ViewVariables] - public NetUserId UserId { get; } - - /// - /// This is a backup copy of the player name stored on connection. - /// This is useful in the event the player disconnects. - /// - [ViewVariables] - public string Name { get; } - - /// - /// The currently occupied mind of the player owning this data. - /// DO NOT DIRECTLY SET THIS UNLESS YOU KNOW WHAT YOU'RE DOING. - /// - [ViewVariables, Access(typeof(MindSystem), typeof(GameTicker))] - public EntityUid? Mind { get; set; } - - /// - /// If true, the player is an admin and they explicitly de-adminned mid-game, - /// so they should not regain admin if they reconnect. - /// - public bool ExplicitlyDeadminned { get; set; } - - public PlayerData(NetUserId userId, string name) - { - UserId = userId; - Name = name; - } - } - public static class PlayerDataExt { - /// - /// Gets the correctly cast instance of content player data from an engine player data storage. - /// - public static PlayerData? ContentData(this IPlayerData data) - { - return (PlayerData?) data.ContentDataUncast; - } - /// /// Gets the correctly cast instance of content player data from an engine player data storage. /// @@ -62,6 +14,11 @@ namespace Content.Server.Players return session.Data.ContentData(); } + public static PlayerData? ContentData(this ICommonSession session) + { + return ((IPlayerSession) session).ContentData(); + } + /// /// Gets the mind that is associated with this player. /// diff --git a/Content.Server/Players/PlayerSystem.cs b/Content.Server/Players/PlayerSystem.cs new file mode 100644 index 0000000000..0c407aa876 --- /dev/null +++ b/Content.Server/Players/PlayerSystem.cs @@ -0,0 +1,12 @@ +using Content.Shared.Players; +using Robust.Shared.Players; + +namespace Content.Server.Players; + +public sealed class PlayerSystem : SharedPlayerSystem +{ + public override PlayerData? ContentData(ICommonSession? session) + { + return session?.ContentData(); + } +} diff --git a/Content.Server/Pointing/EntitySystems/PointingSystem.cs b/Content.Server/Pointing/EntitySystems/PointingSystem.cs index 8194b72927..5d96b4c5bb 100644 --- a/Content.Server/Pointing/EntitySystems/PointingSystem.cs +++ b/Content.Server/Pointing/EntitySystems/PointingSystem.cs @@ -1,6 +1,5 @@ using System.Linq; using Content.Server.Administration.Logs; -using Content.Server.Mind; using Content.Server.Pointing.Components; using Content.Server.Visible; using Content.Shared.Bed.Sleep; @@ -10,6 +9,7 @@ using Content.Shared.IdentityManagement; using Content.Shared.Input; using Content.Shared.Interaction; using Content.Shared.Interaction.Helpers; +using Content.Shared.Mind; using Content.Shared.Mobs.Systems; using Content.Shared.Pointing; using Content.Shared.Popups; @@ -38,7 +38,7 @@ namespace Content.Server.Pointing.EntitySystems [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly VisibilitySystem _visibilitySystem = default!; - [Dependency] private readonly MindSystem _minds = default!; + [Dependency] private readonly SharedMindSystem _minds = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; private static readonly TimeSpan PointDelay = TimeSpan.FromSeconds(0.5f); diff --git a/Content.Server/Polymorph/Systems/PolymorphSystem.cs b/Content.Server/Polymorph/Systems/PolymorphSystem.cs index fae5ce67d2..907e79db7f 100644 --- a/Content.Server/Polymorph/Systems/PolymorphSystem.cs +++ b/Content.Server/Polymorph/Systems/PolymorphSystem.cs @@ -1,7 +1,6 @@ using Content.Server.Actions; using Content.Server.Humanoid; using Content.Server.Inventory; -using Content.Server.Mind; using Content.Server.Mind.Commands; using Content.Server.Nutrition; using Content.Server.Polymorph.Components; @@ -11,6 +10,7 @@ using Content.Shared.Buckle; using Content.Shared.Damage; using Content.Shared.Hands.EntitySystems; using Content.Shared.IdentityManagement; +using Content.Shared.Mind; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Polymorph; @@ -41,7 +41,7 @@ namespace Content.Server.Polymorph.Systems [Dependency] private readonly SharedHandsSystem _hands = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly TransformSystem _transform = default!; - [Dependency] private readonly MindSystem _mindSystem = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; private ISawmill _sawmill = default!; diff --git a/Content.Server/Revenant/EntitySystems/EssenceSystem.cs b/Content.Server/Revenant/EntitySystems/EssenceSystem.cs index 5f95da95e8..f6de79fee5 100644 --- a/Content.Server/Revenant/EntitySystems/EssenceSystem.cs +++ b/Content.Server/Revenant/EntitySystems/EssenceSystem.cs @@ -1,6 +1,6 @@ -using Content.Server.Mind.Components; using Content.Server.Revenant.Components; using Content.Shared.Examine; +using Content.Shared.Mind.Components; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Revenant.Components; diff --git a/Content.Server/Roles/AddRoleCommand.cs b/Content.Server/Roles/AddRoleCommand.cs index 21d7adfed5..e510d24ac0 100644 --- a/Content.Server/Roles/AddRoleCommand.cs +++ b/Content.Server/Roles/AddRoleCommand.cs @@ -1,7 +1,7 @@ using Content.Server.Administration; -using Content.Server.Players; using Content.Server.Roles.Jobs; using Content.Shared.Administration; +using Content.Shared.Players; using Content.Shared.Roles; using Robust.Server.Player; using Robust.Shared.Console; diff --git a/Content.Server/Roles/Jobs/JobSystem.cs b/Content.Server/Roles/Jobs/JobSystem.cs index bdc54bd17c..22d6286215 100644 --- a/Content.Server/Roles/Jobs/JobSystem.cs +++ b/Content.Server/Roles/Jobs/JobSystem.cs @@ -1,23 +1,17 @@ -using System.Diagnostics.CodeAnalysis; -using System.Globalization; +using System.Globalization; using Content.Server.Chat.Managers; using Content.Server.Mind; -using Content.Server.Players; +using Content.Shared.Mind; using Content.Shared.Roles; -using Robust.Server.Player; -using Robust.Shared.Prototypes; +using Content.Shared.Roles.Jobs; namespace Content.Server.Roles.Jobs; -/// -/// Handles the job data on mind entities. -/// -public sealed class JobSystem : EntitySystem +public sealed class JobSystem : SharedJobSystem { [Dependency] private readonly IChatManager _chat = default!; - [Dependency] private readonly MindSystem _mind = default!; - [Dependency] private readonly RoleSystem _roles = default!; - [Dependency] private readonly IPrototypeManager _prototypes = default!; + [Dependency] private readonly MindSystem _minds = default!; + [Dependency] private readonly SharedRoleSystem _roles = default!; public override void Initialize() { @@ -29,7 +23,7 @@ public sealed class JobSystem : EntitySystem if (args.Silent) return; - if (!_mind.TryGetSession(mindId, out var session)) + if (!_minds.TryGetSession(mindId, out var session)) return; if (!MindTryGetJob(mindId, out _, out var prototype)) @@ -51,59 +45,4 @@ public sealed class JobSystem : EntitySystem _roles.MindAddRole(mindId, new JobComponent { PrototypeId = jobPrototypeId }); } - - public bool MindHasJobWithId(EntityUid? mindId, string prototypeId) - { - return CompOrNull(mindId)?.PrototypeId == prototypeId; - } - - public bool MindTryGetJob( - [NotNullWhen(true)] EntityUid? mindId, - [NotNullWhen(true)] out JobComponent? comp, - [NotNullWhen(true)] out JobPrototype? prototype) - { - comp = null; - prototype = null; - - return TryComp(mindId, out comp) && - comp.PrototypeId != null && - _prototypes.TryIndex(comp.PrototypeId, out prototype); - } - - /// - /// Tries to get the job name for this mind. - /// Returns unknown if not found. - /// - public bool MindTryGetJobName([NotNullWhen(true)] EntityUid? mindId, out string name) - { - if (MindTryGetJob(mindId, out _, out var prototype)) - { - name = prototype.LocalizedName; - return true; - } - - name = Loc.GetString("generic-unknown-title"); - return false; - } - - /// - /// Tries to get the job name for this mind. - /// Returns unknown if not found. - /// - public string MindTryGetJobName([NotNullWhen(true)] EntityUid? mindId) - { - MindTryGetJobName(mindId, out var name); - return name; - } - - public bool CanBeAntag(IPlayerSession player) - { - if (player.ContentData() is not { Mind: { } mindId }) - return false; - - if (!MindTryGetJob(mindId, out _, out var prototype)) - return true; - - return prototype.CanBeAntag; - } } diff --git a/Content.Server/Roles/NukeopsRoleComponent.cs b/Content.Server/Roles/NukeopsRoleComponent.cs index 1f11100e0c..5ae893566c 100644 --- a/Content.Server/Roles/NukeopsRoleComponent.cs +++ b/Content.Server/Roles/NukeopsRoleComponent.cs @@ -1,4 +1,6 @@ -namespace Content.Server.Roles; +using Content.Shared.Roles; + +namespace Content.Server.Roles; /// /// Added to mind entities to tag that they are a nuke operative. diff --git a/Content.Server/Roles/RemoveRoleCommand.cs b/Content.Server/Roles/RemoveRoleCommand.cs index 58cea3e23d..edb29da624 100644 --- a/Content.Server/Roles/RemoveRoleCommand.cs +++ b/Content.Server/Roles/RemoveRoleCommand.cs @@ -1,7 +1,8 @@ using Content.Server.Administration; -using Content.Server.Players; -using Content.Server.Roles.Jobs; using Content.Shared.Administration; +using Content.Shared.Players; +using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; @@ -43,8 +44,8 @@ namespace Content.Server.Roles return; } - var roles = _entityManager.System(); - var jobs = _entityManager.System(); + var roles = _entityManager.System(); + var jobs = _entityManager.System(); if (jobs.MindHasJobWithId(mind, args[1])) roles.MindRemoveRole(mind.Value); } diff --git a/Content.Server/Roles/RoleSystem.cs b/Content.Server/Roles/RoleSystem.cs index a70a51e7e5..54160d19e2 100644 --- a/Content.Server/Roles/RoleSystem.cs +++ b/Content.Server/Roles/RoleSystem.cs @@ -1,25 +1,13 @@ -using Content.Server.Administration.Logs; -using Content.Server.Mind; -using Content.Server.Roles.Jobs; -using Content.Shared.Database; -using Content.Shared.Roles; -using Robust.Shared.Prototypes; +using Content.Shared.Roles; namespace Content.Server.Roles; -public sealed class RoleSystem : EntitySystem +public sealed class RoleSystem : SharedRoleSystem { - [Dependency] private readonly IAdminLogManager _adminLogger = default!; - [Dependency] private readonly IPrototypeManager _prototypes = default!; - [Dependency] private readonly MindSystem _minds = default!; - - // TODO please lord make role entities - private readonly HashSet _antagTypes = new(); - public override void Initialize() { // TODO make roles entities - SubscribeLocalEvent(OnJobGetAllRoles); + base.Initialize(); SubscribeAntagEvents(); SubscribeAntagEvents(); @@ -27,142 +15,9 @@ public sealed class RoleSystem : EntitySystem SubscribeAntagEvents(); } - private void OnJobGetAllRoles(EntityUid uid, JobComponent component, ref MindGetAllRolesEvent args) - { - var name = "game-ticker-unknown-role"; - string? playTimeTracker = null; - if (component.PrototypeId != null && _prototypes.TryIndex(component.PrototypeId, out JobPrototype? job)) - { - name = job.Name; - playTimeTracker = job.PlayTimeTracker; - } - - name = Loc.GetString(name); - - args.Roles.Add(new RoleInfo(component, name, false, playTimeTracker)); - } - - private void SubscribeAntagEvents() where T : AntagonistRoleComponent - { - SubscribeLocalEvent((EntityUid _, T component, ref MindGetAllRolesEvent args) => - { - var name = "game-ticker-unknown-role"; - if (component.PrototypeId != null && _prototypes.TryIndex(component.PrototypeId, out AntagPrototype? antag)) - { - name = antag.Name; - } - name = Loc.GetString(name); - - args.Roles.Add(new RoleInfo(component, name, true, null)); - }); - - SubscribeLocalEvent((EntityUid _, T _, ref MindIsAntagonistEvent args) => args.IsAntagonist = true); - _antagTypes.Add(typeof(T)); - } - - /// - /// Gives this mind a new role. - /// - /// The mind to add the role to. - /// The role instance to add. - /// The role type to add. - /// Whether or not the role should be added silently - /// The instance of the role. - /// - /// Thrown if we already have a role with this type. - /// - public void MindAddRole(EntityUid mindId, T component, MindComponent? mind = null, bool silent = false) where T : Component, new() - { - if (!Resolve(mindId, ref mind)) - return; - - if (HasComp(mindId)) - { - throw new ArgumentException($"We already have this role: {typeof(T)}"); - } - - AddComp(mindId, component); - var antagonist = IsAntagonistRole(); - - var mindEv = new MindRoleAddedEvent(); - RaiseLocalEvent(mindId, ref mindEv); - - var message = new RoleAddedEvent(mindId, mind, antagonist, silent); - if (mind.OwnedEntity != null) - { - RaiseLocalEvent(mind.OwnedEntity.Value, message, true); - } - - _adminLogger.Add(LogType.Mind, LogImpact.Low, - $"'Role {typeof(T).Name}' added to mind of {_minds.MindOwnerLoggingString(mind)}"); - } - - /// - /// Removes a role from this mind. - /// - /// The mind to remove the role from. - /// The type of the role to remove. - /// - /// Thrown if we do not have this role. - /// - public void MindRemoveRole(EntityUid mindId) where T : Component - { - if (!RemComp(mindId)) - { - throw new ArgumentException($"We do not have this role: {typeof(T)}"); - } - - var mind = Comp(mindId); - var antagonist = IsAntagonistRole(); - var message = new RoleRemovedEvent(mindId, mind, antagonist); - - if (mind.OwnedEntity != null) - { - RaiseLocalEvent(mind.OwnedEntity.Value, message, true); - } - _adminLogger.Add(LogType.Mind, LogImpact.Low, - $"'Role {typeof(T).Name}' removed from mind of {_minds.MindOwnerLoggingString(mind)}"); - } - - public bool MindTryRemoveRole(EntityUid mindId) where T : Component - { - if (!MindHasRole(mindId)) - return false; - - MindRemoveRole(mindId); - return true; - } - - public bool MindHasRole(EntityUid mindId) where T : Component - { - return HasComp(mindId); - } - - public List MindGetAllRoles(EntityUid mindId) - { - var ev = new MindGetAllRolesEvent(new List()); - RaiseLocalEvent(mindId, ref ev); - return ev.Roles; - } - - public bool MindIsAntagonist(EntityUid? mindId) - { - if (mindId == null) - return false; - - var ev = new MindIsAntagonistEvent(); - RaiseLocalEvent(mindId.Value, ref ev); - return ev.IsAntagonist; - } - public string? MindGetBriefing(EntityUid? mindId) { // TODO this should be an event return CompOrNull(mindId)?.Briefing; } - - public bool IsAntagonistRole() - { - return _antagTypes.Contains(typeof(T)); - } } diff --git a/Content.Server/Roles/SubvertedSiliconRoleComponent.cs b/Content.Server/Roles/SubvertedSiliconRoleComponent.cs index 76d294cebf..70056fbec9 100644 --- a/Content.Server/Roles/SubvertedSiliconRoleComponent.cs +++ b/Content.Server/Roles/SubvertedSiliconRoleComponent.cs @@ -1,4 +1,6 @@ -namespace Content.Server.Roles; +using Content.Shared.Roles; + +namespace Content.Server.Roles; [RegisterComponent] public sealed partial class SubvertedSiliconRoleComponent : AntagonistRoleComponent diff --git a/Content.Server/Roles/TraitorRoleComponent.cs b/Content.Server/Roles/TraitorRoleComponent.cs index 61af9a4390..52e7d25ab7 100644 --- a/Content.Server/Roles/TraitorRoleComponent.cs +++ b/Content.Server/Roles/TraitorRoleComponent.cs @@ -1,4 +1,6 @@ -namespace Content.Server.Roles; +using Content.Shared.Roles; + +namespace Content.Server.Roles; [RegisterComponent] public sealed partial class TraitorRoleComponent : AntagonistRoleComponent diff --git a/Content.Server/Roles/ZombieRoleComponent.cs b/Content.Server/Roles/ZombieRoleComponent.cs index 7f8d9eb44b..8c0354afc4 100644 --- a/Content.Server/Roles/ZombieRoleComponent.cs +++ b/Content.Server/Roles/ZombieRoleComponent.cs @@ -1,4 +1,6 @@ -namespace Content.Server.Roles; +using Content.Shared.Roles; + +namespace Content.Server.Roles; [RegisterComponent] public sealed partial class ZombieRoleComponent : AntagonistRoleComponent diff --git a/Content.Server/Silicons/Borgs/BorgSystem.MMI.cs b/Content.Server/Silicons/Borgs/BorgSystem.MMI.cs index 8a03bd7589..76ccb21da3 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.MMI.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.MMI.cs @@ -1,5 +1,5 @@ -using Content.Server.Mind.Components; -using Content.Shared.Containers.ItemSlots; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Mind.Components; using Content.Shared.Silicons.Borgs.Components; using Robust.Shared.Containers; diff --git a/Content.Server/Silicons/Borgs/BorgSystem.cs b/Content.Server/Silicons/Borgs/BorgSystem.cs index 24608f849b..611dfa6ea2 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.cs @@ -2,8 +2,6 @@ using Content.Server.Administration.Logs; using Content.Server.Administration.Managers; using Content.Server.Hands.Systems; -using Content.Server.Mind; -using Content.Server.Mind.Components; using Content.Server.PowerCell; using Content.Server.UserInterface; using Content.Shared.Access.Systems; @@ -11,6 +9,8 @@ using Content.Shared.Alert; using Content.Shared.Database; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Movement.Systems; using Content.Shared.PowerCell; using Content.Shared.PowerCell.Components; @@ -20,8 +20,8 @@ using Content.Shared.Silicons.Borgs.Components; using Content.Shared.Throwing; using Content.Shared.Wires; using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Containers; +using Robust.Shared.Players; using Robust.Shared.Random; namespace Content.Server.Silicons.Borgs; @@ -38,7 +38,7 @@ public sealed partial class BorgSystem : SharedBorgSystem [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly HandsSystem _hands = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; - [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!; [Dependency] private readonly PowerCellSystem _powerCell = default!; [Dependency] private readonly ThrowingSystem _throwing = default!; @@ -302,7 +302,7 @@ public sealed partial class BorgSystem : SharedBorgSystem /// Checks that a player has fulfilled the requirements for the borg job. /// If they don't have enough hours, they cannot be placed into a chassis. /// - public bool CanPlayerBeBorgged(IPlayerSession session) + public bool CanPlayerBeBorgged(ICommonSession session) { if (_banManager.GetJobBans(session.UserId)?.Contains(BorgJobId) == true) return false; diff --git a/Content.Server/Silicons/Laws/SiliconLawSystem.cs b/Content.Server/Silicons/Laws/SiliconLawSystem.cs index fd1e38ff2c..e83fc9b6aa 100644 --- a/Content.Server/Silicons/Laws/SiliconLawSystem.cs +++ b/Content.Server/Silicons/Laws/SiliconLawSystem.cs @@ -1,8 +1,6 @@ using Content.Server.Administration; using Content.Server.Chat.Managers; using Content.Server.GameTicking; -using Content.Server.Mind; -using Content.Server.Mind.Components; using Content.Server.Radio.Components; using Content.Server.Roles; using Content.Server.Station.Systems; @@ -13,6 +11,9 @@ using Content.Shared.Chat; using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.Examine; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; +using Content.Shared.Roles; using Content.Shared.Silicons.Laws; using Content.Shared.Silicons.Laws.Components; using Content.Shared.Stunnable; @@ -29,13 +30,13 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem { [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; - [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly StationSystem _station = default!; [Dependency] private readonly UserInterfaceSystem _userInterface = default!; [Dependency] private readonly SharedStunSystem _stunSystem = default!; [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly RoleSystem _roles = default!; + [Dependency] private readonly SharedRoleSystem _roles = default!; /// public override void Initialize() diff --git a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs index 80c4ffb4d5..69d1fd7c34 100644 --- a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs +++ b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs @@ -1,19 +1,18 @@ +using System.Numerics; using Content.Server.Administration.Logs; -using Content.Server.Mind.Components; -using Content.Server.Station.Components; using Content.Server.Singularity.Events; +using Content.Server.Station.Components; using Content.Shared.Database; +using Content.Shared.Ghost; +using Content.Shared.Mind.Components; using Content.Shared.Singularity.Components; using Content.Shared.Singularity.EntitySystems; using Content.Shared.Tag; using Robust.Shared.Containers; -using Robust.Shared.Timing; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Physics.Events; -using System.Numerics; -using Content.Shared.Ghost; - +using Robust.Shared.Timing; namespace Content.Server.Singularity.EntitySystems; diff --git a/Content.Server/Station/Systems/StationSpawningSystem.cs b/Content.Server/Station/Systems/StationSpawningSystem.cs index 4229c514db..4aa1b117e5 100644 --- a/Content.Server/Station/Systems/StationSpawningSystem.cs +++ b/Content.Server/Station/Systems/StationSpawningSystem.cs @@ -4,7 +4,6 @@ using Content.Server.Humanoid; using Content.Server.IdentityManagement; using Content.Server.Mind.Commands; using Content.Server.PDA; -using Content.Server.Roles.Jobs; using Content.Server.Station.Components; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; @@ -16,6 +15,7 @@ using Content.Shared.Preferences; using Content.Shared.Random; using Content.Shared.Random.Helpers; using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; using Content.Shared.Station; using Content.Shared.StatusIcon; using JetBrains.Annotations; diff --git a/Content.Server/StationEvents/Events/MassHallucinationsRule.cs b/Content.Server/StationEvents/Events/MassHallucinationsRule.cs index 9e82571c99..722a489541 100644 --- a/Content.Server/StationEvents/Events/MassHallucinationsRule.cs +++ b/Content.Server/StationEvents/Events/MassHallucinationsRule.cs @@ -1,7 +1,7 @@ using Content.Server.GameTicking.Rules.Components; -using Content.Server.Mind.Components; using Content.Server.StationEvents.Components; using Content.Server.Traits.Assorted; +using Content.Shared.Mind.Components; using Content.Shared.Traits.Assorted; namespace Content.Server.StationEvents.Events; diff --git a/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs b/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs index 6f57da1658..4ac6d4798b 100644 --- a/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs +++ b/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs @@ -1,6 +1,5 @@ using System.Linq; using Content.Server.Explosion.EntitySystems; -using Content.Server.Mind.Components; using Content.Server.Resist; using Content.Server.Station.Components; using Content.Server.Storage.Components; @@ -9,6 +8,7 @@ using Content.Shared.Access.Components; using Content.Shared.Coordinates; using Content.Shared.DoAfter; using Content.Shared.Lock; +using Content.Shared.Mind.Components; using Content.Shared.Storage.Components; using Content.Shared.Storage.EntitySystems; using Robust.Shared.Random; diff --git a/Content.Server/Store/Conditions/BuyerAntagCondition.cs b/Content.Server/Store/Conditions/BuyerAntagCondition.cs index 0330a40300..1edc4a3365 100644 --- a/Content.Server/Store/Conditions/BuyerAntagCondition.cs +++ b/Content.Server/Store/Conditions/BuyerAntagCondition.cs @@ -1,5 +1,4 @@ -using Content.Server.Mind; -using Content.Server.Roles; +using Content.Shared.Mind; using Content.Shared.Roles; using Content.Shared.Store; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; @@ -28,12 +27,12 @@ public sealed partial class BuyerAntagCondition : ListingCondition public override bool Condition(ListingConditionArgs args) { var ent = args.EntityManager; - var minds = ent.System(); + var minds = ent.System(); if (!minds.TryGetMind(args.Buyer, out var mindId, out var mind)) return true; - var roleSystem = ent.System(); + var roleSystem = ent.System(); var roles = roleSystem.MindGetAllRoles(mindId); if (Blacklist != null) diff --git a/Content.Server/Store/Conditions/BuyerDepartmentCondition.cs b/Content.Server/Store/Conditions/BuyerDepartmentCondition.cs index a5ed3f2f9a..43175b6a80 100644 --- a/Content.Server/Store/Conditions/BuyerDepartmentCondition.cs +++ b/Content.Server/Store/Conditions/BuyerDepartmentCondition.cs @@ -1,6 +1,6 @@ -using Content.Server.Mind; -using Content.Server.Roles.Jobs; +using Content.Shared.Mind; using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; using Content.Shared.Store; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; @@ -30,13 +30,13 @@ public sealed partial class BuyerDepartmentCondition : ListingCondition var prototypeManager = IoCManager.Resolve(); var ent = args.EntityManager; - var minds = ent.System(); + var minds = ent.System(); // this is for things like surplus crate if (!minds.TryGetMind(args.Buyer, out var mindId, out _)) return true; - var jobs = ent.System(); + var jobs = ent.System(); if (jobs.MindTryGetJob(mindId, out var job, out _)) { if (Blacklist != null) diff --git a/Content.Server/Store/Conditions/BuyerJobCondition.cs b/Content.Server/Store/Conditions/BuyerJobCondition.cs index c85e6f1144..47227cf79c 100644 --- a/Content.Server/Store/Conditions/BuyerJobCondition.cs +++ b/Content.Server/Store/Conditions/BuyerJobCondition.cs @@ -1,6 +1,6 @@ -using Content.Server.Mind; -using Content.Server.Roles.Jobs; +using Content.Shared.Mind; using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; using Content.Shared.Store; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; @@ -27,13 +27,13 @@ public sealed partial class BuyerJobCondition : ListingCondition public override bool Condition(ListingConditionArgs args) { var ent = args.EntityManager; - var minds = ent.System(); + var minds = ent.System(); // this is for things like surplus crate if (!minds.TryGetMind(args.Buyer, out var mindId, out _)) return true; - var jobs = ent.System(); + var jobs = ent.System(); if (jobs.MindTryGetJob(mindId, out var job, out _)) { if (Blacklist != null) diff --git a/Content.Server/Teleportation/PortalSystem.cs b/Content.Server/Teleportation/PortalSystem.cs index c3104f1219..76900a7e19 100644 --- a/Content.Server/Teleportation/PortalSystem.cs +++ b/Content.Server/Teleportation/PortalSystem.cs @@ -1,7 +1,7 @@ -using Content.Server.Mind.Components; -using Content.Shared.Administration.Logs; +using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Ghost; +using Content.Shared.Mind.Components; using Content.Shared.Teleportation.Systems; using Robust.Shared.Map; diff --git a/Content.Server/Worldgen/Systems/WorldControllerSystem.cs b/Content.Server/Worldgen/Systems/WorldControllerSystem.cs index b048ee8c80..19c777e1ad 100644 --- a/Content.Server/Worldgen/Systems/WorldControllerSystem.cs +++ b/Content.Server/Worldgen/Systems/WorldControllerSystem.cs @@ -1,7 +1,7 @@ using System.Linq; -using Content.Server.Mind.Components; using Content.Server.Worldgen.Components; using Content.Shared.Ghost; +using Content.Shared.Mind.Components; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Map; diff --git a/Content.Server/Zombies/ZombieSystem.Transform.cs b/Content.Server/Zombies/ZombieSystem.Transform.cs index 9cfc4c9e26..4bfe961b78 100644 --- a/Content.Server/Zombies/ZombieSystem.Transform.cs +++ b/Content.Server/Zombies/ZombieSystem.Transform.cs @@ -27,6 +27,7 @@ using Content.Shared.Mobs.Systems; using Content.Shared.Movement.Systems; using Content.Shared.Nutrition.Components; using Content.Shared.Popups; +using Content.Shared.Roles; using Content.Shared.Tools.Components; using Content.Shared.Weapons.Melee; using Content.Shared.Zombies; @@ -52,7 +53,7 @@ namespace Content.Server.Zombies [Dependency] private readonly SharedCombatModeSystem _combat = default!; [Dependency] private readonly IChatManager _chatMan = default!; [Dependency] private readonly MindSystem _mind = default!; - [Dependency] private readonly RoleSystem _roles = default!; + [Dependency] private readonly SharedRoleSystem _roles = default!; [Dependency] private readonly MobThresholdSystem _mobThreshold = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; diff --git a/Content.Server/Zombies/ZombieSystem.cs b/Content.Server/Zombies/ZombieSystem.cs index 7b71a429cf..0d51da03ae 100644 --- a/Content.Server/Zombies/ZombieSystem.cs +++ b/Content.Server/Zombies/ZombieSystem.cs @@ -4,13 +4,14 @@ using Content.Server.Chat; using Content.Server.Chat.Systems; using Content.Server.Cloning; using Content.Server.Drone.Components; -using Content.Server.Inventory; -using Content.Shared.Bed.Sleep; using Content.Server.Emoting.Systems; -using Content.Server.Mind; +using Content.Server.Inventory; using Content.Server.Speech.EntitySystems; +using Content.Shared.Bed.Sleep; using Content.Shared.Damage; +using Content.Shared.Humanoid; using Content.Shared.Inventory; +using Content.Shared.Mind; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; @@ -20,7 +21,6 @@ using Content.Shared.Zombies; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; -using Content.Shared.Humanoid; namespace Content.Server.Zombies { diff --git a/Content.Server/Mind/Components/MindContainerComponent.cs b/Content.Shared/Mind/Components/MindContainerComponent.cs similarity index 83% rename from Content.Server/Mind/Components/MindContainerComponent.cs rename to Content.Shared/Mind/Components/MindContainerComponent.cs index c78b18f70c..ca0f14d994 100644 --- a/Content.Server/Mind/Components/MindContainerComponent.cs +++ b/Content.Shared/Mind/Components/MindContainerComponent.cs @@ -1,18 +1,18 @@ using System.Diagnostics.CodeAnalysis; -namespace Content.Server.Mind.Components +namespace Content.Shared.Mind.Components { /// /// Stores a on a mob. /// - [RegisterComponent, Access(typeof(MindSystem))] + [RegisterComponent, Access(typeof(SharedMindSystem))] public sealed partial class MindContainerComponent : Component { /// /// The mind controlling this mob. Can be null. /// [ViewVariables] - [Access(typeof(MindSystem), Other = AccessPermissions.ReadWriteExecute)] // FIXME Friends + [Access(typeof(SharedMindSystem), Other = AccessPermissions.ReadWriteExecute)] // FIXME Friends public EntityUid? Mind { get; set; } /// @@ -34,7 +34,7 @@ namespace Content.Server.Mind.Components /// [ViewVariables(VVAccess.ReadWrite)] [DataField("ghostOnShutdown")] - [Access(typeof(MindSystem), Other = AccessPermissions.ReadWriteExecute)] // FIXME Friends + [Access(typeof(SharedMindSystem), Other = AccessPermissions.ReadWriteExecute)] // FIXME Friends public bool GhostOnShutdown { get; set; } = true; } diff --git a/Content.Server/Mind/Components/TransferMindOnGibComponent.cs b/Content.Shared/Mind/Components/TransferMindOnGibComponent.cs similarity index 89% rename from Content.Server/Mind/Components/TransferMindOnGibComponent.cs rename to Content.Shared/Mind/Components/TransferMindOnGibComponent.cs index afeb1b4d0a..0343796741 100644 --- a/Content.Server/Mind/Components/TransferMindOnGibComponent.cs +++ b/Content.Shared/Mind/Components/TransferMindOnGibComponent.cs @@ -1,7 +1,7 @@ using Content.Shared.Tag; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -namespace Content.Server.Mind.Components; +namespace Content.Shared.Mind.Components; [RegisterComponent] public sealed partial class TransferMindOnGibComponent : Component diff --git a/Content.Server/Mind/Components/VisitingMindComponent.cs b/Content.Shared/Mind/Components/VisitingMindComponent.cs similarity index 85% rename from Content.Server/Mind/Components/VisitingMindComponent.cs rename to Content.Shared/Mind/Components/VisitingMindComponent.cs index ce5ba673ec..2490054fd1 100644 --- a/Content.Server/Mind/Components/VisitingMindComponent.cs +++ b/Content.Shared/Mind/Components/VisitingMindComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.Mind.Components +namespace Content.Shared.Mind.Components { [RegisterComponent] public sealed partial class VisitingMindComponent : Component diff --git a/Content.Server/Mind/MindComponent.cs b/Content.Shared/Mind/MindComponent.cs similarity index 86% rename from Content.Server/Mind/MindComponent.cs rename to Content.Shared/Mind/MindComponent.cs index 3017fbbbe2..ed8eff76e8 100644 --- a/Content.Server/Mind/MindComponent.cs +++ b/Content.Shared/Mind/MindComponent.cs @@ -1,10 +1,10 @@ -using Content.Server.GameTicking; -using Content.Server.Mind.Components; -using Content.Server.Objectives; -using Robust.Server.Player; +using Content.Shared.GameTicking; +using Content.Shared.Mind.Components; +using Content.Shared.Objectives; using Robust.Shared.Network; +using Robust.Shared.Players; -namespace Content.Server.Mind +namespace Content.Shared.Mind { /// /// A mind represents the IC "mind" of a player. @@ -25,14 +25,14 @@ namespace Content.Server.Mind /// /// The session ID of the player owning this mind. /// - [ViewVariables, Access(typeof(MindSystem))] + [ViewVariables, Access(typeof(SharedMindSystem))] public NetUserId? UserId { get; set; } /// /// The session ID of the original owner, if any. /// May end up used for round-end information (as the owner may have abandoned Mind since) /// - [ViewVariables, Access(typeof(MindSystem))] + [ViewVariables, Access(typeof(SharedMindSystem))] public NetUserId? OriginalOwnerUserId { get; set; } /// @@ -44,7 +44,7 @@ namespace Content.Server.Mind [ViewVariables] public bool IsVisitingEntity => VisitingEntity != null; - [ViewVariables, Access(typeof(MindSystem))] + [ViewVariables, Access(typeof(SharedMindSystem))] public EntityUid? VisitingEntity { get; set; } [ViewVariables] @@ -71,7 +71,7 @@ namespace Content.Server.Mind /// The entity currently owned by this mind. /// Can be null. /// - [ViewVariables, Access(typeof(MindSystem))] + [ViewVariables, Access(typeof(SharedMindSystem))] public EntityUid? OwnedEntity { get; set; } // TODO move objectives out of mind component @@ -99,7 +99,7 @@ namespace Content.Server.Mind /// The session of the player owning this mind. /// Can be null, in which case the player is currently not logged in. /// - [ViewVariables, Access(typeof(MindSystem), typeof(GameTicker))] - public IPlayerSession? Session { get; internal set; } + [ViewVariables, Access(typeof(SharedMindSystem), typeof(SharedGameTicker))] + public ICommonSession? Session { get; set; } } } diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs new file mode 100644 index 0000000000..7bada2303f --- /dev/null +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -0,0 +1,411 @@ +using System.Diagnostics.CodeAnalysis; +using Content.Shared.Administration.Logs; +using Content.Shared.Database; +using Content.Shared.Examine; +using Content.Shared.GameTicking; +using Content.Shared.Interaction.Events; +using Content.Shared.Mind.Components; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.Objectives; +using Content.Shared.Players; +using Robust.Shared.Map; +using Robust.Shared.Network; +using Robust.Shared.Players; +using Robust.Shared.Utility; + +namespace Content.Shared.Mind; + +public abstract class SharedMindSystem : EntitySystem +{ + [Dependency] private readonly MobStateSystem _mobStateSystem = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedPlayerSystem _playerSystem = default!; + + // This is dictionary is required to track the minds of disconnected players that may have had their entity deleted. + protected readonly Dictionary UserMinds = new(); + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent(OnSuicide); + SubscribeLocalEvent(OnVisitingTerminating); + SubscribeLocalEvent(OnReset); + } + + public override void Shutdown() + { + base.Shutdown(); + WipeAllMinds(); + } + + private void OnReset(RoundRestartCleanupEvent ev) + { + WipeAllMinds(); + } + + public virtual void WipeAllMinds() + { + foreach (var mind in UserMinds.Values) + { + WipeMind(mind); + } + + DebugTools.Assert(UserMinds.Count == 0); + } + + public EntityUid? GetMind(NetUserId user) + { + TryGetMind(user, out var mind, out _); + return mind; + } + + public virtual bool TryGetMind(NetUserId user, [NotNullWhen(true)] out EntityUid? mindId, [NotNullWhen(true)] out MindComponent? mind) + { + if (UserMinds.TryGetValue(user, out var mindIdValue) && + TryComp(mindIdValue, out mind)) + { + DebugTools.Assert(mind.UserId == user); + mindId = mindIdValue; + return true; + } + + mindId = null; + mind = null; + return false; + } + + private void OnVisitingTerminating(EntityUid uid, VisitingMindComponent component, ref EntityTerminatingEvent args) + { + if (component.MindId != null) + UnVisit(component.MindId.Value); + } + + private void OnExamined(EntityUid uid, MindContainerComponent mindContainer, ExaminedEvent args) + { + if (!mindContainer.ShowExamineInfo || !args.IsInDetailsRange) + return; + + var dead = _mobStateSystem.IsDead(uid); + var hasSession = CompOrNull(mindContainer.Mind)?.Session; + + if (dead && !mindContainer.HasMind) + args.PushMarkup($"[color=mediumpurple]{Loc.GetString("comp-mind-examined-dead-and-irrecoverable", ("ent", uid))}[/color]"); + else if (dead && hasSession == null) + args.PushMarkup($"[color=yellow]{Loc.GetString("comp-mind-examined-dead-and-ssd", ("ent", uid))}[/color]"); + else if (dead) + args.PushMarkup($"[color=red]{Loc.GetString("comp-mind-examined-dead", ("ent", uid))}[/color]"); + else if (!mindContainer.HasMind) + args.PushMarkup($"[color=mediumpurple]{Loc.GetString("comp-mind-examined-catatonic", ("ent", uid))}[/color]"); + else if (hasSession == null) + args.PushMarkup($"[color=yellow]{Loc.GetString("comp-mind-examined-ssd", ("ent", uid))}[/color]"); + } + + private void OnSuicide(EntityUid uid, MindContainerComponent component, SuicideEvent args) + { + if (args.Handled) + return; + + if (TryComp(component.Mind, out MindComponent? mind) && mind.PreventSuicide) + { + args.BlockSuicideAttempt(true); + } + } + + public EntityUid? GetMind(EntityUid uid, MindContainerComponent? mind = null) + { + if (!Resolve(uid, ref mind)) + return null; + + if (mind.HasMind) + return mind.Mind; + + return null; + } + + public EntityUid CreateMind(NetUserId? userId, string? name = null) + { + var mindId = Spawn(null, MapCoordinates.Nullspace); + var mind = EnsureComp(mindId); + mind.CharacterName = name; + SetUserId(mindId, userId, mind); + + Dirty(mindId, MetaData(mindId)); + + return mindId; + } + + /// + /// True if the OwnedEntity of this mind is physically dead. + /// This specific definition, as opposed to CharacterDeadIC, is used to determine if ghosting should allow return. + /// + public bool IsCharacterDeadPhysically(MindComponent mind) + { + // This is written explicitly so that the logic can be understood. + // But it's also weird and potentially situational. + // Specific considerations when updating this: + // + Does being turned into a borg (if/when implemented) count as dead? + // *If not, add specific conditions to users of this property where applicable.* + // + Is being transformed into a donut 'dead'? + // TODO: Consider changing the way ghost roles work. + // Mind is an *IC* mind, therefore ghost takeover is IC revival right now. + // + Is it necessary to have a reference to a specific 'mind iteration' to cycle when certain events happen? + // (If being a borg or AI counts as dead, then this is highly likely, as it's still the same Mind for practical purposes.) + + if (mind.OwnedEntity == null) + return true; + + // This can be null if they're deleted (spike / brain nom) + var targetMobState = EntityManager.GetComponentOrNull(mind.OwnedEntity); + // This can be null if it's a brain (this happens very often) + // Brains are the result of gibbing so should definitely count as dead + if (targetMobState == null) + return true; + // They might actually be alive. + return _mobStateSystem.IsDead(mind.OwnedEntity.Value, targetMobState); + } + + public virtual void Visit(EntityUid mindId, EntityUid entity, MindComponent? mind = null) + { + } + + /// + /// Returns the mind to its original entity. + /// + public virtual void UnVisit(EntityUid mindId, MindComponent? mind = null) + { + } + + /// + /// Returns the mind to its original entity. + /// + public void UnVisit(ICommonSession? player) + { + if (player == null || !TryGetMind(player, out var mindId, out var mind)) + return; + + UnVisit(mindId, mind); + } + + /// + /// Cleans up the VisitingEntity. + /// + /// + protected void RemoveVisitingEntity(MindComponent mind) + { + if (mind.VisitingEntity == null) + return; + + var oldVisitingEnt = mind.VisitingEntity.Value; + // Null this before removing the component to avoid any infinite loops. + mind.VisitingEntity = null; + + if (TryComp(oldVisitingEnt, out VisitingMindComponent? visitComp)) + { + visitComp.MindId = null; + RemCompDeferred(oldVisitingEnt, visitComp); + } + + RaiseLocalEvent(oldVisitingEnt, new MindUnvisitedMessage(), true); + } + + public void WipeMind(ICommonSession player) + { + var mind = _playerSystem.ContentData(player)?.Mind; + DebugTools.Assert(GetMind(player.UserId) == mind); + WipeMind(mind); + } + + /// + /// Detaches a mind from all entities and clears the user ID. + /// + public void WipeMind(EntityUid? mindId, MindComponent? mind = null) + { + if (mindId == null || !Resolve(mindId.Value, ref mind, false)) + return; + + TransferTo(mindId.Value, null, mind: mind); + SetUserId(mindId.Value, null, mind: mind); + } + + /// + /// Transfer this mind's control over to a new entity. + /// + /// The mind to transfer + /// + /// The entity to control. + /// Can be null, in which case it will simply detach the mind from any entity. + /// + /// + /// If true, skips ghost check for Visiting Entity + /// + /// + /// Thrown if is already controlled by another player. + /// + public virtual void TransferTo(EntityUid mindId, EntityUid? entity, bool ghostCheckOverride = false, bool createGhost = true, MindComponent? mind = null) + { + } + + /// + /// Adds an objective to this mind. + /// + public bool TryAddObjective(EntityUid mindId, MindComponent mind, ObjectivePrototype objectivePrototype) + { + if (!objectivePrototype.CanBeAssigned(mindId, mind)) + return false; + var objective = objectivePrototype.GetObjective(mindId, mind); + if (mind.Objectives.Contains(objective)) + return false; + + foreach (var condition in objective.Conditions) + { + _adminLogger.Add(LogType.Mind, LogImpact.Low, $"'{condition.Title}' added to mind of {MindOwnerLoggingString(mind)}"); + } + + mind.Objectives.Add(objective); + return true; + } + + /// + /// Removes an objective to this mind. + /// + /// Returns true if the removal succeeded. + public bool TryRemoveObjective(MindComponent mind, int index) + { + if (index < 0 || index >= mind.Objectives.Count) + return false; + + var objective = mind.Objectives[index]; + + foreach (var condition in objective.Conditions) + { + _adminLogger.Add(LogType.Mind, LogImpact.Low, $"'{condition.Title}' removed from the mind of {MindOwnerLoggingString(mind)}"); + } + + mind.Objectives.Remove(objective); + return true; + } + + public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out ICommonSession? session) + { + session = null; + return TryComp(mindId, out MindComponent? mind) && (session = mind.Session) != null; + } + + /// + /// Gets a mind from uid and/or MindContainerComponent. Used for null checks. + /// + /// Entity UID that owns the mind. + /// The mind id. + /// The returned mind. + /// Mind component on to get the mind from. + /// True if mind found. False if not. + public bool TryGetMind( + EntityUid uid, + out EntityUid mindId, + [NotNullWhen(true)] out MindComponent? mind, + MindContainerComponent? container = null) + { + mindId = default; + mind = null; + + if (!Resolve(uid, ref container, false)) + return false; + + if (!container.HasMind) + return false; + + mindId = container.Mind ?? default; + return TryComp(mindId, out mind); + } + + public bool TryGetMind( + PlayerData player, + out EntityUid mindId, + [NotNullWhen(true)] out MindComponent? mind) + { + mindId = player.Mind ?? default; + return TryComp(mindId, out mind); + } + + public bool TryGetMind( + ICommonSession? player, + out EntityUid mindId, + [NotNullWhen(true)] out MindComponent? mind) + { + mindId = default; + mind = null; + return _playerSystem.ContentData(player) is { } data && TryGetMind(data, out mindId, out mind); + } + + /// + /// Sets the Mind's OwnedComponent and OwnedEntity + /// + /// Mind to set OwnedComponent and OwnedEntity on + /// Entity owned by + /// MindContainerComponent owned by + protected void SetOwnedEntity(MindComponent mind, EntityUid? uid, MindContainerComponent? mindContainerComponent) + { + if (uid != null) + Resolve(uid.Value, ref mindContainerComponent); + + mind.OwnedEntity = uid; + mind.OwnedComponent = mindContainerComponent; + } + + /// + /// Sets the Mind's UserId, Session, and updates the player's PlayerData. This should have no direct effect on the + /// entity that any mind is connected to, except as a side effect of the fact that it may change a player's + /// attached entity. E.g., ghosts get deleted. + /// + public virtual void SetUserId(EntityUid mindId, NetUserId? userId, MindComponent? mind = null) + { + } + + /// + /// True if this Mind is 'sufficiently dead' IC (Objectives, EndText). + /// Note that this is *IC logic*, it's not necessarily tied to any specific truth. + /// "If administrators decide that zombies are dead, this returns true for zombies." + /// (Maybe you were looking for the action blocker system?) + /// + public bool IsCharacterDeadIc(MindComponent mind) + { + if (mind.OwnedEntity is { } owned) + { + var ev = new GetCharactedDeadIcEvent(null); + RaiseLocalEvent(owned, ref ev); + + if (ev.Dead != null) + return ev.Dead.Value; + } + + return IsCharacterDeadPhysically(mind); + } + + /// + /// A string to represent the mind for logging + /// + public string MindOwnerLoggingString(MindComponent mind) + { + if (mind.OwnedEntity != null) + return ToPrettyString(mind.OwnedEntity.Value); + if (mind.UserId != null) + return mind.UserId.Value.ToString(); + return "(originally " + mind.OriginalOwnerUserId + ")"; + } + + public string? GetCharacterName(NetUserId userId) + { + return TryGetMind(userId, out _, out var mind) ? mind.CharacterName : null; + } +} + +/// +/// Raised on an entity to determine whether or not they are "dead" in IC-logic. +/// If not handled, then it will simply check if they are dead physically. +/// +/// +[ByRefEvent] +public record struct GetCharactedDeadIcEvent(bool? Dead); diff --git a/Content.Server/Objectives/Interfaces/IObjectiveCondition.cs b/Content.Shared/Objectives/Interfaces/IObjectiveCondition.cs similarity index 89% rename from Content.Server/Objectives/Interfaces/IObjectiveCondition.cs rename to Content.Shared/Objectives/Interfaces/IObjectiveCondition.cs index ad55984502..79e77e1759 100644 --- a/Content.Server/Objectives/Interfaces/IObjectiveCondition.cs +++ b/Content.Shared/Objectives/Interfaces/IObjectiveCondition.cs @@ -1,10 +1,10 @@ -using Content.Server.Mind; +using Content.Shared.Mind; using Robust.Shared.Utility; -namespace Content.Server.Objectives.Interfaces +namespace Content.Shared.Objectives.Interfaces { // TODO refactor all of this to be ecs - public interface IObjectiveCondition : IEquatable + public interface IObjectiveCondition { /// /// Returns a copy of the IObjectiveCondition which is assigned to the mind. diff --git a/Content.Server/Objectives/Interfaces/IObjectiveRequirement.cs b/Content.Shared/Objectives/Interfaces/IObjectiveRequirement.cs similarity index 83% rename from Content.Server/Objectives/Interfaces/IObjectiveRequirement.cs rename to Content.Shared/Objectives/Interfaces/IObjectiveRequirement.cs index f76ade0463..973a0ea7b0 100644 --- a/Content.Server/Objectives/Interfaces/IObjectiveRequirement.cs +++ b/Content.Shared/Objectives/Interfaces/IObjectiveRequirement.cs @@ -1,6 +1,6 @@ -using Content.Server.Mind; +using Content.Shared.Mind; -namespace Content.Server.Objectives.Interfaces +namespace Content.Shared.Objectives.Interfaces { // TODO refactor all of this to be ecs public interface IObjectiveRequirement diff --git a/Content.Server/Objectives/Objective.cs b/Content.Shared/Objectives/Objective.cs similarity index 94% rename from Content.Server/Objectives/Objective.cs rename to Content.Shared/Objectives/Objective.cs index 27ddd87e33..3f7b75281c 100644 --- a/Content.Server/Objectives/Objective.cs +++ b/Content.Shared/Objectives/Objective.cs @@ -1,7 +1,7 @@ -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; -namespace Content.Server.Objectives +namespace Content.Shared.Objectives { public sealed class Objective : IEquatable { diff --git a/Content.Server/Objectives/ObjectivePrototype.cs b/Content.Shared/Objectives/ObjectivePrototype.cs similarity index 92% rename from Content.Server/Objectives/ObjectivePrototype.cs rename to Content.Shared/Objectives/ObjectivePrototype.cs index f8ede98538..286afb550a 100644 --- a/Content.Server/Objectives/ObjectivePrototype.cs +++ b/Content.Shared/Objectives/ObjectivePrototype.cs @@ -1,9 +1,9 @@ using System.Linq; -using Content.Server.Mind; -using Content.Server.Objectives.Interfaces; +using Content.Shared.Mind; +using Content.Shared.Objectives.Interfaces; using Robust.Shared.Prototypes; -namespace Content.Server.Objectives +namespace Content.Shared.Objectives { /// /// Prototype for objectives. Remember that to be assigned, it should be added to one or more objective groups in prototype. E.g. crew, traitor, wizard @@ -20,7 +20,7 @@ namespace Content.Server.Objectives [ViewVariables] public float Difficulty => _difficultyOverride ?? _conditions.Sum(c => c.Difficulty); - [DataField("conditions")] + [DataField("conditions", serverOnly: true)] private List _conditions = new(); [DataField("requirements")] private List _requirements = new(); diff --git a/Content.Shared/Players/PlayerData.cs b/Content.Shared/Players/PlayerData.cs new file mode 100644 index 0000000000..c6274c950b --- /dev/null +++ b/Content.Shared/Players/PlayerData.cs @@ -0,0 +1,58 @@ +using Content.Shared.GameTicking; +using Content.Shared.Mind; +using Robust.Shared.Network; +using Robust.Shared.Player; + +namespace Content.Shared.Players; + +/// +/// Content side for all data that tracks a player session. +/// Use to retrieve this from an . +/// Not currently used on the client. +/// +public sealed class PlayerData +{ + /// + /// The session ID of the player owning this data. + /// + [ViewVariables] + public NetUserId UserId { get; } + + /// + /// This is a backup copy of the player name stored on connection. + /// This is useful in the event the player disconnects. + /// + [ViewVariables] + public string Name { get; } + + /// + /// The currently occupied mind of the player owning this data. + /// DO NOT DIRECTLY SET THIS UNLESS YOU KNOW WHAT YOU'RE DOING. + /// + [ViewVariables, Access(typeof(SharedMindSystem), typeof(SharedGameTicker))] + public EntityUid? Mind { get; set; } + + /// + /// If true, the player is an admin and they explicitly de-adminned mid-game, + /// so they should not regain admin if they reconnect. + /// + public bool ExplicitlyDeadminned { get; set; } + + public PlayerData(NetUserId userId, string name) + { + UserId = userId; + Name = name; + } +} + + +public static class PlayerDataExt +{ + /// + /// Gets the correctly cast instance of content player data from an engine player data storage. + /// + public static PlayerData? ContentData(this IPlayerData data) + { + return (PlayerData?) data.ContentDataUncast; + } +} diff --git a/Content.Shared/Players/SharedPlayerSystem.cs b/Content.Shared/Players/SharedPlayerSystem.cs new file mode 100644 index 0000000000..6fc7ad6a40 --- /dev/null +++ b/Content.Shared/Players/SharedPlayerSystem.cs @@ -0,0 +1,12 @@ +using Robust.Shared.Players; + +namespace Content.Shared.Players; + +/// +/// To be used from some systems. +/// Otherwise, use +/// +public abstract class SharedPlayerSystem : EntitySystem +{ + public abstract PlayerData? ContentData(ICommonSession? session); +} diff --git a/Content.Server/Roles/AntagonistRoleComponent.cs b/Content.Shared/Roles/AntagonistRoleComponent.cs similarity index 59% rename from Content.Server/Roles/AntagonistRoleComponent.cs rename to Content.Shared/Roles/AntagonistRoleComponent.cs index be29dc278f..1ced44c910 100644 --- a/Content.Server/Roles/AntagonistRoleComponent.cs +++ b/Content.Shared/Roles/AntagonistRoleComponent.cs @@ -1,7 +1,6 @@ -using Content.Shared.Roles; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -namespace Content.Server.Roles; +namespace Content.Shared.Roles; public abstract partial class AntagonistRoleComponent : Component { diff --git a/Content.Server/Roles/Jobs/JobComponent.cs b/Content.Shared/Roles/Jobs/JobComponent.cs similarity index 68% rename from Content.Server/Roles/Jobs/JobComponent.cs rename to Content.Shared/Roles/Jobs/JobComponent.cs index e3878cc725..c9053c1c6f 100644 --- a/Content.Server/Roles/Jobs/JobComponent.cs +++ b/Content.Shared/Roles/Jobs/JobComponent.cs @@ -1,7 +1,6 @@ -using Content.Shared.Roles; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -namespace Content.Server.Roles.Jobs; +namespace Content.Shared.Roles.Jobs; /// /// Added to mind entities to hold the data for the player's current job. diff --git a/Content.Shared/Roles/Jobs/SharedJobSystem.cs b/Content.Shared/Roles/Jobs/SharedJobSystem.cs new file mode 100644 index 0000000000..f172b3d310 --- /dev/null +++ b/Content.Shared/Roles/Jobs/SharedJobSystem.cs @@ -0,0 +1,70 @@ +using System.Diagnostics.CodeAnalysis; +using Content.Shared.Players; +using Robust.Shared.Players; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Roles.Jobs; + +/// +/// Handles the job data on mind entities. +/// +public abstract class SharedJobSystem : EntitySystem +{ + [Dependency] private readonly IPrototypeManager _prototypes = default!; + [Dependency] private readonly SharedPlayerSystem _playerSystem = default!; + + public bool MindHasJobWithId(EntityUid? mindId, string prototypeId) + { + return CompOrNull(mindId)?.PrototypeId == prototypeId; + } + + public bool MindTryGetJob( + [NotNullWhen(true)] EntityUid? mindId, + [NotNullWhen(true)] out JobComponent? comp, + [NotNullWhen(true)] out JobPrototype? prototype) + { + comp = null; + prototype = null; + + return TryComp(mindId, out comp) && + comp.PrototypeId != null && + _prototypes.TryIndex(comp.PrototypeId, out prototype); + } + + /// + /// Tries to get the job name for this mind. + /// Returns unknown if not found. + /// + public bool MindTryGetJobName([NotNullWhen(true)] EntityUid? mindId, out string name) + { + if (MindTryGetJob(mindId, out _, out var prototype)) + { + name = prototype.LocalizedName; + return true; + } + + name = Loc.GetString("generic-unknown-title"); + return false; + } + + /// + /// Tries to get the job name for this mind. + /// Returns unknown if not found. + /// + public string MindTryGetJobName([NotNullWhen(true)] EntityUid? mindId) + { + MindTryGetJobName(mindId, out var name); + return name; + } + + public bool CanBeAntag(ICommonSession player) + { + if (_playerSystem.ContentData(player) is not { Mind: { } mindId }) + return false; + + if (!MindTryGetJob(mindId, out _, out var prototype)) + return true; + + return prototype.CanBeAntag; + } +} diff --git a/Content.Server/Roles/MindGetAllRolesEvent.cs b/Content.Shared/Roles/MindGetAllRolesEvent.cs similarity index 96% rename from Content.Server/Roles/MindGetAllRolesEvent.cs rename to Content.Shared/Roles/MindGetAllRolesEvent.cs index dd66197403..9313d94edf 100644 --- a/Content.Server/Roles/MindGetAllRolesEvent.cs +++ b/Content.Shared/Roles/MindGetAllRolesEvent.cs @@ -1,6 +1,6 @@ using Content.Shared.Players.PlayTimeTracking; -namespace Content.Server.Roles; +namespace Content.Shared.Roles; /// /// Event raised on a mind entity to get all roles that a player has. diff --git a/Content.Server/Roles/MindIsAntagonistEvent.cs b/Content.Shared/Roles/MindIsAntagonistEvent.cs similarity index 90% rename from Content.Server/Roles/MindIsAntagonistEvent.cs rename to Content.Shared/Roles/MindIsAntagonistEvent.cs index b5012823f0..e37715d803 100644 --- a/Content.Server/Roles/MindIsAntagonistEvent.cs +++ b/Content.Shared/Roles/MindIsAntagonistEvent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.Roles; +namespace Content.Shared.Roles; /// /// Event raised on a mind entity id to get whether or not the player is considered an antagonist, diff --git a/Content.Server/Roles/MindRoleAddedEvent.cs b/Content.Shared/Roles/MindRoleAddedEvent.cs similarity index 87% rename from Content.Server/Roles/MindRoleAddedEvent.cs rename to Content.Shared/Roles/MindRoleAddedEvent.cs index f523819893..4f6b50d417 100644 --- a/Content.Server/Roles/MindRoleAddedEvent.cs +++ b/Content.Shared/Roles/MindRoleAddedEvent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.Roles; +namespace Content.Shared.Roles; /// /// Raised on mind entities when a role is added to them. diff --git a/Content.Server/Roles/RoleAddedEvent.cs b/Content.Shared/Roles/RoleAddedEvent.cs similarity index 90% rename from Content.Server/Roles/RoleAddedEvent.cs rename to Content.Shared/Roles/RoleAddedEvent.cs index 1e88e78fb8..48bc3c7814 100644 --- a/Content.Server/Roles/RoleAddedEvent.cs +++ b/Content.Shared/Roles/RoleAddedEvent.cs @@ -1,6 +1,6 @@ -using Content.Server.Mind; +using Content.Shared.Mind; -namespace Content.Server.Roles; +namespace Content.Shared.Roles; /// /// Raised on player entities when a role is added to them. diff --git a/Content.Server/Roles/RoleEvent.cs b/Content.Shared/Roles/RoleEvent.cs similarity index 88% rename from Content.Server/Roles/RoleEvent.cs rename to Content.Shared/Roles/RoleEvent.cs index a7b28379b2..ae6c330423 100644 --- a/Content.Server/Roles/RoleEvent.cs +++ b/Content.Shared/Roles/RoleEvent.cs @@ -1,6 +1,6 @@ -using Content.Server.Mind; +using Content.Shared.Mind; -namespace Content.Server.Roles; +namespace Content.Shared.Roles; /// /// Base event raised on player entities to indicate that something changed about one of their roles. diff --git a/Content.Server/Roles/RoleRemovedEvent.cs b/Content.Shared/Roles/RoleRemovedEvent.cs similarity index 90% rename from Content.Server/Roles/RoleRemovedEvent.cs rename to Content.Shared/Roles/RoleRemovedEvent.cs index 11104a5db1..3a0f4989d3 100644 --- a/Content.Server/Roles/RoleRemovedEvent.cs +++ b/Content.Shared/Roles/RoleRemovedEvent.cs @@ -1,6 +1,6 @@ -using Content.Server.Mind; +using Content.Shared.Mind; -namespace Content.Server.Roles; +namespace Content.Shared.Roles; /// /// Event raised on player entities to indicate that a role was removed from their mind. diff --git a/Content.Shared/Roles/SharedRoleSystem.cs b/Content.Shared/Roles/SharedRoleSystem.cs new file mode 100644 index 0000000000..75296b96f4 --- /dev/null +++ b/Content.Shared/Roles/SharedRoleSystem.cs @@ -0,0 +1,156 @@ +using Content.Shared.Administration.Logs; +using Content.Shared.Database; +using Content.Shared.Mind; +using Content.Shared.Roles.Jobs; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Roles; + +public abstract class SharedRoleSystem : EntitySystem +{ + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly IPrototypeManager _prototypes = default!; + [Dependency] private readonly SharedMindSystem _minds = default!; + + // TODO please lord make role entities + private readonly HashSet _antagTypes = new(); + + public override void Initialize() + { + // TODO make roles entities + SubscribeLocalEvent(OnJobGetAllRoles); + } + + private void OnJobGetAllRoles(EntityUid uid, JobComponent component, ref MindGetAllRolesEvent args) + { + var name = "game-ticker-unknown-role"; + string? playTimeTracker = null; + if (component.PrototypeId != null && _prototypes.TryIndex(component.PrototypeId, out JobPrototype? job)) + { + name = job.Name; + playTimeTracker = job.PlayTimeTracker; + } + + name = Loc.GetString(name); + + args.Roles.Add(new RoleInfo(component, name, false, playTimeTracker)); + } + + protected void SubscribeAntagEvents() where T : AntagonistRoleComponent + { + SubscribeLocalEvent((EntityUid _, T component, ref MindGetAllRolesEvent args) => + { + var name = "game-ticker-unknown-role"; + if (component.PrototypeId != null && _prototypes.TryIndex(component.PrototypeId, out AntagPrototype? antag)) + { + name = antag.Name; + } + name = Loc.GetString(name); + + args.Roles.Add(new RoleInfo(component, name, true, null)); + }); + + SubscribeLocalEvent((EntityUid _, T _, ref MindIsAntagonistEvent args) => args.IsAntagonist = true); + _antagTypes.Add(typeof(T)); + } + + /// + /// Gives this mind a new role. + /// + /// The mind to add the role to. + /// The role instance to add. + /// The role type to add. + /// Whether or not the role should be added silently + /// The instance of the role. + /// + /// Thrown if we already have a role with this type. + /// + public void MindAddRole(EntityUid mindId, T component, MindComponent? mind = null, bool silent = false) where T : Component, new() + { + if (!Resolve(mindId, ref mind)) + return; + + if (HasComp(mindId)) + { + throw new ArgumentException($"We already have this role: {typeof(T)}"); + } + + AddComp(mindId, component); + var antagonist = IsAntagonistRole(); + + var mindEv = new MindRoleAddedEvent(); + RaiseLocalEvent(mindId, ref mindEv); + + var message = new RoleAddedEvent(mindId, mind, antagonist, silent); + if (mind.OwnedEntity != null) + { + RaiseLocalEvent(mind.OwnedEntity.Value, message, true); + } + + _adminLogger.Add(LogType.Mind, LogImpact.Low, + $"'Role {typeof(T).Name}' added to mind of {_minds.MindOwnerLoggingString(mind)}"); + } + + /// + /// Removes a role from this mind. + /// + /// The mind to remove the role from. + /// The type of the role to remove. + /// + /// Thrown if we do not have this role. + /// + public void MindRemoveRole(EntityUid mindId) where T : Component + { + if (!RemComp(mindId)) + { + throw new ArgumentException($"We do not have this role: {typeof(T)}"); + } + + var mind = Comp(mindId); + var antagonist = IsAntagonistRole(); + var message = new RoleRemovedEvent(mindId, mind, antagonist); + + if (mind.OwnedEntity != null) + { + RaiseLocalEvent(mind.OwnedEntity.Value, message, true); + } + _adminLogger.Add(LogType.Mind, LogImpact.Low, + $"'Role {typeof(T).Name}' removed from mind of {_minds.MindOwnerLoggingString(mind)}"); + } + + public bool MindTryRemoveRole(EntityUid mindId) where T : Component + { + if (!MindHasRole(mindId)) + return false; + + MindRemoveRole(mindId); + return true; + } + + public bool MindHasRole(EntityUid mindId) where T : Component + { + return HasComp(mindId); + } + + public List MindGetAllRoles(EntityUid mindId) + { + var ev = new MindGetAllRolesEvent(new List()); + RaiseLocalEvent(mindId, ref ev); + return ev.Roles; + } + + public bool MindIsAntagonist(EntityUid? mindId) + { + if (mindId == null) + return false; + + var ev = new MindIsAntagonistEvent(); + RaiseLocalEvent(mindId.Value, ref ev); + return ev.IsAntagonist; + } + + public bool IsAntagonistRole() + { + return _antagTypes.Contains(typeof(T)); + } +}