2021-11-09 08:08:30 +01:00
using System.Threading.Tasks ;
2022-03-25 22:10:43 +01:00
using Content.Server.Administration.Logs ;
2021-11-09 08:08:30 +01:00
using Content.Server.Coordinates.Helpers ;
using Content.Server.Pulling ;
using Content.Server.Tools ;
2022-04-02 16:52:44 +13:00
using Content.Shared.Construction.Components ;
using Content.Shared.Construction.EntitySystems ;
2022-03-25 22:10:43 +01:00
using Content.Shared.Database ;
2021-11-09 08:08:30 +01:00
using Content.Shared.Pulling.Components ;
2022-04-02 16:52:44 +13:00
using Content.Shared.Tools.Components ;
2021-11-09 08:08:30 +01:00
namespace Content.Server.Construction
{
2022-04-02 16:52:44 +13:00
public sealed class AnchorableSystem : SharedAnchorableSystem
2021-11-09 08:08:30 +01:00
{
2022-03-25 22:10:43 +01:00
[Dependency] private readonly AdminLogSystem _adminLogs = default ! ;
2021-11-09 08:08:30 +01:00
[Dependency] private readonly ToolSystem _toolSystem = default ! ;
[Dependency] private readonly PullingSystem _pullingSystem = default ! ;
/// <summary>
/// Checks if a tool can change the anchored status.
/// </summary>
/// <returns>true if it is valid, false otherwise</returns>
private async Task < bool > Valid ( EntityUid uid , EntityUid userUid , EntityUid usingUid , bool anchoring , AnchorableComponent ? anchorable = null , ToolComponent ? usingTool = null )
{
if ( ! Resolve ( uid , ref anchorable ) )
return false ;
if ( ! Resolve ( usingUid , ref usingTool ) )
return false ;
BaseAnchoredAttemptEvent attempt =
anchoring ? new AnchorAttemptEvent ( userUid , usingUid ) : new UnanchorAttemptEvent ( userUid , usingUid ) ;
// Need to cast the event or it will be raised as BaseAnchoredAttemptEvent.
if ( anchoring )
RaiseLocalEvent ( uid , ( AnchorAttemptEvent ) attempt , false ) ;
else
RaiseLocalEvent ( uid , ( UnanchorAttemptEvent ) attempt , false ) ;
if ( attempt . Cancelled )
return false ;
2022-02-07 14:06:11 +11:00
return await _toolSystem . UseTool ( usingUid , userUid , uid , 0f , anchorable . Delay + attempt . Delay , anchorable . Tool , toolComponent : usingTool ) ;
2021-11-09 08:08:30 +01:00
}
/// <summary>
/// Tries to anchor the entity.
/// </summary>
/// <returns>true if anchored, false otherwise</returns>
public async Task < bool > TryAnchor ( EntityUid uid , EntityUid userUid , EntityUid usingUid ,
AnchorableComponent ? anchorable = null ,
TransformComponent ? transform = null ,
SharedPullableComponent ? pullable = null ,
ToolComponent ? usingTool = null )
{
if ( ! Resolve ( uid , ref anchorable , ref transform ) )
return false ;
// Optional resolves.
2022-01-11 07:43:58 +11:00
Resolve ( uid , ref pullable , false ) ;
2021-11-09 08:08:30 +01:00
if ( ! Resolve ( usingUid , ref usingTool ) )
return false ;
if ( ! ( await Valid ( uid , userUid , usingUid , true , anchorable , usingTool ) ) )
{
return false ;
}
// Snap rotation to cardinal (multiple of 90)
var rot = transform . LocalRotation ;
transform . LocalRotation = Math . Round ( rot / ( Math . PI / 2 ) ) * ( Math . PI / 2 ) ;
if ( pullable is { Puller : { } } )
{
_pullingSystem . TryStopPull ( pullable ) ;
}
if ( anchorable . Snap )
transform . Coordinates = transform . Coordinates . SnapToGrid ( ) ;
RaiseLocalEvent ( uid , new BeforeAnchoredEvent ( userUid , usingUid ) , false ) ;
transform . Anchored = true ;
2022-01-13 06:49:28 +13:00
RaiseLocalEvent ( uid , new UserAnchoredEvent ( userUid , usingUid ) , false ) ;
2021-11-09 08:08:30 +01:00
2022-03-25 22:10:43 +01:00
_adminLogs . Add (
LogType . Action ,
LogImpact . Low ,
$"{EntityManager.ToPrettyString(userUid):user} anchored {EntityManager.ToPrettyString(uid):anchored} using {EntityManager.ToPrettyString(usingUid):using}"
) ;
2021-11-09 08:08:30 +01:00
return true ;
}
/// <summary>
/// Tries to unanchor the entity.
/// </summary>
/// <returns>true if unanchored, false otherwise</returns>
public async Task < bool > TryUnAnchor ( EntityUid uid , EntityUid userUid , EntityUid usingUid ,
AnchorableComponent ? anchorable = null ,
TransformComponent ? transform = null ,
ToolComponent ? usingTool = null )
{
if ( ! Resolve ( uid , ref anchorable , ref transform ) )
return false ;
if ( ! Resolve ( usingUid , ref usingTool ) )
return false ;
if ( ! ( await Valid ( uid , userUid , usingUid , false ) ) )
{
return false ;
}
RaiseLocalEvent ( uid , new BeforeUnanchoredEvent ( userUid , usingUid ) , false ) ;
transform . Anchored = false ;
2022-01-13 06:49:28 +13:00
RaiseLocalEvent ( uid , new UserUnanchoredEvent ( userUid , usingUid ) , false ) ;
2021-11-09 08:08:30 +01:00
2022-03-25 22:10:43 +01:00
_adminLogs . Add (
LogType . Action ,
LogImpact . Low ,
$"{EntityManager.ToPrettyString(userUid):user} unanchored {EntityManager.ToPrettyString(uid):anchored} using {EntityManager.ToPrettyString(usingUid):using}"
) ;
2021-11-09 08:08:30 +01:00
return true ;
}
/// <summary>
/// Tries to toggle the anchored status of this component's owner.
/// </summary>
/// <returns>true if toggled, false otherwise</returns>
2022-04-02 16:52:44 +13:00
public override async Task < bool > TryToggleAnchor ( EntityUid uid , EntityUid userUid , EntityUid usingUid ,
2021-11-09 08:08:30 +01:00
AnchorableComponent ? anchorable = null ,
TransformComponent ? transform = null ,
SharedPullableComponent ? pullable = null ,
ToolComponent ? usingTool = null )
{
if ( ! Resolve ( uid , ref transform ) )
return false ;
return transform . Anchored ?
await TryUnAnchor ( uid , userUid , usingUid , anchorable , transform , usingTool ) :
await TryAnchor ( uid , userUid , usingUid , anchorable , transform , pullable , usingTool ) ;
}
}
}