2021-11-22 19:31:12 +00:00
using Content.Shared.ActionBlocker ;
2022-12-18 19:15:55 -06:00
using Content.Shared.Administration.Logs ;
2021-11-13 21:43:37 +00:00
using Content.Shared.Buckle.Components ;
2022-12-18 19:15:55 -06:00
using Content.Shared.Database ;
2022-06-21 07:00:11 -07:00
using Content.Shared.Hands.EntitySystems ;
2022-10-26 14:15:48 +13:00
using Content.Shared.Interaction ;
2021-10-04 16:10:54 +01:00
using Content.Shared.Physics.Pull ;
using Content.Shared.Pulling.Components ;
using Content.Shared.Pulling.Events ;
using Robust.Shared.Containers ;
using Robust.Shared.Map ;
using Robust.Shared.Physics ;
2022-09-14 17:26:26 +10:00
using Robust.Shared.Physics.Components ;
2023-01-15 15:38:59 +11:00
using Robust.Shared.Physics.Systems ;
2021-10-04 16:10:54 +01:00
namespace Content.Shared.Pulling
{
2023-01-15 15:38:59 +11:00
public abstract partial class SharedPullingSystem
2021-10-04 16:10:54 +01:00
{
2021-11-22 19:31:12 +00:00
[Dependency] private readonly ActionBlockerSystem _blocker = default ! ;
2022-01-31 20:08:53 +13:00
[Dependency] private readonly SharedContainerSystem _containerSystem = default ! ;
2022-06-21 07:00:11 -07:00
[Dependency] private readonly SharedHandsSystem _handsSystem = default ! ;
2022-10-26 14:15:48 +13:00
[Dependency] private readonly SharedInteractionSystem _interaction = default ! ;
2023-01-15 15:38:59 +11:00
[Dependency] private readonly SharedPhysicsSystem _physics = default ! ;
2022-12-18 19:15:55 -06:00
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default ! ;
2021-11-22 19:31:12 +00:00
2021-12-04 12:59:44 +01:00
public bool CanPull ( EntityUid puller , EntityUid pulled )
2021-10-04 16:10:54 +01:00
{
2022-06-21 07:00:11 -07:00
if ( ! EntityManager . TryGetComponent < SharedPullerComponent > ( puller , out var comp ) )
{
return false ;
}
if ( comp . NeedsHands & & ! _handsSystem . TryGetEmptyHand ( puller , out _ ) )
2021-10-04 16:10:54 +01:00
{
return false ;
}
2022-02-15 17:06:52 +13:00
if ( ! _blocker . CanInteract ( puller , pulled ) )
2021-11-22 19:31:12 +00:00
{
return false ;
}
2023-01-03 17:45:18 +11:00
if ( ! EntityManager . TryGetComponent < PhysicsComponent > ( pulled , out var physics ) )
2021-10-04 16:10:54 +01:00
{
return false ;
}
2022-05-16 22:24:52 +10:00
if ( physics . BodyType = = BodyType . Static )
2021-10-04 16:10:54 +01:00
{
return false ;
}
if ( puller = = pulled )
{
return false ;
}
2022-01-31 20:08:53 +13:00
if ( ! _containerSystem . IsInSameOrNoContainer ( puller , pulled ) )
2021-10-04 16:10:54 +01:00
{
return false ;
}
2022-12-23 23:55:31 -05:00
if ( EntityManager . TryGetComponent < BuckleComponent ? > ( puller , out var buckle ) )
2021-11-13 21:43:37 +00:00
{
// Prevent people pulling the chair they're on, etc.
2021-12-03 15:53:09 +01:00
if ( buckle . Buckled & & ( buckle . LastEntityBuckledTo = = pulled ) )
2021-11-13 21:43:37 +00:00
{
return false ;
}
}
2022-06-15 21:10:03 -04:00
var getPulled = new BeingPulledAttemptEvent ( puller , pulled ) ;
2022-06-22 09:53:41 +10:00
RaiseLocalEvent ( pulled , getPulled , true ) ;
2021-10-04 16:10:54 +01:00
var startPull = new StartPullAttemptEvent ( puller , pulled ) ;
2022-06-22 09:53:41 +10:00
RaiseLocalEvent ( puller , startPull , true ) ;
2022-06-15 21:10:03 -04:00
return ( ! startPull . Cancelled & & ! getPulled . Cancelled ) ;
2021-10-04 16:10:54 +01:00
}
2021-12-04 12:59:44 +01:00
public bool TogglePull ( EntityUid puller , SharedPullableComponent pullable )
2021-10-04 16:10:54 +01:00
{
if ( pullable . Puller = = puller )
{
return TryStopPull ( pullable ) ;
}
return TryStartPull ( puller , pullable . Owner ) ;
}
// -- Core attempted actions --
2021-12-04 12:59:44 +01:00
public bool TryStopPull ( SharedPullableComponent pullable , EntityUid ? user = null )
2021-10-04 16:10:54 +01:00
{
if ( ! pullable . BeingPulled )
{
return false ;
}
2021-12-03 15:53:09 +01:00
var msg = new StopPullingEvent ( user ) ;
2022-06-22 09:53:41 +10:00
RaiseLocalEvent ( pullable . Owner , msg , true ) ;
2021-10-04 16:10:54 +01:00
if ( msg . Cancelled ) return false ;
2022-06-16 05:15:56 -04:00
// Stop pulling confirmed!
if ( TryComp < PhysicsComponent > ( pullable . Owner , out var pullablePhysics ) )
{
2023-01-15 15:38:59 +11:00
_physics . SetFixedRotation ( pullable . Owner , pullable . PrevFixedRotation , body : pullablePhysics ) ;
2022-06-16 05:15:56 -04:00
}
2021-10-04 16:10:54 +01:00
_pullSm . ForceRelationship ( null , pullable ) ;
return true ;
}
2021-12-04 12:59:44 +01:00
public bool TryStartPull ( EntityUid puller , EntityUid pullable )
2021-10-04 16:10:54 +01:00
{
2021-12-04 12:59:44 +01:00
if ( ! EntityManager . TryGetComponent < SharedPullerComponent ? > ( puller , out var pullerComp ) )
2021-10-04 16:10:54 +01:00
{
return false ;
}
2021-12-04 12:59:44 +01:00
if ( ! EntityManager . TryGetComponent < SharedPullableComponent ? > ( pullable , out var pullableComp ) )
2021-10-04 16:10:54 +01:00
{
return false ;
}
return TryStartPull ( pullerComp , pullableComp ) ;
}
// The main "start pulling" function.
public bool TryStartPull ( SharedPullerComponent puller , SharedPullableComponent pullable )
{
2021-11-23 14:02:08 +01:00
if ( puller . Pulling = = pullable . Owner )
2021-10-04 16:10:54 +01:00
return true ;
// Pulling a new object : Perform sanity checks.
2021-12-04 12:59:44 +01:00
if ( ! CanPull ( puller . Owner , pullable . Owner ) )
2021-10-04 16:10:54 +01:00
{
return false ;
}
2022-05-16 22:24:52 +10:00
if ( ! EntityManager . TryGetComponent < PhysicsComponent > ( puller . Owner , out var pullerPhysics ) )
2021-10-04 16:10:54 +01:00
{
return false ;
}
2022-05-16 22:24:52 +10:00
if ( ! EntityManager . TryGetComponent < PhysicsComponent > ( pullable . Owner , out var pullablePhysics ) )
2021-10-04 16:10:54 +01:00
{
return false ;
}
// Ensure that the puller is not currently pulling anything.
// If this isn't done, then it happens too late, and the start/stop messages go out of order,
// and next thing you know it thinks it's not pulling anything even though it is!
var oldPullable = puller . Pulling ;
if ( oldPullable ! = null )
{
2021-12-04 12:59:44 +01:00
if ( EntityManager . TryGetComponent < SharedPullableComponent ? > ( oldPullable . Value , out var oldPullableComp ) )
2021-10-04 16:10:54 +01:00
{
if ( ! TryStopPull ( oldPullableComp ) )
{
return false ;
}
}
else
{
Logger . WarningS ( "c.go.c.pulling" , "Well now you've done it, haven't you? Someone transferred pulling (onto {0}) while presently pulling something that has no Pullable component (on {1})!" , pullable . Owner , oldPullable ) ;
return false ;
}
}
// Ensure that the pullable is not currently being pulled.
// Same sort of reasons as before.
var oldPuller = pullable . Puller ;
if ( oldPuller ! = null )
{
if ( ! TryStopPull ( pullable ) )
{
return false ;
}
}
// Continue with pulling process.
2022-05-16 22:24:52 +10:00
var pullAttempt = new PullAttemptEvent ( pullerPhysics , pullablePhysics ) ;
2021-10-04 16:10:54 +01:00
2021-12-07 22:22:34 +11:00
RaiseLocalEvent ( puller . Owner , pullAttempt , broadcast : false ) ;
2021-10-04 16:10:54 +01:00
if ( pullAttempt . Cancelled )
{
return false ;
}
2022-06-22 09:53:41 +10:00
RaiseLocalEvent ( pullable . Owner , pullAttempt , true ) ;
2021-10-04 16:10:54 +01:00
if ( pullAttempt . Cancelled )
return false ;
2022-10-26 14:15:48 +13:00
_interaction . DoContactInteraction ( pullable . Owner , puller . Owner ) ;
2021-10-04 16:10:54 +01:00
_pullSm . ForceRelationship ( puller , pullable ) ;
2022-06-16 05:15:56 -04:00
pullable . PrevFixedRotation = pullablePhysics . FixedRotation ;
2023-01-15 15:38:59 +11:00
_physics . SetFixedRotation ( pullable . Owner , pullable . FixedRotationOnPull , body : pullablePhysics ) ;
2022-12-18 19:15:55 -06:00
_adminLogger . Add ( LogType . Action , LogImpact . Low ,
$"{ToPrettyString(puller.Owner):user} started pulling {ToPrettyString(pullable.Owner):target}" ) ;
2021-10-04 16:10:54 +01:00
return true ;
}
2022-03-18 15:40:02 +11:00
public bool TryMoveTo ( SharedPullableComponent pullable , EntityCoordinates to )
2021-10-04 16:10:54 +01:00
{
if ( pullable . Puller = = null )
{
return false ;
}
2021-12-07 22:22:34 +11:00
if ( ! EntityManager . HasComponent < PhysicsComponent > ( pullable . Owner ) )
2021-10-04 16:10:54 +01:00
{
return false ;
}
2022-03-18 15:40:02 +11:00
_pullSm . ForceSetMovingTo ( pullable , to ) ;
2021-10-04 16:10:54 +01:00
return true ;
}
2022-03-18 15:40:02 +11:00
public void StopMoveTo ( SharedPullableComponent pullable )
{
_pullSm . ForceSetMovingTo ( pullable , null ) ;
}
2021-10-04 16:10:54 +01:00
}
}