Skip to content

Commit

Permalink
Senior ID cards get a custom job name: Attempt 3 (#1425)
Browse files Browse the repository at this point in the history
* revert 1218

* oops wrong file

* commit changes

* it works!!!

* revert accidental changes

* hide senior virtual job prototypes from job select

* remove whitespace diff

* consolidate comments

* remove virtual job prototypes

* these changes were not staged

* remove whitespace diff

* remove whitespace diff again and revert test change

* Update station_engineer.yml

Signed-off-by: WarMechanic <69510347+WarMechanic@users.noreply.github.com>

* Update SharedJobSystem.cs

Signed-off-by: WarMechanic <69510347+WarMechanic@users.noreply.github.com>

* fix capitalisation typo

* consolidate comments and dependencies, also change Mind to use VirtualJobName

* comment correction

* localise senior job names

* fix build error

* fix spawned cards being broken

* reduced logging for finding PresetIdCard

* more fixes

* fix

---------

Signed-off-by: WarMechanic <69510347+WarMechanic@users.noreply.github.com>
  • Loading branch information
WarMechanic authored Aug 6, 2024
1 parent e399d3f commit 10b7e40
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 110 deletions.
16 changes: 12 additions & 4 deletions Content.Server/Access/Components/PresetIdCardComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,23 @@ namespace Content.Server.Access.Components;
[RegisterComponent]
public sealed partial class PresetIdCardComponent : Component
{
[DataField("job")]
[DataField]
public ProtoId<JobPrototype>? JobName;

[DataField("name")]
[DataField]
public string? IdName;

/// <summary>
/// DeltaV: Allow changing the job title, even if it'd be otherwise set by the JobPrototype
/// </summary>
[DataField("customJob")]
public string? CustomJobName;
[DataField]
public string? VirtualJobName;

[ViewVariables(VVAccess.ReadOnly)]
public string? VirtualJobLocalizedName => (VirtualJobName != null) ? Loc.GetString(VirtualJobName) : null;
/// <summary>
/// DeltaV: Allow changing the job icon, even if it'd be otherwise set by the JobPrototype
/// </summary>
[DataField]
public string? VirtualJobIcon;
}
33 changes: 6 additions & 27 deletions Content.Server/Access/Systems/PresetIdCardSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<PresetIdCardComponent, MapInitEvent>(OnMapInit);
Expand All @@ -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
}
}

Expand All @@ -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)
Expand All @@ -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<StationRecordKeyStorageComponent>(uid, out var keyStorage)
|| keyStorage.Key is not { } key
|| !_record.TryGetRecord<GeneralStationRecord>(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)
Expand All @@ -103,10 +78,14 @@ private void SetupIdAccess(EntityUid uid, PresetIdCardComponent id, bool extende

_accessSystem.SetAccessToJob(uid, job, extended);

_cardSystem.TryChangeJobTitle(uid, job.LocalizedName);
//flag
_cardSystem.TryChangeJobTitle(uid, !string.IsNullOrEmpty(id.VirtualJobLocalizedName) ? id.VirtualJobLocalizedName : job.LocalizedName); // DeltaV #1425 - Attempt to use virtual job information before using job information
_cardSystem.TryChangeJobDepartment(uid, job);

// DeltaV #1425 - Attempt to use virtual job information before using job information
_prototypeManager.TryIndex<StatusIconPrototype>(id.VirtualJobIcon ?? string.Empty, out var virtualJobIcon);
if (_prototypeManager.TryIndex(job.Icon, out var jobIcon))
_cardSystem.TryChangeJobIcon(uid, jobIcon);
_cardSystem.TryChangeJobIcon(uid, virtualJobIcon ?? jobIcon);
// End of DeltaV code
}
}
89 changes: 84 additions & 5 deletions Content.Server/GameTicking/GameTicker.Spawning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
using Content.Server.Spawners.Components;
using Content.Server.Speech.Components;
using Content.Server.Station.Components;
using Content.Server.Access.Components;
using Content.Shared.Database;
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.PDA;
using JetBrains.Annotations;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
Expand All @@ -21,13 +25,13 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;

