Travelling pointing arrows, brains can no longer point (#24864)

* Decoupled from gravity, constant animation time, manual networking, cubic interpolation

* Reduced overshoot

* Implemented PointAttemptEvent, reacts with mobstate & sleeping

* Brains can no longer point, PBs must be inside a chassis

* Removed chassis check, made callback more obvious
This commit is contained in:
Krunklehorn
2024-02-03 03:09:20 -05:00
committed by GitHub
parent 240ebfa3a6
commit d01d75073c
10 changed files with 172 additions and 64 deletions

View File

@@ -1,19 +1,12 @@
using System.Numerics;
using Content.Shared.Pointing.Components; using Content.Shared.Pointing.Components;
using System.Numerics;
namespace Content.Client.Pointing.Components; namespace Content.Client.Pointing.Components;
[RegisterComponent] [RegisterComponent]
public sealed partial class PointingArrowComponent : SharedPointingArrowComponent public sealed partial class PointingArrowComponent : SharedPointingArrowComponent
{ {
/// <summary> /// <summary>
/// How long it takes to go from the bottom of the animation to the top. /// How far the arrow moves up and down during the floating phase.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("animationTime")]
public float AnimationTime = 0.5f;
/// <summary>
/// How far it goes in any direction.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("offset")] [DataField("offset")]

View File

@@ -0,0 +1,62 @@
using Content.Client.Pointing.Components;
using Content.Shared.Pointing;
using Robust.Client.GameObjects;
using Robust.Client.Animations;
using Robust.Shared.Animations;
using System.Numerics;
namespace Content.Client.Pointing;
public sealed partial class PointingSystem : SharedPointingSystem
{
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
public void InitializeVisualizer()
{
SubscribeLocalEvent<PointingArrowComponent, AnimationCompletedEvent>(OnAnimationCompleted);
}
private void OnAnimationCompleted(EntityUid uid, PointingArrowComponent component, AnimationCompletedEvent args)
{
if (args.Key == component.AnimationKey)
_animationPlayer.Stop(uid, component.AnimationKey);
}
private void BeginPointAnimation(EntityUid uid, Vector2 startPosition, Vector2 offset, string animationKey)
{
if (_animationPlayer.HasRunningAnimation(uid, animationKey))
return;
var animation = new Animation
{
Length = PointDuration,
AnimationTracks =
{
new AnimationTrackComponentProperty
{
ComponentType = typeof(SpriteComponent),
Property = nameof(SpriteComponent.Offset),
InterpolationMode = AnimationInterpolationMode.Cubic,
KeyFrames =
{
// We pad here to prevent improper looping and tighten the overshoot, just a touch
new AnimationTrackProperty.KeyFrame(startPosition, 0f),
new AnimationTrackProperty.KeyFrame(Vector2.Lerp(startPosition, offset, 0.9f), PointKeyTimeMove),
new AnimationTrackProperty.KeyFrame(offset, PointKeyTimeMove),
new AnimationTrackProperty.KeyFrame(Vector2.Zero, PointKeyTimeMove),
new AnimationTrackProperty.KeyFrame(offset, PointKeyTimeHover),
new AnimationTrackProperty.KeyFrame(Vector2.Zero, PointKeyTimeHover),
new AnimationTrackProperty.KeyFrame(offset, PointKeyTimeHover),
new AnimationTrackProperty.KeyFrame(Vector2.Zero, PointKeyTimeHover),
new AnimationTrackProperty.KeyFrame(offset, PointKeyTimeHover),
new AnimationTrackProperty.KeyFrame(Vector2.Zero, PointKeyTimeHover),
new AnimationTrackProperty.KeyFrame(offset, PointKeyTimeHover),
new AnimationTrackProperty.KeyFrame(Vector2.Zero, PointKeyTimeHover),
}
}
}
};
_animationPlayer.Play(uid, animation, animationKey);
}
}

View File

@@ -1,32 +1,25 @@
using Content.Client.Pointing.Components; using Content.Client.Pointing.Components;
using Content.Client.Gravity;
using Content.Shared.Mobs.Systems;
using Content.Shared.Pointing; using Content.Shared.Pointing;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using DrawDepth = Content.Shared.DrawDepth.DrawDepth; using DrawDepth = Content.Shared.DrawDepth.DrawDepth;
namespace Content.Client.Pointing; namespace Content.Client.Pointing;
public sealed class PointingSystem : SharedPointingSystem public sealed partial class PointingSystem : SharedPointingSystem
{ {
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly FloatingVisualizerSystem _floatingSystem = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<GetVerbsEvent<Verb>>(AddPointingVerb); SubscribeLocalEvent<GetVerbsEvent<Verb>>(AddPointingVerb);
SubscribeLocalEvent<PointingArrowComponent, ComponentStartup>(OnArrowStartup); SubscribeLocalEvent<PointingArrowComponent, ComponentStartup>(OnArrowStartup);
SubscribeLocalEvent<PointingArrowComponent, AnimationCompletedEvent>(OnArrowAnimation);
SubscribeLocalEvent<RoguePointingArrowComponent, ComponentStartup>(OnRogueArrowStartup); SubscribeLocalEvent<RoguePointingArrowComponent, ComponentStartup>(OnRogueArrowStartup);
} SubscribeLocalEvent<PointingArrowComponent, ComponentHandleState>(HandleCompState);
private void OnArrowAnimation(EntityUid uid, PointingArrowComponent component, AnimationCompletedEvent args) InitializeVisualizer();
{
_floatingSystem.FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime);
} }
private void AddPointingVerb(GetVerbsEvent<Verb> args) private void AddPointingVerb(GetVerbsEvent<Verb> args)
@@ -38,15 +31,11 @@ public sealed class PointingSystem : SharedPointingSystem
// I'm just adding this verb exclusively to clients so that the verb-loading pop-in on the verb menu isn't // I'm just adding this verb exclusively to clients so that the verb-loading pop-in on the verb menu isn't
// as bad. Important for this verb seeing as its usually an option on just about any entity. // as bad. Important for this verb seeing as its usually an option on just about any entity.
// this is a pointing arrow. no pointing here...
if (HasComp<PointingArrowComponent>(args.Target)) if (HasComp<PointingArrowComponent>(args.Target))
{
// this is a pointing arrow. no pointing here...
return; return;
}
// Can the user point? Checking mob state directly instead of some action blocker, as many action blockers are blocked for if (!CanPoint(args.User))
// ghosts and there is no obvious choice for pointing (unless ghosts CanEmote?).
if (_mobState.IsIncapacitated(args.User))
return; return;
// We won't check in range or visibility, as this verb is currently only executable via the context menu, // We won't check in range or visibility, as this verb is currently only executable via the context menu,
@@ -66,11 +55,9 @@ public sealed class PointingSystem : SharedPointingSystem
private void OnArrowStartup(EntityUid uid, PointingArrowComponent component, ComponentStartup args) private void OnArrowStartup(EntityUid uid, PointingArrowComponent component, ComponentStartup args)
{ {
if (TryComp<SpriteComponent>(uid, out var sprite)) if (TryComp<SpriteComponent>(uid, out var sprite))
{
sprite.DrawDepth = (int) DrawDepth.Overlays; sprite.DrawDepth = (int) DrawDepth.Overlays;
}
_floatingSystem.FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime); BeginPointAnimation(uid, component.StartPosition, component.Offset, component.AnimationKey);
} }
private void OnRogueArrowStartup(EntityUid uid, RoguePointingArrowComponent arrow, ComponentStartup args) private void OnRogueArrowStartup(EntityUid uid, RoguePointingArrowComponent arrow, ComponentStartup args)
@@ -81,4 +68,13 @@ public sealed class PointingSystem : SharedPointingSystem
sprite.NoRotation = false; sprite.NoRotation = false;
} }
} }
private void HandleCompState(Entity<PointingArrowComponent> entity, ref ComponentHandleState args)
{
if (args.Current is not SharedPointingArrowComponentState state)
return;
entity.Comp.StartPosition = state.StartPosition;
entity.Comp.EndTime = state.EndTime;
}
} }

