2021-06-09 22:19:39 +02:00
using Content.Shared.Buckle.Components ;
2021-10-13 13:14:30 +11:00
using Content.Shared.Interaction.Events ;
2021-08-10 10:34:01 +10:00
using Content.Shared.Movement ;
2022-06-24 17:44:30 +10:00
using Content.Shared.Movement.Events ;
2021-06-27 19:02:46 +10:00
using Content.Shared.Standing ;
2021-06-28 14:17:08 +10:00
using Content.Shared.Throwing ;
2021-05-30 23:30:44 +10:00
using Robust.Shared.Physics.Dynamics ;
2022-09-14 17:26:26 +10:00
using Robust.Shared.Physics.Events ;
2022-08-22 12:44:37 +12:00
using Robust.Shared.Timing ;
2021-05-30 23:30:44 +10:00
2021-06-09 22:19:39 +02:00
namespace Content.Shared.Buckle
2021-05-30 23:30:44 +10:00
{
public abstract class SharedBuckleSystem : EntitySystem
{
2022-08-22 12:44:37 +12:00
[Dependency] protected readonly IGameTiming GameTiming = default ! ;
2021-05-30 23:30:44 +10:00
public override void Initialize ( )
{
base . Initialize ( ) ;
2022-09-23 15:57:30 +12:00
SubscribeLocalEvent < SharedStrapComponent , MoveEvent > ( OnStrapRotate ) ;
2022-07-16 13:51:52 +10:00
2021-05-30 23:30:44 +10:00
SubscribeLocalEvent < SharedBuckleComponent , PreventCollideEvent > ( PreventCollision ) ;
2021-06-27 19:02:46 +10:00
SubscribeLocalEvent < SharedBuckleComponent , DownAttemptEvent > ( HandleDown ) ;
SubscribeLocalEvent < SharedBuckleComponent , StandAttemptEvent > ( HandleStand ) ;
2021-06-28 14:17:08 +10:00
SubscribeLocalEvent < SharedBuckleComponent , ThrowPushbackAttemptEvent > ( HandleThrowPushback ) ;
2022-04-10 16:48:11 +12:00
SubscribeLocalEvent < SharedBuckleComponent , UpdateCanMoveEvent > ( HandleMove ) ;
2021-10-13 13:14:30 +11:00
SubscribeLocalEvent < SharedBuckleComponent , ChangeDirectionAttemptEvent > ( OnBuckleChangeDirectionAttempt ) ;
}
2022-09-23 15:57:30 +12:00
private void OnStrapRotate ( EntityUid uid , SharedStrapComponent component , ref MoveEvent args )
2022-07-16 13:51:52 +10:00
{
// TODO: This looks dirty af.
// On rotation of a strap, reattach all buckled entities.
// This fixes buckle offsets and draw depths.
2022-08-22 12:44:37 +12:00
// This is mega cursed. Please somebody save me from Mr Buckle's wild ride.
2022-09-23 15:57:30 +12:00
// Oh god I'm back here again. Send help.
2022-08-22 12:44:37 +12:00
// Consider a chair that has a player strapped to it. Then the client receives a new server state, showing
// that the player entity has moved elsewhere, and the chair has rotated. If the client applies the player
// state, then the chairs transform comp state, and then the buckle state. The transform state will
// forcefully teleport the player back to the chair (client-side only). This causes even more issues if the
// chair was teleporting in from nullspace after having left PVS.
//
// One option is to just never trigger re-buckles during state application.
// another is to.. just not do this? Like wtf is this code. But I CBF with buckle atm.
2022-09-23 15:57:30 +12:00
if ( GameTiming . ApplyingState | | args . NewRotation = = args . OldRotation )
2022-08-22 12:44:37 +12:00
return ;
2022-07-16 13:51:52 +10:00
foreach ( var buckledEntity in component . BuckledEntities )
{
if ( ! EntityManager . TryGetComponent ( buckledEntity , out SharedBuckleComponent ? buckled ) )
{
continue ;
}
2022-08-22 12:44:37 +12:00
if ( ! buckled . Buckled | | buckled . LastEntityBuckledTo ! = uid )
{
Logger . Error ( $"A moving strap entity {ToPrettyString(uid)} attempted to re-parent an entity that does not 'belong' to it {ToPrettyString(buckledEntity)}" ) ;
continue ;
}
2022-07-16 13:51:52 +10:00
buckled . ReAttach ( component ) ;
Dirty ( buckled ) ;
}
}
2022-09-06 00:28:23 +10:00
public bool IsBuckled ( EntityUid uid , SharedBuckleComponent ? component = null )
{
return Resolve ( uid , ref component , false ) & & component . Buckled ;
}
2021-10-13 13:14:30 +11:00
private void OnBuckleChangeDirectionAttempt ( EntityUid uid , SharedBuckleComponent component , ChangeDirectionAttemptEvent args )
{
if ( component . Buckled )
args . Cancel ( ) ;
2021-08-10 10:34:01 +10:00
}
2022-04-10 16:48:11 +12:00
private void HandleMove ( EntityUid uid , SharedBuckleComponent component , UpdateCanMoveEvent args )
2021-08-10 10:34:01 +10:00
{
2022-04-10 16:48:11 +12:00
if ( component . LifeStage > ComponentLifeStage . Running )
return ;
2021-08-10 10:34:01 +10:00
if ( component . Buckled )
args . Cancel ( ) ;
2021-06-27 19:02:46 +10:00
}
private void HandleStand ( EntityUid uid , SharedBuckleComponent component , StandAttemptEvent args )
{
if ( component . Buckled )
{
args . Cancel ( ) ;
}
}
private void HandleDown ( EntityUid uid , SharedBuckleComponent component , DownAttemptEvent args )
{
if ( component . Buckled )
{
args . Cancel ( ) ;
}
2021-05-30 23:30:44 +10:00
}
2021-06-28 14:17:08 +10:00
private void HandleThrowPushback ( EntityUid uid , SharedBuckleComponent component , ThrowPushbackAttemptEvent args )
{
if ( ! component . Buckled ) return ;
args . Cancel ( ) ;
}
2022-09-14 17:26:26 +10:00
private void PreventCollision ( EntityUid uid , SharedBuckleComponent component , ref PreventCollideEvent args )
2021-05-30 23:30:44 +10:00
{
2021-12-03 16:30:34 +01:00
if ( args . BodyB . Owner ! = component . LastEntityBuckledTo ) return ;
2021-05-30 23:30:44 +10:00
if ( component . Buckled | | component . DontCollide )
{
2022-09-14 17:26:26 +10:00
args . Cancelled = true ;
2021-05-30 23:30:44 +10:00
}
}
}
}