| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- using System.Linq;
- using Content.Server.Chat.Managers;
- using Content.Server.Chat.Systems;
- using Content.Shared.Chat;
- using Content.Shared.Mind;
- using Content.Shared.Roles;
- using Content.Shared.Silicons.StationAi;
- using Content.Shared.StationAi;
- using Robust.Shared.Audio;
- using Robust.Shared.Map.Components;
- using Robust.Shared.Player;
- using static Content.Server.Chat.Systems.ChatSystem;
- namespace Content.Server.Silicons.StationAi;
- public sealed class StationAiSystem : SharedStationAiSystem
- {
- [Dependency] private readonly IChatManager _chats = default!;
- [Dependency] private readonly EntityLookupSystem _lookup = default!;
- [Dependency] private readonly SharedTransformSystem _xforms = default!;
- [Dependency] private readonly SharedMindSystem _mind = default!;
- [Dependency] private readonly SharedRoleSystem _roles = default!;
- private readonly HashSet<Entity<StationAiCoreComponent>> _ais = new();
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<ExpandICChatRecipientsEvent>(OnExpandICChatRecipients);
- }
- private void OnExpandICChatRecipients(ExpandICChatRecipientsEvent ev)
- {
- var xformQuery = GetEntityQuery<TransformComponent>();
- var sourceXform = Transform(ev.Source);
- var sourcePos = _xforms.GetWorldPosition(sourceXform, xformQuery);
- // This function ensures that chat popups appear on camera views that have connected microphones.
- var query = EntityManager.EntityQueryEnumerator<StationAiCoreComponent, TransformComponent>();
- while (query.MoveNext(out var ent, out var entStationAiCore, out var entXform))
- {
- var stationAiCore = new Entity<StationAiCoreComponent?>(ent, entStationAiCore);
- if (!TryGetHeld(stationAiCore, out var insertedAi) || !TryComp(insertedAi, out ActorComponent? actor))
- continue;
- if (stationAiCore.Comp?.RemoteEntity == null || stationAiCore.Comp.Remote)
- continue;
- var xform = Transform(stationAiCore.Comp.RemoteEntity.Value);
- var range = (xform.MapID != sourceXform.MapID)
- ? -1
- : (sourcePos - _xforms.GetWorldPosition(xform, xformQuery)).Length();
- if (range < 0 || range > ev.VoiceRange)
- continue;
- ev.Recipients.TryAdd(actor.PlayerSession, new ICChatRecipientData(range, false));
- }
- }
- public override bool SetVisionEnabled(Entity<StationAiVisionComponent> entity, bool enabled, bool announce = false)
- {
- if (!base.SetVisionEnabled(entity, enabled, announce))
- return false;
- if (announce)
- {
- AnnounceSnip(entity.Owner);
- }
- return true;
- }
- public override bool SetWhitelistEnabled(Entity<StationAiWhitelistComponent> entity, bool enabled, bool announce = false)
- {
- if (!base.SetWhitelistEnabled(entity, enabled, announce))
- return false;
- if (announce)
- {
- AnnounceSnip(entity.Owner);
- }
- return true;
- }
- public override void AnnounceIntellicardUsage(EntityUid uid, SoundSpecifier? cue = null)
- {
- if (!TryComp<ActorComponent>(uid, out var actor))
- return;
- var msg = Loc.GetString("ai-consciousness-download-warning");
- var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", msg));
- _chats.ChatMessageToOne(ChatChannel.Server, msg, wrappedMessage, default, false, actor.PlayerSession.Channel, colorOverride: Color.Red);
- if (cue != null && _mind.TryGetMind(uid, out var mindId, out _))
- _roles.MindPlaySound(mindId, cue);
- }
- private void AnnounceSnip(EntityUid entity)
- {
- var xform = Transform(entity);
- if (!TryComp(xform.GridUid, out MapGridComponent? grid))
- return;
- _ais.Clear();
- _lookup.GetChildEntities(xform.GridUid.Value, _ais);
- var filter = Filter.Empty();
- foreach (var ai in _ais)
- {
- // TODO: Filter API?
- if (TryComp(ai.Owner, out ActorComponent? actorComp))
- {
- filter.AddPlayer(actorComp.PlayerSession);
- }
- }
- // TEST
- // filter = Filter.Broadcast();
- // No easy way to do chat notif embeds atm.
- var tile = Maps.LocalToTile(xform.GridUid.Value, grid, xform.Coordinates);
- var msg = Loc.GetString("ai-wire-snipped", ("coords", tile));
- _chats.ChatMessageToMany(ChatChannel.Notifications, msg, msg, entity, false, true, filter.Recipients.Select(o => o.Channel));
- // Apparently there's no sound for this.
- }
- }
|