namespace Content.Server.GameTicking
{
public sealed partial class GameTicker
{
[Dependency] private readonly IAdminManager _adminManager = default!;
[Dependency] private readonly SharedJobSystem _jobs = default!;
[Dependency] private readonly IComponentFactory _componentFactory = default!; // DeltaV #1425

[ValidatePrototypeId<EntityPrototype>]
public const string ObserverPrototypeName = "MobObserver";
Expand Down Expand Up @@ -224,6 +228,30 @@ private void SpawnPlayer(ICommonSession player,

var jobPrototype = _prototypeManager.Index<JobPrototype>(jobId);
var job = new JobComponent {Prototype = jobId};
// DeltaV #1425 - Loadout stuff to get Senior ID
// Get the PresetIdCardComponent and its VirtualJobName/Icon vars;
var jobLoadout = LoadoutSystem.GetJobPrototype(jobPrototype.ID);

if (_prototypeManager.TryIndex(jobLoadout, out RoleLoadoutPrototype? roleProto))
{
RoleLoadout? loadout = null;
character.Loadouts.TryGetValue(jobLoadout, out loadout);

// Set to default if not present
if (loadout == null)
{
loadout = new RoleLoadout(jobLoadout);
loadout.SetDefault(character, player, _prototypeManager);
}

// Get the ID
if (GetPresetIdFromLoadout(loadout, roleProto, character, out var presetId))
{
job.VirtualJobName = presetId?.VirtualJobName;
job.VirtualJobIcon = presetId?.VirtualJobIcon;
}
}
// End of DeltaV code
_roles.MindAddRole(newMind, job, silent: silent);
var jobName = _jobs.MindTryGetJobName(newMind);

Expand Down Expand Up @@ -302,14 +330,65 @@ private void SpawnPlayer(ICommonSession player,
PlayersJoinedRoundNormally++;
var aev = new PlayerSpawnCompleteEvent(mob,
player,
jobId,
job, // DeltaV #1425 - Use Job instead of JobId to pass VirtualJobLocalizedName/Icon.
lateJoin,
PlayersJoinedRoundNormally,
station,
character);
RaiseLocalEvent(mob, aev, true);
}

// DeltaV #1425 - Go through loadout items to find ID card and its attached job
private bool GetPresetIdFromLoadout(RoleLoadout loadout, RoleLoadoutPrototype roleProto, HumanoidCharacterProfile character, out PresetIdCardComponent? presetId)
{
presetId = 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.Debug($"Unable to find loadout prototype for {items.Prototype}");
continue;
}
if (!_prototypeManager.TryIndex(loadoutProto.Equipment, out var startingGear))
{
Log.Debug($"Unable to find starting gear {loadoutProto.Equipment} for loadout {loadoutProto}");
continue;
}
var entProtoId = startingGear.GetGear("id");
if (!_prototypeManager.TryIndex<EntityPrototype>(entProtoId, out var idProto))
{
Log.Debug($"Unable to find prototype for {startingGear} for starting gear {loadoutProto.Equipment} for loadout {loadoutProto}");
continue;
}
if (idProto.TryGetComponent<PdaComponent>(out var pdaComponent, _componentFactory) && pdaComponent.IdCard != null)
{
ProtoId<EntityPrototype> idProtoId = pdaComponent.IdCard;
if (!_prototypeManager.TryIndex<EntityPrototype>(idProtoId, out idProto))
{
Log.Warning($"Unable to find an idCard in {idProto}");
return false;
}
}

if (!idProto.TryGetComponent<PresetIdCardComponent>(out var idComponent, _componentFactory))
{
Log.Debug($"Unable to find presetIdCard for {idProto}");
continue;
}

presetId = idComponent;
Log.Debug($"Successfully outputted {presetId} from {idProto}");
return true;
}
}
Log.Warning($"All other options exhausted");
return false;
}
// End of DeltaV code

