mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-19 22:49:01 +03:00
# Description This adds the wonderful `Psionics Registry Computer` which allows you to, just like Criminal Records, mark people that will show their icons to other individuals wearing the appropriate gear, and will allow you to keep track of such individuals in a similar way by making a `PsiWatch` app that will show the reasons. For the purposes of easement, I've left the fingerprints and DNA in there, but individuals will not show up with it in the actual file. The game would just crash when I removed the filters, so I left them in. The dropdown also just looked cleaner when it was there instead of removing it and replacing it with a label. I've recolored the sprites for the sec-glasses and sec-HUD to make the epi-glasses and epi-HUD using Epistemics colors. I've recolored the sprite for the CriminalRecords computer to look different and be cool. --- # TODO A list of things I've done split into categories. ### Spriting - [x] (Recolor) Sprite the epi-glasses and epi-HUD. - [x] Sprite the PsionicsRecords computer screen. - [x] Sprite the Psionics Status icons. - [x] Change the sprite for the Psionics Abusing (it is hard to tell any difference from suspected right now). ### Records - [x] Set up records XAML that basically duplicates the Criminal Records. - [x] Remove History (not necessary). - [x] Change all the naming schema to match. - [x] Change the categories and setup reason-requirement for each submission type. - [x] Change the "reason" to "psionics" so it is more intuitive. ### Computer Setup - [x] Setup computer to show UI. - [x] Setup system to report to report to Epistemics (Science) radio when anything is changed. - [x] Setup the system to only accept Epistemics (Research) access. - [x] Setup the computer board. - [x] Setup the sprites for the computers. ### Equipment and Icons - [x] Create the icons and ensure the ShowPsionicsRecordIcons prototype works. - [x] Create the entity prototypes for the glasses and HUD in the game to show textures. - [x] Set it up so the glasses and HUD show the user the icons when they're wearing them (having hard time fixing this at 06:00 in the morning). ### PDA App - [x] Setup the PDA app to mimic the SecWatch app as its own (PsiWatch). - [x] Add the PDA app cartridge to Chaplain, Mantis, Cataloguer, and Mystagogue. - [x] Add cartridge to the Mystagogue locker (so they can give others it). ### Loadouts - [x] Add the epi-HUD to the Chaplain, Mantis, Cataloguer and Mystagogue. - [x] Add the epi-glasses to the Mystagogue. - [x] Add the epi-glasses to Chaplain, Mantis, and Cataloguer (for 3 points). ### Mapping - [x] Add the Psionics Registry Computer to every map. ### Miscellaneous Fixes/Changes - [x] Make the computer only work for Chaplain (Chapel), Cataloguer (Library), Mantis (Mantis), and Mystagogue (ResearchDirector). - [x] Fix Chaplain PDA (did not have any programs installed automatically, now it does). --- # Media I will add more media when I finish the rest. For now, it's just us. <details><summary><h3>Registry Working</h3></summary> <p> https://github.com/user-attachments/assets/f534a1b6-6873-4bcd-9fe5-c7138069ecc0 </p> </details> <details><summary><h3>Loadouts and PsiWatch</h3></summary> <p> Cataloguer  Chaplain  Mantis  Mystagogue  --- No Users in PsiWatch  Suspected in PsiWatch  Registered in PsiWatch  Abusing in PsiWatch  PsiWatch in PDA  Picture of the PDAs and PsiWatch Cartridge  --- Mystagogue Lockers with PsiWatch Cartridge  </p> </details> <details><summary><h3>Mapping Locations</h3></summary> <p> Arena  Asterisk  Core  Edge  Europa  Gaxstation  Glacier  Hive  Lighthouse  Meta  Pebble  Radstation  Saltern  Shoukou  Submarine  Tortuga  </p> </details> --- # Changelog 🆑 - add: Added Psionics Registry Computer. Now you can record Psionics users in Epistemics. - add: Added epi-glasses and epi-HUD to see Psionics Users icons. (Chaplain, Cataloguer, Mantis, and Mystagogue have access in loadout). - add: Added PsiWatch. Now you can see the Psionics Records data on your PDA! - fix: Fixed Chaplain not having any programs in their PDA on spawn. --------- Signed-off-by: sleepyyapril <123355664+sleepyyapril@users.noreply.github.com> Co-authored-by: sleepyyapril <123355664+sleepyyapril@users.noreply.github.com> (cherry picked from commit fc7ecc44a748f8ef7a4cec613033f51acf238288)
180 lines
6.9 KiB
C#
180 lines
6.9 KiB
C#
using Content.Server.Access.Systems;
|
|
using Content.Server.Administration.Logs;
|
|
using Content.Server.CriminalRecords.Systems;
|
|
using Content.Server.PsionicsRecords.Systems;
|
|
using Content.Server.Humanoid;
|
|
using Content.Shared.Clothing;
|
|
using Content.Shared.Database;
|
|
using Content.Shared.Hands;
|
|
using Content.Shared.Humanoid;
|
|
using Content.Shared.IdentityManagement;
|
|
using Content.Shared.IdentityManagement.Components;
|
|
using Content.Shared.Inventory;
|
|
using Content.Shared.Inventory.Events;
|
|
using Robust.Shared.Containers;
|
|
using Robust.Shared.Enums;
|
|
using Robust.Shared.GameObjects.Components.Localization;
|
|
|
|
namespace Content.Server.IdentityManagement;
|
|
|
|
/// <summary>
|
|
/// Responsible for updating the identity of an entity on init or clothing equip/unequip.
|
|
/// </summary>
|
|
public sealed class IdentitySystem : SharedIdentitySystem
|
|
{
|
|
[Dependency] private readonly IdCardSystem _idCard = default!;
|
|
[Dependency] private readonly IAdminLogManager _adminLog = default!;
|
|
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
|
[Dependency] private readonly SharedContainerSystem _container = default!;
|
|
[Dependency] private readonly HumanoidAppearanceSystem _humanoid = default!;
|
|
[Dependency] private readonly CriminalRecordsConsoleSystem _criminalRecordsConsole = default!;
|
|
[Dependency] private readonly PsionicsRecordsConsoleSystem _psionicsRecordsConsole = default!;
|
|
|
|
private HashSet<EntityUid> _queuedIdentityUpdates = new();
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<IdentityComponent, DidEquipEvent>((uid, _, _) => QueueIdentityUpdate(uid));
|
|
SubscribeLocalEvent<IdentityComponent, DidEquipHandEvent>((uid, _, _) => QueueIdentityUpdate(uid));
|
|
SubscribeLocalEvent<IdentityComponent, DidUnequipEvent>((uid, _, _) => QueueIdentityUpdate(uid));
|
|
SubscribeLocalEvent<IdentityComponent, DidUnequipHandEvent>((uid, _, _) => QueueIdentityUpdate(uid));
|
|
SubscribeLocalEvent<IdentityComponent, WearerMaskToggledEvent>((uid, _, _) => QueueIdentityUpdate(uid));
|
|
SubscribeLocalEvent<IdentityComponent, MapInitEvent>(OnMapInit);
|
|
}
|
|
|
|
public override void Update(float frameTime)
|
|
{
|
|
base.Update(frameTime);
|
|
|
|
foreach (var ent in _queuedIdentityUpdates)
|
|
{
|
|
if (!TryComp<IdentityComponent>(ent, out var identity))
|
|
continue;
|
|
|
|
UpdateIdentityInfo(ent, identity);
|
|
}
|
|
|
|
_queuedIdentityUpdates.Clear();
|
|
}
|
|
|
|
// This is where the magic happens
|
|
private void OnMapInit(EntityUid uid, IdentityComponent component, MapInitEvent args)
|
|
{
|
|
var ident = Spawn(null, Transform(uid).Coordinates);
|
|
|
|
_metaData.SetEntityName(ident, "identity");
|
|
QueueIdentityUpdate(uid);
|
|
_container.Insert(ident, component.IdentityEntitySlot);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Queues an identity update to the start of the next tick.
|
|
/// </summary>
|
|
public void QueueIdentityUpdate(EntityUid uid)
|
|
{
|
|
_queuedIdentityUpdates.Add(uid);
|
|
}
|
|
|
|
#region Private API
|
|
|
|
/// <summary>
|
|
/// Updates the metadata name for the id(entity) from the current state of the character.
|
|
/// </summary>
|
|
private void UpdateIdentityInfo(EntityUid uid, IdentityComponent identity)
|
|
{
|
|
if (identity.IdentityEntitySlot.ContainedEntity is not { } ident)
|
|
return;
|
|
|
|
var representation = GetIdentityRepresentation(uid);
|
|
var name = GetIdentityName(uid, representation);
|
|
|
|
// Clone the old entity's grammar to the identity entity, for loc purposes.
|
|
if (TryComp<GrammarComponent>(uid, out var grammar))
|
|
{
|
|
var identityGrammar = EnsureComp<GrammarComponent>(ident);
|
|
identityGrammar.Attributes.Clear();
|
|
|
|
foreach (var (k, v) in grammar.Attributes)
|
|
{
|
|
identityGrammar.Attributes.Add(k, v);
|
|
}
|
|
|
|
// If presumed name is null and we're using that, we set proper noun to be false ("the old woman")
|
|
if (name != representation.TrueName && representation.PresumedName == null)
|
|
identityGrammar.ProperNoun = false;
|
|
}
|
|
|
|
if (name == Name(ident))
|
|
return;
|
|
|
|
_metaData.SetEntityName(ident, name);
|
|
|
|
_adminLog.Add(LogType.Identity, LogImpact.Medium, $"{ToPrettyString(uid)} changed identity to {name}");
|
|
var identityChangedEvent = new IdentityChangedEvent(uid, ident);
|
|
RaiseLocalEvent(uid, ref identityChangedEvent);
|
|
SetIdentityRecordsIcon(uid);
|
|
}
|
|
|
|
private string GetIdentityName(EntityUid target, IdentityRepresentation representation)
|
|
{
|
|
var ev = new SeeIdentityAttemptEvent();
|
|
|
|
RaiseLocalEvent(target, ev);
|
|
return representation.ToStringKnown(!ev.Cancelled);
|
|
}
|
|
|
|
/// <summary>
|
|
/// When the identity of a person is changed, searches the criminal records and psionics records to see if the name
|
|
/// of the new identity has a record. If the new name has a criminal status or psionics status attached to it, the
|
|
/// person will get the criminal status and/or psionics status until they change identity again.
|
|
/// </summary>
|
|
private void SetIdentityRecordsIcon(EntityUid uid)
|
|
{
|
|
_criminalRecordsConsole.CheckNewIdentity(uid);
|
|
_psionicsRecordsConsole.CheckNewIdentity(uid);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets an 'identity representation' of an entity, with their true name being the entity name
|
|
/// and their 'presumed name' and 'presumed job' being the name/job on their ID card, if they have one.
|
|
/// </summary>
|
|
private IdentityRepresentation GetIdentityRepresentation(EntityUid target,
|
|
InventoryComponent? inventory=null,
|
|
HumanoidAppearanceComponent? appearance=null)
|
|
{
|
|
int age = 18;
|
|
Gender gender = Gender.Epicene;
|
|
string species = SharedHumanoidAppearanceSystem.DefaultSpecies;
|
|
|
|
// Always use their actual age and gender, since that can't really be changed by an ID.
|
|
if (Resolve(target, ref appearance, false))
|
|
{
|
|
gender = appearance.Gender;
|
|
age = appearance.Age;
|
|
species = appearance.Species;
|
|
}
|
|
|
|
var ageString = _humanoid.GetAgeRepresentation(species, age);
|
|
var trueName = Name(target);
|
|
if (!Resolve(target, ref inventory, false))
|
|
return new(trueName, gender, ageString, string.Empty);
|
|
|
|
string? presumedJob = null;
|
|
string? presumedName = null;
|
|
|
|
// Get their name and job from their ID for their presumed name.
|
|
if (_idCard.TryFindIdCard(target, out var id))
|
|
{
|
|
presumedName = string.IsNullOrWhiteSpace(id.Comp.FullName) ? null : id.Comp.FullName;
|
|
presumedJob = id.Comp.LocalizedJobTitle?.ToLowerInvariant();
|
|
}
|
|
|
|
// If it didn't find a job, that's fine.
|
|
return new(trueName, gender, ageString, presumedName, presumedJob);
|
|
}
|
|
|
|
#endregion
|
|
}
|