Files
OldThink/Content.Shared/Chemistry/Solution/Solution.cs

391 lines
12 KiB
C#
Raw Normal View History

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
2021-06-09 22:19:39 +02:00
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
Serialization v3 content PR (#3491) * serv3 in shared pt 1 * beginning of deepclone api * progress in implementing ideepclone & serv3 in content * adds target * its cant hurt you it cant hurt you * more changes to content.server * adds dataclasses * almost there * renamed & edited entry * finishes refactoring content to use serv3 * gasmixture runtimes, next: reagentunit * fucin hell that was an annoying one * adds flags * fixes some yaml errors * removes comment * fixes generic components for now * removes todo actually clones values my god paul fixes bug involving resolving custom data classes from other proj renames dataclass fixes spritecomp adds WithFormat.Constants support * adds deepclone to ResistanceSet * adds a bunch of deepclone implementations adds a deepclone analyzer (TODO) adds a deep clone fallback for classes & structs * fixes a bunch of runtimes * adds deepclone to entityuid * adds generator to sln * gets rid of warnings * fixes * argh * componentdata refactors * more deepclone impl * heck me i reworked all of content deepclone * renames custom dataclasstarget * misc * reworks prototypes * deepclone nuke * renamed customdataclass attribute * fixes everything * misc fixed * the killcommit * getting there * changed yamlfieldattribute namespace * adds back iselfserialize * renames everything to data(field/definition) * ouch * Fix most errors on content * Fix more errors in content * Fix some components * work on tests * fixes some customdataclasses * fuggin shit * yes * yeas * Remove data classes * Data field naming fixes * arg * Git resetti RobustToolbox * Merge fixes * General fixes * Fix startup serialization errors * Fix DamageContainerPrototype when supported classes or types are null * Implement construction graph step type serializer * Fix up construction serialization * Fix up construction serialization part 2 * Fix null list in technology database component * Fix body serialization * Fix entity storage serialization * Fix actions serialization * Fix AI serialization * Fix reaction serialization * Fix body serialization * Fix grid atmosphere serialization * Rename IServ3Manager to ISerializationManager * Convert every non generic serializer to the new format, general fixes * Serialization and body system fix * pushinheritance fix * Update all prototypes to have a parent and have consistent id/parent properties * Merge fixes * smh my head * cuddling slaps * Content commit for engine PR * stuff * more fixes * argh * yes even you are fixed * changelog fixes * fixes seeds * argh * Test fixes * Add writing for alert order prototype * Fix alert order writing * FIX * its been alot ok * Fix the rest of the visualizers * Fix server alerts component tests * Fix alert prototype tests not using the read value * Fix alert prototype tests initializing serialization multiple times * THIS IS AN AMERICAN CODEBASE GOD BLESS THE USA * Add ImplicitDataDefinitionForInheritors to IMechanismBehavior Fixes the behaviors not being found * Fix NRE in strap component Good night to the 1 buckle optimization * Fix clothing component slot flags serialization tag * Fix body component in all components test * Merge fixes * ffs * Make construction graph prototype use serialization hooks * human yaml linted * a * Do the thing for construction * stuff * a * monke see yaml linter * LINT HARDER * Remove redundant todo * yes * Add skip hook argument to readers and copiers * we gamin * test/datafield fixes * adds more verbose validation * moves linter to action * Improve construction graph step type serializer error message * Fix ammo box component NRE * gamin * some updates to the linter * yes * removes that test * misc fixes * array fix priority fix misc fixes * adds proper info the validation * adds alwaysrelevant usa * Make yaml linter take half as long to run (~50% less) * Make yaml linter 5 times faster (~80% less execution time) * based vera being based * fixes mapsaving * warning cleanup & moves surpressor * removes old msbuild targets * Revert "Make yaml linter 5 times faster (~80% less execution time)" This reverts commit 3e6091359a26252c3e98828199553de668031c63. * Add -nowarn to yaml linter run configuration * Improve yaml linter message feedback * Make dependencies an argument instead of a property on the serialization manager * yamllinting slaps * Clean up type serializers * Move yaml linter code to its own method * Fix yaml errors * Change yaml linter action name and remove -nowarn * yaml linter please shut * Git resetti robust toolbox Co-authored-by: Paul <ritter.paul1+git@googlemail.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
2021-03-05 01:08:38 +01:00
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
2021-06-09 22:19:39 +02:00
namespace Content.Shared.Chemistry.Solution
{
/// <summary>
/// A solution of reagents.
/// </summary>
[Serializable, NetSerializable]
Serialization v3 content PR (#3491) * serv3 in shared pt 1 * beginning of deepclone api * progress in implementing ideepclone & serv3 in content * adds target * its cant hurt you it cant hurt you * more changes to content.server * adds dataclasses * almost there * renamed & edited entry * finishes refactoring content to use serv3 * gasmixture runtimes, next: reagentunit * fucin hell that was an annoying one * adds flags * fixes some yaml errors * removes comment * fixes generic components for now * removes todo actually clones values my god paul fixes bug involving resolving custom data classes from other proj renames dataclass fixes spritecomp adds WithFormat.Constants support * adds deepclone to ResistanceSet * adds a bunch of deepclone implementations adds a deepclone analyzer (TODO) adds a deep clone fallback for classes & structs * fixes a bunch of runtimes * adds deepclone to entityuid * adds generator to sln * gets rid of warnings * fixes * argh * componentdata refactors * more deepclone impl * heck me i reworked all of content deepclone * renames custom dataclasstarget * misc * reworks prototypes * deepclone nuke * renamed customdataclass attribute * fixes everything * misc fixed * the killcommit * getting there * changed yamlfieldattribute namespace * adds back iselfserialize * renames everything to data(field/definition) * ouch * Fix most errors on content * Fix more errors in content * Fix some components * work on tests * fixes some customdataclasses * fuggin shit * yes * yeas * Remove data classes * Data field naming fixes * arg * Git resetti RobustToolbox * Merge fixes * General fixes * Fix startup serialization errors * Fix DamageContainerPrototype when supported classes or types are null * Implement construction graph step type serializer * Fix up construction serialization * Fix up construction serialization part 2 * Fix null list in technology database component * Fix body serialization * Fix entity storage serialization * Fix actions serialization * Fix AI serialization * Fix reaction serialization * Fix body serialization * Fix grid atmosphere serialization * Rename IServ3Manager to ISerializationManager * Convert every non generic serializer to the new format, general fixes * Serialization and body system fix * pushinheritance fix * Update all prototypes to have a parent and have consistent id/parent properties * Merge fixes * smh my head * cuddling slaps * Content commit for engine PR * stuff * more fixes * argh * yes even you are fixed * changelog fixes * fixes seeds * argh * Test fixes * Add writing for alert order prototype * Fix alert order writing * FIX * its been alot ok * Fix the rest of the visualizers * Fix server alerts component tests * Fix alert prototype tests not using the read value * Fix alert prototype tests initializing serialization multiple times * THIS IS AN AMERICAN CODEBASE GOD BLESS THE USA * Add ImplicitDataDefinitionForInheritors to IMechanismBehavior Fixes the behaviors not being found * Fix NRE in strap component Good night to the 1 buckle optimization * Fix clothing component slot flags serialization tag * Fix body component in all components test * Merge fixes * ffs * Make construction graph prototype use serialization hooks * human yaml linted * a * Do the thing for construction * stuff * a * monke see yaml linter * LINT HARDER * Remove redundant todo * yes * Add skip hook argument to readers and copiers * we gamin * test/datafield fixes * adds more verbose validation * moves linter to action * Improve construction graph step type serializer error message * Fix ammo box component NRE * gamin * some updates to the linter * yes * removes that test * misc fixes * array fix priority fix misc fixes * adds proper info the validation * adds alwaysrelevant usa * Make yaml linter take half as long to run (~50% less) * Make yaml linter 5 times faster (~80% less execution time) * based vera being based * fixes mapsaving * warning cleanup & moves surpressor * removes old msbuild targets * Revert "Make yaml linter 5 times faster (~80% less execution time)" This reverts commit 3e6091359a26252c3e98828199553de668031c63. * Add -nowarn to yaml linter run configuration * Improve yaml linter message feedback * Make dependencies an argument instead of a property on the serialization manager * yamllinting slaps * Clean up type serializers * Move yaml linter code to its own method * Fix yaml errors * Change yaml linter action name and remove -nowarn * yaml linter please shut * Git resetti robust toolbox Co-authored-by: Paul <ritter.paul1+git@googlemail.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
2021-03-05 01:08:38 +01:00
[DataDefinition]
public class Solution : IEnumerable<Solution.ReagentQuantity>, ISerializationHooks
{
// Most objects on the station hold only 1 or 2 reagents
[ViewVariables]
Serialization v3 content PR (#3491) * serv3 in shared pt 1 * beginning of deepclone api * progress in implementing ideepclone & serv3 in content * adds target * its cant hurt you it cant hurt you * more changes to content.server * adds dataclasses * almost there * renamed & edited entry * finishes refactoring content to use serv3 * gasmixture runtimes, next: reagentunit * fucin hell that was an annoying one * adds flags * fixes some yaml errors * removes comment * fixes generic components for now * removes todo actually clones values my god paul fixes bug involving resolving custom data classes from other proj renames dataclass fixes spritecomp adds WithFormat.Constants support * adds deepclone to ResistanceSet * adds a bunch of deepclone implementations adds a deepclone analyzer (TODO) adds a deep clone fallback for classes & structs * fixes a bunch of runtimes * adds deepclone to entityuid * adds generator to sln * gets rid of warnings * fixes * argh * componentdata refactors * more deepclone impl * heck me i reworked all of content deepclone * renames custom dataclasstarget * misc * reworks prototypes * deepclone nuke * renamed customdataclass attribute * fixes everything * misc fixed * the killcommit * getting there * changed yamlfieldattribute namespace * adds back iselfserialize * renames everything to data(field/definition) * ouch * Fix most errors on content * Fix more errors in content * Fix some components * work on tests * fixes some customdataclasses * fuggin shit * yes * yeas * Remove data classes * Data field naming fixes * arg * Git resetti RobustToolbox * Merge fixes * General fixes * Fix startup serialization errors * Fix DamageContainerPrototype when supported classes or types are null * Implement construction graph step type serializer * Fix up construction serialization * Fix up construction serialization part 2 * Fix null list in technology database component * Fix body serialization * Fix entity storage serialization * Fix actions serialization * Fix AI serialization * Fix reaction serialization * Fix body serialization * Fix grid atmosphere serialization * Rename IServ3Manager to ISerializationManager * Convert every non generic serializer to the new format, general fixes * Serialization and body system fix * pushinheritance fix * Update all prototypes to have a parent and have consistent id/parent properties * Merge fixes * smh my head * cuddling slaps * Content commit for engine PR * stuff * more fixes * argh * yes even you are fixed * changelog fixes * fixes seeds * argh * Test fixes * Add writing for alert order prototype * Fix alert order writing * FIX * its been alot ok * Fix the rest of the visualizers * Fix server alerts component tests * Fix alert prototype tests not using the read value * Fix alert prototype tests initializing serialization multiple times * THIS IS AN AMERICAN CODEBASE GOD BLESS THE USA * Add ImplicitDataDefinitionForInheritors to IMechanismBehavior Fixes the behaviors not being found * Fix NRE in strap component Good night to the 1 buckle optimization * Fix clothing component slot flags serialization tag * Fix body component in all components test * Merge fixes * ffs * Make construction graph prototype use serialization hooks * human yaml linted * a * Do the thing for construction * stuff * a * monke see yaml linter * LINT HARDER * Remove redundant todo * yes * Add skip hook argument to readers and copiers * we gamin * test/datafield fixes * adds more verbose validation * moves linter to action * Improve construction graph step type serializer error message * Fix ammo box component NRE * gamin * some updates to the linter * yes * removes that test * misc fixes * array fix priority fix misc fixes * adds proper info the validation * adds alwaysrelevant usa * Make yaml linter take half as long to run (~50% less) * Make yaml linter 5 times faster (~80% less execution time) * based vera being based * fixes mapsaving * warning cleanup & moves surpressor * removes old msbuild targets * Revert "Make yaml linter 5 times faster (~80% less execution time)" This reverts commit 3e6091359a26252c3e98828199553de668031c63. * Add -nowarn to yaml linter run configuration * Improve yaml linter message feedback * Make dependencies an argument instead of a property on the serialization manager * yamllinting slaps * Clean up type serializers * Move yaml linter code to its own method * Fix yaml errors * Change yaml linter action name and remove -nowarn * yaml linter please shut * Git resetti robust toolbox Co-authored-by: Paul <ritter.paul1+git@googlemail.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
2021-03-05 01:08:38 +01:00
[DataField("reagents")]
private List<ReagentQuantity> _contents = new(2);
Reagent dispensers (#360) * Expose more private values of Solution and SolutionComponent Expose SolutionComponent.ContainedSolution and Solution.Contents. Both needed by ReagentDispenserComponent. * Implement IExamine for SolutionComponent Allows players to see the contents of a solution by examining the entity which contains it. * Implement ReagentDispenserComponent Adds ReagentDispenserComponent. A component which can add or remove reagents from a solution container. It's written in a general way so that it can be used for things such as the Chemical dispensers in chemistry, but also the booze and soda dispensers in the bar. The chemicals it may dispense are defined in yaml, similar to the way that vending machines define which entities they can dispense, by defining a reagent pack. * Add chemical dispenser and equipment Adds the chemical dispenser, beaker, large beaker, dropper, and a few more chemicals. * Add booze and soda dispensers. Adds the booze and soda dispensers, and a few chemicals for them to dispense. There's no drink mixing or drunkenness yet. * Update engine submodule. * Remove unneeded and commented out code Had a few WIP notes and debug code bits I forgot to remove beforehand. * Make SolutionComponent._containedSolution and it's values private again - Remove `SolutionComponent.ContainedSolution` property, replace with specific access functions to maintain safety. - Make Solution.Contents return a `ReadOnlyCollection` instead of `_contents` to prevent uncontrolled access to the Solution values. - Add `SolutionComponent.RemoveAllSolution()` * Update Content.Shared/Chemistry/Solution.cs Commits a suggestion from RemieRichards to match the coding style of the rest of the codebase. Using `IReadOnlyList` instead of `IReadOnlyCollection`. Co-Authored-By: Remie Richards <remierichards@gmail.com> * Update Content.Shared/GameObjects/Components/Chemistry/SolutionComponent.cs Commits a suggestion from RemieRichards to match the coding style of the rest of the codebase. Using `IReadOnlyList` instead of `IReadOnlyCollection`. Co-Authored-By: Remie Richards <remierichards@gmail.com> * Add import for IReadOnlyList to Shared/SolutionComponent.cs * Add documentation * Improve localization Improve use of ILocalizationManager. * Resolve ReagentDispenserWindow._localizationManager before using it Forgot to do this in the last commit, resulting in a crash. Oops. * Add SolutionCaps.FitsInDispenser. Use in ReagentDispenserComponent. Used to limit large containers like buckets or mop buckets from being placed in a dispenser. Both have large capacities (500) and weren't designed to hold certain chemicals like a beaker is, so for now they can be blocked from being put in a dispenser by giving them that flag. * Add colors to new reagents * Update engine submodule
2019-10-05 09:10:05 -04:00
public IReadOnlyList<ReagentQuantity> Contents => _contents;
/// <summary>
/// The calculated total volume of all reagents in the solution (ex. Total volume of liquid in beaker).
/// </summary>
[ViewVariables]
2020-04-05 11:36:12 +02:00
public ReagentUnit TotalVolume { get; private set; }
public Color Color => GetColor();
/// <summary>
/// Constructs an empty solution (ex. an empty beaker).
/// </summary>
public Solution() { }
/// <summary>
/// Constructs a solution containing 100% of a reagent (ex. A beaker of pure water).
/// </summary>
/// <param name="reagentId">The prototype ID of the reagent to add.</param>
/// <param name="quantity">The quantity in milli-units.</param>
2020-04-05 11:36:12 +02:00
public Solution(string reagentId, ReagentUnit quantity)
{
AddReagent(reagentId, quantity);
}
Serialization v3 content PR (#3491) * serv3 in shared pt 1 * beginning of deepclone api * progress in implementing ideepclone & serv3 in content * adds target * its cant hurt you it cant hurt you * more changes to content.server * adds dataclasses * almost there * renamed & edited entry * finishes refactoring content to use serv3 * gasmixture runtimes, next: reagentunit * fucin hell that was an annoying one * adds flags * fixes some yaml errors * removes comment * fixes generic components for now * removes todo actually clones values my god paul fixes bug involving resolving custom data classes from other proj renames dataclass fixes spritecomp adds WithFormat.Constants support * adds deepclone to ResistanceSet * adds a bunch of deepclone implementations adds a deepclone analyzer (TODO) adds a deep clone fallback for classes & structs * fixes a bunch of runtimes * adds deepclone to entityuid * adds generator to sln * gets rid of warnings * fixes * argh * componentdata refactors * more deepclone impl * heck me i reworked all of content deepclone * renames custom dataclasstarget * misc * reworks prototypes * deepclone nuke * renamed customdataclass attribute * fixes everything * misc fixed * the killcommit * getting there * changed yamlfieldattribute namespace * adds back iselfserialize * renames everything to data(field/definition) * ouch * Fix most errors on content * Fix more errors in content * Fix some components * work on tests * fixes some customdataclasses * fuggin shit * yes * yeas * Remove data classes * Data field naming fixes * arg * Git resetti RobustToolbox * Merge fixes * General fixes * Fix startup serialization errors * Fix DamageContainerPrototype when supported classes or types are null * Implement construction graph step type serializer * Fix up construction serialization * Fix up construction serialization part 2 * Fix null list in technology database component * Fix body serialization * Fix entity storage serialization * Fix actions serialization * Fix AI serialization * Fix reaction serialization * Fix body serialization * Fix grid atmosphere serialization * Rename IServ3Manager to ISerializationManager * Convert every non generic serializer to the new format, general fixes * Serialization and body system fix * pushinheritance fix * Update all prototypes to have a parent and have consistent id/parent properties * Merge fixes * smh my head * cuddling slaps * Content commit for engine PR * stuff * more fixes * argh * yes even you are fixed * changelog fixes * fixes seeds * argh * Test fixes * Add writing for alert order prototype * Fix alert order writing * FIX * its been alot ok * Fix the rest of the visualizers * Fix server alerts component tests * Fix alert prototype tests not using the read value * Fix alert prototype tests initializing serialization multiple times * THIS IS AN AMERICAN CODEBASE GOD BLESS THE USA * Add ImplicitDataDefinitionForInheritors to IMechanismBehavior Fixes the behaviors not being found * Fix NRE in strap component Good night to the 1 buckle optimization * Fix clothing component slot flags serialization tag * Fix body component in all components test * Merge fixes * ffs * Make construction graph prototype use serialization hooks * human yaml linted * a * Do the thing for construction * stuff * a * monke see yaml linter * LINT HARDER * Remove redundant todo * yes * Add skip hook argument to readers and copiers * we gamin * test/datafield fixes * adds more verbose validation * moves linter to action * Improve construction graph step type serializer error message * Fix ammo box component NRE * gamin * some updates to the linter * yes * removes that test * misc fixes * array fix priority fix misc fixes * adds proper info the validation * adds alwaysrelevant usa * Make yaml linter take half as long to run (~50% less) * Make yaml linter 5 times faster (~80% less execution time) * based vera being based * fixes mapsaving * warning cleanup & moves surpressor * removes old msbuild targets * Revert "Make yaml linter 5 times faster (~80% less execution time)" This reverts commit 3e6091359a26252c3e98828199553de668031c63. * Add -nowarn to yaml linter run configuration * Improve yaml linter message feedback * Make dependencies an argument instead of a property on the serialization manager * yamllinting slaps * Clean up type serializers * Move yaml linter code to its own method * Fix yaml errors * Change yaml linter action name and remove -nowarn * yaml linter please shut * Git resetti robust toolbox Co-authored-by: Paul <ritter.paul1+git@googlemail.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
2021-03-05 01:08:38 +01:00
void ISerializationHooks.AfterDeserialization()
{
Serialization v3 content PR (#3491) * serv3 in shared pt 1 * beginning of deepclone api * progress in implementing ideepclone & serv3 in content * adds target * its cant hurt you it cant hurt you * more changes to content.server * adds dataclasses * almost there * renamed & edited entry * finishes refactoring content to use serv3 * gasmixture runtimes, next: reagentunit * fucin hell that was an annoying one * adds flags * fixes some yaml errors * removes comment * fixes generic components for now * removes todo actually clones values my god paul fixes bug involving resolving custom data classes from other proj renames dataclass fixes spritecomp adds WithFormat.Constants support * adds deepclone to ResistanceSet * adds a bunch of deepclone implementations adds a deepclone analyzer (TODO) adds a deep clone fallback for classes & structs * fixes a bunch of runtimes * adds deepclone to entityuid * adds generator to sln * gets rid of warnings * fixes * argh * componentdata refactors * more deepclone impl * heck me i reworked all of content deepclone * renames custom dataclasstarget * misc * reworks prototypes * deepclone nuke * renamed customdataclass attribute * fixes everything * misc fixed * the killcommit * getting there * changed yamlfieldattribute namespace * adds back iselfserialize * renames everything to data(field/definition) * ouch * Fix most errors on content * Fix more errors in content * Fix some components * work on tests * fixes some customdataclasses * fuggin shit * yes * yeas * Remove data classes * Data field naming fixes * arg * Git resetti RobustToolbox * Merge fixes * General fixes * Fix startup serialization errors * Fix DamageContainerPrototype when supported classes or types are null * Implement construction graph step type serializer * Fix up construction serialization * Fix up construction serialization part 2 * Fix null list in technology database component * Fix body serialization * Fix entity storage serialization * Fix actions serialization * Fix AI serialization * Fix reaction serialization * Fix body serialization * Fix grid atmosphere serialization * Rename IServ3Manager to ISerializationManager * Convert every non generic serializer to the new format, general fixes * Serialization and body system fix * pushinheritance fix * Update all prototypes to have a parent and have consistent id/parent properties * Merge fixes * smh my head * cuddling slaps * Content commit for engine PR * stuff * more fixes * argh * yes even you are fixed * changelog fixes * fixes seeds * argh * Test fixes * Add writing for alert order prototype * Fix alert order writing * FIX * its been alot ok * Fix the rest of the visualizers * Fix server alerts component tests * Fix alert prototype tests not using the read value * Fix alert prototype tests initializing serialization multiple times * THIS IS AN AMERICAN CODEBASE GOD BLESS THE USA * Add ImplicitDataDefinitionForInheritors to IMechanismBehavior Fixes the behaviors not being found * Fix NRE in strap component Good night to the 1 buckle optimization * Fix clothing component slot flags serialization tag * Fix body component in all components test * Merge fixes * ffs * Make construction graph prototype use serialization hooks * human yaml linted * a * Do the thing for construction * stuff * a * monke see yaml linter * LINT HARDER * Remove redundant todo * yes * Add skip hook argument to readers and copiers * we gamin * test/datafield fixes * adds more verbose validation * moves linter to action * Improve construction graph step type serializer error message * Fix ammo box component NRE * gamin * some updates to the linter * yes * removes that test * misc fixes * array fix priority fix misc fixes * adds proper info the validation * adds alwaysrelevant usa * Make yaml linter take half as long to run (~50% less) * Make yaml linter 5 times faster (~80% less execution time) * based vera being based * fixes mapsaving * warning cleanup & moves surpressor * removes old msbuild targets * Revert "Make yaml linter 5 times faster (~80% less execution time)" This reverts commit 3e6091359a26252c3e98828199553de668031c63. * Add -nowarn to yaml linter run configuration * Improve yaml linter message feedback * Make dependencies an argument instead of a property on the serialization manager * yamllinting slaps * Clean up type serializers * Move yaml linter code to its own method * Fix yaml errors * Change yaml linter action name and remove -nowarn * yaml linter please shut * Git resetti robust toolbox Co-authored-by: Paul <ritter.paul1+git@googlemail.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
2021-03-05 01:08:38 +01:00
TotalVolume = ReagentUnit.Zero;
_contents.ForEach(reagent => TotalVolume += reagent.Quantity);
}
public bool ContainsReagent(string reagentId)
{
return ContainsReagent(reagentId, out _);
}
public bool ContainsReagent(string reagentId, out ReagentUnit quantity)
{
foreach (var reagent in Contents)
{
if (reagent.ReagentId == reagentId)
{
quantity = reagent.Quantity;
return true;
}
}
quantity = ReagentUnit.New(0);
return false;
}
public string GetPrimaryReagentId()
{
if (Contents.Count == 0)
{
return "";
}
A big hecking chemistry-related refactor. (#3055) * A big hecking chemistry-related refactor. Changed SolutionContainerCaps. It now describes "stock" behavior for interacting with solutions that is pre-implemented by SolutionContainerComponent. As such things like syringes do not check it anymore (on themselves) to see "can we remove reagent from ourselves". That's assumed by it... being a syringe. SolutionContainerCaps now has different flags more accurately describing possible reagent interaction behaviors. ISolutionInteractionsComponent is the interface that describes the common behaviors like "what happens when injected with a syringe". This is implemented by SolutionContainerComponent but could be implemented by other classes. One notable example that drove me to making this interface was the /vg/station circuit imprinter which splits reagent poured in into its two reservoir beakers. Having this interface allows us to do this "proxying" behavior hack-free. (the hacks in /vg/ code were somewhat dirty...). PourableComponent has been replaced SolutionTransferComponent. It now describes both give-and-take behavior for the common reagent containers. This is in line with /vg/'s /obj/item/weapon/reagent_containers architecture. "Taking" in this context is ONLY from reagent tanks like fuel tanks. Oh, should I mention that fuel tanks and such have a proper component now? They do. Because of this behavioral change, reagent tanks DO NOT have Pourable anymore. Removing from reagent tanks is now in the hands of the item used on them. Welders and fire extinguishers now have code for removing from them. This sounds bad at first but remember that all have quite unique behavior related to this: Welders cause explosions if lit and can ONLY be fueled at fuel tanks. Extinguishers can be filled at any tank, etc... The code for this is also simpler due to ISolutionInteractionsComponent now so... IAfterInteract now works like IInteractUsing with the Priority levels and "return true to block further handlers" behavior. This was necessary to make extinguishers prioritize taking from tanks over spraying. Explicitly coded interactions like welders refueling also means they refuse instantly to full now, which they didn't before. And it plays the sound. Etc... Probably more stuff I'm forgetting. * Review improvements.
2021-02-03 14:05:31 +01:00
var majorReagent = Contents.OrderByDescending(reagent => reagent.Quantity).First();
return majorReagent.ReagentId;
}
/// <summary>
2019-07-31 15:02:36 +02:00
/// Adds a given quantity of a reagent directly into the solution.
/// </summary>
/// <param name="reagentId">The prototype ID of the reagent to add.</param>
/// <param name="quantity">The quantity in milli-units.</param>
2020-04-05 11:36:12 +02:00
public void AddReagent(string reagentId, ReagentUnit quantity)
{
if (quantity <= 0)
return;
for (var i = 0; i < _contents.Count; i++)
{
var reagent = _contents[i];
if (reagent.ReagentId != reagentId)
continue;
_contents[i] = new ReagentQuantity(reagentId, reagent.Quantity + quantity);
TotalVolume += quantity;
return;
}
_contents.Add(new ReagentQuantity(reagentId, quantity));
TotalVolume += quantity;
}
/// <summary>
/// Scales the amount of solution.
/// </summary>
/// <param name="scale">The scalar to modify the solution by.</param>
public void ScaleSolution(float scale)
{
if (scale == 1) return;
var tempContents = new List<ReagentQuantity>(_contents);
foreach(ReagentQuantity current in tempContents)
{
if(scale > 1)
{
AddReagent(current.ReagentId, current.Quantity * scale - current.Quantity);
}
else
{
RemoveReagent(current.ReagentId, current.Quantity - current.Quantity * scale);
}
}
}
/// <summary>
/// Returns the amount of a single reagent inside the solution.
/// </summary>
/// <param name="reagentId">The prototype ID of the reagent to add.</param>
/// <returns>The quantity in milli-units.</returns>
2020-04-05 11:36:12 +02:00
public ReagentUnit GetReagentQuantity(string reagentId)
{
for (var i = 0; i < _contents.Count; i++)
{
if (_contents[i].ReagentId == reagentId)
return _contents[i].Quantity;
}
2020-04-05 11:36:12 +02:00
return ReagentUnit.New(0);
}
2020-04-05 11:36:12 +02:00
public void RemoveReagent(string reagentId, ReagentUnit quantity)
{
if(quantity <= 0)
return;
for (var i = 0; i < _contents.Count; i++)
{
var reagent = _contents[i];
if(reagent.ReagentId != reagentId)
continue;
var curQuantity = reagent.Quantity;
2020-04-05 11:36:12 +02:00
var newQuantity = curQuantity - quantity;
if (newQuantity <= 0)
{
_contents.RemoveSwap(i);
TotalVolume -= curQuantity;
}
else
{
_contents[i] = new ReagentQuantity(reagentId, newQuantity);
TotalVolume -= quantity;
}
return;
}
}
Add solution pouring / click-transfer (#574) * Add click-based solution transfer For example, clicking on a beaker with a soda can to transfer the soda to the beaker. Works on plain solution containers like beakers and also on open drink containers like soda cans as long as they have the `PourIn` and `PourOut` solution capabilities. If no `SolutionComponent` is added to a drink entity, the `DrinkComponent` will give the entity one. This PR extends that behavior slightly by also giving these default `SolutionComponent`'s the proper capabilities for pouring in/out. * Improve fix for poured drinks not immediately disappearing Instead of making `DrinkComponent.Use` public this splits out the code important to both users and made that function public, leaving `Use` private. * Shorten solution transfer popup * Make code review changes - Move pouring code from SolutionComponent to new PourableComponent. Added PourableComponent to client ignore list and added to existing container prototypes. - Added EmptyVolume property to shared SolutionComponent for convenience. - Removed DrinkComponent fix from pouring AttackBy code. Instead DrinkComponent subscribes to the SolutionChanged action and updates its self when necessary. - Fixed pouring being able to add more than a containers max volume and sometimes deleting reagents. - Added message for when a container is full. * More code review changes - Remove IAttackBy ComponentReference attribute in PourableComponent - Remove _transferAmount from shared SolutionComponent. Left over var from previous commit not being used anymore.
2020-01-28 20:07:02 -05:00
/// <summary>
/// Remove the specified quantity from this solution.
/// </summary>
/// <param name="quantity">The quantity of this solution to remove</param>
2020-04-05 11:36:12 +02:00
public void RemoveSolution(ReagentUnit quantity)
{
Add solution pouring / click-transfer (#574) * Add click-based solution transfer For example, clicking on a beaker with a soda can to transfer the soda to the beaker. Works on plain solution containers like beakers and also on open drink containers like soda cans as long as they have the `PourIn` and `PourOut` solution capabilities. If no `SolutionComponent` is added to a drink entity, the `DrinkComponent` will give the entity one. This PR extends that behavior slightly by also giving these default `SolutionComponent`'s the proper capabilities for pouring in/out. * Improve fix for poured drinks not immediately disappearing Instead of making `DrinkComponent.Use` public this splits out the code important to both users and made that function public, leaving `Use` private. * Shorten solution transfer popup * Make code review changes - Move pouring code from SolutionComponent to new PourableComponent. Added PourableComponent to client ignore list and added to existing container prototypes. - Added EmptyVolume property to shared SolutionComponent for convenience. - Removed DrinkComponent fix from pouring AttackBy code. Instead DrinkComponent subscribes to the SolutionChanged action and updates its self when necessary. - Fixed pouring being able to add more than a containers max volume and sometimes deleting reagents. - Added message for when a container is full. * More code review changes - Remove IAttackBy ComponentReference attribute in PourableComponent - Remove _transferAmount from shared SolutionComponent. Left over var from previous commit not being used anymore.
2020-01-28 20:07:02 -05:00
if(quantity <= 0)
return;
var ratio = (TotalVolume - quantity).Double() / TotalVolume.Double();
if (ratio <= 0)
{
RemoveAllSolution();
return;
}
for (var i = 0; i < _contents.Count; i++)
{
var reagent = _contents[i];
var oldQuantity = reagent.Quantity;
// quantity taken is always a little greedy, so fractional quantities get rounded up to the nearest
// whole unit. This should prevent little bits of chemical remaining because of float rounding errors.
2020-04-05 11:36:12 +02:00
var newQuantity = oldQuantity * ratio;
_contents[i] = new ReagentQuantity(reagent.ReagentId, newQuantity);
}
2020-04-05 11:36:12 +02:00
TotalVolume = TotalVolume * ratio;
}
public void RemoveAllSolution()
{
_contents.Clear();
2020-04-05 11:36:12 +02:00
TotalVolume = ReagentUnit.New(0);
}
2020-04-05 11:36:12 +02:00
public Solution SplitSolution(ReagentUnit quantity)
{
if (quantity <= 0)
2020-04-05 11:36:12 +02:00
return new Solution();
Solution newSolution;
if (quantity >= TotalVolume)
{
newSolution = Clone();
RemoveAllSolution();
return newSolution;
}
2020-04-05 11:36:12 +02:00
newSolution = new Solution();
var newTotalVolume = ReagentUnit.New(0);
2020-04-14 15:41:23 +02:00
var remainingVolume = TotalVolume;
for (var i = 0; i < _contents.Count; i++)
{
var reagent = _contents[i];
var ratio = (remainingVolume - quantity).Double() / remainingVolume.Double();
2020-04-14 15:41:23 +02:00
remainingVolume -= reagent.Quantity;
2020-04-05 11:36:12 +02:00
var newQuantity = reagent.Quantity * ratio;
var splitQuantity = reagent.Quantity - newQuantity;
_contents[i] = new ReagentQuantity(reagent.ReagentId, newQuantity);
newSolution._contents.Add(new ReagentQuantity(reagent.ReagentId, splitQuantity));
newTotalVolume += splitQuantity;
2020-04-14 15:41:23 +02:00
quantity -= splitQuantity;
}
newSolution.TotalVolume = newTotalVolume;
2020-04-14 15:41:23 +02:00
TotalVolume -= newTotalVolume;
return newSolution;
}
2019-07-31 15:02:36 +02:00
public void AddSolution(Solution otherSolution)
{
for (var i = 0; i < otherSolution._contents.Count; i++)
{
var otherReagent = otherSolution._contents[i];
var found = false;
for (var j = 0; j < _contents.Count; j++)
{
var reagent = _contents[j];
if (reagent.ReagentId == otherReagent.ReagentId)
{
found = true;
_contents[j] = new ReagentQuantity(reagent.ReagentId, reagent.Quantity + otherReagent.Quantity);
break;
}
}
if (!found)
{
_contents.Add(new ReagentQuantity(otherReagent.ReagentId, otherReagent.Quantity));
}
}
TotalVolume += otherSolution.TotalVolume;
}
private Color GetColor()
{
if (TotalVolume == 0)
{
return Color.Transparent;
}
Color mixColor = default;
var runningTotalQuantity = ReagentUnit.New(0);
var protoManager = IoCManager.Resolve<IPrototypeManager>();
foreach (var reagent in Contents)
{
runningTotalQuantity += reagent.Quantity;
if (!protoManager.TryIndex(reagent.ReagentId, out ReagentPrototype? proto))
{
continue;
}
if (mixColor == default)
{
mixColor = proto.SubstanceColor;
continue;
}
var interpolateValue = (1 / runningTotalQuantity.Float()) * reagent.Quantity.Float();
mixColor = Color.InterpolateBetween(mixColor, proto.SubstanceColor, interpolateValue);
}
return mixColor;
}
public Solution Clone()
{
2020-04-05 11:36:12 +02:00
var volume = ReagentUnit.New(0);
var newSolution = new Solution();
for (var i = 0; i < _contents.Count; i++)
{
var reagent = _contents[i];
newSolution._contents.Add(reagent);
volume += reagent.Quantity;
}
2019-07-31 15:02:36 +02:00
newSolution.TotalVolume = volume;
return newSolution;
}
public void DoEntityReaction(IEntity entity, ReactionMethod method)
{
var chemistry = EntitySystem.Get<ChemistrySystem>();
foreach (var (reagentId, quantity) in _contents.ToArray())
{
chemistry.ReactionEntity(entity, method, reagentId, quantity, this);
}
}
[Serializable, NetSerializable]
Serialization v3 content PR (#3491) * serv3 in shared pt 1 * beginning of deepclone api * progress in implementing ideepclone & serv3 in content * adds target * its cant hurt you it cant hurt you * more changes to content.server * adds dataclasses * almost there * renamed & edited entry * finishes refactoring content to use serv3 * gasmixture runtimes, next: reagentunit * fucin hell that was an annoying one * adds flags * fixes some yaml errors * removes comment * fixes generic components for now * removes todo actually clones values my god paul fixes bug involving resolving custom data classes from other proj renames dataclass fixes spritecomp adds WithFormat.Constants support * adds deepclone to ResistanceSet * adds a bunch of deepclone implementations adds a deepclone analyzer (TODO) adds a deep clone fallback for classes & structs * fixes a bunch of runtimes * adds deepclone to entityuid * adds generator to sln * gets rid of warnings * fixes * argh * componentdata refactors * more deepclone impl * heck me i reworked all of content deepclone * renames custom dataclasstarget * misc * reworks prototypes * deepclone nuke * renamed customdataclass attribute * fixes everything * misc fixed * the killcommit * getting there * changed yamlfieldattribute namespace * adds back iselfserialize * renames everything to data(field/definition) * ouch * Fix most errors on content * Fix more errors in content * Fix some components * work on tests * fixes some customdataclasses * fuggin shit * yes * yeas * Remove data classes * Data field naming fixes * arg * Git resetti RobustToolbox * Merge fixes * General fixes * Fix startup serialization errors * Fix DamageContainerPrototype when supported classes or types are null * Implement construction graph step type serializer * Fix up construction serialization * Fix up construction serialization part 2 * Fix null list in technology database component * Fix body serialization * Fix entity storage serialization * Fix actions serialization * Fix AI serialization * Fix reaction serialization * Fix body serialization * Fix grid atmosphere serialization * Rename IServ3Manager to ISerializationManager * Convert every non generic serializer to the new format, general fixes * Serialization and body system fix * pushinheritance fix * Update all prototypes to have a parent and have consistent id/parent properties * Merge fixes * smh my head * cuddling slaps * Content commit for engine PR * stuff * more fixes * argh * yes even you are fixed * changelog fixes * fixes seeds * argh * Test fixes * Add writing for alert order prototype * Fix alert order writing * FIX * its been alot ok * Fix the rest of the visualizers * Fix server alerts component tests * Fix alert prototype tests not using the read value * Fix alert prototype tests initializing serialization multiple times * THIS IS AN AMERICAN CODEBASE GOD BLESS THE USA * Add ImplicitDataDefinitionForInheritors to IMechanismBehavior Fixes the behaviors not being found * Fix NRE in strap component Good night to the 1 buckle optimization * Fix clothing component slot flags serialization tag * Fix body component in all components test * Merge fixes * ffs * Make construction graph prototype use serialization hooks * human yaml linted * a * Do the thing for construction * stuff * a * monke see yaml linter * LINT HARDER * Remove redundant todo * yes * Add skip hook argument to readers and copiers * we gamin * test/datafield fixes * adds more verbose validation * moves linter to action * Improve construction graph step type serializer error message * Fix ammo box component NRE * gamin * some updates to the linter * yes * removes that test * misc fixes * array fix priority fix misc fixes * adds proper info the validation * adds alwaysrelevant usa * Make yaml linter take half as long to run (~50% less) * Make yaml linter 5 times faster (~80% less execution time) * based vera being based * fixes mapsaving * warning cleanup & moves surpressor * removes old msbuild targets * Revert "Make yaml linter 5 times faster (~80% less execution time)" This reverts commit 3e6091359a26252c3e98828199553de668031c63. * Add -nowarn to yaml linter run configuration * Improve yaml linter message feedback * Make dependencies an argument instead of a property on the serialization manager * yamllinting slaps * Clean up type serializers * Move yaml linter code to its own method * Fix yaml errors * Change yaml linter action name and remove -nowarn * yaml linter please shut * Git resetti robust toolbox Co-authored-by: Paul <ritter.paul1+git@googlemail.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
2021-03-05 01:08:38 +01:00
[DataDefinition]
public readonly struct ReagentQuantity: IComparable<ReagentQuantity>
{
[DataField("ReagentId", customTypeSerializer:typeof(PrototypeIdSerializer<ReagentPrototype>))]
public readonly string ReagentId;
Serialization v3 content PR (#3491) * serv3 in shared pt 1 * beginning of deepclone api * progress in implementing ideepclone & serv3 in content * adds target * its cant hurt you it cant hurt you * more changes to content.server * adds dataclasses * almost there * renamed & edited entry * finishes refactoring content to use serv3 * gasmixture runtimes, next: reagentunit * fucin hell that was an annoying one * adds flags * fixes some yaml errors * removes comment * fixes generic components for now * removes todo actually clones values my god paul fixes bug involving resolving custom data classes from other proj renames dataclass fixes spritecomp adds WithFormat.Constants support * adds deepclone to ResistanceSet * adds a bunch of deepclone implementations adds a deepclone analyzer (TODO) adds a deep clone fallback for classes & structs * fixes a bunch of runtimes * adds deepclone to entityuid * adds generator to sln * gets rid of warnings * fixes * argh * componentdata refactors * more deepclone impl * heck me i reworked all of content deepclone * renames custom dataclasstarget * misc * reworks prototypes * deepclone nuke * renamed customdataclass attribute * fixes everything * misc fixed * the killcommit * getting there * changed yamlfieldattribute namespace * adds back iselfserialize * renames everything to data(field/definition) * ouch * Fix most errors on content * Fix more errors in content * Fix some components * work on tests * fixes some customdataclasses * fuggin shit * yes * yeas * Remove data classes * Data field naming fixes * arg * Git resetti RobustToolbox * Merge fixes * General fixes * Fix startup serialization errors * Fix DamageContainerPrototype when supported classes or types are null * Implement construction graph step type serializer * Fix up construction serialization * Fix up construction serialization part 2 * Fix null list in technology database component * Fix body serialization * Fix entity storage serialization * Fix actions serialization * Fix AI serialization * Fix reaction serialization * Fix body serialization * Fix grid atmosphere serialization * Rename IServ3Manager to ISerializationManager * Convert every non generic serializer to the new format, general fixes * Serialization and body system fix * pushinheritance fix * Update all prototypes to have a parent and have consistent id/parent properties * Merge fixes * smh my head * cuddling slaps * Content commit for engine PR * stuff * more fixes * argh * yes even you are fixed * changelog fixes * fixes seeds * argh * Test fixes * Add writing for alert order prototype * Fix alert order writing * FIX * its been alot ok * Fix the rest of the visualizers * Fix server alerts component tests * Fix alert prototype tests not using the read value * Fix alert prototype tests initializing serialization multiple times * THIS IS AN AMERICAN CODEBASE GOD BLESS THE USA * Add ImplicitDataDefinitionForInheritors to IMechanismBehavior Fixes the behaviors not being found * Fix NRE in strap component Good night to the 1 buckle optimization * Fix clothing component slot flags serialization tag * Fix body component in all components test * Merge fixes * ffs * Make construction graph prototype use serialization hooks * human yaml linted * a * Do the thing for construction * stuff * a * monke see yaml linter * LINT HARDER * Remove redundant todo * yes * Add skip hook argument to readers and copiers * we gamin * test/datafield fixes * adds more verbose validation * moves linter to action * Improve construction graph step type serializer error message * Fix ammo box component NRE * gamin * some updates to the linter * yes * removes that test * misc fixes * array fix priority fix misc fixes * adds proper info the validation * adds alwaysrelevant usa * Make yaml linter take half as long to run (~50% less) * Make yaml linter 5 times faster (~80% less execution time) * based vera being based * fixes mapsaving * warning cleanup & moves surpressor * removes old msbuild targets * Revert "Make yaml linter 5 times faster (~80% less execution time)" This reverts commit 3e6091359a26252c3e98828199553de668031c63. * Add -nowarn to yaml linter run configuration * Improve yaml linter message feedback * Make dependencies an argument instead of a property on the serialization manager * yamllinting slaps * Clean up type serializers * Move yaml linter code to its own method * Fix yaml errors * Change yaml linter action name and remove -nowarn * yaml linter please shut * Git resetti robust toolbox Co-authored-by: Paul <ritter.paul1+git@googlemail.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
2021-03-05 01:08:38 +01:00
[DataField("Quantity")]
2020-04-05 11:36:12 +02:00
public readonly ReagentUnit Quantity;
2020-04-05 11:36:12 +02:00
public ReagentQuantity(string reagentId, ReagentUnit quantity)
{
ReagentId = reagentId;
Quantity = quantity;
}
[ExcludeFromCodeCoverage]
public override string ToString()
{
return $"{ReagentId}:{Quantity}";
}
public int CompareTo(ReagentQuantity other) { return Quantity.Float().CompareTo(other.Quantity.Float()); }
public void Deconstruct(out string reagentId, out ReagentUnit quantity)
{
reagentId = ReagentId;
quantity = Quantity;
}
}
#region Enumeration
2019-07-31 15:02:36 +02:00
public IEnumerator<ReagentQuantity> GetEnumerator()
{
return _contents.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
}