View File

@@ -4,6 +4,7 @@ using Content.Shared.Body.Components;
using Content.Shared.Body.Events; using Content.Shared.Body.Events;
using Content.Shared.Mind; using Content.Shared.Mind;
using Content.Shared.Mind.Components; using Content.Shared.Mind.Components;
using Content.Shared.Pointing;
namespace Content.Server.Body.Systems namespace Content.Server.Body.Systems
{ {
@@ -17,6 +18,7 @@ namespace Content.Server.Body.Systems
SubscribeLocalEvent<BrainComponent, AddedToPartInBodyEvent>((uid, _, args) => HandleMind(args.Body, uid)); SubscribeLocalEvent<BrainComponent, AddedToPartInBodyEvent>((uid, _, args) => HandleMind(args.Body, uid));
SubscribeLocalEvent<BrainComponent, RemovedFromPartInBodyEvent>((uid, _, args) => HandleMind(uid, args.OldBody)); SubscribeLocalEvent<BrainComponent, RemovedFromPartInBodyEvent>((uid, _, args) => HandleMind(uid, args.OldBody));
SubscribeLocalEvent<BrainComponent, PointAttemptEvent>(OnPointAttempt);
} }
private void HandleMind(EntityUid newEntity, EntityUid oldEntity) private void HandleMind(EntityUid newEntity, EntityUid oldEntity)
@@ -36,5 +38,10 @@ namespace Content.Server.Body.Systems
_mindSystem.TransferTo(mindId, newEntity, mind: mind); _mindSystem.TransferTo(mindId, newEntity, mind: mind);
} }
private void OnPointAttempt(EntityUid uid, BrainComponent component, PointAttemptEvent args)
{
args.Cancel();
}
} }
} }

