2021-11-22 23:51:43 -07:00
using Content.Shared.Administration.Logs ;
2021-09-26 15:19:00 +02:00
using Content.Shared.Chemistry.Components ;
2021-06-09 22:19:39 +02:00
using Content.Shared.Chemistry.Reaction ;
using Content.Shared.Chemistry.Reagent ;
2021-11-28 14:56:53 +01:00
using Content.Shared.Database ;
2021-11-03 16:48:03 -07:00
using Content.Shared.FixedPoint ;
2020-04-08 15:53:15 +05:00
using JetBrains.Annotations ;
2021-02-11 01:13:03 -08:00
using Robust.Shared.GameObjects ;
2021-03-26 12:02:41 +01:00
using Robust.Shared.IoC ;
using Robust.Shared.Prototypes ;
2021-11-20 16:47:53 -07:00
using Robust.Shared.Random ;
2020-04-08 15:53:15 +05:00
2021-06-09 22:19:39 +02:00
namespace Content.Shared.Chemistry
2020-04-08 15:53:15 +05:00
{
[UsedImplicitly]
2022-02-16 00:23:23 -07:00
public sealed class ReactiveSystem : EntitySystem
2020-04-08 15:53:15 +05:00
{
2021-03-26 12:02:41 +01:00
[Dependency] private readonly IPrototypeManager _prototypeManager = default ! ;
2021-11-20 16:47:53 -07:00
[Dependency] private readonly IRobustRandom _robustRandom = default ! ;
2021-11-22 23:51:43 -07:00
[Dependency] private readonly SharedAdminLogSystem _logSystem = default ! ;
2021-03-26 12:02:41 +01:00
2021-11-09 11:28:27 +01:00
public void ReactionEntity ( EntityUid uid , ReactionMethod method , Solution solution )
2021-09-26 15:19:00 +02:00
{
foreach ( var ( id , quantity ) in solution )
{
2021-11-09 11:28:27 +01:00
ReactionEntity ( uid , method , id , quantity , solution ) ;
2021-09-26 15:19:00 +02:00
}
}
2021-11-09 11:28:27 +01:00
public void ReactionEntity ( EntityUid uid , ReactionMethod method , string reagentId , FixedPoint2 reactVolume , Solution ? source )
2021-03-26 12:02:41 +01:00
{
// We throw if the reagent specified doesn't exist.
2021-11-09 11:28:27 +01:00
ReactionEntity ( uid , method , _prototypeManager . Index < ReagentPrototype > ( reagentId ) , reactVolume , source ) ;
2021-03-26 12:02:41 +01:00
}
2021-11-09 11:28:27 +01:00
public void ReactionEntity ( EntityUid uid , ReactionMethod method , ReagentPrototype reagent ,
2021-11-03 16:48:03 -07:00
FixedPoint2 reactVolume , Solution ? source )
2021-03-26 12:02:41 +01:00
{
2021-11-09 11:28:27 +01:00
if ( ! EntityManager . TryGetComponent ( uid , out ReactiveComponent ? reactive ) )
2021-03-26 12:02:41 +01:00
return ;
2021-11-10 03:11:28 -07:00
// If we have a source solution, use the reagent quantity we have left. Otherwise, use the reaction volume specified.
var args = new ReagentEffectArgs ( uid , null , source , reagent ,
source ? . GetReagentQuantity ( reagent . ID ) ? ? reactVolume , EntityManager , method ) ;
2021-11-22 02:17:35 -07:00
// First, check if the reagent wants to apply any effects.
if ( reagent . ReactiveEffects ! = null & & reactive . ReactiveGroups ! = null )
2021-03-26 12:02:41 +01:00
{
2021-11-22 02:17:35 -07:00
foreach ( var ( key , val ) in reagent . ReactiveEffects )
{
if ( ! val . Methods . Contains ( method ) )
continue ;
2021-11-10 03:11:28 -07:00
2021-11-22 02:17:35 -07:00
if ( ! reactive . ReactiveGroups . ContainsKey ( key ) )
continue ;
2021-11-10 03:11:28 -07:00
2021-11-22 02:17:35 -07:00
if ( ! reactive . ReactiveGroups [ key ] . Contains ( method ) )
continue ;
foreach ( var effect in val . Effects )
{
if ( ! effect . ShouldApply ( args , _robustRandom ) )
continue ;
2021-11-27 00:31:56 -07:00
if ( effect . ShouldLog )
{
2021-12-05 18:09:01 +01:00
var entity = args . SolutionEntity ;
2021-11-27 00:31:56 -07:00
_logSystem . Add ( LogType . ReagentEffect , effect . LogImpact ,
2021-12-14 00:22:58 +13:00
$"Reactive effect {effect.GetType().Name:effect} of reagent {reagent.ID:reagent} with method {method} applied on entity {ToPrettyString(entity):entity} at {Transform(entity).Coordinates:coordinates}" ) ;
2021-11-27 00:31:56 -07:00
}
2021-11-27 01:27:47 -07:00
effect . Effect ( args ) ;
2021-11-22 02:17:35 -07:00
}
}
}
// Then, check if the prototype has any effects it can apply as well.
if ( reactive . Reactions ! = null )
{
foreach ( var entry in reactive . Reactions )
2021-11-10 03:11:28 -07:00
{
2021-11-22 02:17:35 -07:00
if ( ! entry . Methods . Contains ( method ) )
2021-11-10 03:11:28 -07:00
continue ;
2021-11-22 02:17:35 -07:00
if ( entry . Reagents ! = null & & ! entry . Reagents . Contains ( reagent . ID ) )
continue ;
foreach ( var effect in entry . Effects )
{
if ( ! effect . ShouldApply ( args , _robustRandom ) )
continue ;
2021-11-27 00:31:56 -07:00
if ( effect . ShouldLog )
{
2021-12-05 18:09:01 +01:00
var entity = args . SolutionEntity ;
2021-11-27 00:31:56 -07:00
_logSystem . Add ( LogType . ReagentEffect , effect . LogImpact ,
2021-12-14 00:22:58 +13:00
$"Reactive effect {effect.GetType().Name:effect} of {ToPrettyString(entity):entity} using reagent {reagent.ID:reagent} with method {method} at {Transform(entity).Coordinates:coordinates}" ) ;
2021-11-27 00:31:56 -07:00
}
2021-11-27 01:27:47 -07:00
effect . Effect ( args ) ;
2021-11-22 02:17:35 -07:00
}
2021-11-10 03:11:28 -07:00
}
2021-03-26 12:02:41 +01:00
}
}
2020-04-08 15:53:15 +05:00
}
}