* feat: now when research is unlocked in console, approver of reasearch is radio-ed too
* refactor: now most of events that require actor name to be radio-ed or logged use TryGetIdentityShortInfoEvent which is subscibed by id-card system and borg system (to work for both carbon and synthetic life-forms)
* refactor: moved TryGetIdentityShortInfoEvent on id card system to shared, fixed cargo cent-com-originated orders
* remove unused check
* refactor: decoupled systems from IdCardSystem (those that are not dependent on it anymore)
* refactor: removed unuseed usings
* feat: emagged cargo/research consoles wont radio messages on buy/research confirm anymore
---------
Co-authored-by: pa.pecherskij <pa.pecherskij@interfax.ru>
public override void Initialize()
{
base.Initialize();
+
SubscribeLocalEvent<IdCardComponent, BeingMicrowavedEvent>(OnMicrowaved);
}
using Content.Shared.Cargo.Events;
using Content.Shared.Cargo.Prototypes;
using Content.Shared.Database;
+using Content.Shared.Emag.Components;
+using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Paper;
using Robust.Shared.Map;
RaiseLocalEvent(ref ev);
ev.FulfillmentEntity ??= station.Value;
- _idCardSystem.TryFindIdCard(player, out var idCard);
- // ReSharper disable once ConditionalAccessQualifierIsNonNullableAccordingToAPIContract
- order.SetApproverData(idCard.Comp?.FullName, idCard.Comp?.JobTitle);
-
if (!ev.Handled)
{
ev.FulfillmentEntity = TryFulfillOrder((station.Value, stationData), order, orderDatabase);
order.Approved = true;
_audio.PlayPvs(component.ConfirmSound, uid);
- var message = Loc.GetString("cargo-console-unlock-approved-order-broadcast",
- ("productName", Loc.GetString(order.ProductName)),
- ("orderAmount", order.OrderQuantity),
- ("approver", order.Approver ?? string.Empty),
- ("cost", cost));
- _radio.SendRadioMessage(uid, message, component.AnnouncementChannel, uid, escapeMarkup: false);
+ if (!HasComp<EmaggedComponent>(uid))
+ {
+ var tryGetIdentityShortInfoEvent = new TryGetIdentityShortInfoEvent(uid, player);
+ RaiseLocalEvent(tryGetIdentityShortInfoEvent);
+ order.SetApproverData(tryGetIdentityShortInfoEvent.Title);
+
+ var message = Loc.GetString("cargo-console-unlock-approved-order-broadcast",
+ ("productName", Loc.GetString(order.ProductName)),
+ ("orderAmount", order.OrderQuantity),
+ ("approver", order.Approver ?? string.Empty),
+ ("cost", cost));
+ _radio.SendRadioMessage(uid, message, component.AnnouncementChannel, uid, escapeMarkup: false);
+ }
+
ConsolePopup(args.Actor, Loc.GetString("cargo-console-trade-station", ("destination", MetaData(ev.FulfillmentEntity.Value).EntityName)));
// Log order approval
-using Content.Server.Access.Systems;
using Content.Server.Cargo.Components;
using Content.Server.DeviceLinking.Systems;
using Content.Server.Popups;
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
[Dependency] private readonly DeviceLinkSystem _linker = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
- [Dependency] private readonly IdCardSystem _idCardSystem = default!;
[Dependency] private readonly ItemSlotsSystem _slots = default!;
[Dependency] private readonly PaperSystem _paperSystem = default!;
[Dependency] private readonly PopupSystem _popup = default!;
-using System.Globalization;
-using Content.Server.Access.Systems;
using Content.Server.Administration.Logs;
using Content.Server.AlertLevel;
using Content.Server.Chat.Systems;
-using Content.Server.DeviceNetwork;
using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Systems;
using Content.Server.Interaction;
using Content.Server.Popups;
using Content.Server.RoundEnd;
-using Content.Server.Screens;
using Content.Server.Screens.Components;
using Content.Server.Shuttles.Systems;
using Content.Server.Station.Systems;
using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.Emag.Components;
+using Content.Shared.IdentityManagement;
using Content.Shared.Popups;
-using Content.Shared.Silicons.Borgs.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Configuration;
[Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly DeviceNetworkSystem _deviceNetworkSystem = default!;
[Dependency] private readonly EmergencyShuttleSystem _emergency = default!;
- [Dependency] private readonly IdCardSystem _idCardSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly RoundEndSystem _roundEndSystem = default!;
[Dependency] private readonly StationSystem _stationSystem = default!;
return;
}
- // User has an id
- if (_idCardSystem.TryFindIdCard(mob, out var id))
- {
- author = $"{id.Comp.FullName} ({CultureInfo.CurrentCulture.TextInfo.ToTitleCase(id.Comp.JobTitle ?? string.Empty)})".Trim();
- }
-
- // User does not have an id and is a borg, so use the borg's name
- if (HasComp<BorgChassisComponent>(mob))
- {
- author = Name(mob).Trim();
- }
+ var tryGetIdentityShortInfoEvent = new TryGetIdentityShortInfoEvent(uid, mob);
+ RaiseLocalEvent(tryGetIdentityShortInfoEvent);
+ author = tryGetIdentityShortInfoEvent.Title;
}
comp.AnnouncementCooldownRemaining = comp.Delay;
using Content.Shared.Security;
using Content.Shared.StationRecords;
using Robust.Server.GameObjects;
-using Robust.Shared.Player;
using System.Diagnostics.CodeAnalysis;
using Content.Shared.IdentityManagement;
using Content.Shared.Security.Components;
[Dependency] private readonly CriminalRecordsSystem _criminalRecords = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly RadioSystem _radio = default!;
- [Dependency] private readonly SharedIdCardSystem _idCard = default!;
[Dependency] private readonly StationRecordsSystem _records = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
var name = _records.RecordName(key.Value);
var officer = Loc.GetString("criminal-records-console-unknown-officer");
- if (_idCard.TryFindIdCard(mob.Value, out var id) && id.Comp.FullName is { } fullName)
- officer = fullName;
+
+ var tryGetIdentityShortInfoEvent = new TryGetIdentityShortInfoEvent(null, mob.Value);
+ RaiseLocalEvent(tryGetIdentityShortInfoEvent);
+ if (tryGetIdentityShortInfoEvent.Title != null)
+ {
+ officer = tryGetIdentityShortInfoEvent.Title;
+ }
(string, object)[] args;
if (reason != null)
using System.Diagnostics.CodeAnalysis;
-using Content.Server.Access.Systems;
using Content.Server.Administration.Logs;
using Content.Server.CartridgeLoader;
using Content.Server.CartridgeLoader.Cartridges;
using Content.Shared.Popups;
using Robust.Server.GameObjects;
using Robust.Shared.Audio.Systems;
+using Content.Shared.IdentityManagement;
using Robust.Shared.Timing;
namespace Content.Server.MassMedia.Systems;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly GameTicker _ticker = default!;
- [Dependency] private readonly IdCardSystem _idCardSystem = default!;
+ [Dependency] private readonly AccessReaderSystem _accessReader = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
public override void Initialize()
ent.Comp.PublishEnabled = false;
ent.Comp.NextPublish = _timing.CurTime + TimeSpan.FromSeconds(ent.Comp.PublishCooldown);
- string? authorName = null;
- if (_idCardSystem.TryFindIdCard(msg.Actor, out var idCard))
- authorName = idCard.Comp.FullName;
+ var tryGetIdentityShortInfoEvent = new TryGetIdentityShortInfoEvent(ent, msg.Actor);
+ RaiseLocalEvent(tryGetIdentityShortInfoEvent);
+ string? authorName = tryGetIdentityShortInfoEvent.Title;
var title = msg.Title.Trim();
var content = msg.Content.Trim();
using Content.Server.Research.Components;
using Content.Shared.UserInterface;
using Content.Shared.Access.Components;
+using Content.Shared.Emag.Components;
+using Content.Shared.IdentityManagement;
using Content.Shared.Research.Components;
using Content.Shared.Research.Prototypes;
if (!UnlockTechnology(uid, args.Id, act))
return;
- var message = Loc.GetString("research-console-unlock-technology-radio-broadcast",
- ("technology", Loc.GetString(technologyPrototype.Name)),
- ("amount", technologyPrototype.Cost));
- _radio.SendRadioMessage(uid, message, component.AnnouncementChannel, uid, escapeMarkup: false);
+ if (!HasComp<EmaggedComponent>(uid))
+ {
+ var getIdentityEvent = new TryGetIdentityShortInfoEvent(uid, act);
+ RaiseLocalEvent(getIdentityEvent);
+
+ var message = Loc.GetString(
+ "research-console-unlock-technology-radio-broadcast",
+ ("technology", Loc.GetString(technologyPrototype.Name)),
+ ("amount", technologyPrototype.Cost),
+ ("approver", getIdentityEvent.Title ?? string.Empty)
+ );
+ _radio.SendRadioMessage(uid, message, component.AnnouncementChannel, uid, escapeMarkup: false);
+ }
+
SyncClientWithServer(uid);
UpdateConsoleInterface(uid, component);
}
{
UpdateConsoleInterface(uid, component);
}
+
}
using Content.Shared.Inventory;
using Content.Shared.NameIdentifier;
using Content.Shared.PDA;
-using Content.Shared.Silicons.Borgs.Components;
using Content.Shared.StationRecords;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Content.Shared.GameTicking;
+using Content.Shared.IdentityManagement;
using Robust.Shared.Collections;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly SharedGameTicker _gameTicker = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
- [Dependency] private readonly SharedIdCardSystem _idCardSystem = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedStationRecordsSystem _recordsSystem = default!;
// TODO pass the ID card on IsAllowed() instead of using this expensive method
// Set name if the accessor has a card and that card has a name and allows itself to be recorded
- if (_idCardSystem.TryFindIdCard(accessor, out var idCard)
- && idCard.Comp is { BypassLogging: false, FullName: not null })
- name = idCard.Comp.FullName;
+ var getIdentityShortInfoEvent = new TryGetIdentityShortInfoEvent(ent, accessor, true);
+ RaiseLocalEvent(getIdentityShortInfoEvent);
+ if (getIdentityShortInfoEvent.Title != null)
+ {
+ name = getIdentityShortInfoEvent.Title;
+ }
LogAccess(ent, name ?? Loc.GetString("access-reader-unknown-id"));
}
+using System.Globalization;
using Content.Shared.Access.Components;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Content.Shared.Hands.Components;
+using Content.Shared.IdentityManagement;
using Content.Shared.Inventory;
using Content.Shared.PDA;
using Content.Shared.Roles;
public override void Initialize()
{
base.Initialize();
+
SubscribeLocalEvent<IdCardComponent, MapInitEvent>(OnMapInit);
+ SubscribeLocalEvent<TryGetIdentityShortInfoEvent>(OnTryGetIdentityShortInfo);
}
private void OnMapInit(EntityUid uid, IdCardComponent id, MapInitEvent args)
UpdateEntityName(uid, id);
}
+ private void OnTryGetIdentityShortInfo(TryGetIdentityShortInfoEvent ev)
+ {
+ if (ev.Handled)
+ {
+ return;
+ }
+
+ string? title = null;
+ if (TryFindIdCard(ev.ForActor, out var idCard) && !(ev.RequestForAccessLogging && idCard.Comp.BypassLogging))
+ {
+ title = ExtractFullTitle(idCard);
+ }
+
+ ev.Title = title;
+ ev.Handled = true;
+ }
+
/// <summary>
/// Attempt to find an ID card on an entity. This will look in the entity itself, in the entity's hands, and
/// in the entity's inventory.
("jobSuffix", jobSuffix));
_metaSystem.SetEntityName(uid, val);
}
+
+ private static string ExtractFullTitle(IdCardComponent idCardComponent)
+ {
+ return $"{idCardComponent.FullName} ({CultureInfo.CurrentCulture.TextInfo.ToTitleCase(idCardComponent.JobTitle ?? string.Empty)})"
+ .Trim();
+ }
}
Reason = reason;
}
+ public void SetApproverData(string? approver)
+ {
+ Approver = approver;
+ }
+
public void SetApproverData(string? fullName, string? jobTitle)
{
var sb = new StringBuilder();
--- /dev/null
+namespace Content.Shared.IdentityManagement;
+
+/// <summary>
+/// Event of attempt to collect actor full title - full name + job from id card for employee or entity name for borgs.
+/// </summary>
+public sealed class TryGetIdentityShortInfoEvent(EntityUid? whileInteractingWith, EntityUid forActor, bool forLogging = false) : HandledEntityEventArgs
+{
+ /// <summary>
+ /// Full name of <see cref="ForActor"/>, with JobTitle.
+ /// Can be null if no system could find actor name / job.
+ /// </summary>
+ public string? Title;
+
+ /// <summary>
+ /// Entity for interacting with which title should be collected.
+ /// Could be used to black-out name of people when announcing actions
+ /// on e-magged devices.
+ /// </summary>
+ public readonly EntityUid? WhileInteractingWith = whileInteractingWith;
+
+ /// <summary>
+ /// Actor for whom title should be collected.
+ /// </summary>
+ public readonly EntityUid ForActor = forActor;
+
+ /// <summary>
+ /// Marker that title info was requested for access logging.
+ /// Is required as event handlers can determine, if they don't need
+ /// to place title info due to access logging restrictions.
+ /// </summary>
+ public readonly bool RequestForAccessLogging = forLogging;
+}
-using Content.Shared.Access.Components;
using Content.Shared.Containers.ItemSlots;
+using Content.Shared.IdentityManagement;
using Content.Shared.Item.ItemToggle;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems;
SubscribeLocalEvent<BorgChassisComponent, EntRemovedFromContainerMessage>(OnRemoved);
SubscribeLocalEvent<BorgChassisComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeedModifiers);
SubscribeLocalEvent<BorgChassisComponent, ActivatableUIOpenAttemptEvent>(OnUIOpenAttempt);
-
+ SubscribeLocalEvent<TryGetIdentityShortInfoEvent>(OnTryGetIdentityShortInfo);
+
InitializeRelay();
}
+ private void OnTryGetIdentityShortInfo(TryGetIdentityShortInfoEvent args)
+ {
+ if (args.Handled)
+ {
+ return;
+ }
+
+ if (!HasComp<BorgChassisComponent>(args.ForActor))
+ {
+ return;
+ }
+
+ args.Title = Name(args.ForActor).Trim();
+ args.Handled = true;
+ }
+
private void OnItemSlotInsertAttempt(EntityUid uid, BorgChassisComponent component, ref ItemSlotInsertAttemptEvent args)
{
if (args.Cancelled)
research-console-prereqs-list-entry = - [color=orchid]{$text}[/color]
research-console-no-access-popup = No access!
-research-console-unlock-technology-radio-broadcast = Unlocked [bold]{$technology}[/bold] for [bold]{$amount}[/bold] research.
+research-console-unlock-technology-radio-broadcast = Unlocked [bold]{$technology}[/bold] for [bold]{$amount}[/bold] research by [bold]{$approver}[/bold].