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 Content.Server.Chemistry;
using Content.Server.GameObjects.Components.GUI;
@@ -51,10 +51,10 @@ namespace Content.Server.GameObjects.Components.Chemistry
public ReagentUnit EmptyVolume => MaxVolume - CurrentVolume;
public IReadOnlyList<Solution.ReagentQuantity> ReagentList => Solution.Contents;
public bool CanExamineContents => (Capabilities & SolutionContainerCaps.NoExamine) == 0;
public bool CanUseWithChemDispenser => (Capabilities & SolutionContainerCaps.FitsInDispenser) != 0;
public bool CanAddSolutions => (Capabilities & SolutionContainerCaps.AddTo) != 0;
public bool CanRemoveSolutions => (Capabilities & SolutionContainerCaps.RemoveFrom) != 0;
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)
@@ -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.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 _fillInitSteps, "fillingSteps", 7);
}
@@ -134,35 +134,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
protected void RecalculateColor()
{
if (Solution.TotalVolume == 0)
{
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;
SubstanceColor = Solution.Color;
}
/// <summary>
@@ -460,28 +432,14 @@ namespace Content.Server.GameObjects.Components.Chemistry
/// <returns>Return true if the solution contains the reagent.</returns>
public bool ContainsReagent(string reagentId, out ReagentUnit quantity)
{
foreach (var reagent in Solution.Contents)
{
if (reagent.ReagentId == reagentId)
{
quantity = reagent.Quantity;
return true;
}
}
quantity = ReagentUnit.New(0);
return false;
var containsReagent = Solution.ContainsReagent(reagentId, out var quantityFound);
quantity = quantityFound;
return containsReagent;
}
public string GetMajorReagentId()
{
if (Solution.Contents.Count == 0)
{
return "";
}
var majorReagent = Solution.Contents.OrderByDescending(reagent => reagent.Quantity).First();;
return majorReagent.ReagentId;
return Solution.GetPrimaryReagentId();
}
protected void UpdateFillIcon()

View File

@@ -1,8 +1,12 @@
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Robust.Shared.Interfaces.Serialization;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
@@ -27,6 +31,8 @@ namespace Content.Shared.Chemistry
[ViewVariables]
public ReagentUnit TotalVolume { get; private set; }
public Color Color => GetColor();
/// <summary>
/// Constructs an empty solution (ex. an empty beaker).
/// </summary>
@@ -57,6 +63,32 @@ namespace Content.Shared.Chemistry
() => _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>
/// Adds a given quantity of a reagent directly into the solution.
/// </summary>
@@ -231,6 +263,37 @@ namespace Content.Shared.Chemistry
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()
{
var volume = ReagentUnit.New(0);

View File

@@ -1,4 +1,4 @@
using System;
using System;
using Robust.Shared.Serialization;
namespace Content.Shared.Chemistry
@@ -33,6 +33,14 @@ namespace Content.Shared.Chemistry
/// <summary>
/// Can people examine the solution in the container or is it impossible to see?
/// </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
- type: SolutionContainer
maxVol: 200
caps: AddTo, NoExamine
caps: AddTo
- type: Pourable
- type: SnapGrid
offset: Center

View File

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

View File

@@ -1,10 +1,10 @@
- type: entity
- type: entity
parent: BaseItem
id: ProduceBase
abstract: true
components:
- type: SolutionContainer
caps: NoExamine
caps: None
- type: Sprite
state: produce
- type: Produce
@@ -18,7 +18,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/wheat.rsi
- type: SolutionContainer
caps: NoExamine
caps: None
contents:
reagents:
- ReagentId: chem.Nutriment
@@ -38,7 +38,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/sugarcane.rsi
- type: SolutionContainer
caps: NoExamine
caps: None
contents:
reagents:
- ReagentId: chem.Nutriment
@@ -58,7 +58,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/towercap.rsi
- type: SolutionContainer
caps: NoExamine
caps: None
- type: MeleeWeapon
- type: Produce
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: Move bottles to their own yml
- type: entity
@@ -8,7 +8,6 @@
components:
- type: SolutionContainer
maxVol: 50
caps: AddTo, RemoveFrom
- type: Pourable
transferAmount: 5
- type: Drink
@@ -55,7 +54,6 @@
- type: SolutionContainer
fillingState: glass
maxVol: 50
caps: AddTo, RemoveFrom
- type: Pourable
transferAmount: 5
- type: TransformableContainer

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,6 @@
components:
- type: SolutionContainer
maxVol: 50
caps: AddTo, RemoveFrom
contents:
reagents:
- 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
name: base empty bottle
parent: BaseItem
@@ -12,7 +12,6 @@
- type: SolutionContainer
maxVol: 10
caps: AddTo, RemoveFrom
- type: Pourable
transferAmount: 5
- type: Drink

View File

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

View File

@@ -13,7 +13,7 @@
- type: SolutionContainer
fillingState: beaker
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
transferAmount: 5.0
- type: Spillable
@@ -34,7 +34,7 @@
- type: SolutionContainer
fillingState: beakerlarge
maxVol: 100
caps: AddTo, RemoveFrom, FitsInDispenser
caps: CanExamine, AddTo, RemoveFrom, FitsInDispenser
- type: Pourable
transferAmount: 5.0
- type: Spillable
@@ -53,7 +53,6 @@
fillingState: dropper
fillingSteps: 2
maxVol: 5
caps: AddTo, RemoveFrom
- type: Pourable
transferAmount: 5.0
- type: Spillable
@@ -71,7 +70,6 @@
fillingState: syringe
fillingSteps: 5
maxVol: 15
caps: AddTo, RemoveFrom
- type: Injector
injectOnly: false
- type: Spillable
@@ -87,7 +85,6 @@
- type: Drink
- type: SolutionContainer
maxVol: 30
caps: AddTo, RemoveFrom
- type: Pourable
transferAmount: 5
- type: Spillable
@@ -104,4 +101,4 @@
- type: Pill
- type: SolutionContainer
maxVol: 50
caps: RemoveFrom
caps: None

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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