2023-08-04 21:26:42 -05:00
using Content.Server.Administration.Logs ;
2023-06-03 04:31:47 +01:00
using Content.Shared.IdentityManagement ;
using Content.Shared.Popups ;
using Content.Shared.Item ;
using Content.Shared.Glue ;
using Content.Shared.Interaction ;
2023-06-30 22:07:44 +03:00
using Content.Server.Chemistry.EntitySystems ;
2023-06-03 04:31:47 +01:00
using Content.Server.Nutrition.Components ;
2023-08-04 21:26:42 -05:00
using Content.Shared.Database ;
2023-06-30 22:07:44 +03:00
using Content.Shared.Hands ;
using Robust.Shared.Timing ;
using Content.Shared.Interaction.Components ;
2023-06-03 04:31:47 +01:00
2023-06-30 22:07:44 +03:00
namespace Content.Server.Glue ;
public sealed class GlueSystem : SharedGlueSystem
2023-06-03 04:31:47 +01:00
{
2023-06-30 22:07:44 +03:00
[Dependency] private readonly SharedAudioSystem _audio = default ! ;
[Dependency] private readonly SharedPopupSystem _popup = default ! ;
[Dependency] private readonly SolutionContainerSystem _solutionContainer = default ! ;
[Dependency] private readonly IGameTiming _timing = default ! ;
[Dependency] private readonly MetaDataSystem _metaData = default ! ;
2023-08-04 21:26:42 -05:00
[Dependency] private readonly IAdminLogManager _adminLogger = default ! ;
2023-06-30 22:07:44 +03:00
public override void Initialize ( )
2023-06-03 04:31:47 +01:00
{
2023-06-30 22:07:44 +03:00
base . Initialize ( ) ;
2023-06-03 04:31:47 +01:00
2023-06-30 22:07:44 +03:00
SubscribeLocalEvent < GlueComponent , AfterInteractEvent > ( OnInteract ) ;
SubscribeLocalEvent < GluedComponent , ComponentInit > ( OnGluedInit ) ;
SubscribeLocalEvent < GluedComponent , GotEquippedHandEvent > ( OnHandPickUp ) ;
}
2023-06-03 04:31:47 +01:00
2023-06-30 22:07:44 +03:00
// When glue bottle is used on item it will apply the glued and unremoveable components.
private void OnInteract ( EntityUid uid , GlueComponent component , AfterInteractEvent args )
{
if ( args . Handled )
return ;
if ( ! args . CanReach | | args . Target is not { Valid : true } target )
return ;
2023-06-03 04:31:47 +01:00
2023-06-30 22:07:44 +03:00
if ( TryComp < DrinkComponent > ( uid , out var drink ) & & ! drink . Opened )
{
return ;
2023-06-03 04:31:47 +01:00
}
2023-08-04 21:26:42 -05:00
if ( TryGlue ( uid , component , target , args . User ) )
2023-06-30 22:07:44 +03:00
{
args . Handled = true ;
_audio . PlayPvs ( component . Squeeze , uid ) ;
_popup . PopupEntity ( Loc . GetString ( "glue-success" , ( "target" , target ) ) , args . User , args . User , PopupType . Medium ) ;
}
else
2023-06-03 04:31:47 +01:00
{
2023-06-30 22:07:44 +03:00
_popup . PopupEntity ( Loc . GetString ( "glue-failure" , ( "target" , target ) ) , args . User , args . User , PopupType . Medium ) ;
}
}
2023-06-03 04:31:47 +01:00
2023-08-04 21:26:42 -05:00
private bool TryGlue ( EntityUid uid , GlueComponent component , EntityUid target , EntityUid actor )
2023-06-30 22:07:44 +03:00
{
// if item is glued then don't apply glue again so it can be removed for reasonable time
if ( HasComp < GluedComponent > ( target ) | | ! HasComp < ItemComponent > ( target ) )
{
return false ;
}
2023-06-03 04:31:47 +01:00
2023-06-30 22:07:44 +03:00
if ( HasComp < ItemComponent > ( target ) & & _solutionContainer . TryGetSolution ( uid , component . Solution , out var solution ) )
{
var quantity = solution . RemoveReagent ( component . Reagent , component . ConsumptionUnit ) ;
if ( quantity > 0 )
2023-06-03 04:31:47 +01:00
{
2023-06-30 22:07:44 +03:00
EnsureComp < GluedComponent > ( target ) . Duration = quantity . Double ( ) * component . DurationPerUnit ;
2023-08-04 21:26:42 -05:00
_adminLogger . Add ( LogType . Action , LogImpact . Medium , $"{ToPrettyString(actor):actor} glued {ToPrettyString(target):subject} with {ToPrettyString(uid):tool}" ) ;
2023-06-30 22:07:44 +03:00
return true ;
2023-06-03 04:31:47 +01:00
}
2023-06-30 22:07:44 +03:00
}
return false ;
}
2023-06-03 04:31:47 +01:00
2023-06-30 22:07:44 +03:00
public override void Update ( float frameTime )
{
base . Update ( frameTime ) ;
2023-06-03 04:31:47 +01:00
2023-06-30 22:07:44 +03:00
var query = EntityQueryEnumerator < GluedComponent , UnremoveableComponent > ( ) ;
while ( query . MoveNext ( out var uid , out var glue , out _ ) )
{
if ( _timing . CurTime < glue . Until )
continue ;
2023-06-03 04:31:47 +01:00
2023-06-30 22:07:44 +03:00
_metaData . SetEntityName ( uid , glue . BeforeGluedEntityName ) ;
RemComp < UnremoveableComponent > ( uid ) ;
RemComp < GluedComponent > ( uid ) ;
2023-06-03 04:31:47 +01:00
}
2023-06-30 22:07:44 +03:00
}
2023-06-03 04:31:47 +01:00
2023-06-30 22:07:44 +03:00
private void OnGluedInit ( EntityUid uid , GluedComponent component , ComponentInit args )
{
var meta = MetaData ( uid ) ;
var name = meta . EntityName ;
component . BeforeGluedEntityName = meta . EntityName ;
_metaData . SetEntityName ( uid , Loc . GetString ( "glued-name-prefix" , ( "target" , name ) ) ) ;
}
private void OnHandPickUp ( EntityUid uid , GluedComponent component , GotEquippedHandEvent args )
{
EnsureComp < UnremoveableComponent > ( uid ) ;
component . Until = _timing . CurTime + component . Duration ;
2023-06-03 04:31:47 +01:00
}
}