View File

@@ -1,7 +1,6 @@
using System.Linq; using System.Linq;
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Server.Pointing.Components; using Content.Server.Pointing.Components;
using Content.Shared.Bed.Sleep;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.Eye; using Content.Shared.Eye;
@@ -10,13 +9,13 @@ using Content.Shared.IdentityManagement;
using Content.Shared.Input; using Content.Shared.Input;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Mind; using Content.Shared.Mind;
using Content.Shared.Mobs.Systems;
using Content.Shared.Pointing; using Content.Shared.Pointing;
using Content.Shared.Popups; using Content.Shared.Popups;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Server.Player; using Robust.Server.Player;
using Robust.Shared.Enums; using Robust.Shared.Enums;
using Robust.Shared.GameStates;
using Robust.Shared.Input.Binding; using Robust.Shared.Input.Binding;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Player; using Robust.Shared.Player;
@@ -34,7 +33,6 @@ namespace Content.Server.Pointing.EntitySystems
[Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly RotateToFaceSystem _rotateToFaceSystem = default!; [Dependency] private readonly RotateToFaceSystem _rotateToFaceSystem = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly VisibilitySystem _visibilitySystem = default!; [Dependency] private readonly VisibilitySystem _visibilitySystem = default!;
[Dependency] private readonly SharedMindSystem _minds = default!; [Dependency] private readonly SharedMindSystem _minds = default!;
@@ -50,6 +48,15 @@ namespace Content.Server.Pointing.EntitySystems
private const float PointingRange = 15f; private const float PointingRange = 15f;
private void GetCompState(Entity<PointingArrowComponent> entity, ref ComponentGetState args)
{
args.State = new SharedPointingArrowComponentState
{
StartPosition = entity.Comp.StartPosition,
EndTime = entity.Comp.EndTime
};
}
private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e) private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
{ {
if (e.NewStatus != SessionStatus.Disconnected) if (e.NewStatus != SessionStatus.Disconnected)
@@ -97,7 +104,7 @@ namespace Content.Server.Pointing.EntitySystems
} }
} }
public bool TryPoint(ICommonSession? session, EntityCoordinates coords, EntityUid pointed) public bool TryPoint(ICommonSession? session, EntityCoordinates coordsPointed, EntityUid pointed)
{ {
if (session?.AttachedEntity is not { } player) if (session?.AttachedEntity is not { } player)
{ {
@@ -105,9 +112,9 @@ namespace Content.Server.Pointing.EntitySystems
return false; return false;
} }
if (!coords.IsValid(EntityManager)) if (!coordsPointed.IsValid(EntityManager))
{ {
Log.Warning($"Player {ToPrettyString(player)} attempted to point at invalid coordinates: {coords}"); Log.Warning($"Player {ToPrettyString(player)} attempted to point at invalid coordinates: {coordsPointed}");
return false; return false;
} }
@@ -123,33 +130,30 @@ namespace Content.Server.Pointing.EntitySystems
return false; return false;
} }
// Checking mob state directly instead of some action blocker, as many action blockers are blocked for if (!CanPoint(player))
// ghosts and there is no obvious choice for pointing.
if (_mobState.IsIncapacitated(player))
{ {
return false; return false;
} }
if (HasComp<SleepingComponent>(player)) if (!InRange(player, coordsPointed))
{
return false;
}
if (!InRange(player, coords))
{ {
_popup.PopupEntity(Loc.GetString("pointing-system-try-point-cannot-reach"), player, player); _popup.PopupEntity(Loc.GetString("pointing-system-try-point-cannot-reach"), player, player);
return false; return false;
} }
var mapCoordsPointed = coordsPointed.ToMap(EntityManager);
_rotateToFaceSystem.TryFaceCoordinates(player, mapCoordsPointed.Position);
var mapCoords = coords.ToMap(EntityManager); var arrow = EntityManager.SpawnEntity("PointingArrow", coordsPointed);
_rotateToFaceSystem.TryFaceCoordinates(player, mapCoords.Position);
var arrow = EntityManager.SpawnEntity("PointingArrow", coords);
if (TryComp<PointingArrowComponent>(arrow, out var pointing)) if (TryComp<PointingArrowComponent>(arrow, out var pointing))
{ {
pointing.EndTime = _gameTiming.CurTime + TimeSpan.FromSeconds(4); if (TryComp(player, out TransformComponent? xformPlayer))
pointing.StartPosition = EntityCoordinates.FromMap(arrow, xformPlayer.Coordinates.ToMap(EntityManager)).Position;
pointing.EndTime = _gameTiming.CurTime + PointDuration;
Dirty(arrow, pointing);
} }
if (EntityQuery<PointingArrowAngeringComponent>().FirstOrDefault() != null) if (EntityQuery<PointingArrowAngeringComponent>().FirstOrDefault() != null)
@@ -215,10 +219,10 @@ namespace Content.Server.Pointing.EntitySystems
TileRef? tileRef = null; TileRef? tileRef = null;
string? position = null; string? position = null;
if (_mapManager.TryFindGridAt(mapCoords, out var gridUid, out var grid)) if (_mapManager.TryFindGridAt(mapCoordsPointed, out var gridUid, out var grid))
{ {
position = $"EntId={gridUid} {grid.WorldToTile(mapCoords.Position)}"; position = $"EntId={gridUid} {grid.WorldToTile(mapCoordsPointed.Position)}";
tileRef = grid.GetTileRef(grid.WorldToTile(mapCoords.Position)); tileRef = grid.GetTileRef(grid.WorldToTile(mapCoordsPointed.Position));
} }
var tileDef = _tileDefinitionManager[tileRef?.Tile.TypeId ?? 0]; var tileDef = _tileDefinitionManager[tileRef?.Tile.TypeId ?? 0];
@@ -228,7 +232,7 @@ namespace Content.Server.Pointing.EntitySystems
viewerMessage = Loc.GetString("pointing-system-other-point-at-tile", ("otherName", playerName), ("tileName", name)); viewerMessage = Loc.GetString("pointing-system-other-point-at-tile", ("otherName", playerName), ("tileName", name));
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(player):user} pointed at {name} {(position == null ? mapCoords : position)}"); _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(player):user} pointed at {name} {(position == null ? mapCoordsPointed : position)}");
} }
_pointers[session] = _gameTiming.CurTime; _pointers[session] = _gameTiming.CurTime;
@@ -242,6 +246,8 @@ namespace Content.Server.Pointing.EntitySystems
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<PointingArrowComponent, ComponentGetState>(GetCompState);
SubscribeNetworkEvent<PointingAttemptEvent>(OnPointAttempt); SubscribeNetworkEvent<PointingAttemptEvent>(OnPointAttempt);
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged; _playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
@@ -255,8 +261,8 @@ namespace Content.Server.Pointing.EntitySystems
{ {
var target = GetEntity(ev.Target); var target = GetEntity(ev.Target);
if (TryComp(target, out TransformComponent? xform)) if (TryComp(target, out TransformComponent? xformTarget))
TryPoint(args.SenderSession, xform.Coordinates, target); TryPoint(args.SenderSession, xformTarget.Coordinates, target);
else else
Log.Warning($"User {args.SenderSession} attempted to point at a non-existent entity uid: {ev.Target}"); Log.Warning($"User {args.SenderSession} attempted to point at a non-existent entity uid: {ev.Target}");
} }

