2021-09-06 15:49:44 +02:00
using System.Diagnostics.CodeAnalysis ;
2022-12-20 04:05:02 +00:00
using System.Linq ;
2021-10-29 13:40:15 +01:00
using Content.Server.Chemistry.Components.SolutionManager ;
using Content.Shared.Chemistry ;
2021-09-06 15:49:44 +02:00
using Content.Shared.Chemistry.Components ;
using Content.Shared.Chemistry.Reaction ;
using Content.Shared.Chemistry.Reagent ;
using Content.Shared.Examine ;
2021-11-03 16:48:03 -07:00
using Content.Shared.FixedPoint ;
2021-09-06 15:49:44 +02:00
using JetBrains.Annotations ;
using Robust.Shared.Prototypes ;
2022-12-20 04:05:02 +00:00
using Robust.Shared.Utility ;
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
namespace Content.Server.Chemistry.EntitySystems ;
/// <summary>
/// This event alerts system that the solution was changed
/// </summary>
public sealed class SolutionChangedEvent : EntityEventArgs
2021-09-06 15:49:44 +02:00
{
2023-01-01 19:03:26 +13:00
public readonly Solution Solution ;
public SolutionChangedEvent ( Solution solution )
{
Solution = solution ;
}
2022-02-18 03:42:39 +01:00
}
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
/// <summary>
/// Part of Chemistry system deal with SolutionContainers
/// </summary>
[UsedImplicitly]
public sealed partial class SolutionContainerSystem : EntitySystem
{
[Dependency]
private readonly SharedChemicalReactionSystem _chemistrySystem = default ! ;
2021-09-06 15:49:44 +02:00
2023-01-14 13:21:15 +13:00
[Dependency] private readonly SharedAppearanceSystem _appearance = default ! ;
2022-02-18 03:42:39 +01:00
[Dependency]
private readonly IPrototypeManager _prototypeManager = default ! ;
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
public override void Initialize ( )
{
base . Initialize ( ) ;
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
SubscribeLocalEvent < SolutionContainerManagerComponent , ComponentInit > ( InitSolution ) ;
SubscribeLocalEvent < ExaminableSolutionComponent , ExaminedEvent > ( OnExamineSolution ) ;
}
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
private void InitSolution ( EntityUid uid , SolutionContainerManagerComponent component , ComponentInit args )
{
2022-04-05 04:02:33 +12:00
foreach ( var ( name , solutionHolder ) in component . Solutions )
2021-09-06 15:49:44 +02:00
{
2022-04-05 04:02:33 +12:00
solutionHolder . Name = name ;
2023-01-12 16:41:40 +13:00
solutionHolder . ValidateSolution ( ) ;
2022-02-18 03:42:39 +01:00
UpdateAppearance ( uid , solutionHolder ) ;
2021-09-06 15:49:44 +02:00
}
2022-02-18 03:42:39 +01:00
}
private void OnExamineSolution ( EntityUid uid , ExaminableSolutionComponent examinableComponent ,
ExaminedEvent args )
{
SolutionContainerManagerComponent ? solutionsManager = null ;
if ( ! Resolve ( args . Examined , ref solutionsManager )
| | ! solutionsManager . Solutions . TryGetValue ( examinableComponent . Solution , out var solutionHolder ) )
return ;
2021-09-06 15:49:44 +02:00
2023-01-12 16:41:40 +13:00
var primaryReagent = solutionHolder . GetPrimaryReagentId ( ) ;
if ( string . IsNullOrEmpty ( primaryReagent ) )
2021-09-06 15:49:44 +02:00
{
2022-02-18 03:42:39 +01:00
args . PushText ( Loc . GetString ( "shared-solution-container-component-on-examine-empty-container" ) ) ;
return ;
}
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
if ( ! _prototypeManager . TryIndex ( primaryReagent , out ReagentPrototype ? proto ) )
{
Logger . Error (
$"{nameof(Solution)} could not find the prototype associated with {primaryReagent}." ) ;
return ;
}
2021-09-06 15:49:44 +02:00
2023-01-12 16:41:40 +13:00
var colorHex = solutionHolder . GetColor ( _prototypeManager )
2022-02-18 03:42:39 +01:00
. ToHexNoAlpha ( ) ; //TODO: If the chem has a dark color, the examine text becomes black on a black background, which is unreadable.
var messageString = "shared-solution-container-component-on-examine-main-text" ;
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
args . PushMarkup ( Loc . GetString ( messageString ,
( "color" , colorHex ) ,
( "wordedAmount" , Loc . GetString ( solutionHolder . Contents . Count = = 1
? "shared-solution-container-component-on-examine-worded-amount-one-reagent"
: "shared-solution-container-component-on-examine-worded-amount-multiple-reagents" ) ) ,
2022-05-12 14:06:01 +03:00
( "desc" , proto . LocalizedPhysicalDescription ) ) ) ;
2022-02-18 03:42:39 +01:00
}
2021-09-06 15:49:44 +02:00
2022-03-25 17:17:29 +13:00
public void UpdateAppearance ( EntityUid uid , Solution solution ,
2022-02-18 03:42:39 +01:00
AppearanceComponent ? appearanceComponent = null )
{
if ( ! EntityManager . EntityExists ( uid )
| | ! Resolve ( uid , ref appearanceComponent , false ) )
return ;
2021-09-06 15:49:44 +02:00
2023-01-14 13:21:15 +13:00
_appearance . SetData ( uid , SolutionContainerVisuals . FillFraction , solution . FillFraction , appearanceComponent ) ;
_appearance . SetData ( uid , SolutionContainerVisuals . Color , solution . GetColor ( _prototypeManager ) , appearanceComponent ) ;
2023-02-18 19:00:31 -06:00
if ( solution . GetPrimaryReagentId ( ) is { } reagent )
{
_appearance . SetData ( uid , SolutionContainerVisuals . BaseOverride , reagent , appearanceComponent ) ;
}
else
{
_appearance . SetData ( uid , SolutionContainerVisuals . BaseOverride , string . Empty , appearanceComponent ) ;
}
2022-02-18 03:42:39 +01:00
}
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
/// <summary>
/// Removes part of the solution in the container.
/// </summary>
/// <param name="targetUid"></param>
/// <param name="solutionHolder"></param>
/// <param name="quantity">the volume of solution to remove.</param>
/// <returns>The solution that was removed.</returns>
public Solution SplitSolution ( EntityUid targetUid , Solution solutionHolder , FixedPoint2 quantity )
{
var splitSol = solutionHolder . SplitSolution ( quantity ) ;
UpdateChemicals ( targetUid , solutionHolder ) ;
return splitSol ;
}
2021-09-06 15:49:44 +02:00
2022-12-20 04:05:02 +00:00
public void UpdateChemicals ( EntityUid uid , Solution solutionHolder , bool needsReactionsProcessing = false , ReactionMixerComponent ? mixerComponent = null )
2022-02-18 03:42:39 +01:00
{
2023-01-01 19:03:26 +13:00
DebugTools . Assert ( solutionHolder . Name ! = null & & TryGetSolution ( uid , solutionHolder . Name , out var tmp ) & & tmp = = solutionHolder ) ;
2022-02-18 03:42:39 +01:00
// Process reactions
if ( needsReactionsProcessing & & solutionHolder . CanReact )
2021-09-06 15:49:44 +02:00
{
2022-12-20 04:05:02 +00:00
_chemistrySystem . FullyReactSolution ( solutionHolder , uid , solutionHolder . MaxVolume , mixerComponent ) ;
2021-09-06 15:49:44 +02:00
}
2022-02-18 03:42:39 +01:00
UpdateAppearance ( uid , solutionHolder ) ;
2023-01-01 19:03:26 +13:00
RaiseLocalEvent ( uid , new SolutionChangedEvent ( solutionHolder ) ) ;
2022-02-18 03:42:39 +01:00
}
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
public void RemoveAllSolution ( EntityUid uid , Solution solutionHolder )
{
2023-01-12 16:41:40 +13:00
if ( solutionHolder . Volume = = 0 )
2022-02-18 03:42:39 +01:00
return ;
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
solutionHolder . RemoveAllSolution ( ) ;
UpdateChemicals ( uid , solutionHolder ) ;
}
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
public void RemoveAllSolution ( EntityUid uid , SolutionContainerManagerComponent ? solutionContainerManager = null )
{
if ( ! Resolve ( uid , ref solutionContainerManager ) )
return ;
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
foreach ( var solution in solutionContainerManager . Solutions . Values )
2021-09-06 15:49:44 +02:00
{
2022-02-18 03:42:39 +01:00
RemoveAllSolution ( uid , solution ) ;
2021-09-06 15:49:44 +02:00
}
2022-02-18 03:42:39 +01:00
}
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
/// <summary>
/// Sets the capacity (maximum volume) of a solution to a new value.
/// </summary>
/// <param name="targetUid">The entity containing the solution.</param>
/// <param name="targetSolution">The solution to set the capacity of.</param>
/// <param name="capacity">The value to set the capacity of the solution to.</param>
public void SetCapacity ( EntityUid targetUid , Solution targetSolution , FixedPoint2 capacity )
{
if ( targetSolution . MaxVolume = = capacity )
return ;
2021-12-24 01:22:34 -08:00
2022-02-18 03:42:39 +01:00
targetSolution . MaxVolume = capacity ;
2023-01-12 16:41:40 +13:00
if ( capacity < targetSolution . Volume )
targetSolution . RemoveSolution ( targetSolution . Volume - capacity ) ;
2021-12-24 01:22:34 -08:00
2022-02-18 03:42:39 +01:00
UpdateChemicals ( targetUid , targetSolution ) ;
}
2021-12-24 01:22:34 -08:00
2022-02-18 03:42:39 +01:00
/// <summary>
/// Adds reagent of an Id to the container.
/// </summary>
/// <param name="targetUid"></param>
/// <param name="targetSolution">Container to which we are adding reagent</param>
/// <param name="reagentId">The Id of the reagent to add.</param>
/// <param name="quantity">The amount of reagent to add.</param>
/// <param name="acceptedQuantity">The amount of reagent successfully added.</param>
/// <returns>If all the reagent could be added.</returns>
public bool TryAddReagent ( EntityUid targetUid , Solution targetSolution , string reagentId , FixedPoint2 quantity ,
out FixedPoint2 acceptedQuantity , float? temperature = null )
{
acceptedQuantity = targetSolution . AvailableVolume > quantity ? quantity : targetSolution . AvailableVolume ;
2021-09-06 15:49:44 +02:00
2023-01-12 16:41:40 +13:00
if ( acceptedQuantity < = 0 )
return quantity = = 0 ;
2021-09-06 15:49:44 +02:00
2023-01-12 16:41:40 +13:00
if ( temperature = = null )
targetSolution . AddReagent ( reagentId , acceptedQuantity ) ;
else
targetSolution . AddReagent ( _prototypeManager . Index < ReagentPrototype > ( reagentId ) , acceptedQuantity , temperature . Value , _prototypeManager ) ;
UpdateChemicals ( targetUid , targetSolution , true ) ;
2022-02-18 03:42:39 +01:00
return acceptedQuantity = = quantity ;
}
2021-09-06 15:49:44 +02:00
2023-01-12 16:41:40 +13:00
2022-02-18 03:42:39 +01:00
/// <summary>
/// Removes reagent of an Id to the container.
/// </summary>
/// <param name="targetUid"></param>
/// <param name="container">Solution container from which we are removing reagent</param>
/// <param name="reagentId">The Id of the reagent to remove.</param>
/// <param name="quantity">The amount of reagent to remove.</param>
/// <returns>If the reagent to remove was found in the container.</returns>
public bool TryRemoveReagent ( EntityUid targetUid , Solution ? container , string reagentId , FixedPoint2 quantity )
{
if ( container = = null | | ! container . ContainsReagent ( reagentId ) )
return false ;
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
container . RemoveReagent ( reagentId , quantity ) ;
UpdateChemicals ( targetUid , container ) ;
return true ;
}
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
/// <summary>
/// Adds a solution to the container, if it can fully fit.
/// </summary>
/// <param name="targetUid">entity holding targetSolution</param>
/// <param name="targetSolution">entity holding targetSolution</param>
/// <param name="addedSolution">solution being added</param>
/// <returns>If the solution could be added.</returns>
public bool TryAddSolution ( EntityUid targetUid , Solution ? targetSolution , Solution addedSolution )
{
if ( targetSolution = = null
2023-01-12 16:41:40 +13:00
| | ! targetSolution . CanAddSolution ( addedSolution ) | | addedSolution . Volume = = 0 )
2022-02-18 03:42:39 +01:00
return false ;
2022-02-15 03:22:26 +01:00
2023-01-12 16:41:40 +13:00
targetSolution . AddSolution ( addedSolution , _prototypeManager ) ;
2022-02-18 03:42:39 +01:00
UpdateChemicals ( targetUid , targetSolution , true ) ;
return true ;
}
2022-02-15 03:22:26 +01:00
2023-01-01 19:03:26 +13:00
/// <summary>
/// Moves some quantity of a solution from one solution to another.
/// </summary>
/// <param name="sourceUid">entity holding the source solution</param>
/// <param name="targetUid">entity holding the target solution</param>
/// <param name="source">source solution</param>
/// <param name="target">target solution</param>
/// <param name="quantity">quantity of solution to move from source to target. If this is a negative number, the source & target roles are reversed.</param>
public bool TryTransferSolution ( EntityUid sourceUid , EntityUid targetUid , Solution source , Solution target , FixedPoint2 quantity )
{
if ( quantity < 0 )
return TryTransferSolution ( targetUid , sourceUid , target , source , - quantity ) ;
2023-01-12 16:41:40 +13:00
quantity = FixedPoint2 . Min ( quantity , target . AvailableVolume , source . Volume ) ;
2023-01-01 19:03:26 +13:00
if ( quantity = = 0 )
return false ;
2023-01-12 16:41:40 +13:00
// TODO This should be made into a function that directly transfers reagents. currently this is quite
// inefficient.
target . AddSolution ( source . SplitSolution ( quantity ) , _prototypeManager ) ;
2023-01-01 19:03:26 +13:00
UpdateChemicals ( sourceUid , source , false ) ;
UpdateChemicals ( targetUid , target , true ) ;
return true ;
}
/// <summary>
/// Moves some quantity of a solution from one solution to another.
/// </summary>
/// <param name="sourceUid">entity holding the source solution</param>
/// <param name="targetUid">entity holding the target solution</param>
/// <param name="source">source solution</param>
/// <param name="target">target solution</param>
/// <param name="quantity">quantity of solution to move from source to target. If this is a negative number, the source & target roles are reversed.</param>
public bool TryTransferSolution ( EntityUid sourceUid , EntityUid targetUid , string source , string target , FixedPoint2 quantity )
{
if ( ! TryGetSolution ( sourceUid , source , out var sourceSoln ) )
return false ;
if ( ! TryGetSolution ( targetUid , target , out var targetSoln ) )
return false ;
return TryTransferSolution ( sourceUid , targetUid , sourceSoln , targetSoln , quantity ) ;
}
2022-02-18 03:42:39 +01:00
/// <summary>
/// Adds a solution to the container, overflowing the rest.
/// It will
/// Unlike <see cref="TryAddSolution"/> it will ignore size limits.
/// </summary>
/// <param name="targetUid">entity holding targetSolution</param>
/// <param name="targetSolution">The container to which we try to add.</param>
/// <param name="addedSolution">solution being added</param>
/// <param name="overflowThreshold">After addition this much will be left in targetSolution. Should be less
/// than targetSolution.TotalVolume</param>
/// <param name="overflowingSolution">Solution that exceeded overflowThreshold</param>
/// <returns></returns>
public bool TryMixAndOverflow ( EntityUid targetUid , Solution targetSolution ,
Solution addedSolution ,
FixedPoint2 overflowThreshold ,
[NotNullWhen(true)] out Solution ? overflowingSolution )
{
2023-01-12 16:41:40 +13:00
if ( addedSolution . Volume = = 0 | | overflowThreshold > targetSolution . MaxVolume )
2021-09-06 15:49:44 +02:00
{
2022-02-18 03:42:39 +01:00
overflowingSolution = null ;
return false ;
2021-09-06 15:49:44 +02:00
}
2023-01-12 16:41:40 +13:00
targetSolution . AddSolution ( addedSolution , _prototypeManager ) ;
2022-02-18 03:42:39 +01:00
UpdateChemicals ( targetUid , targetSolution , true ) ;
overflowingSolution = targetSolution . SplitSolution ( FixedPoint2 . Max ( FixedPoint2 . Zero ,
2023-01-12 16:41:40 +13:00
targetSolution . Volume - overflowThreshold ) ) ;
2022-02-18 03:42:39 +01:00
return true ;
}
public bool TryGetSolution ( EntityUid uid , string name ,
[NotNullWhen(true)] out Solution ? solution ,
SolutionContainerManagerComponent ? solutionsMgr = null )
{
if ( ! Resolve ( uid , ref solutionsMgr , false ) )
2021-09-06 15:49:44 +02:00
{
2022-02-18 03:42:39 +01:00
solution = null ;
return false ;
}
2021-09-06 15:49:44 +02:00
2022-02-18 03:42:39 +01:00
return solutionsMgr . Solutions . TryGetValue ( name , out solution ) ;
}
2023-01-12 16:41:40 +13:00
2022-02-18 03:42:39 +01:00
/// <summary>
/// Will ensure a solution is added to given entity even if it's missing solutionContainerManager
/// </summary>
/// <param name="uid">EntityUid to which to add solution</param>
/// <param name="name">name for the solution</param>
/// <param name="solutionsMgr">solution components used in resolves</param>
2023-01-12 16:41:40 +13:00
/// <param name="existed">true if the solution already existed</param>
2022-02-18 03:42:39 +01:00
/// <returns>solution</returns>
2023-01-12 16:41:40 +13:00
public Solution EnsureSolution ( EntityUid uid , string name , out bool existed ,
2022-02-18 03:42:39 +01:00
SolutionContainerManagerComponent ? solutionsMgr = null )
{
if ( ! Resolve ( uid , ref solutionsMgr , false ) )
{
solutionsMgr = EntityManager . EnsureComponent < SolutionContainerManagerComponent > ( uid ) ;
2021-09-06 15:49:44 +02:00
}
2023-01-12 16:41:40 +13:00
if ( ! solutionsMgr . Solutions . TryGetValue ( name , out var existing ) )
2021-10-27 09:24:18 +01:00
{
2022-04-05 04:02:33 +12:00
var newSolution = new Solution ( ) { Name = name } ;
2022-02-18 03:42:39 +01:00
solutionsMgr . Solutions . Add ( name , newSolution ) ;
2023-01-12 16:41:40 +13:00
existed = false ;
return newSolution ;
2022-02-18 03:42:39 +01:00
}
2021-10-27 09:24:18 +01:00
2023-01-12 16:41:40 +13:00
existed = true ;
return existing ;
2022-02-18 03:42:39 +01:00
}
2021-09-06 15:49:44 +02:00
2023-01-12 16:41:40 +13:00
/// <summary>
/// Will ensure a solution is added to given entity even if it's missing solutionContainerManager
/// </summary>
/// <param name="uid">EntityUid to which to add solution</param>
/// <param name="name">name for the solution</param>
/// <param name="solutionsMgr">solution components used in resolves</param>
/// <returns>solution</returns>
public Solution EnsureSolution ( EntityUid uid , string name , SolutionContainerManagerComponent ? solutionsMgr = null )
= > EnsureSolution ( uid , name , out _ , solutionsMgr ) ;
/// <summary>
/// Will ensure a solution is added to given entity even if it's missing solutionContainerManager
/// </summary>
/// <param name="uid">EntityUid to which to add solution</param>
/// <param name="name">name for the solution</param>
2023-01-19 03:56:45 +01:00
/// <param name="minVol">Ensures that the solution's maximum volume is larger than this value.</param>
2023-01-12 16:41:40 +13:00
/// <param name="solutionsMgr">solution components used in resolves</param>
/// <returns>solution</returns>
public Solution EnsureSolution ( EntityUid uid , string name , FixedPoint2 minVol , out bool existed ,
SolutionContainerManagerComponent ? solutionsMgr = null )
{
if ( ! Resolve ( uid , ref solutionsMgr , false ) )
{
solutionsMgr = EntityManager . EnsureComponent < SolutionContainerManagerComponent > ( uid ) ;
}
if ( ! solutionsMgr . Solutions . TryGetValue ( name , out var existing ) )
{
var newSolution = new Solution ( ) { Name = name } ;
solutionsMgr . Solutions . Add ( name , newSolution ) ;
existed = false ;
newSolution . MaxVolume = minVol ;
return newSolution ;
}
existed = true ;
existing . MaxVolume = FixedPoint2 . Max ( existing . MaxVolume , minVol ) ;
return existing ;
}
public Solution EnsureSolution ( EntityUid uid , string name ,
IEnumerable < Solution . ReagentQuantity > reagents ,
bool setMaxVol = true ,
SolutionContainerManagerComponent ? solutionsMgr = null )
{
if ( ! Resolve ( uid , ref solutionsMgr , false ) )
solutionsMgr = EntityManager . EnsureComponent < SolutionContainerManagerComponent > ( uid ) ;
2023-01-19 03:56:45 +01:00
2023-01-12 16:41:40 +13:00
if ( ! solutionsMgr . Solutions . TryGetValue ( name , out var existing ) )
{
var newSolution = new Solution ( reagents , setMaxVol ) ;
solutionsMgr . Solutions . Add ( name , newSolution ) ;
return newSolution ;
}
existing . SetContents ( reagents , setMaxVol ) ;
return existing ;
}
2022-03-23 14:05:10 +01:00
/// <summary>
/// Removes an amount from all reagents in a solution, adding it to a new solution.
/// </summary>
/// <param name="uid">The entity containing the solution.</param>
/// <param name="solution">The solution to remove reagents from.</param>
/// <param name="quantity">The amount to remove from every reagent in the solution.</param>
/// <returns>A new solution containing every removed reagent from the original solution.</returns>
public Solution RemoveEachReagent ( EntityUid uid , Solution solution , FixedPoint2 quantity )
2022-02-18 03:42:39 +01:00
{
if ( quantity < = 0 )
2022-03-23 14:05:10 +01:00
return new Solution ( ) ;
2021-09-06 15:49:44 +02:00
2022-03-23 14:05:10 +01:00
var removedSolution = new Solution ( ) ;
// RemoveReagent does a RemoveSwap, meaning we don't have to copy the list if we iterate it backwards.
for ( var i = solution . Contents . Count - 1 ; i > = 0 ; i - - )
2021-09-06 15:49:44 +02:00
{
2022-03-23 14:05:10 +01:00
var ( reagentId , _ ) = solution . Contents [ i ] ;
2021-09-06 15:49:44 +02:00
2022-03-23 14:05:10 +01:00
var removedQuantity = solution . RemoveReagent ( reagentId , quantity ) ;
if ( removedQuantity > 0 )
removedSolution . AddReagent ( reagentId , removedQuantity ) ;
2021-09-06 15:49:44 +02:00
}
2022-02-18 03:42:39 +01:00
UpdateChemicals ( uid , solution ) ;
2022-03-23 14:05:10 +01:00
return removedSolution ;
2022-02-18 03:42:39 +01:00
}
public FixedPoint2 GetReagentQuantity ( EntityUid owner , string reagentId )
{
var reagentQuantity = FixedPoint2 . New ( 0 ) ;
if ( EntityManager . EntityExists ( owner )
& & EntityManager . TryGetComponent ( owner , out SolutionContainerManagerComponent ? managerComponent ) )
2021-09-06 15:49:44 +02:00
{
2022-02-18 03:42:39 +01:00
foreach ( var solution in managerComponent . Solutions . Values )
2021-09-06 15:49:44 +02:00
{
2022-02-18 03:42:39 +01:00
reagentQuantity + = solution . GetReagentQuantity ( reagentId ) ;
2021-09-06 15:49:44 +02:00
}
}
2021-12-24 01:22:34 -08:00
2022-02-18 03:42:39 +01:00
return reagentQuantity ;
}
2021-12-24 01:22:34 -08:00
2022-12-20 04:05:02 +00:00
public bool TryGetMixableSolution ( EntityUid uid ,
[NotNullWhen(true)] out Solution ? solution ,
SolutionContainerManagerComponent ? solutionsMgr = null )
{
if ( ! Resolve ( uid , ref solutionsMgr , false ) )
{
solution = null ;
return false ;
}
var getMixableSolutionAttempt = new GetMixableSolutionAttemptEvent ( uid ) ;
RaiseLocalEvent ( uid , ref getMixableSolutionAttempt ) ;
if ( getMixableSolutionAttempt . MixedSolution ! = null )
{
solution = getMixableSolutionAttempt . MixedSolution ;
return true ;
}
var tryGetSolution = solutionsMgr . Solutions . FirstOrNull ( x = > x . Value . CanMix ) ;
if ( tryGetSolution . HasValue )
{
solution = tryGetSolution . Value . Value ;
return true ;
}
solution = null ;
return false ;
}
2021-12-24 01:22:34 -08:00
2022-02-18 03:42:39 +01:00
// Thermal energy and temperature management.
2021-12-24 01:22:34 -08:00
2022-02-18 03:42:39 +01:00
#region Thermal Energy and Temperature
2021-12-24 01:22:34 -08:00
2022-02-18 03:42:39 +01:00
/// <summary>
/// Sets the temperature of a solution to a new value and then checks for reaction processing.
/// </summary>
/// <param name="owner">The entity in which the solution is located.</param>
/// <param name="solution">The solution to set the temperature of.</param>
/// <param name="temperature">The new value to set the temperature to.</param>
public void SetTemperature ( EntityUid owner , Solution solution , float temperature )
{
if ( temperature = = solution . Temperature )
return ;
2021-12-24 01:22:34 -08:00
2022-02-18 03:42:39 +01:00
solution . Temperature = temperature ;
UpdateChemicals ( owner , solution , true ) ;
}
2021-12-24 01:22:34 -08:00
2022-02-18 03:42:39 +01:00
/// <summary>
/// Sets the thermal energy of a solution to a new value and then checks for reaction processing.
/// </summary>
/// <param name="owner">The entity in which the solution is located.</param>
/// <param name="solution">The solution to set the thermal energy of.</param>
/// <param name="thermalEnergy">The new value to set the thermal energy to.</param>
public void SetThermalEnergy ( EntityUid owner , Solution solution , float thermalEnergy )
{
2023-01-12 16:41:40 +13:00
var heatCap = solution . GetHeatCapacity ( _prototypeManager ) ;
solution . Temperature = heatCap = = 0 ? 0 : thermalEnergy / heatCap ;
2022-02-18 03:42:39 +01:00
UpdateChemicals ( owner , solution , true ) ;
}
/// <summary>
/// Adds some thermal energy to a solution and then checks for reaction processing.
/// </summary>
/// <param name="owner">The entity in which the solution is located.</param>
/// <param name="solution">The solution to set the thermal energy of.</param>
/// <param name="thermalEnergy">The new value to set the thermal energy to.</param>
public void AddThermalEnergy ( EntityUid owner , Solution solution , float thermalEnergy )
{
if ( thermalEnergy = = 0.0f )
return ;
2021-12-24 01:22:34 -08:00
2023-01-12 16:41:40 +13:00
var heatCap = solution . GetHeatCapacity ( _prototypeManager ) ;
solution . Temperature + = heatCap = = 0 ? 0 : thermalEnergy / heatCap ;
2022-02-18 03:42:39 +01:00
UpdateChemicals ( owner , solution , true ) ;
2021-09-06 15:49:44 +02:00
}
2022-02-18 03:42:39 +01:00
#endregion Thermal Energy and Temperature
2021-09-06 15:49:44 +02:00
}