diff --git a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs index ec4701dbe31..5b6cbf46283 100644 --- a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs +++ b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs @@ -851,6 +851,10 @@ public void RefreshJobs() foreach (var job in jobs) { + // DeltaV #1418 - Allow hiding jobs to hide senior virtual jobs + if (job.EditorHidden) + continue; + var jobContainer = new BoxContainer() { Orientation = LayoutOrientation.Horizontal, diff --git a/Content.Server/Access/Components/PresetIdCardComponent.cs b/Content.Server/Access/Components/PresetIdCardComponent.cs index 8fd0e10d423..94aef2e6ca0 100644 --- a/Content.Server/Access/Components/PresetIdCardComponent.cs +++ b/Content.Server/Access/Components/PresetIdCardComponent.cs @@ -11,10 +11,4 @@ public sealed partial class PresetIdCardComponent : Component [DataField("name")] public string? IdName; - - /// - /// DeltaV: Allow changing the job title, even if it'd be otherwise set by the JobPrototype - /// - [DataField("customJob")] - public string? CustomJobName; } diff --git a/Content.Server/Access/Systems/PresetIdCardSystem.cs b/Content.Server/Access/Systems/PresetIdCardSystem.cs index 7aed03b74a8..719d61b356a 100644 --- a/Content.Server/Access/Systems/PresetIdCardSystem.cs +++ b/Content.Server/Access/Systems/PresetIdCardSystem.cs @@ -2,10 +2,8 @@ using Content.Server.GameTicking; using Content.Server.Station.Components; using Content.Server.Station.Systems; -using Content.Server.StationRecords.Systems; using Content.Shared.Access.Systems; using Content.Shared.Roles; -using Content.Shared.StationRecords; using Content.Shared.StatusIcon; using Robust.Shared.Prototypes; @@ -17,8 +15,6 @@ public sealed class PresetIdCardSystem : EntitySystem [Dependency] private readonly IdCardSystem _cardSystem = default!; [Dependency] private readonly SharedAccessSystem _accessSystem = default!; [Dependency] private readonly StationSystem _stationSystem = default!; - [Dependency] private readonly StationRecordsSystem _record = default!; // DeltaV - Allow changing the job title within the prototype - public override void Initialize() { SubscribeLocalEvent(OnMapInit); @@ -41,7 +37,6 @@ private void PlayerJobsAssigned(RulePlayerJobsAssignedEvent ev) SetupIdAccess(uid, card, true); SetupIdName(uid, card); - SetupIdJob(uid, card); // DeltaV - Allow changing the job title within the prototype } } @@ -61,7 +56,6 @@ private void OnMapInit(EntityUid uid, PresetIdCardComponent id, MapInitEvent arg SetupIdAccess(uid, id, extended); SetupIdName(uid, id); - SetupIdJob(uid, id); // DeltaV - Allow changing the job title within the prototype } private void SetupIdName(EntityUid uid, PresetIdCardComponent id) @@ -71,25 +65,6 @@ private void SetupIdName(EntityUid uid, PresetIdCardComponent id) _cardSystem.TryChangeFullName(uid, id.IdName); } - // DeltaV - Allow changing the job title within the prototype - private void SetupIdJob(EntityUid uid, PresetIdCardComponent id) - { - if (id.CustomJobName == null) - return; - _cardSystem.TryChangeJobTitle(uid, id.CustomJobName); - - // The following code is taken from IdCardConsoleSystem - if (!TryComp(uid, out var keyStorage) - || keyStorage.Key is not { } key - || !_record.TryGetRecord(key, out var record)) - { - return; - } - record.JobTitle = id.CustomJobName; - _record.Synchronize(key); - } - // End of DeltaV code - private void SetupIdAccess(EntityUid uid, PresetIdCardComponent id, bool extended) { if (id.JobName == null) diff --git a/Content.Server/GameTicking/GameTicker.Spawning.cs b/Content.Server/GameTicking/GameTicker.Spawning.cs index 5f20feee754..c842db1c005 100644 --- a/Content.Server/GameTicking/GameTicker.Spawning.cs +++ b/Content.Server/GameTicking/GameTicker.Spawning.cs @@ -11,8 +11,11 @@ using Content.Shared.Mind; using Content.Shared.Players; using Content.Shared.Preferences; +using Content.Shared.Preferences.Loadouts; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; +using Content.Shared.Clothing; +using Content.Shared.Access.Components; using JetBrains.Annotations; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -21,6 +24,11 @@ using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; +using Microsoft.CodeAnalysis; +using Content.Shared.PDA; +using FastAccessors; +using Content.Server.Access.Components; +using Content.Shared.Destructible; namespace Content.Server.GameTicking { @@ -28,6 +36,7 @@ public sealed partial class GameTicker { [Dependency] private readonly IAdminManager _adminManager = default!; [Dependency] private readonly SharedJobSystem _jobs = default!; + [Dependency] private readonly IComponentFactory _componentFactory = default!; // DeltaV #1418 [ValidatePrototypeId] public const string ObserverPrototypeName = "MobObserver"; @@ -224,6 +233,33 @@ private void SpawnPlayer(ICommonSession player, var jobPrototype = _prototypeManager.Index(jobId); var job = new JobComponent {Prototype = jobId}; + // DeltaV #1418 - Loadout stuff to get Senior ID + // We don't want to inherit everything, so we store the job component in a VirtualJob + do + { + var jobLoadout = LoadoutSystem.GetJobPrototype(jobPrototype.ID); + + if (!_prototypeManager.TryIndex(jobLoadout, out RoleLoadoutPrototype? roleProto)) + break; + + RoleLoadout? loadout = null; + character.Loadouts.TryGetValue(jobLoadout, out loadout); + + // Set to default if not present + if (loadout == null) + { + loadout = new RoleLoadout(jobLoadout); + loadout.SetDefault(_prototypeManager); + } + + // Get the ID + if (GetVirtualJobFromRoleLoadout(loadout, roleProto, character, out var virtualJobId) && _prototypeManager.TryIndex(virtualJobId, out var virtualJobProto)) + { + job.VirtualJob = new JobComponent {Prototype = virtualJobProto}; + } + } + while (false); + // End of DeltaV code _roles.MindAddRole(newMind, job, silent: silent); var jobName = _jobs.MindTryGetJobName(newMind); @@ -302,7 +338,7 @@ private void SpawnPlayer(ICommonSession player, PlayersJoinedRoundNormally++; var aev = new PlayerSpawnCompleteEvent(mob, player, - jobId, + job, lateJoin, PlayersJoinedRoundNormally, station, @@ -310,6 +346,63 @@ private void SpawnPlayer(ICommonSession player, RaiseLocalEvent(mob, aev, true); } + // DeltaV #1418 - Go through loadout items to find ID card and its attached job + private bool GetVirtualJobFromRoleLoadout(RoleLoadout loadout, RoleLoadoutPrototype roleProto, HumanoidCharacterProfile character, out ProtoId? virtualJob) + { + virtualJob = null; + + // Use to read job loadout and find an ID card + foreach (var group in loadout.SelectedLoadouts.OrderBy(x => roleProto.Groups.FindIndex(e => e == x.Key))) + { + foreach (var items in group.Value) + { + if (!_prototypeManager.TryIndex(items.Prototype, out var loadoutProto)) + { + Log.Warning($"Unable to find loadout prototype for {items.Prototype}"); + continue; + } + if (!_prototypeManager.TryIndex(loadoutProto.Equipment, out var startingGear)) + { + Log.Warning($"Unable to find starting gear {loadoutProto.Equipment} for loadout {loadoutProto}"); + continue; + } + var entProtoId = startingGear.GetGear("id"); + if (!_prototypeManager.TryIndex(entProtoId, out var idProto)) + { + Log.Warning($"Unable to find prototype for {startingGear} for starting gear {loadoutProto.Equipment} for loadout {loadoutProto}"); + continue; + } + if (idProto.TryGetComponent(out var pdaComponent, _componentFactory) && pdaComponent.IdCard != null) + { + ProtoId idProtoId = pdaComponent.IdCard; + if (!_prototypeManager.TryIndex(idProtoId, out idProto)) + { + Log.Warning($"Unable to find an idCard in {idProto}"); + return false; + } + } + + if (!idProto.TryGetComponent(out var idComponent, _componentFactory)) + { + Log.Warning($"Unable to find presetIdCard for {idProto}"); + continue; + } + + ProtoId jobProtoId = idComponent.JobName ?? string.Empty; + if (jobProtoId == string.Empty) + { + Log.Warning($"Empty jobProtoId!"); + return false; + } + virtualJob = jobProtoId; + Log.Debug($"Successfully outputted {virtualJob} from {idProto}"); + return true; + } + } + Log.Warning($"All other options exhausted"); + return false; + } + public void Respawn(ICommonSession player) { _mind.WipeMind(player); @@ -500,7 +593,7 @@ public sealed class PlayerSpawnCompleteEvent : EntityEventArgs { public EntityUid Mob { get; } public ICommonSession Player { get; } - public string? JobId { get; } + public JobComponent? Job { get; } // DeltaV #1418 - Replace JobId with Job to parse VirtualJob public bool LateJoin { get; } public EntityUid Station { get; } public HumanoidCharacterProfile Profile { get; } @@ -510,7 +603,7 @@ public sealed class PlayerSpawnCompleteEvent : EntityEventArgs public PlayerSpawnCompleteEvent(EntityUid mob, ICommonSession player, - string? jobId, + JobComponent? job, // DeltaV #1418 bool lateJoin, int joinOrder, EntityUid station, @@ -518,7 +611,7 @@ public PlayerSpawnCompleteEvent(EntityUid mob, { Mob = mob; Player = player; - JobId = jobId; + Job = job; // DeltaV #1418 LateJoin = lateJoin; Station = station; Profile = profile; diff --git a/Content.Server/Station/Systems/StationSpawningSystem.cs b/Content.Server/Station/Systems/StationSpawningSystem.cs index ce8177e1039..0b9427e66f4 100644 --- a/Content.Server/Station/Systems/StationSpawningSystem.cs +++ b/Content.Server/Station/Systems/StationSpawningSystem.cs @@ -144,6 +144,7 @@ public EntityUid SpawnPlayerMob( EntityUid? entity = null) { _prototypeManager.TryIndex(job?.Prototype ?? string.Empty, out var prototype); + _prototypeManager.TryIndex(job?.VirtualJob?.Prototype ?? string.Empty, out var virtualJobPrototype); // DeltaV #1418 - Get the VirtualJob too // If we're not spawning a humanoid, we're gonna exit early without doing all the humanoid stuff. if (prototype?.JobEntity != null) @@ -212,7 +213,7 @@ public EntityUid SpawnPlayerMob( if (profile != null) { if (prototype != null) - SetPdaAndIdCardData(entity.Value, profile.Name, prototype, station); + SetPdaAndIdCardData(entity.Value, profile.Name, virtualJobPrototype ?? prototype, station); // DeltaV #1418 - Inherit job data from a VirtualJob if one exists _humanoidSystem.LoadProfile(entity.Value, profile); _metaSystem.SetEntityName(entity.Value, profile.Name); diff --git a/Content.Server/StationRecords/Systems/StationRecordsSystem.cs b/Content.Server/StationRecords/Systems/StationRecordsSystem.cs index 8c8ba7132bb..ffe97963e38 100644 --- a/Content.Server/StationRecords/Systems/StationRecordsSystem.cs +++ b/Content.Server/StationRecords/Systems/StationRecordsSystem.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Content.Server.Forensics; using Content.Server.GameTicking; @@ -5,6 +6,7 @@ using Content.Shared.PDA; using Content.Shared.Preferences; using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; using Content.Shared.StationRecords; using Robust.Shared.Enums; using Robust.Shared.Prototypes; @@ -48,13 +50,20 @@ private void OnPlayerSpawn(PlayerSpawnCompleteEvent args) if (!TryComp(args.Station, out var stationRecords)) return; - CreateGeneralRecord(args.Station, args.Mob, args.Profile, args.JobId, stationRecords); + CreateGeneralRecord(args.Station, args.Mob, args.Profile, args.Job, stationRecords); // DeltaV #1418 - JobId replaced with Job to parse VirtualJob } private void CreateGeneralRecord(EntityUid station, EntityUid player, HumanoidCharacterProfile profile, - string? jobId, StationRecordsComponent records) + JobComponent? job, StationRecordsComponent records) // DeltaV #1418 { - // TODO make PlayerSpawnCompleteEvent.JobId a ProtoId + // DeltaV #1418 - Inherit from VirtualJob if possible + _prototypeManager.TryIndex(job?.VirtualJob?.Prototype, out var a); + if (!_prototypeManager.TryIndex(job?.Prototype, out var b)) + return; + + ProtoId jobId = a?.ID ?? b.ID; + // TODO make PlayerSpawnCompleteEvent.JobId a ProtoId // DeltaV #1418 - :blunt: + // End of DeltaV code if (string.IsNullOrEmpty(jobId) || !_prototypeManager.HasIndex(jobId)) return; diff --git a/Content.Shared/Roles/JobPrototype.cs b/Content.Shared/Roles/JobPrototype.cs index 71bd41c89fb..eafc1c21c79 100644 --- a/Content.Shared/Roles/JobPrototype.cs +++ b/Content.Shared/Roles/JobPrototype.cs @@ -123,6 +123,10 @@ public sealed partial class JobPrototype : IPrototype [DataField] public bool Whitelisted; + + // DeltaV #1418 - Allow hiding virtual jobs like the senior job prototypes + [DataField] + public bool EditorHidden; } /// diff --git a/Content.Shared/Roles/Jobs/JobComponent.cs b/Content.Shared/Roles/Jobs/JobComponent.cs index 7191e8b3971..b7802f76813 100644 --- a/Content.Shared/Roles/Jobs/JobComponent.cs +++ b/Content.Shared/Roles/Jobs/JobComponent.cs @@ -11,4 +11,8 @@ public sealed partial class JobComponent : Component { [DataField(required: true), AutoNetworkedField] public ProtoId? Prototype; + + // DeltaV #1418 - Inherit job prototype information from a loadout-specified ID + [DataField] + public JobComponent? VirtualJob; } diff --git a/Content.Shared/Roles/Jobs/SharedJobSystem.cs b/Content.Shared/Roles/Jobs/SharedJobSystem.cs index ce4428d9fea..d7235330986 100644 --- a/Content.Shared/Roles/Jobs/SharedJobSystem.cs +++ b/Content.Shared/Roles/Jobs/SharedJobSystem.cs @@ -39,6 +39,8 @@ private void SetupTrackerLookup() // This breaks if you have N trackers to 1 JobId but future concern. foreach (var job in _protoManager.EnumeratePrototypes()) { + if (_inverseTrackerLookup.ContainsKey(job.PlayTimeTracker)) continue; // DeltaV #1418 - we have N trackers to 1 JobId... (senior job prototypes) + _inverseTrackerLookup.Add(job.PlayTimeTracker, job.ID); } } @@ -118,6 +120,21 @@ public bool MindTryGetJob( _prototypes.TryIndex(comp.Prototype, out prototype); } + // DeltaV #1418 - lazy copy paste, nothing ground-breaking + public bool MindTryGetVirtualJob( // DeltaV - Senior ID cards + [NotNullWhen(true)] EntityUid? mindId, + [NotNullWhen(true)] out JobComponent? comp, + [NotNullWhen(true)] out JobPrototype? virtualJob) + { + comp = null; + virtualJob = null; + + return TryComp(mindId, out comp) && + comp.VirtualJob != null && + _prototypes.TryIndex(comp.VirtualJob.Prototype, out virtualJob); + } + // End of DeltaV code + public bool MindTryGetJobId([NotNullWhen(true)] EntityUid? mindId, out ProtoId? job) { if (!TryComp(mindId, out JobComponent? comp)) @@ -136,14 +153,21 @@ public bool MindTryGetJobId([NotNullWhen(true)] EntityUid? mindId, out ProtoId public bool MindTryGetJobName([NotNullWhen(true)] EntityUid? mindId, out string name) { - if (MindTryGetJob(mindId, out _, out var prototype)) + // DeltaV #1418 - Try to get the VirtualJob, and return if we don't have an actual job + MindTryGetVirtualJob(mindId, out _, out var virtualJob); + if (!MindTryGetJob(mindId, out _, out var prototype)) { - name = prototype.LocalizedName; - return true; + name = Loc.GetString("generic-unknown-title"); + return false; } - name = Loc.GetString("generic-unknown-title"); - return false; + name = virtualJob?.LocalizedName ?? string.Empty; + if (string.IsNullOrEmpty(name)) + name = prototype.LocalizedName; + + Log.Debug(name); + return true; + // End of DeltaV code } /// diff --git a/Resources/Locale/en-US/job/job-names.ftl b/Resources/Locale/en-US/job/job-names.ftl index 4b7b5ccc421..645a05578fb 100644 --- a/Resources/Locale/en-US/job/job-names.ftl +++ b/Resources/Locale/en-US/job/job-names.ftl @@ -47,6 +47,11 @@ job-name-ertjanitor = ERT Janitor job-name-boxer = Boxer job-name-zookeeper = Zookeeper job-name-visitor = Visitor +# DeltaV #1418 - Define senior job names for use in job prototypes +job-name-seniorengineer = Senior Engineer +job-name-seniorphysician = Senior Physician +job-name-seniorresearcher = Senior Researcher +job-name-seniorofficer = Senior Officer # Role timers - Make these alphabetical or I cut you JobAtmosphericTechnician = Atmospheric Technician diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml index 2f232c566a3..1b29c7dc7e1 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml @@ -822,8 +822,8 @@ layers: - state: default - state: idseniorengineer - - type: PresetIdCard # DeltaV - Change senior job titles - customJob: Senior Engineer + - type: PresetIdCard + job: SeniorEngineer # DeltaV #1418 - Change senior job titles - type: entity parent: ResearchIDCard @@ -834,8 +834,8 @@ layers: - state: default - state: idseniorresearcher - - type: PresetIdCard # DeltaV - Change senior job titles - customJob: Senior Researcher + - type: PresetIdCard + job: SeniorResearcher # DeltaV #1418 - type: entity parent: MedicalIDCard @@ -846,8 +846,8 @@ layers: - state: default - state: idseniorphysician - - type: PresetIdCard # DeltaV - Change senior job titles - customJob: Senior Physician + - type: PresetIdCard + job: SeniorPhysician # DeltaV #1418 - type: entity parent: SecurityIDCard @@ -858,8 +858,8 @@ layers: - state: default - state: idseniorofficer - - type: PresetIdCard # DeltaV - Change senior job titles - customJob: Senior Officer + - type: PresetIdCard + job: SeniorOfficer # DeltaV #1418 - type: entity parent: IDCardStandard diff --git a/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml b/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml index 15aabc4ab86..8d7a4f85cc4 100644 --- a/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml +++ b/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml @@ -24,3 +24,26 @@ eyes: ClothingEyesGlassesMeson belt: ClothingBeltUtilityEngineering ears: ClothingHeadsetEngineering + +# DeltaV #1418 - Define senior job names as separate prototypes +- type: job + id: SeniorEngineer + #parent: StationEngineer # So sad parent-child relationships don't seem to work here + editorHidden: true + name: job-name-seniorengineer + description: job-description-engineer + playTimeTracker: JobStationEngineer + antagAdvantage: 3 + requirements: + - !type:DepartmentTimeRequirement + department: Engineering + time: 216000 # 60 hrs + startingGear: StationEngineerGear + icon: "JobIconSeniorEngineer" + supervisors: job-supervisors-ce + access: + - Maintenance + - Engineering + - External + extendedAccess: + - Atmospherics \ No newline at end of file diff --git a/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml b/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml index daed73984fe..f2b4d3ad90a 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml @@ -22,3 +22,25 @@ equipment: ears: ClothingHeadsetMedical belt: ClothingBeltMedicalFilled + +# DeltaV #1418 - Define senior job names as separate prototypes +- type: job + id: SeniorPhysician + #parent: MedicalDoctor # So sad parent-child relationships don't seem to work here + editorHidden: true + name: job-name-seniorphysician + description: job-description-doctor + playTimeTracker: JobMedicalDoctor + requirements: + - !type:DepartmentTimeRequirement + department: Medical + time: 216000 # 60 hrs + startingGear: DoctorGear + icon: "JobIconSeniorPhysician" + supervisors: job-supervisors-cmo + access: + - Medical + - Maintenance + extendedAccess: + - Chemistry + - Paramedic \ No newline at end of file diff --git a/Resources/Prototypes/Roles/Jobs/Science/scientist.yml b/Resources/Prototypes/Roles/Jobs/Science/scientist.yml index b005accc79f..fc1ccf3e270 100644 --- a/Resources/Prototypes/Roles/Jobs/Science/scientist.yml +++ b/Resources/Prototypes/Roles/Jobs/Science/scientist.yml @@ -20,3 +20,22 @@ equipment: ears: ClothingHeadsetScience +# DeltaV #1418 - Define senior job names as separate prototypes +- type: job + id: SeniorResearcher + #parent: Scientist # So sad parent-child relationships don't seem to work here + editorHidden: true + name: job-name-seniorresearcher + description: job-description-scientist + playTimeTracker: JobScientist + antagAdvantage: 2 + requirements: + - !type:DepartmentTimeRequirement + department: Epistemics # DeltaV - Epistemics Department replacing Science + time: 216000 # 60 hrs + startingGear: ScientistGear + icon: "JobIconSeniorResearcher" + supervisors: job-supervisors-rd + access: + - Research + - Maintenance \ No newline at end of file diff --git a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml index 6de806f7189..d1c503f7120 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml @@ -28,3 +28,27 @@ eyes: ClothingEyesGlassesSecurity ears: ClothingHeadsetSecurity pocket1: WeaponPistolMk58Nonlethal + +# DeltaV #1418 - Define senior job names as separate prototypes +- type: job + id: SeniorOfficer + #parent: SecurityOfficer # So sad parent-child relationships don't seem to work here + editorHidden: true + name: job-name-seniorofficer + description: job-description-security + playTimeTracker: JobSecurityOfficer + requirements: + - !type:DepartmentTimeRequirement + department: Security + time: 216000 # 60 hrs + startingGear: SecurityOfficerGear + icon: "JobIconSeniorOfficer" + supervisors: job-supervisors-hos + canBeAntag: false + access: + - Security + - Maintenance + - External + special: + - !type:AddImplantSpecial + implants: [ MindShieldImplant ] \ No newline at end of file diff --git a/Resources/Prototypes/Roles/Jobs/departments.yml b/Resources/Prototypes/Roles/Jobs/departments.yml index 5512fb2b330..5b7f571f917 100644 --- a/Resources/Prototypes/Roles/Jobs/departments.yml +++ b/Resources/Prototypes/Roles/Jobs/departments.yml @@ -63,6 +63,7 @@ - ChiefEngineer - StationEngineer - TechnicalAssistant + - SeniorEngineer # DeltaV #1418 - Senior ID cards - type: department id: Medical @@ -76,6 +77,7 @@ - Psychologist - Paramedic - MedicalBorg # Delta V - Medical Borg, see Resources/Prototypes/DeltaV/Roles/Jobs/Medical/medicalborg.yml + - SeniorPhysician # DeltaV #1418 - Senior ID cards - type: department id: Security @@ -90,6 +92,7 @@ - Warden - PrisonGuard # Nyanotrasen - PrisonGuard, see Resources/Prototypes/Nyanotrasen/Roles/Jobs/Security/prisonguard.yml - Brigmedic # DeltaV - Brigmedic, see Resources/Prototypes/DeltaV/Roles/Jobs/Security/brigmedic.yml + - SeniorOfficer # DeltaV #1418 - Senior ID cards - type: department id: Epistemics # DeltaV - Epistemics Department replacing Science @@ -101,6 +104,7 @@ - ResearchAssistant - Chaplain # DeltaV - Move Chaplain into Epistemics - ForensicMantis # Nyanotrasen - ForensicMantis, see Resources/Prototypes/Nyanotrasen/Roles/Jobs/Epistemics/forensicmantis.yml + - SeniorResearcher # DeltaV #1418 - Senior ID cards - type: department id: Specific