View File

@@ -14,6 +14,7 @@ using Content.Shared.Mind.Components;
using Content.Shared.Mobs; using Content.Shared.Mobs;
using Content.Shared.Mobs.Systems; using Content.Shared.Mobs.Systems;
using Content.Shared.Movement.Systems; using Content.Shared.Movement.Systems;
using Content.Shared.Pointing;
using Content.Shared.PowerCell; using Content.Shared.PowerCell;
using Content.Shared.PowerCell.Components; using Content.Shared.PowerCell.Components;
using Content.Shared.Roles; using Content.Shared.Roles;
@@ -67,6 +68,7 @@ public sealed partial class BorgSystem : SharedBorgSystem
SubscribeLocalEvent<BorgChassisComponent, GetCharactedDeadIcEvent>(OnGetDeadIC); SubscribeLocalEvent<BorgChassisComponent, GetCharactedDeadIcEvent>(OnGetDeadIC);
SubscribeLocalEvent<BorgBrainComponent, MindAddedMessage>(OnBrainMindAdded); SubscribeLocalEvent<BorgBrainComponent, MindAddedMessage>(OnBrainMindAdded);
SubscribeLocalEvent<BorgBrainComponent, PointAttemptEvent>(OnBrainPointAttempt);
InitializeModules(); InitializeModules();
InitializeMMI(); InitializeMMI();
@@ -242,6 +244,11 @@ public sealed partial class BorgSystem : SharedBorgSystem
_mind.TransferTo(mindId, containerEnt, mind: mind); _mind.TransferTo(mindId, containerEnt, mind: mind);
} }
private void OnBrainPointAttempt(EntityUid uid, BorgBrainComponent component, PointAttemptEvent args)
{
args.Cancel();
}
private void UpdateBatteryAlert(EntityUid uid, PowerCellSlotComponent? slotComponent = null) private void UpdateBatteryAlert(EntityUid uid, PowerCellSlotComponent? slotComponent = null)
{ {
if (!_powerCell.TryGetBatteryFromSlot(uid, out var battery, slotComponent)) if (!_powerCell.TryGetBatteryFromSlot(uid, out var battery, slotComponent))

View File

@@ -2,6 +2,7 @@ using Content.Shared.Actions;
using Content.Shared.Bed.Sleep; using Content.Shared.Bed.Sleep;
using Content.Shared.Damage.ForceSay; using Content.Shared.Damage.ForceSay;
using Content.Shared.Eye.Blinding.Systems; using Content.Shared.Eye.Blinding.Systems;
using Content.Shared.Pointing;
using Content.Shared.Speech; using Content.Shared.Speech;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -25,6 +26,7 @@ namespace Content.Server.Bed.Sleep
SubscribeLocalEvent<SleepingComponent, ComponentShutdown>(OnShutdown); SubscribeLocalEvent<SleepingComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<SleepingComponent, SpeakAttemptEvent>(OnSpeakAttempt); SubscribeLocalEvent<SleepingComponent, SpeakAttemptEvent>(OnSpeakAttempt);
SubscribeLocalEvent<SleepingComponent, CanSeeAttemptEvent>(OnSeeAttempt); SubscribeLocalEvent<SleepingComponent, CanSeeAttemptEvent>(OnSeeAttempt);
SubscribeLocalEvent<SleepingComponent, PointAttemptEvent>(OnPointAttempt);
SubscribeLocalEvent<SleepingComponent, EntityUnpausedEvent>(OnSleepUnpaused); SubscribeLocalEvent<SleepingComponent, EntityUnpausedEvent>(OnSleepUnpaused);
} }
@@ -70,6 +72,11 @@ namespace Content.Server.Bed.Sleep
if (component.LifeStage <= ComponentLifeStage.Running) if (component.LifeStage <= ComponentLifeStage.Running)
args.Cancel(); args.Cancel();
} }
private void OnPointAttempt(EntityUid uid, SleepingComponent component, PointAttemptEvent args)
{
args.Cancel();
}
} }
} }

