SolutionContainerComponent refactors (#2746)

* Moves ContainsReagent from SolutionContainer to Solution

* GetMajorReagentId from SOlutionContainer to Solution

* Makes capability checks use HasFlag

* Moves Solution Color calculation from SolutionContainer to Solution

* Replaces SolutionContainerCaps.NoExamine with CanExamine

* Misc SolutionContainer.Capabilities yaml cleanup

* Removes HasFlag usage in SolutionContainerComponent

Co-authored-by: py01 <pyronetics01@gmail.com>
This commit is contained in:
py01
2021-01-06 06:31:41 -06:00
committed by GitHub
parent 482106e827
commit 2d1fe31bce
21 changed files with 112 additions and 99 deletions

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Content.Server.Chemistry; using Content.Server.Chemistry;
using Content.Server.GameObjects.Components.GUI; using Content.Server.GameObjects.Components.GUI;
@@ -51,10 +51,10 @@ namespace Content.Server.GameObjects.Components.Chemistry
public ReagentUnit EmptyVolume => MaxVolume - CurrentVolume; public ReagentUnit EmptyVolume => MaxVolume - CurrentVolume;
public IReadOnlyList<Solution.ReagentQuantity> ReagentList => Solution.Contents; public IReadOnlyList<Solution.ReagentQuantity> ReagentList => Solution.Contents;
public bool CanExamineContents => (Capabilities & SolutionContainerCaps.NoExamine) == 0; public bool CanExamineContents => Capabilities.HasCap(SolutionContainerCaps.CanExamine);
public bool CanUseWithChemDispenser => (Capabilities & SolutionContainerCaps.FitsInDispenser) != 0; public bool CanUseWithChemDispenser => Capabilities.HasCap(SolutionContainerCaps.FitsInDispenser);
public bool CanAddSolutions => (Capabilities & SolutionContainerCaps.AddTo) != 0; public bool CanAddSolutions => Capabilities.HasCap(SolutionContainerCaps.AddTo);
public bool CanRemoveSolutions => (Capabilities & SolutionContainerCaps.RemoveFrom) != 0; public bool CanRemoveSolutions => Capabilities.HasCap(SolutionContainerCaps.RemoveFrom);
/// <inheritdoc /> /// <inheritdoc />
public override void ExposeData(ObjectSerializer serializer) public override void ExposeData(ObjectSerializer serializer)
@@ -63,7 +63,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
serializer.DataField(this, x => x.MaxVolume, "maxVol", ReagentUnit.New(0)); serializer.DataField(this, x => x.MaxVolume, "maxVol", ReagentUnit.New(0));
serializer.DataField(this, x => x.Solution, "contents", new Solution()); serializer.DataField(this, x => x.Solution, "contents", new Solution());
serializer.DataField(this, x => x.Capabilities, "caps", SolutionContainerCaps.AddTo | SolutionContainerCaps.RemoveFrom); serializer.DataField(this, x => x.Capabilities, "caps", SolutionContainerCaps.AddTo | SolutionContainerCaps.RemoveFrom | SolutionContainerCaps.CanExamine);
serializer.DataField(ref _fillInitState, "fillingState", string.Empty); serializer.DataField(ref _fillInitState, "fillingState", string.Empty);
serializer.DataField(ref _fillInitSteps, "fillingSteps", 7); serializer.DataField(ref _fillInitSteps, "fillingSteps", 7);
} }
@@ -134,35 +134,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
protected void RecalculateColor() protected void RecalculateColor()
{ {
if (Solution.TotalVolume == 0) SubstanceColor = Solution.Color;
{
SubstanceColor = Color.Transparent;
return;
}
Color mixColor = default;
var runningTotalQuantity = ReagentUnit.New(0);
foreach (var reagent in Solution)
{
runningTotalQuantity += reagent.Quantity;
if (!_prototypeManager.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);
}
SubstanceColor = mixColor;
} }
/// <summary> /// <summary>
@@ -460,28 +432,14 @@ namespace Content.Server.GameObjects.Components.Chemistry
/// <returns>Return true if the solution contains the reagent.</returns> /// <returns>Return true if the solution contains the reagent.</returns>
public bool ContainsReagent(string reagentId, out ReagentUnit quantity) public bool ContainsReagent(string reagentId, out ReagentUnit quantity)
{ {
foreach (var reagent in Solution.Contents) var containsReagent = Solution.ContainsReagent(reagentId, out var quantityFound);
{ quantity = quantityFound;
if (reagent.ReagentId == reagentId) return containsReagent;
{
quantity = reagent.Quantity;
return true;
}
}
quantity = ReagentUnit.New(0);
return false;
} }
public string GetMajorReagentId() public string GetMajorReagentId()
{ {
if (Solution.Contents.Count == 0) return Solution.GetPrimaryReagentId();
{
return "";
}
var majorReagent = Solution.Contents.OrderByDescending(reagent => reagent.Quantity).First();;
return majorReagent.ReagentId;
} }
protected void UpdateFillIcon() protected void UpdateFillIcon()

