using Content.Shared.Configurable; using Content.Shared.DeviceNetwork.Components; using Content.Shared.DeviceNetwork.Events; using Content.Shared.DeviceNetwork.Systems; using Content.Shared.Disposal.Components; using Content.Shared.Disposal.Unit; using Content.Shared.Interaction; using Robust.Shared.Player; namespace Content.Shared.Disposal.Mailing; public abstract partial class SharedMailingUnitSystem : EntitySystem { [Dependency] private SharedDeviceNetworkSystem _deviceNetwork = default!; [Dependency] private SharedUserInterfaceSystem _userInterface = default!; private const string MailTag = "mail"; private const string TagConfigurationKey = "tag"; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnComponentInit); SubscribeLocalEvent(OnBeforeFlush); SubscribeLocalEvent(OnConfigurationUpdated); SubscribeLocalEvent(HandleActivate, before: new[] { typeof(SharedDisposalUnitSystem) }); SubscribeLocalEvent(OnTargetSelected); } private void OnComponentInit(Entity ent, ref ComponentInit args) { UpdateTargetList(ent); } [SubscribeLocalEvent] private void OnRequestTag(Entity ent, ref DeviceNetworkPacketEvent args) { if (ent.Comp.Tag == null) return; var tagPayload = new MailTagPayload { Tag = ent.Comp.Tag, }; _deviceNetwork.SendPacket(ent.Owner, args.SenderAddress, ref tagPayload, args.Frequency); } [SubscribeLocalEvent] private void OnTag(Entity ent, ref DeviceNetworkPacketEvent args) { ent.Comp.TargetList.Add(args.Data.Tag); Dirty(ent); } /// /// Prevents the unit from flushing if no target is selected /// private void OnBeforeFlush(Entity ent, ref BeforeDisposalFlushEvent args) { if (string.IsNullOrEmpty(ent.Comp.Target)) { args.Cancel(); return; } Dirty(ent); args.Tags.Add(MailTag); args.Tags.Add(ent.Comp.Target); BroadcastSentMessage(ent); } /// /// Broadcast that a mail was sent including the src and target tags /// private void BroadcastSentMessage(Entity ent, DeviceNetworkComponent? device = null) { if (string.IsNullOrEmpty(ent.Comp.Tag) || string.IsNullOrEmpty(ent.Comp.Target) || !Resolve(ent, ref device)) return; var payload = new MailSendPayload { Tag = ent.Comp.Tag, Target = ent.Comp.Target, }; _deviceNetwork.SendPacket((ent.Owner, device), null, ref payload); } /// /// Clears the units target list and broadcasts a . /// The target list will then get populated with responses from all active mailing units on the same grid /// private void UpdateTargetList(Entity ent, DeviceNetworkComponent? device = null) { if (!Resolve(ent, ref device, false)) return; var payload = new MailRequestTagPayload(); ent.Comp.TargetList.Clear(); _deviceNetwork.SendPacket((ent.Owner, device), null, ref payload); } /// /// Gets called when the units tag got updated /// private void OnConfigurationUpdated(Entity ent, ref ConfigurationUpdatedEvent args) { var configuration = args.Configuration.Config; if (!configuration.ContainsKey(TagConfigurationKey) || configuration[TagConfigurationKey] == string.Empty) { ent.Comp.Tag = null; return; } ent.Comp.Tag = configuration[TagConfigurationKey]; Dirty(ent); } private void HandleActivate(Entity ent, ref ActivateInWorldEvent args) { if (args.Handled || !args.Complex) return; if (!TryComp(args.User, out ActorComponent? actor)) return; args.Handled = true; UpdateTargetList(ent); _userInterface.OpenUi(ent.Owner, MailingUnitUiKey.Key, actor.PlayerSession); } private void OnTargetSelected(Entity ent, ref TargetSelectedMessage args) { ent.Comp.Target = args.Target; Dirty(ent); if (_userInterface.TryGetOpenUi(ent.Owner, MailingUnitUiKey.Key, out var bui)) { bui.Update(); } } }