View File

@@ -9,6 +9,7 @@ using Content.Shared.Inventory.Events;
using Content.Shared.Item; using Content.Shared.Item;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using Content.Shared.Movement.Events; using Content.Shared.Movement.Events;
using Content.Shared.Pointing;
using Content.Shared.Pulling.Events; using Content.Shared.Pulling.Events;
using Content.Shared.Speech; using Content.Shared.Speech;
using Content.Shared.Standing; using Content.Shared.Standing;
@@ -38,6 +39,7 @@ public partial class MobStateSystem
SubscribeLocalEvent<MobStateComponent, StartPullAttemptEvent>(CheckAct); SubscribeLocalEvent<MobStateComponent, StartPullAttemptEvent>(CheckAct);
SubscribeLocalEvent<MobStateComponent, UpdateCanMoveEvent>(CheckAct); SubscribeLocalEvent<MobStateComponent, UpdateCanMoveEvent>(CheckAct);
SubscribeLocalEvent<MobStateComponent, StandAttemptEvent>(CheckAct); SubscribeLocalEvent<MobStateComponent, StandAttemptEvent>(CheckAct);
SubscribeLocalEvent<MobStateComponent, PointAttemptEvent>(CheckAct);
SubscribeLocalEvent<MobStateComponent, TryingToSleepEvent>(OnSleepAttempt); SubscribeLocalEvent<MobStateComponent, TryingToSleepEvent>(OnSleepAttempt);
SubscribeLocalEvent<MobStateComponent, CombatModeShouldHandInteractEvent>(OnCombatModeShouldHandInteract); SubscribeLocalEvent<MobStateComponent, CombatModeShouldHandInteractEvent>(OnCombatModeShouldHandInteract);
SubscribeLocalEvent<MobStateComponent, AttemptPacifiedAttackEvent>(OnAttemptPacifiedAttack); SubscribeLocalEvent<MobStateComponent, AttemptPacifiedAttackEvent>(OnAttemptPacifiedAttack);

