2023-09-05 00:07:01 +10:00
using Content.Shared.Administration.Logs ;
2023-01-02 22:39:48 -06:00
using Content.Shared.Database ;
2022-05-09 08:51:52 +03:00
using Content.Shared.Examine ;
using Content.Shared.Interaction ;
using Content.Shared.Tools.Components ;
2023-03-13 15:26:20 -04:00
using Robust.Shared.Physics ;
using Robust.Shared.Physics.Systems ;
2023-09-05 00:07:01 +10:00
using LayerChangeOnWeldComponent = Content . Shared . Tools . Components . LayerChangeOnWeldComponent ;
2022-05-09 08:51:52 +03:00
2023-09-05 00:07:01 +10:00
namespace Content.Shared.Tools.Systems ;
2022-05-09 08:51:52 +03:00
public sealed class WeldableSystem : EntitySystem
{
2023-09-05 00:07:01 +10:00
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default ! ;
2023-02-24 19:01:25 -05:00
[Dependency] private readonly SharedToolSystem _toolSystem = default ! ;
2023-02-02 17:34:53 +01:00
[Dependency] private readonly SharedAppearanceSystem _appearance = default ! ;
2023-03-13 15:26:20 -04:00
[Dependency] private readonly SharedPhysicsSystem _physics = default ! ;
2023-09-05 00:07:01 +10:00
public bool IsWelded ( EntityUid uid , WeldableComponent ? component = null )
{
if ( ! Resolve ( uid , ref component , false ) )
return false ;
return component . IsWelded ;
}
2022-05-09 08:51:52 +03:00
public override void Initialize ( )
{
base . Initialize ( ) ;
SubscribeLocalEvent < WeldableComponent , InteractUsingEvent > ( OnInteractUsing ) ;
SubscribeLocalEvent < WeldableComponent , WeldFinishedEvent > ( OnWeldFinished ) ;
2023-03-13 15:26:20 -04:00
SubscribeLocalEvent < LayerChangeOnWeldComponent , WeldableChangedEvent > ( OnWeldChanged ) ;
2022-05-09 08:51:52 +03:00
SubscribeLocalEvent < WeldableComponent , ExaminedEvent > ( OnExamine ) ;
}
private void OnExamine ( EntityUid uid , WeldableComponent component , ExaminedEvent args )
{
if ( component . IsWelded & & component . WeldedExamineMessage ! = null )
args . PushText ( Loc . GetString ( component . WeldedExamineMessage ) ) ;
}
private void OnInteractUsing ( EntityUid uid , WeldableComponent component , InteractUsingEvent args )
{
if ( args . Handled )
return ;
args . Handled = TryWeld ( uid , args . Used , args . User , component ) ;
}
private bool CanWeld ( EntityUid uid , EntityUid tool , EntityUid user , WeldableComponent ? component = null )
{
if ( ! Resolve ( uid , ref component ) )
return false ;
// Other component systems
var attempt = new WeldableAttemptEvent ( user , tool ) ;
2023-09-05 00:07:01 +10:00
RaiseLocalEvent ( uid , attempt ) ;
2022-05-09 08:51:52 +03:00
if ( attempt . Cancelled )
return false ;
return true ;
}
private bool TryWeld ( EntityUid uid , EntityUid tool , EntityUid user , WeldableComponent ? component = null )
{
if ( ! Resolve ( uid , ref component ) )
return false ;
if ( ! CanWeld ( uid , tool , user , component ) )
return false ;
2023-06-28 01:46:48 +00:00
if ( ! _toolSystem . UseTool ( tool , user , uid , component . WeldingTime . Seconds , component . WeldingQuality , new WeldFinishedEvent ( ) ) )
2023-04-03 13:13:48 +12:00
return false ;
2022-05-09 08:51:52 +03:00
2023-01-02 22:39:48 -06:00
// Log attempt
_adminLogger . Add ( LogType . Action , LogImpact . Low , $"{ToPrettyString(user):user} is {(component.IsWelded ? " un " : " ")}welding {ToPrettyString(uid):target} at {Transform(uid).Coordinates:targetlocation}" ) ;
2022-05-09 08:51:52 +03:00
return true ;
}
private void OnWeldFinished ( EntityUid uid , WeldableComponent component , WeldFinishedEvent args )
{
2023-04-03 13:13:48 +12:00
if ( args . Cancelled | | args . Used = = null )
return ;
2022-05-09 08:51:52 +03:00
// Check if target is still valid
2023-04-03 13:13:48 +12:00
if ( ! CanWeld ( uid , args . Used . Value , args . User , component ) )
2022-05-09 08:51:52 +03:00
return ;
2023-09-05 00:07:01 +10:00
SetWeldedState ( uid , ! component . IsWelded , component ) ;
2023-01-02 22:39:48 -06:00
// Log success
_adminLogger . Add ( LogType . Action , LogImpact . Low , $"{ToPrettyString(args.User):user} {(!component.IsWelded ? " un " : " ")}welded {ToPrettyString(uid):target}" ) ;
2022-05-09 08:51:52 +03:00
}
2023-09-05 00:07:01 +10:00
private void OnWeldChanged ( EntityUid uid , LayerChangeOnWeldComponent component , ref WeldableChangedEvent args )
2023-03-13 15:26:20 -04:00
{
if ( ! TryComp < FixturesComponent > ( uid , out var fixtures ) )
return ;
2023-08-23 18:55:58 +10:00
foreach ( var ( id , fixture ) in fixtures . Fixtures )
2023-03-13 15:26:20 -04:00
{
switch ( args . IsWelded )
{
case true when fixture . CollisionLayer = = ( int ) component . UnWeldedLayer :
2023-08-23 18:55:58 +10:00
_physics . SetCollisionLayer ( uid , id , fixture , ( int ) component . WeldedLayer ) ;
2023-03-13 15:26:20 -04:00
break ;
case false when fixture . CollisionLayer = = ( int ) component . WeldedLayer :
2023-08-23 18:55:58 +10:00
_physics . SetCollisionLayer ( uid , id , fixture , ( int ) component . UnWeldedLayer ) ;
2023-03-13 15:26:20 -04:00
break ;
}
}
}
2022-05-09 08:51:52 +03:00
private void UpdateAppearance ( EntityUid uid , WeldableComponent ? component = null )
{
if ( ! Resolve ( uid , ref component ) )
return ;
if ( ! TryComp ( uid , out AppearanceComponent ? appearance ) )
return ;
2023-02-02 17:34:53 +01:00
_appearance . SetData ( uid , WeldableVisuals . IsWelded , component . IsWelded , appearance ) ;
2022-05-09 08:51:52 +03:00
}
2023-09-05 00:07:01 +10:00
public void SetWeldedState ( EntityUid uid , bool state , WeldableComponent ? component = null )
2022-07-21 17:30:00 -05:00
{
if ( ! Resolve ( uid , ref component ) )
return ;
2023-09-05 00:07:01 +10:00
if ( component . IsWelded = = state )
return ;
2022-07-21 17:30:00 -05:00
2023-09-05 00:07:01 +10:00
component . IsWelded = state ;
var ev = new WeldableChangedEvent ( component . IsWelded ) ;
2022-07-21 17:30:00 -05:00
2023-09-05 00:07:01 +10:00
RaiseLocalEvent ( uid , ref ev ) ;
2022-07-21 17:30:00 -05:00
UpdateAppearance ( uid , component ) ;
2023-09-05 00:07:01 +10:00
Dirty ( uid , component ) ;
2022-07-21 17:30:00 -05:00
}
2022-05-09 08:51:52 +03:00
public void SetWeldingTime ( EntityUid uid , TimeSpan time , WeldableComponent ? component = null )
{
if ( ! Resolve ( uid , ref component ) )
return ;
2023-09-05 00:07:01 +10:00
if ( component . WeldingTime . Equals ( time ) )
return ;
2022-05-09 08:51:52 +03:00
2023-09-05 00:07:01 +10:00
component . WeldingTime = time ;
Dirty ( uid , component ) ;
2022-05-09 08:51:52 +03:00
}
}