SolutionContainer refactors (#2954)
* removes unused method * Code uncluttering (Also removed the netcode, color code, and visuals, need to rewrite) * SolutionContainerVisualState * Removes caching of SolutionContainer Color * ChemicalsAdded() and ChemicalsRemoved() for updating appearance and handling reaction checks * SolutionContainerComponentState * Netcode * ChemMasterComponent no longer creates a SolutionContainerComponent with new(), uses a Solution instead * Enable nullable in SolutionContainer implementations * Some review fixes * uses IReadOnlyLists in ChemMaster * Comments * review fixes 3 * ReagentUnit documentation * Review fixes * spelling fix * spelling 2 * typo Co-authored-by: py01 <pyronetics01@gmail.com>
This commit is contained in:
@@ -1,144 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Server.Chemistry;
|
||||
#nullable enable
|
||||
using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.GameObjects.Components.Chemistry;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.EntitySystems.ActionBlocker;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Chemistry
|
||||
{
|
||||
/// <summary>
|
||||
/// ECS component that manages a liquid solution of reagents.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedSolutionContainerComponent))]
|
||||
public class SolutionContainerComponent : SharedSolutionContainerComponent, IExamine
|
||||
public class SolutionContainerComponent : SharedSolutionContainerComponent
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||
|
||||
private IEnumerable<ReactionPrototype> _reactions;
|
||||
private ChemicalReactionSystem _reactionSystem;
|
||||
private string _fillInitState;
|
||||
private int _fillInitSteps;
|
||||
private string _fillPathString = "Objects/Specific/Chemistry/fillings.rsi";
|
||||
private ResourcePath _fillPath;
|
||||
private SpriteSpecifier _fillSprite;
|
||||
private AudioSystem _audioSystem;
|
||||
private ChemistrySystem _chemistrySystem;
|
||||
private SpriteComponent _spriteComponent;
|
||||
|
||||
/// <summary>
|
||||
/// The volume without reagents remaining in the container.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public ReagentUnit EmptyVolume => MaxVolume - CurrentVolume;
|
||||
public IReadOnlyList<Solution.ReagentQuantity> ReagentList => Solution.Contents;
|
||||
public bool CanExamineContents => Capabilities.HasCap(SolutionContainerCaps.CanExamine);
|
||||
public bool CanUseWithChemDispenser => Capabilities.HasCap(SolutionContainerCaps.FitsInDispenser);
|
||||
public bool CanAddSolutions => Capabilities.HasCap(SolutionContainerCaps.AddTo);
|
||||
public bool CanRemoveSolutions => Capabilities.HasCap(SolutionContainerCaps.RemoveFrom);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
serializer.DataField(this, x => x.MaxVolume, "maxVol", ReagentUnit.New(0));
|
||||
serializer.DataField(this, x => x.Solution, "contents", new Solution());
|
||||
serializer.DataField(this, x => x.Capabilities, "caps", SolutionContainerCaps.AddTo | SolutionContainerCaps.RemoveFrom | SolutionContainerCaps.CanExamine);
|
||||
serializer.DataField(ref _fillInitState, "fillingState", string.Empty);
|
||||
serializer.DataField(ref _fillInitSteps, "fillingSteps", 7);
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_audioSystem = EntitySystem.Get<AudioSystem>();
|
||||
_chemistrySystem = _entitySystemManager.GetEntitySystem<ChemistrySystem>();
|
||||
_reactions = _prototypeManager.EnumeratePrototypes<ReactionPrototype>();
|
||||
_reactionSystem = _entitySystemManager.GetEntitySystem<ChemicalReactionSystem>();
|
||||
}
|
||||
|
||||
protected override void Startup()
|
||||
{
|
||||
base.Startup();
|
||||
RecalculateColor();
|
||||
if (!string.IsNullOrEmpty(_fillInitState))
|
||||
{
|
||||
_spriteComponent = Owner.GetComponent<SpriteComponent>();
|
||||
_fillPath = new ResourcePath(_fillPathString);
|
||||
_fillSprite = new SpriteSpecifier.Rsi(_fillPath, _fillInitState + (_fillInitSteps - 1));
|
||||
_spriteComponent.AddLayerWithSprite(_fillSprite);
|
||||
UpdateFillIcon();
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAllSolution()
|
||||
{
|
||||
Solution.RemoveAllSolution();
|
||||
OnSolutionChanged(false);
|
||||
}
|
||||
|
||||
public override bool TryRemoveReagent(string reagentId, ReagentUnit quantity)
|
||||
{
|
||||
if (!Solution.ContainsReagent(reagentId, out var currentQuantity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Solution.RemoveReagent(reagentId, quantity);
|
||||
OnSolutionChanged(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to remove the specified quantity from this solution
|
||||
/// </summary>
|
||||
/// <param name="quantity">Quantity of this solution to remove</param>
|
||||
/// <returns>Whether or not the solution was successfully removed</returns>
|
||||
public bool TryRemoveSolution(ReagentUnit quantity)
|
||||
{
|
||||
if (CurrentVolume == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Solution.RemoveSolution(quantity);
|
||||
OnSolutionChanged(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Solution SplitSolution(ReagentUnit quantity)
|
||||
{
|
||||
var solutionSplit = Solution.SplitSolution(quantity);
|
||||
OnSolutionChanged(false);
|
||||
return solutionSplit;
|
||||
}
|
||||
|
||||
protected void RecalculateColor()
|
||||
{
|
||||
SubstanceColor = Solution.Color;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transfers solution from the held container to the target container.
|
||||
/// </summary>
|
||||
@@ -195,43 +70,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
}
|
||||
}
|
||||
|
||||
void IExamine.Examine(FormattedMessage message, bool inDetailsRange)
|
||||
{
|
||||
if (!CanExamineContents)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReagentList.Count == 0)
|
||||
{
|
||||
message.AddText(Loc.GetString("It's empty."));
|
||||
}
|
||||
else if (ReagentList.Count == 1)
|
||||
{
|
||||
var reagent = ReagentList[0];
|
||||
|
||||
if (_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype proto))
|
||||
{
|
||||
message.AddMarkup(
|
||||
Loc.GetString("It contains a [color={0}]{1}[/color] substance.",
|
||||
proto.GetSubstanceTextColor().ToHexNoAlpha(),
|
||||
Loc.GetString(proto.PhysicalDescription)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var reagent = ReagentList.Max();
|
||||
|
||||
if (_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype proto))
|
||||
{
|
||||
message.AddMarkup(
|
||||
Loc.GetString("It contains a [color={0}]{1}[/color] mixture of substances.",
|
||||
SubstanceColor.ToHexNoAlpha(),
|
||||
Loc.GetString(proto.PhysicalDescription)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transfers solution from a target container to the held container.
|
||||
/// </summary>
|
||||
@@ -288,86 +126,5 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
handSolutionComp.TryAddSolution(transferSolution);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckForReaction()
|
||||
{
|
||||
_reactionSystem.FullyReactSolution(Solution, Owner, MaxVolume);
|
||||
}
|
||||
|
||||
public bool TryAddReagent(string reagentId, ReagentUnit quantity, out ReagentUnit acceptedQuantity, bool skipReactionCheck = false, bool skipColor = false)
|
||||
{
|
||||
var toAcceptQuantity = MaxVolume - Solution.TotalVolume;
|
||||
if (quantity > toAcceptQuantity)
|
||||
{
|
||||
acceptedQuantity = toAcceptQuantity;
|
||||
if (acceptedQuantity == 0) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
acceptedQuantity = quantity;
|
||||
}
|
||||
|
||||
Solution.AddReagent(reagentId, acceptedQuantity);
|
||||
if (!skipColor) {
|
||||
RecalculateColor();
|
||||
}
|
||||
if(!skipReactionCheck)
|
||||
CheckForReaction();
|
||||
OnSolutionChanged(skipColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CanAddSolution(Solution solution)
|
||||
{
|
||||
return solution.TotalVolume <= (MaxVolume - Solution.TotalVolume);
|
||||
}
|
||||
|
||||
public override bool TryAddSolution(Solution solution, bool skipReactionCheck = false, bool skipColor = false)
|
||||
{
|
||||
if (!CanAddSolution(solution))
|
||||
return false;
|
||||
|
||||
Solution.AddSolution(solution);
|
||||
if (!skipColor) {
|
||||
RecalculateColor();
|
||||
}
|
||||
if(!skipReactionCheck)
|
||||
CheckForReaction();
|
||||
OnSolutionChanged(skipColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void UpdateFillIcon()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_fillInitState))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var percentage = (CurrentVolume / MaxVolume).Double();
|
||||
var level = ContentHelpers.RoundToLevels(percentage * 100, 100, _fillInitSteps);
|
||||
|
||||
//Transformed glass uses special fancy sprites so we don't bother
|
||||
if (level == 0 || (Owner.TryGetComponent<TransformableContainerComponent>(out var transformComp) && transformComp.Transformed))
|
||||
{
|
||||
_spriteComponent.LayerSetColor(1, Color.Transparent);
|
||||
return;
|
||||
}
|
||||
|
||||
_fillSprite = new SpriteSpecifier.Rsi(_fillPath, _fillInitState + level);
|
||||
_spriteComponent.LayerSetSprite(1, _fillSprite);
|
||||
_spriteComponent.LayerSetColor(1, SubstanceColor);
|
||||
}
|
||||
|
||||
protected virtual void OnSolutionChanged(bool skipColor)
|
||||
{
|
||||
if (!skipColor)
|
||||
{
|
||||
RecalculateColor();
|
||||
}
|
||||
|
||||
UpdateFillIcon();
|
||||
_chemistrySystem.HandleSolutionChange(Owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user