using System.Numerics;
using Content.Client.Animations;
+using Content.Client.Gameplay;
using Content.Client.Items;
using Content.Client.Weapons.Ranged.Components;
using Content.Shared.Camera;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.Player;
+using Robust.Client.State;
using Robust.Shared.Animations;
using Robust.Shared.Input;
using Robust.Shared.Map;
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IInputManager _inputManager = default!;
[Dependency] private readonly IPlayerManager _player = default!;
+ [Dependency] private readonly IStateManager _state = default!;
[Dependency] private readonly AnimationPlayerSystem _animPlayer = default!;
[Dependency] private readonly InputSystem _inputSystem = default!;
[Dependency] private readonly SharedCameraRecoilSystem _recoil = default!;
// Define target coordinates relative to gun entity, so that network latency on moving grids doesn't fuck up the target location.
var coordinates = EntityCoordinates.FromMap(entity, mousePos, TransformSystem, EntityManager);
+ NetEntity? target = null;
+ if (_state.CurrentState is GameplayStateBase screen)
+ target = GetNetEntity(screen.GetClickedEntity(mousePos));
+
Log.Debug($"Sending shoot request tick {Timing.CurTick} / {Timing.CurTime}");
EntityManager.RaisePredictiveEvent(new RequestShootEvent
{
+ Target = target,
Coordinates = GetNetCoordinates(coordinates),
Gun = GetNetEntity(gunUid),
});
private void ShootOrThrow(EntityUid uid, Vector2 mapDirection, Vector2 gunVelocity, GunComponent gun, EntityUid gunUid, EntityUid? user)
{
+ if (gun.Target is { } target && !TerminatingOrDeleted(target))
+ {
+ var targeted = EnsureComp<TargetedProjectileComponent>(uid);
+ targeted.Target = target;
+ Dirty(uid, targeted);
+ }
+
// Do a throw
if (!HasComp<ProjectileComponent>(uid))
{
using Content.Shared.Mobs.Components;
using Content.Shared.Movement.Events;
using Content.Shared.Pointing;
+using Content.Shared.Projectiles;
using Content.Shared.Pulling.Events;
using Content.Shared.Speech;
using Content.Shared.Standing;
using Content.Shared.Strip.Components;
using Content.Shared.Throwing;
+using Content.Shared.Weapons.Ranged.Components;
using Robust.Shared.Physics.Components;
+using Robust.Shared.Physics.Events;
namespace Content.Shared.Mobs.Systems;
SubscribeLocalEvent<MobStateComponent, TryingToSleepEvent>(OnSleepAttempt);
SubscribeLocalEvent<MobStateComponent, CombatModeShouldHandInteractEvent>(OnCombatModeShouldHandInteract);
SubscribeLocalEvent<MobStateComponent, AttemptPacifiedAttackEvent>(OnAttemptPacifiedAttack);
+ SubscribeLocalEvent<MobStateComponent, PreventCollideEvent>(OnPreventCollide);
}
private void OnStateExitSubscribers(EntityUid target, MobStateComponent component, MobState state)
args.Cancelled = true;
}
+ private void OnPreventCollide(Entity<MobStateComponent> ent, ref PreventCollideEvent args)
+ {
+ if (args.Cancelled)
+ return;
+
+ if (IsAlive(ent, ent))
+ return;
+
+ var other = args.OtherEntity;
+ if (HasComp<ProjectileComponent>(other) &&
+ CompOrNull<TargetedProjectileComponent>(other)?.Target != ent.Owner)
+ {
+ args.Cancelled = true;
+ }
+ }
+
#endregion
}
-using Content.Shared.Damage;
-using Content.Shared.Tag;
using Content.Shared.Weapons.Ranged.Events;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Audio;
[ViewVariables]
public EntityCoordinates? ShootCoordinates = null;
+ /// <summary>
+ /// Who the gun is being requested to shoot at directly.
+ /// </summary>
+ [ViewVariables]
+ public EntityUid? Target = null;
+
/// <summary>
/// The base value for how many shots to fire per burst.
/// </summary>
--- /dev/null
+using Content.Shared.Weapons.Ranged.Systems;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Weapons.Ranged.Components;
+
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(SharedGunSystem))]
+public sealed partial class TargetedProjectileComponent : Component
+{
+ [DataField, AutoNetworkedField]
+ public EntityUid Target;
+}
{
public NetEntity Gun;
public NetCoordinates Coordinates;
+ public NetEntity? Target;
}
return;
gun.ShootCoordinates = GetCoordinates(msg.Coordinates);
+ gun.Target = GetEntity(msg.Target);
AttemptShoot(user.Value, ent, gun);
}
gun.ShotCounter = 0;
gun.ShootCoordinates = null;
+ gun.Target = null;
Dirty(uid, gun);
}