From f7bb674fc9c41a7d98431ebe1d171cd66be0eb0d Mon Sep 17 00:00:00 2001 From: Debug Date: Fri, 29 Sep 2023 13:28:42 +0200 Subject: [PATCH] Readd character ghost role spawners --- .../GhostRoleCharacterSpawnerComponent.cs | 22 +++++++ .../Ghost/Roles/GhostRoleSystem.Character.cs | 63 +++++++++++++++++++ Content.Server/Ghost/Roles/GhostRoleSystem.cs | 3 +- .../Entities/Markers/Spawners/ghost_roles.yml | 17 +++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 Content.Server/DeltaV/Ghost/Roles/Components/GhostRoleCharacterSpawnerComponent.cs create mode 100644 Content.Server/DeltaV/Ghost/Roles/GhostRoleSystem.Character.cs create mode 100644 Resources/Prototypes/DeltaV/Entities/Markers/Spawners/ghost_roles.yml diff --git a/Content.Server/DeltaV/Ghost/Roles/Components/GhostRoleCharacterSpawnerComponent.cs b/Content.Server/DeltaV/Ghost/Roles/Components/GhostRoleCharacterSpawnerComponent.cs new file mode 100644 index 00000000000..e2aaa94d948 --- /dev/null +++ b/Content.Server/DeltaV/Ghost/Roles/Components/GhostRoleCharacterSpawnerComponent.cs @@ -0,0 +1,22 @@ +namespace Content.Server.Ghost.Roles.Components +{ + /// + /// Allows a ghost to take this role, spawning their selected character. + /// + [RegisterComponent] + [Access(typeof(GhostRoleSystem))] + public sealed partial class GhostRoleCharacterSpawnerComponent : Component + { + [ViewVariables(VVAccess.ReadWrite)] [DataField("deleteOnSpawn")] + public bool DeleteOnSpawn = true; + + [ViewVariables(VVAccess.ReadWrite)] [DataField("availableTakeovers")] + public int AvailableTakeovers = 1; + + [ViewVariables] + public int CurrentTakeovers = 0; + + [ViewVariables(VVAccess.ReadWrite)] [DataField("outfitPrototype")] + public string OutfitPrototype = "PassengerGear"; + } +} diff --git a/Content.Server/DeltaV/Ghost/Roles/GhostRoleSystem.Character.cs b/Content.Server/DeltaV/Ghost/Roles/GhostRoleSystem.Character.cs new file mode 100644 index 00000000000..ced4ec802d8 --- /dev/null +++ b/Content.Server/DeltaV/Ghost/Roles/GhostRoleSystem.Character.cs @@ -0,0 +1,63 @@ +using Content.Server.Administration.Commands; +using Content.Server.Ghost.Roles.Components; +using Content.Server.Ghost.Roles.Events; +using Content.Server.Preferences.Managers; +using Content.Server.Station.Systems; +using Content.Shared.Mind.Components; +using Content.Shared.Preferences; +using Content.Shared.Roles; +using Robust.Shared.Prototypes; + +namespace Content.Server.Ghost.Roles +{ + public sealed partial class GhostRoleSystem + { + [Dependency] private readonly IServerPreferencesManager _prefs = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + private void OnSpawnerTakeCharacter( EntityUid uid, GhostRoleCharacterSpawnerComponent component, + ref TakeGhostRoleEvent args) + { + if (!TryComp(uid, out GhostRoleComponent? ghostRole) || + ghostRole.Taken) + { + args.TookRole = false; + return; + } + + var character = (HumanoidCharacterProfile) _prefs.GetPreferences(args.Player.UserId).SelectedCharacter; + + var mob = _entityManager.System() + .SpawnPlayerMob(Transform(uid).Coordinates, null, character, null); + _transform.AttachToGridOrMap(mob); + + string? outfit = null; + if (_prototypeManager.TryIndex(component.OutfitPrototype, out var outfitProto)) + outfit = outfitProto.ID; + + var spawnedEvent = new GhostRoleSpawnerUsedEvent(uid, mob); + RaiseLocalEvent(mob, spawnedEvent); + + EnsureComp(mob); + + GhostRoleInternalCreateMindAndTransfer(args.Player, uid, mob, ghostRole); + + if (outfit != null) + SetOutfitCommand.SetOutfit(mob, outfit, _entityManager); + + if (++component.CurrentTakeovers < component.AvailableTakeovers) + { + args.TookRole = true; + return; + } + + ghostRole.Taken = true; + + if (component.DeleteOnSpawn) + QueueDel(uid); + + args.TookRole = true; + } + } +} diff --git a/Content.Server/Ghost/Roles/GhostRoleSystem.cs b/Content.Server/Ghost/Roles/GhostRoleSystem.cs index 98a62d39707..cb44b196d35 100644 --- a/Content.Server/Ghost/Roles/GhostRoleSystem.cs +++ b/Content.Server/Ghost/Roles/GhostRoleSystem.cs @@ -27,7 +27,7 @@ namespace Content.Server.Ghost.Roles { [UsedImplicitly] - public sealed class GhostRoleSystem : EntitySystem + public sealed partial class GhostRoleSystem : EntitySystem // Converted to partial to allow for DeltaV character ghost roles { [Dependency] private readonly EuiManager _euiManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; @@ -62,6 +62,7 @@ public override void Initialize() SubscribeLocalEvent(OnUnpaused); SubscribeLocalEvent(OnSpawnerTakeRole); SubscribeLocalEvent(OnTakeoverTakeRole); + SubscribeLocalEvent(OnSpawnerTakeCharacter); // DeltaV - Character ghost roles, see Content.Server/DeltaV/Ghost/Roles/GhostRoleSystem.Character.cs _playerManager.PlayerStatusChanged += PlayerStatusChanged; } diff --git a/Resources/Prototypes/DeltaV/Entities/Markers/Spawners/ghost_roles.yml b/Resources/Prototypes/DeltaV/Entities/Markers/Spawners/ghost_roles.yml new file mode 100644 index 00000000000..e1f06b82ec0 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Entities/Markers/Spawners/ghost_roles.yml @@ -0,0 +1,17 @@ +- type: entity + id: SpawnPointPlayerCharacter + name: ghost role spawn point + suffix: player character, DO NOT MAP + parent: MarkerBase + components: + - type: GhostRole + name: Roleplay Ghost Role + description: Placeholder + rules: Placeholder + - type: GhostRoleCharacterSpawner + - type: Sprite + sprite: Markers/jobs.rsi + layers: + - state: green + - sprite: Mobs/Species/Human/parts.rsi + state: full