View File

@@ -1,8 +1,12 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Robust.Shared.Interfaces.Serialization; using Robust.Shared.Interfaces.Serialization;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Robust.Shared.ViewVariables; using Robust.Shared.ViewVariables;
@@ -27,6 +31,8 @@ namespace Content.Shared.Chemistry
[ViewVariables] [ViewVariables]
public ReagentUnit TotalVolume { get; private set; } public ReagentUnit TotalVolume { get; private set; }
public Color Color => GetColor();
/// <summary> /// <summary>
/// Constructs an empty solution (ex. an empty beaker). /// Constructs an empty solution (ex. an empty beaker).
/// </summary> /// </summary>
@@ -57,6 +63,32 @@ namespace Content.Shared.Chemistry
() => _contents); () => _contents);
} }
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 "";
}
var majorReagent = Contents.OrderByDescending(reagent => reagent.Quantity).First(); ;
return majorReagent.ReagentId;
}
/// <summary> /// <summary>
/// Adds a given quantity of a reagent directly into the solution. /// Adds a given quantity of a reagent directly into the solution.
/// </summary> /// </summary>
@@ -231,6 +263,37 @@ namespace Content.Shared.Chemistry
TotalVolume += otherSolution.TotalVolume; TotalVolume += otherSolution.TotalVolume;
} }
private Color GetColor()
{
if (TotalVolume == 0)
{
return Color.Transparent;
}
Color mixColor = default;
var runningTotalQuantity = ReagentUnit.New(0);
foreach (var reagent in Contents)
{
runningTotalQuantity += reagent.Quantity;
if (!IoCManager.Resolve<IPrototypeManager>().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() public Solution Clone()
{ {
var volume = ReagentUnit.New(0); var volume = ReagentUnit.New(0);

View File

@@ -1,4 +1,4 @@
using System; using System;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
namespace Content.Shared.Chemistry namespace Content.Shared.Chemistry
@@ -33,6 +33,14 @@ namespace Content.Shared.Chemistry
/// <summary> /// <summary>
/// Can people examine the solution in the container or is it impossible to see? /// Can people examine the solution in the container or is it impossible to see?
/// </summary> /// </summary>
NoExamine = 8, CanExamine = 8,
}
public static class SolutionContainerCapsHelpers
{
public static bool HasCap(this SolutionContainerCaps cap, SolutionContainerCaps other)
{
return (cap & other) == other;
}
} }
} }

View File

@@ -38,7 +38,7 @@
drawWarnings: false drawWarnings: false
- type: SolutionContainer - type: SolutionContainer
maxVol: 200 maxVol: 200
caps: AddTo, NoExamine caps: AddTo
- type: Pourable - type: Pourable
- type: SnapGrid - type: SnapGrid
offset: Center offset: Center

View File

@@ -20,7 +20,7 @@
# Organs # Organs
- type: SolutionContainer - type: SolutionContainer
maxVol: 250 maxVol: 250
caps: AddTo, RemoveFrom, NoExamine caps: AddTo, RemoveFrom
- type: Bloodstream - type: Bloodstream
max_volume: 100 max_volume: 100
# StatusEffects # StatusEffects

View File

@@ -1,10 +1,10 @@
- type: entity - type: entity
parent: BaseItem parent: BaseItem
id: ProduceBase id: ProduceBase
abstract: true abstract: true
components: components:
- type: SolutionContainer - type: SolutionContainer
caps: NoExamine caps: None
- type: Sprite - type: Sprite
state: produce state: produce
- type: Produce - type: Produce
@@ -18,7 +18,7 @@
- type: Sprite - type: Sprite
sprite: Objects/Specific/Hydroponics/wheat.rsi sprite: Objects/Specific/Hydroponics/wheat.rsi
- type: SolutionContainer - type: SolutionContainer
caps: NoExamine caps: None
contents: contents:
reagents: reagents:
- ReagentId: chem.Nutriment - ReagentId: chem.Nutriment
@@ -38,7 +38,7 @@
- type: Sprite - type: Sprite
sprite: Objects/Specific/Hydroponics/sugarcane.rsi sprite: Objects/Specific/Hydroponics/sugarcane.rsi
- type: SolutionContainer - type: SolutionContainer
caps: NoExamine caps: None
contents: contents:
reagents: reagents:
- ReagentId: chem.Nutriment - ReagentId: chem.Nutriment
@@ -58,7 +58,7 @@
- type: Sprite - type: Sprite
sprite: Objects/Specific/Hydroponics/towercap.rsi sprite: Objects/Specific/Hydroponics/towercap.rsi
- type: SolutionContainer - type: SolutionContainer
caps: NoExamine caps: None
- type: MeleeWeapon - type: MeleeWeapon
- type: Produce - type: Produce
seed: towercap seed: towercap

View File

@@ -1,4 +1,4 @@
# TODO: Find remaining cans and move to drinks_cans # TODO: Find remaining cans and move to drinks_cans
# TODO: Find empty containers (e.g. mug, pitcher) and move to their own yml # TODO: Find empty containers (e.g. mug, pitcher) and move to their own yml
# TODO: Move bottles to their own yml # TODO: Move bottles to their own yml
- type: entity - type: entity
@@ -8,7 +8,6 @@
components: components:
- type: SolutionContainer - type: SolutionContainer
maxVol: 50 maxVol: 50
caps: AddTo, RemoveFrom
- type: Pourable - type: Pourable
transferAmount: 5 transferAmount: 5
- type: Drink - type: Drink
@@ -55,7 +54,6 @@
- type: SolutionContainer - type: SolutionContainer
fillingState: glass fillingState: glass
maxVol: 50 maxVol: 50
caps: AddTo, RemoveFrom
- type: Pourable - type: Pourable
transferAmount: 5 transferAmount: 5
- type: TransformableContainer - type: TransformableContainer

View File

@@ -6,7 +6,6 @@
- type: Drink - type: Drink
openSounds: bottleOpenSounds openSounds: bottleOpenSounds
- type: SolutionContainer - type: SolutionContainer
caps: AddTo, RemoveFrom
- type: Pourable - type: Pourable
transferAmount: 5 transferAmount: 5
- type: Sprite - type: Sprite

View File

@@ -7,7 +7,6 @@
components: components:
- type: SolutionContainer - type: SolutionContainer
maxVol: 20 maxVol: 20
caps: AddTo, RemoveFrom
- type: Pourable - type: Pourable
transferAmount: 5 transferAmount: 5
- type: Drink - type: Drink

View File

@@ -6,7 +6,7 @@
- type: Food - type: Food
- type: LoopingSound - type: LoopingSound
- type: SolutionContainer - type: SolutionContainer
caps: NoExamine caps: None
- type: Sprite - type: Sprite
state: icon state: icon
netsync: false netsync: false

View File

@@ -6,7 +6,6 @@
components: components:
- type: SolutionContainer - type: SolutionContainer
maxVol: 50 maxVol: 50
caps: AddTo, RemoveFrom
contents: contents:
reagents: reagents:
- ReagentId: chem.Flour - ReagentId: chem.Flour

View File

@@ -1,4 +1,4 @@
# These can still be used as containers # These can still be used as containers
- type: entity - type: entity
name: base empty bottle name: base empty bottle
parent: BaseItem parent: BaseItem
@@ -12,7 +12,6 @@
- type: SolutionContainer - type: SolutionContainer
maxVol: 10 maxVol: 10
caps: AddTo, RemoveFrom
- type: Pourable - type: Pourable
transferAmount: 5 transferAmount: 5
- type: Drink - type: Drink

View File

@@ -14,7 +14,7 @@
size: 10 size: 10
- type: SolutionContainer - type: SolutionContainer
maxVol: 100 maxVol: 100
caps: AddTo, RemoveFrom, NoExamine caps: AddTo, RemoveFrom
contents: contents:
reagents: reagents:
- ReagentId: chem.Water - ReagentId: chem.Water

View File

@@ -13,7 +13,7 @@
- type: SolutionContainer - type: SolutionContainer
fillingState: beaker fillingState: beaker
maxVol: 50 maxVol: 50
caps: AddTo, RemoveFrom, FitsInDispenser # can add and remove solutions and fits in the chemmaster. caps: CanExamine, AddTo, RemoveFrom, FitsInDispenser # can add and remove solutions and fits in the chemmaster.
- type: Pourable - type: Pourable
transferAmount: 5.0 transferAmount: 5.0
- type: Spillable - type: Spillable
@@ -34,7 +34,7 @@
- type: SolutionContainer - type: SolutionContainer
fillingState: beakerlarge fillingState: beakerlarge
maxVol: 100 maxVol: 100
caps: AddTo, RemoveFrom, FitsInDispenser caps: CanExamine, AddTo, RemoveFrom, FitsInDispenser
- type: Pourable - type: Pourable
transferAmount: 5.0 transferAmount: 5.0
- type: Spillable - type: Spillable
@@ -53,7 +53,6 @@
fillingState: dropper fillingState: dropper
fillingSteps: 2 fillingSteps: 2
maxVol: 5 maxVol: 5
caps: AddTo, RemoveFrom
- type: Pourable - type: Pourable
transferAmount: 5.0 transferAmount: 5.0
- type: Spillable - type: Spillable
@@ -71,7 +70,6 @@
fillingState: syringe fillingState: syringe
fillingSteps: 5 fillingSteps: 5
maxVol: 15 maxVol: 15
caps: AddTo, RemoveFrom
- type: Injector - type: Injector
injectOnly: false injectOnly: false
- type: Spillable - type: Spillable
@@ -87,7 +85,6 @@
- type: Drink - type: Drink
- type: SolutionContainer - type: SolutionContainer
maxVol: 30 maxVol: 30
caps: AddTo, RemoveFrom
- type: Pourable - type: Pourable
transferAmount: 5 transferAmount: 5
- type: Spillable - type: Spillable
@@ -104,4 +101,4 @@
- type: Pill - type: Pill
- type: SolutionContainer - type: SolutionContainer
maxVol: 50 maxVol: 50
caps: RemoveFrom caps: None

View File

@@ -1,4 +1,4 @@
- type: entity - type: entity
parent: BaseItem parent: BaseItem
name: mop name: mop
id: MopItem id: MopItem
@@ -13,7 +13,6 @@
- type: Mop - type: Mop
- type: SolutionContainer - type: SolutionContainer
maxVol: 10 maxVol: 10
caps: AddTo, RemoveFrom
- type: LoopingSound - type: LoopingSound
- type: entity - type: entity
@@ -33,7 +32,6 @@
- type: LoopingSound - type: LoopingSound
- type: SolutionContainer - type: SolutionContainer
maxVol: 500 maxVol: 500
caps: AddTo, RemoveFrom
- type: Physics - type: Physics
mass: 5 mass: 5
anchored: false anchored: false
@@ -65,7 +63,6 @@
- type: LoopingSound - type: LoopingSound
- type: SolutionContainer - type: SolutionContainer
maxVol: 500 maxVol: 500
caps: AddTo, RemoveFrom
- type: Physics - type: Physics
mass: 5 mass: 5
anchored: false anchored: false
@@ -219,7 +216,6 @@
components: components:
- type: SolutionContainer - type: SolutionContainer
maxVol: 100 maxVol: 100
caps: AddTo, RemoveFrom
contents: contents:
reagents: reagents:
- ReagentId: chem.Water - ReagentId: chem.Water
@@ -234,7 +230,6 @@
components: components:
- type: SolutionContainer - type: SolutionContainer
maxVol: 100 maxVol: 100
caps: AddTo, RemoveFrom
contents: contents:
reagents: reagents:
- ReagentId: chem.SpaceCleaner - ReagentId: chem.SpaceCleaner

View File

@@ -1,11 +1,11 @@
- type: entity - type: entity
parent: BaseItem parent: BaseItem
id: SeedBase id: SeedBase
abstract: true abstract: true
components: components:
- type: Seed - type: Seed
- type: SolutionContainer - type: SolutionContainer
caps: NoExamine caps: None
- type: Sprite - type: Sprite
sprite: Objects/Specific/Hydroponics/seeds.rsi sprite: Objects/Specific/Hydroponics/seeds.rsi
state: seed state: seed

View File

@@ -1,4 +1,4 @@
- type: entity - type: entity
name: mini hoe name: mini hoe
parent: BaseItem parent: BaseItem
id: MiniHoe id: MiniHoe
@@ -24,7 +24,7 @@
state: plantbgone state: plantbgone
- type: SolutionContainer - type: SolutionContainer
maxVol: 100 maxVol: 100
caps: RemoveFrom, NoExamine caps: RemoveFrom
contents: contents:
reagents: reagents:
- ReagentId: chem.PlantBGone - ReagentId: chem.PlantBGone
@@ -42,7 +42,7 @@
state: weedspray state: weedspray
- type: SolutionContainer - type: SolutionContainer
maxVol: 50 maxVol: 50
caps: RemoveFrom, NoExamine caps: RemoveFrom
contents: contents:
reagents: reagents:
- ReagentId: chem.WeedKiller - ReagentId: chem.WeedKiller
@@ -65,7 +65,7 @@
state: pestspray state: pestspray
- type: SolutionContainer - type: SolutionContainer
maxVol: 50 maxVol: 50
caps: RemoveFrom, NoExamine caps: RemoveFrom
contents: contents:
reagents: reagents:
- ReagentId: chem.PestKiller - ReagentId: chem.PestKiller

View File

@@ -1,4 +1,4 @@
- type: entity - type: entity
name: haycutters name: haycutters
parent: BaseItem parent: BaseItem
id: Haycutters id: Haycutters
@@ -114,7 +114,7 @@
- type: ItemStatus - type: ItemStatus
- type: SolutionContainer - type: SolutionContainer
maxVol: 50 maxVol: 50
caps: AddTo, NoExamine caps: AddTo
contents: contents:
reagents: reagents:
- ReagentId: chem.WeldingFuel - ReagentId: chem.WeldingFuel

View File

@@ -20,7 +20,7 @@
- type: ItemStatus - type: ItemStatus
- type: SolutionContainer - type: SolutionContainer
maxVol: 100 maxVol: 100
caps: AddTo, NoExamine caps: AddTo
contents: contents:
reagents: reagents:
- ReagentId: chem.WeldingFuel - ReagentId: chem.WeldingFuel
@@ -44,7 +44,7 @@
sprite: Objects/Tools/welder_experimental.rsi sprite: Objects/Tools/welder_experimental.rsi
- type: SolutionContainer - type: SolutionContainer
maxVol: 1000 maxVol: 1000
caps: AddTo, NoExamine caps: AddTo
contents: contents:
reagents: reagents:
- ReagentId: chem.WeldingFuel - ReagentId: chem.WeldingFuel
@@ -66,7 +66,7 @@
sprite: Objects/Tools/welder_mini.rsi sprite: Objects/Tools/welder_mini.rsi
- type: SolutionContainer - type: SolutionContainer
maxVol: 25 maxVol: 25
caps: AddTo, NoExamine caps: AddTo
contents: contents:
reagents: reagents:
- ReagentId: chem.WeldingFuel - ReagentId: chem.WeldingFuel

View File

@@ -1,4 +1,4 @@
- type: entity - type: entity
name: spear name: spear
parent: BaseItem parent: BaseItem
id: Spear id: Spear
@@ -22,7 +22,6 @@
- type: MeleeChemicalInjector - type: MeleeChemicalInjector
- type: SolutionContainer - type: SolutionContainer
maxVol: 5 maxVol: 5
caps: AddTo, RemoveFrom
- type: Pourable - type: Pourable
- type: MeleeWeaponAnimation - type: MeleeWeaponAnimation

View File

@@ -8,7 +8,6 @@
- type: Sprite - type: Sprite
drawdepth: FloorObjects drawdepth: FloorObjects
- type: SolutionContainer - type: SolutionContainer
caps: AddTo, RemoveFrom
- type: Puddle - type: Puddle
spill_sound: /Audio/Effects/Fluids/splat.ogg spill_sound: /Audio/Effects/Fluids/splat.ogg
recolor: true recolor: true