2023-08-27 13:39:49 +03:00
|
|
|
using Content.Shared.Interaction;
|
2023-08-24 21:05:56 +03:00
|
|
|
using Content.Shared.Movement.Events;
|
|
|
|
|
using Content.Shared.Projectiles;
|
|
|
|
|
using Robust.Shared.Physics;
|
|
|
|
|
using Robust.Shared.Physics.Components;
|
|
|
|
|
using Robust.Shared.Physics.Systems;
|
|
|
|
|
|
2024-01-28 18:37:24 +07:00
|
|
|
namespace Content.Shared._White.Crossbow;
|
2023-08-24 21:05:56 +03:00
|
|
|
|
|
|
|
|
public sealed class PenetratedSystem : EntitySystem
|
|
|
|
|
{
|
|
|
|
|
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
|
|
|
|
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
|
|
|
|
[Dependency] private readonly SharedProjectileSystem _projectile = default!;
|
|
|
|
|
|
|
|
|
|
public override void Initialize()
|
|
|
|
|
{
|
|
|
|
|
base.Initialize();
|
|
|
|
|
|
|
|
|
|
SubscribeLocalEvent<PenetratedComponent, MoveInputEvent>(OnMoveInput);
|
2023-08-27 13:39:49 +03:00
|
|
|
SubscribeLocalEvent<PenetratedComponent, InteractHandEvent>(OnInteract);
|
2023-08-24 21:05:56 +03:00
|
|
|
}
|
|
|
|
|
|
2023-08-27 13:39:49 +03:00
|
|
|
private bool AttemptEmbedRemove(EntityUid uid, EntityUid user, PenetratedComponent component)
|
2023-08-24 21:05:56 +03:00
|
|
|
{
|
|
|
|
|
if (component is {ProjectileUid: not null, IsPinned: true})
|
2023-08-27 00:01:55 +03:00
|
|
|
{
|
2023-08-27 13:39:49 +03:00
|
|
|
if (!_projectile.AttemptEmbedRemove(component.ProjectileUid.Value, user))
|
2023-08-27 00:01:55 +03:00
|
|
|
FreePenetrated(uid, component);
|
2023-08-27 13:39:49 +03:00
|
|
|
else
|
|
|
|
|
return true;
|
2023-08-27 00:01:55 +03:00
|
|
|
}
|
2023-08-26 22:01:15 +03:00
|
|
|
else if (component.ProjectileUid == null && TryComp(uid, out PhysicsComponent? physics) &&
|
|
|
|
|
physics.BodyType == BodyType.Static)
|
2023-08-27 00:01:55 +03:00
|
|
|
{
|
2023-08-26 22:01:15 +03:00
|
|
|
FreePenetrated(uid, component, physics);
|
2023-08-27 00:01:55 +03:00
|
|
|
}
|
2023-08-27 13:39:49 +03:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnInteract(EntityUid uid, PenetratedComponent component, InteractHandEvent args)
|
|
|
|
|
{
|
|
|
|
|
if (AttemptEmbedRemove(uid, args.User, component))
|
|
|
|
|
args.Handled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnMoveInput(EntityUid uid, PenetratedComponent component, ref MoveInputEvent args)
|
|
|
|
|
{
|
|
|
|
|
AttemptEmbedRemove(uid, uid, component);
|
2023-08-24 21:05:56 +03:00
|
|
|
}
|
|
|
|
|
|
2023-08-26 22:01:15 +03:00
|
|
|
public void FreePenetrated(EntityUid uid, PenetratedComponent? penetrated = null, PhysicsComponent? physics = null)
|
2023-08-24 21:05:56 +03:00
|
|
|
{
|
2023-08-26 22:01:15 +03:00
|
|
|
var xform = Transform(uid);
|
|
|
|
|
_transform.AttachToGridOrMap(uid, xform);
|
|
|
|
|
|
|
|
|
|
if (Resolve(uid, ref physics, false))
|
|
|
|
|
{
|
|
|
|
|
_physics.SetBodyType(uid, BodyType.KinematicController, body: physics, xform: xform);
|
|
|
|
|
_physics.WakeBody(uid, body: physics);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-24 21:05:56 +03:00
|
|
|
if (!Resolve(uid, ref penetrated, false))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
penetrated.ProjectileUid = null;
|
|
|
|
|
penetrated.IsPinned = false;
|
2023-08-26 22:01:15 +03:00
|
|
|
Dirty(uid, penetrated);
|
2023-08-24 21:05:56 +03:00
|
|
|
}
|
|
|
|
|
}
|