| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- using Content.Shared.Administration.Logs;
- using Content.Shared.Database;
- using Content.Shared.Emag.Systems;
- using Content.Shared.Examine;
- using Content.Shared.IdentityManagement;
- using Content.Shared.Interaction;
- namespace Content.Shared.Pinpointer;
- public abstract class SharedPinpointerSystem : EntitySystem
- {
- [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
- [Dependency] private readonly EmagSystem _emag = default!;
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<PinpointerComponent, GotEmaggedEvent>(OnEmagged);
- SubscribeLocalEvent<PinpointerComponent, AfterInteractEvent>(OnAfterInteract);
- SubscribeLocalEvent<PinpointerComponent, ExaminedEvent>(OnExamined);
- }
- /// <summary>
- /// Set the target if capable
- /// </summary>
- private void OnAfterInteract(EntityUid uid, PinpointerComponent component, AfterInteractEvent args)
- {
- if (!args.CanReach || args.Target is not { } target)
- return;
- if (!component.CanRetarget || component.IsActive)
- return;
- // TODO add doafter once the freeze is lifted
- args.Handled = true;
- component.Target = args.Target;
- _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):player} set target of {ToPrettyString(uid):pinpointer} to {ToPrettyString(component.Target.Value):target}");
- if (component.UpdateTargetName)
- component.TargetName = component.Target == null ? null : Identity.Name(component.Target.Value, EntityManager);
- }
- /// <summary>
- /// Set pinpointers target to track
- /// </summary>
- public virtual void SetTarget(EntityUid uid, EntityUid? target, PinpointerComponent? pinpointer = null)
- {
- if (!Resolve(uid, ref pinpointer))
- return;
- if (pinpointer.Target == target)
- return;
- pinpointer.Target = target;
- if (pinpointer.UpdateTargetName)
- pinpointer.TargetName = target == null ? null : Identity.Name(target.Value, EntityManager);
- if (pinpointer.IsActive)
- UpdateDirectionToTarget(uid, pinpointer);
- }
- /// <summary>
- /// Update direction from pinpointer to selected target (if it was set)
- /// </summary>
- protected virtual void UpdateDirectionToTarget(EntityUid uid, PinpointerComponent? pinpointer = null)
- {
- }
- private void OnExamined(EntityUid uid, PinpointerComponent component, ExaminedEvent args)
- {
- if (!args.IsInDetailsRange || component.TargetName == null)
- return;
- args.PushMarkup(Loc.GetString("examine-pinpointer-linked", ("target", component.TargetName)));
- }
- /// <summary>
- /// Manually set distance from pinpointer to target
- /// </summary>
- public void SetDistance(EntityUid uid, Distance distance, PinpointerComponent? pinpointer = null)
- {
- if (!Resolve(uid, ref pinpointer))
- return;
- if (distance == pinpointer.DistanceToTarget)
- return;
- pinpointer.DistanceToTarget = distance;
- Dirty(uid, pinpointer);
- }
- /// <summary>
- /// Try to manually set pinpointer arrow direction.
- /// If difference between current angle and new angle is smaller than
- /// pinpointer precision, new value will be ignored and it will return false.
- /// </summary>
- public bool TrySetArrowAngle(EntityUid uid, Angle arrowAngle, PinpointerComponent? pinpointer = null)
- {
- if (!Resolve(uid, ref pinpointer))
- return false;
- if (pinpointer.ArrowAngle.EqualsApprox(arrowAngle, pinpointer.Precision))
- return false;
- pinpointer.ArrowAngle = arrowAngle;
- Dirty(uid, pinpointer);
- return true;
- }
- /// <summary>
- /// Activate/deactivate pinpointer screen. If it has target it will start tracking it.
- /// </summary>
- public void SetActive(EntityUid uid, bool isActive, PinpointerComponent? pinpointer = null)
- {
- if (!Resolve(uid, ref pinpointer))
- return;
- if (isActive == pinpointer.IsActive)
- return;
- pinpointer.IsActive = isActive;
- Dirty(uid, pinpointer);
- }
- /// <summary>
- /// Toggle Pinpointer screen. If it has target it will start tracking it.
- /// </summary>
- /// <returns>True if pinpointer was activated, false otherwise</returns>
- public virtual bool TogglePinpointer(EntityUid uid, PinpointerComponent? pinpointer = null)
- {
- if (!Resolve(uid, ref pinpointer))
- return false;
- var isActive = !pinpointer.IsActive;
- SetActive(uid, isActive, pinpointer);
- return isActive;
- }
- private void OnEmagged(EntityUid uid, PinpointerComponent component, ref GotEmaggedEvent args)
- {
- if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
- return;
- if (_emag.CheckFlag(uid, EmagType.Interaction))
- return;
- if (component.CanRetarget)
- return;
- args.Handled = true;
- component.CanRetarget = true;
- }
- }
|