2023-01-12 16:41:40 +13:00
using Content.Server.Body.Components ;
2021-11-30 16:47:21 -07:00
using Content.Server.Body.Systems ;
2021-10-29 13:40:15 +01:00
using Content.Server.Chemistry.EntitySystems ;
2022-12-15 12:33:27 -06:00
using Content.Shared.Administration.Logs ;
using Content.Shared.Database ;
2021-11-03 16:48:03 -07:00
using Content.Shared.FixedPoint ;
2021-06-09 22:19:39 +02:00
using Content.Shared.Foam ;
using Content.Shared.Inventory ;
2023-01-12 16:41:40 +13:00
using Robust.Shared.Prototypes ;
2021-02-03 11:26:46 -03:00
2021-06-09 22:19:39 +02:00
namespace Content.Server.Chemistry.Components
2021-02-03 11:26:46 -03:00
{
[RegisterComponent]
[ComponentReference(typeof(SolutionAreaEffectComponent))]
2022-02-16 00:23:23 -07:00
public sealed class FoamSolutionAreaEffectComponent : SolutionAreaEffectComponent
2021-02-03 11:26:46 -03:00
{
2021-12-08 17:04:21 +01:00
[Dependency] private readonly IEntityManager _entMan = default ! ;
2023-01-12 16:41:40 +13:00
[Dependency] private readonly IPrototypeManager _proto = default ! ;
2022-12-15 12:33:27 -06:00
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default ! ;
2021-12-08 17:04:21 +01:00
2021-11-22 01:40:14 -07:00
public new const string SolutionName = "solutionArea" ;
2021-02-03 11:26:46 -03:00
2021-03-05 01:08:38 +01:00
[DataField("foamedMetalPrototype")] private string? _foamedMetalPrototype ;
2021-02-03 11:26:46 -03:00
protected override void UpdateVisuals ( )
{
2021-12-08 17:04:21 +01:00
if ( _entMan . TryGetComponent ( Owner , out AppearanceComponent ? appearance ) & &
2021-12-03 15:53:09 +01:00
EntitySystem . Get < SolutionContainerSystem > ( ) . TryGetSolution ( Owner , SolutionName , out var solution ) )
2021-02-03 11:26:46 -03:00
{
2023-01-12 16:41:40 +13:00
appearance . SetData ( FoamVisuals . Color , solution . GetColor ( _proto ) . WithAlpha ( 0.80f ) ) ;
2021-02-03 11:26:46 -03:00
}
}
2021-12-05 18:09:01 +01:00
protected override void ReactWithEntity ( EntityUid entity , double solutionFraction )
2021-02-03 11:26:46 -03:00
{
2021-12-03 15:53:09 +01:00
if ( ! EntitySystem . Get < SolutionContainerSystem > ( ) . TryGetSolution ( Owner , SolutionName , out var solution ) )
2021-02-03 11:26:46 -03:00
return ;
2021-12-08 17:04:21 +01:00
if ( ! _entMan . TryGetComponent ( entity , out BloodstreamComponent ? bloodstream ) )
2021-02-03 11:26:46 -03:00
return ;
2021-12-30 22:56:10 +01:00
var invSystem = EntitySystem . Get < InventorySystem > ( ) ;
2021-02-03 11:26:46 -03:00
// TODO: Add a permeability property to clothing
// For now it just adds to protection for each clothing equipped
var protection = 0f ;
2021-12-30 22:56:10 +01:00
if ( invSystem . TryGetSlots ( entity , out var slotDefinitions ) )
2021-02-03 11:26:46 -03:00
{
2021-12-30 22:56:10 +01:00
foreach ( var slot in slotDefinitions )
2021-02-03 11:26:46 -03:00
{
2021-12-30 22:56:10 +01:00
if ( slot . Name = = "back" | |
slot . Name = = "pocket1" | |
slot . Name = = "pocket2" | |
slot . Name = = "id" )
2021-02-03 11:26:46 -03:00
continue ;
2021-12-30 22:56:10 +01:00
if ( invSystem . TryGetSlotEntity ( entity , slot . Name , out _ ) )
2021-02-03 11:26:46 -03:00
protection + = 0.025f ;
}
}
2021-11-30 16:47:21 -07:00
var bloodstreamSys = EntitySystem . Get < BloodstreamSystem > ( ) ;
2021-09-06 15:49:44 +02:00
var cloneSolution = solution . Clone ( ) ;
2023-01-12 16:41:40 +13:00
var transferAmount = FixedPoint2 . Min ( cloneSolution . Volume * solutionFraction * ( 1 - protection ) ,
2022-02-17 15:00:41 -07:00
bloodstream . ChemicalSolution . AvailableVolume ) ;
2021-02-03 11:26:46 -03:00
var transferSolution = cloneSolution . SplitSolution ( transferAmount ) ;
2022-12-15 12:33:27 -06:00
if ( bloodstreamSys . TryAddToChemicals ( entity , transferSolution , bloodstream ) )
{
// Log solution addition by foam
_adminLogger . Add ( LogType . ForceFeed , LogImpact . Medium , $"{_entMan.ToPrettyString(entity):target} was affected by foam {SolutionContainerSystem.ToPrettyString(transferSolution)}" ) ;
}
2021-02-03 11:26:46 -03:00
}
protected override void OnKill ( )
{
2021-12-09 12:29:27 +01:00
if ( _entMan . Deleted ( Owner ) )
2021-02-03 11:26:46 -03:00
return ;
2021-12-08 17:04:21 +01:00
if ( _entMan . TryGetComponent ( Owner , out AppearanceComponent ? appearance ) )
2021-02-03 11:26:46 -03:00
{
appearance . SetData ( FoamVisuals . State , true ) ;
}
2021-09-06 15:49:44 +02:00
2021-02-03 11:26:46 -03:00
Owner . SpawnTimer ( 600 , ( ) = >
{
if ( ! string . IsNullOrEmpty ( _foamedMetalPrototype ) )
{
2021-12-08 17:04:21 +01:00
_entMan . SpawnEntity ( _foamedMetalPrototype , _entMan . GetComponent < TransformComponent > ( Owner ) . Coordinates ) ;
2021-02-03 11:26:46 -03:00
}
2021-09-06 15:49:44 +02:00
2021-12-08 17:04:21 +01:00
_entMan . QueueDeleteEntity ( Owner ) ;
2021-02-03 11:26:46 -03:00
} ) ;
}
}
}