View File

@@ -1,13 +1,22 @@
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using System.Numerics;
namespace Content.Shared.Pointing.Components; namespace Content.Shared.Pointing.Components;
[NetworkedComponent] [NetworkedComponent]
public abstract partial class SharedPointingArrowComponent : Component public abstract partial class SharedPointingArrowComponent : Component
{ {
/// <summary>
/// The position of the sender when the point began.
/// </summary>
[DataField]
[ViewVariables(VVAccess.ReadWrite)]
public Vector2 StartPosition;
/// <summary> /// <summary>
/// When the pointing arrow ends /// When the pointing arrow ends
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("endTime")] [DataField]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan EndTime; public TimeSpan EndTime;
} }

View File

@@ -1,17 +1,36 @@
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using System.Numerics;
namespace Content.Shared.Pointing; namespace Content.Shared.Pointing;
public abstract class SharedPointingSystem : EntitySystem public abstract class SharedPointingSystem : EntitySystem
{ {
[Serializable, NetSerializable] protected readonly TimeSpan PointDuration = TimeSpan.FromSeconds(4);
protected sealed class PointingArrowComponentState : ComponentState protected readonly float PointKeyTimeMove = 0.1f;
{ protected readonly float PointKeyTimeHover = 0.5f;
public TimeSpan EndTime;
public PointingArrowComponentState(TimeSpan endTime) [Serializable, NetSerializable]
{ public sealed class SharedPointingArrowComponentState : ComponentState
EndTime = endTime; {
} public Vector2 StartPosition { get; init; }
public TimeSpan EndTime { get; init; }
}
public bool CanPoint(EntityUid uid)
{
var ev = new PointAttemptEvent(uid);
RaiseLocalEvent(uid, ev, true);
return !ev.Cancelled;
} }
} }
public sealed class PointAttemptEvent : CancellableEntityEventArgs
{
public PointAttemptEvent(EntityUid uid)
{
Uid = uid;
}
public EntityUid Uid { get; }
}