public void Respawn(ICommonSession player)
{
_mind.WipeMind(player);
Expand Down Expand Up @@ -500,7 +579,7 @@ public sealed class PlayerSpawnCompleteEvent : EntityEventArgs
{
public EntityUid Mob { get; }
public ICommonSession Player { get; }
public string? JobId { get; }
public JobComponent? Job { get; } // DeltaV #1425 - Replace JobId with Job to parse VirtualJob
public bool LateJoin { get; }
public EntityUid Station { get; }
public HumanoidCharacterProfile Profile { get; }
Expand All @@ -510,15 +589,15 @@ public sealed class PlayerSpawnCompleteEvent : EntityEventArgs

public PlayerSpawnCompleteEvent(EntityUid mob,
ICommonSession player,
string? jobId,
JobComponent? job, // DeltaV #1425
bool lateJoin,
int joinOrder,
EntityUid station,
HumanoidCharacterProfile profile)
{
Mob = mob;
Player = player;
JobId = jobId;
Job = job; // DeltaV #1425
LateJoin = lateJoin;
Station = station;
Profile = profile;
Expand Down
14 changes: 9 additions & 5 deletions Content.Server/Station/Systems/StationSpawningSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ public EntityUid SpawnPlayerMob(

if (profile != null)
{
if (prototype != null)
SetPdaAndIdCardData(entity.Value, profile.Name, prototype, station);
if (job != null)
SetPdaAndIdCardData(entity.Value, profile.Name, job, station); // DeltaV #1425 - Inherit job data from a VirtualJob if one exists

_humanoidSystem.LoadProfile(entity.Value, profile);
_metaSystem.SetEntityName(entity.Value, profile.Name);
Expand Down Expand Up @@ -254,8 +254,11 @@ private void DoJobSpecials(JobComponent? job, EntityUid entity)
/// <param name="characterName">Character name to use for the ID.</param>
/// <param name="jobPrototype">Job prototype to use for the PDA and ID.</param>
/// <param name="station">The station this player is being spawned on.</param>
public void SetPdaAndIdCardData(EntityUid entity, string characterName, JobPrototype jobPrototype, EntityUid? station)
public void SetPdaAndIdCardData(EntityUid entity, string characterName, JobComponent job, EntityUid? station) // DeltaV #1425 - Use Job instead of JobId to pass VirtualJobLocalizedName/Icon
{
if (!_prototypeManager.TryIndex(job.Prototype, out var jobPrototype)) // DeltaV #1425 - Get jobPrototype separately as a result
return;

if (!InventorySystem.TryGetSlotEntity(entity, "id", out var idUid))
return;

Expand All @@ -267,10 +270,11 @@ public void SetPdaAndIdCardData(EntityUid entity, string characterName, JobProto
return;

_cardSystem.TryChangeFullName(cardId, characterName, card);
_cardSystem.TryChangeJobTitle(cardId, jobPrototype.LocalizedName, card);
_cardSystem.TryChangeJobTitle(cardId, job.VirtualJobLocalizedName ?? jobPrototype.LocalizedName, card); // DeltaV #1425 - Use VirtualJobLocalizedName if possible

_prototypeManager.TryIndex<StatusIconPrototype>(job.VirtualJobIcon ?? string.Empty, out var virtualJobIcon);
if (_prototypeManager.TryIndex(jobPrototype.Icon, out var jobIcon))
_cardSystem.TryChangeJobIcon(cardId, jobIcon, card);
_cardSystem.TryChangeJobIcon(cardId, virtualJobIcon ?? jobIcon, card); // DeltaV #1425 - Use VirtualJobIcon if possible

var extendedAccess = false;
if (station != null)
Expand Down
28 changes: 18 additions & 10 deletions Content.Server/StationRecords/Systems/StationRecordsSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,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;
Expand Down Expand Up @@ -48,15 +49,19 @@ private void OnPlayerSpawn(PlayerSpawnCompleteEvent args)
if (!TryComp<StationRecordsComponent>(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 #1425 - 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 #1425
{
// TODO make PlayerSpawnCompleteEvent.JobId a ProtoId
if (string.IsNullOrEmpty(jobId)
|| !_prototypeManager.HasIndex<JobPrototype>(jobId))
// DeltaV #1425 - Inherit from VirtualJob if possible
if (!_prototypeManager.TryIndex<JobPrototype>(job?.Prototype, out var jobProto))
return;
// End of DeltaV code

if (string.IsNullOrEmpty(job?.Prototype)
|| !_prototypeManager.HasIndex<JobPrototype>(jobProto))
return;

if (!_inventory.TryGetSlotEntity(player, "id", out var idUid))
Expand All @@ -65,7 +70,7 @@ private void CreateGeneralRecord(EntityUid station, EntityUid player, HumanoidCh
TryComp<FingerprintComponent>(player, out var fingerprintComponent);
TryComp<DnaComponent>(player, out var dnaComponent);

CreateGeneralRecord(station, idUid.Value, profile.Name, profile.Age, profile.Species, profile.Gender, jobId, fingerprintComponent?.Fingerprint, dnaComponent?.DNA, profile, records);
CreateGeneralRecord(station, idUid.Value, profile.Name, profile.Age, profile.Species, profile.Gender, job, fingerprintComponent?.Fingerprint, dnaComponent?.DNA, profile, records);
}


Expand Down Expand Up @@ -103,14 +108,17 @@ public void CreateGeneralRecord(
int age,
string species,
Gender gender,
string jobId,
JobComponent job, // DeltaV #1425 - Use Job instead of JobId to pass VirtualJobLocalizedName/Icon
string? mobFingerprint,
string? dna,
HumanoidCharacterProfile profile,
StationRecordsComponent records)
{
if (!_prototypeManager.TryIndex<JobPrototype>(jobId, out var jobPrototype))
// DeltaV #1425 - Get jobId separately as a result
string? jobId = job.Prototype;
if (string.IsNullOrEmpty(jobId) || !_prototypeManager.TryIndex<JobPrototype>(job.Prototype, out var jobPrototype))
throw new ArgumentException($"Invalid job prototype ID: {jobId}");
// End of DeltaV code

// when adding a record that already exists use the old one
// this happens when respawning as the same character
Expand All @@ -124,8 +132,8 @@ public void CreateGeneralRecord(
{
Name = name,
Age = age,
JobTitle = jobPrototype.LocalizedName,
JobIcon = jobPrototype.Icon,
JobTitle = job.VirtualJobLocalizedName ?? jobPrototype.LocalizedName,// DeltaV #1425 - Use VirtualJobLocalizedName if possible
JobIcon = job.VirtualJobIcon ?? jobPrototype.Icon, // DeltaV #1425 - Use VirtualJobIcon if possible
JobPrototype = jobId,
Species = species,
Gender = gender,
Expand Down
14 changes: 13 additions & 1 deletion Content.Shared/Roles/Jobs/JobComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Robust.Shared.GameStates;
using Content.Shared.Chat.V2.Repository;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;

namespace Content.Shared.Roles.Jobs;
Expand All @@ -11,4 +12,15 @@ public sealed partial class JobComponent : Component
{
[DataField(required: true), AutoNetworkedField]
public ProtoId<JobPrototype>? Prototype;

// DeltaV #1425 - Pass VirtualJobLocalizedName/Icon with the JobComponent to override job information
[DataField]
public string? VirtualJobName;

[ViewVariables(VVAccess.ReadOnly)]
public string? VirtualJobLocalizedName => (VirtualJobName != null) ? Loc.GetString(VirtualJobName) : null;

[DataField]
public string? VirtualJobIcon;
// End of DeltaV code
}
Loading

0 comments on commit 10b7e40

Please sign in to comment.