using Content.Server._White.Other; using Content.Server.Hands.Systems; using Content.Server.Popups; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.Coordinates; using Content.Shared.Interaction; using Content.Shared.Popups; using Content.Shared.Tag; using Content.Shared.UserInterface; using Content.Shared.Verbs; using Content.Shared.Wall; using Robust.Server.GameObjects; using Robust.Shared.Player; using static Content.Shared._White.InteractiveBoard.SharedInteractiveBoardComponent; namespace Content.Server._White.InteractiveBoard; public sealed class InteractiveBoardSystem : EntitySystem { [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedInteractionSystem _interaction = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!; [Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly TransformSystem _transformSystem = default!; [Dependency] private readonly HandsSystem _handsSystem = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(BeforeUIOpen); SubscribeLocalEvent(OnInteractUsing); SubscribeLocalEvent(OnInputTextMessage); SubscribeLocalEvent>(OnAltVerb); SubscribeLocalEvent(BeforeRangedInteract); SubscribeLocalEvent(OnInteractiveBoardWrite); } private void OnInit(EntityUid uid, InteractiveBoardComponent component, ComponentInit args) { component.Mode = InteractiveBoardAction.Read; UpdateUserInterface(uid, component); if (!TryComp(uid, out var appearance)) return; if (component.Content != "") _appearance.SetData(uid, InteractiveBoardVisuals.Status, InteractiveBoardStatus.Written, appearance); } private void OnAltVerb(EntityUid uid, InteractiveBoardComponent component, GetVerbsEvent args) { if (!args.CanAccess || !args.CanInteract) return; if(!HasComp(args.Target)) return; AlternativeVerb verb = new() { Act = () => { TakeOffInteractiveBoard(args.User, args.Target); }, Disabled = false, Priority = 1, Text = Loc.GetString("interactive-board-take-off"), }; args.Verbs.Add(verb); } private void TakeOffInteractiveBoard(EntityUid uid, EntityUid target) { if(!TryComp(target, out var transformComponent)) return; if(!HasComp(target)) return; if(!transformComponent.Anchored) return; _transformSystem.Unanchor(target, transformComponent); RemComp(target); if (!_handsSystem.TryPickupAnyHand(uid, target)) { _transformSystem.SetCoordinates(target, uid.ToCoordinates()); } } private void BeforeUIOpen(EntityUid uid, InteractiveBoardComponent component, BeforeActivatableUIOpenEvent args) { component.Mode = InteractiveBoardAction.Read; if (!TryComp(args.User, out var actor)) return; UpdateUserInterface(uid, component, actor.PlayerSession); } private void BeforeRangedInteract(EntityUid uid, InteractiveBoardComponent component, BeforeRangedInteractEvent args) { if (_tagSystem.HasTag(args.Used, "InteractiveBoard")) { if (!HasComp(args.Target) && !HasComp(args.Target)) return; if(!TryComp(args.Target, out var transformComponent)) return; if (!TryComp(args.Used, out var xform)) return; _handsSystem.TryDrop(args.User, args.Used); _transformSystem.SetCoordinates(args.Used, transformComponent.Coordinates); _transformSystem.AnchorEntity(args.Used, xform); _transformSystem.AttachToGridOrMap(args.Used, xform); AddComp(args.Used).Arc = new Angle(360); } } private void OnInteractUsing(EntityUid uid, InteractiveBoardComponent component, InteractUsingEvent args) { if (!_tagSystem.HasTag(args.Used, "InteractivePen")) return; if(!TryComp(args.Target, out var accessReaderComponent)) return; if (!_accessReaderSystem.IsAllowed(args.User, args.Target, accessReaderComponent)) { _popupSystem.PopupEntity(Loc.GetString("interactive-board-not-allowed"), args.User, args.User, PopupType.Medium); return; } var writeEvent = new InteractiveBoardWriteEvent(uid, args.User); RaiseLocalEvent(args.Used, ref writeEvent); if (!TryComp(args.User, out var actor)) return; component.Mode = InteractiveBoardAction.Write; _uiSystem.OpenUi(uid, InteractiveBoardUiKey.Key, actor.PlayerSession); UpdateUserInterface(uid, component, actor.PlayerSession); args.Handled = true; } private void OnInputTextMessage(EntityUid uid, InteractiveBoardComponent component, InteractiveBoardInputTextMessage args) { if (args.Text.Length <= component.ContentSize) { if (!TryComp(uid, out var appearance)) return; component.Content = args.Text.Replace("[", "(").Replace("]", ")"); if (string.IsNullOrWhiteSpace(component.Content)) { component.Mode = InteractiveBoardAction.Read; _appearance.SetData(uid, InteractiveBoardVisuals.Status, InteractiveBoardStatus.Blank, appearance); return; } _appearance.SetData(uid, InteractiveBoardVisuals.Status, InteractiveBoardStatus.Written, appearance); } if (args.Text.Length > component.ContentSize) { component.Content = args.Text.Remove(component.ContentSize, (args.Text.Length - component.ContentSize)); if (TryComp(uid, out var appearance)) _appearance.SetData(uid, InteractiveBoardVisuals.Status, InteractiveBoardStatus.Written, appearance); } component.Mode = InteractiveBoardAction.Read; UpdateUserInterface(uid, component); } private void OnInteractiveBoardWrite(EntityUid uid, OnInteractiveBoardWriteComponent comp, ref InteractiveBoardWriteEvent args) { _interaction.UseInHandInteraction(args.User, uid); } public void SetContent(EntityUid uid, string content, InteractiveBoardComponent? component = null) { if (!Resolve(uid, ref component)) return; component.Content = content + '\n'; UpdateUserInterface(uid, component); if (!TryComp(uid, out var appearance)) return; var status = string.IsNullOrWhiteSpace(content) ? InteractiveBoardStatus.Blank : InteractiveBoardStatus.Written; _appearance.SetData(uid, InteractiveBoardVisuals.Status, status, appearance); } public void UpdateUserInterface(EntityUid uid, InteractiveBoardComponent? component = null, ICommonSession? session = null) { if (!Resolve(uid, ref component)) return; _uiSystem.SetUiState(uid, InteractiveBoardUiKey.Key, new InteractiveBoardBoundUserInterfaceState(component.Content, component.Mode)); } } [ByRefEvent] public record struct InteractiveBoardWriteEvent(EntityUid User, EntityUid InteractiveBoard);