Files
tbd-station-14/Content.Server/Nutrition/EntitySystems/FlavorProfileSystem.cs
TemporalOroboros d75e743dd7 Solution Entities (#21916)
* Creates Content.Shared.Chemistry.Solutions
Copies Solution class to new namespace
Obsoletes old Solution class

* Switches over to the Solutions.Solution Solution

* Creates Content.Shared.Chemistry.Containers
Copies relevant components/systems to the new namespace
Obsoletes old versions

* Switches over to the Containers.XYZ namespace

* Creates SolutionSystem and obsoletes old SolutionContainerSystem methods

* Start using SolutionSystem for Solution manipulation

* EnumerateSolutions

* Move TryGetMixableSolution

* Move EnsureSolution to Server

* Create Solution Entities

* Stop using obsolete solution system methods

* Fix prototype component tests

* Add using ..Audio.Systems; back

* Wrap solution container slots in ContainerSlots

* Actually add the slot to the solution container map

* Dirty SolutionContainerComponent when ensuring solutions

* Revert namespace changes

* Remerge SolutionSystem and SolutionContainerSystem

* SolutionContainerManagerComponent refactor

* Avoid wrapping necessary code in DebugTools.Assert as it is removed when compiling for release

* Readd examine reagent sorting

* Fix errors

* Poke tests

* Fix solution names not being applied

* Fix WoolyComponent including statement

* Fix merge skew

* Fix compile errors

* Make reactions use solntities

* Reindent solution class namespace

* Field attribute changes

* AutoGenerateComponentState for SolutionContainerComponent

* SolutionContainerComponent -> ContainedSolutionComponent

* ref ReactionAttemptEvent

* Denetwork preinit solutions

* Misc 1

* Nullable TryGetSolution out vars

* Cache associated solutions

* Fix merge skew

* Use explicit regions in SharedSolutionContainerSystem.Capabilities

* Add debug assert

* Use explicit regions in SharedSolutionContainerSystem.Relay + ref SolutionContainerChangedEvent

* ContainedSolutionComponent.Name -> ContainedSolutionComponent.ContainerName

* SolutionComponent doc comments

* Implicit DataField names and property purge

* ReagentEffect DataField names

* Local variables for readability

* Sort using statements + Entity<T> event handlers

* Fix compile erros

* Fix compile errors

---------

Co-authored-by: ElectroJr <leonsfriedrich@gmail.com>
2023-12-28 17:58:14 -08:00

121 lines
3.9 KiB
C#

using Content.Server.Nutrition.Components;
using Content.Shared.CCVar;
using Content.Shared.Chemistry.Components;
using Content.Shared.Nutrition;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using System.Linq;
namespace Content.Server.Nutrition.EntitySystems;
/// <summary>
/// Deals with flavor profiles when you eat something.
/// </summary>
public sealed class FlavorProfileSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
private const string BackupFlavorMessage = "flavor-profile-unknown";
private int FlavorLimit => _configManager.GetCVar(CCVars.FlavorLimit);
public string GetLocalizedFlavorsMessage(EntityUid uid, EntityUid user, Solution solution,
FlavorProfileComponent? flavorProfile = null)
{
if (!Resolve(uid, ref flavorProfile, false))
{
return Loc.GetString(BackupFlavorMessage);
}
var flavors = new HashSet<string>(flavorProfile.Flavors);
flavors.UnionWith(GetFlavorsFromReagents(solution, FlavorLimit - flavors.Count, flavorProfile.IgnoreReagents));
var ev = new FlavorProfileModificationEvent(user, flavors);
RaiseLocalEvent(ev);
RaiseLocalEvent(uid, ev);
RaiseLocalEvent(user, ev);
return FlavorsToFlavorMessage(flavors);
}
public string GetLocalizedFlavorsMessage(EntityUid user, Solution solution)
{
var flavors = GetFlavorsFromReagents(solution, FlavorLimit);
var ev = new FlavorProfileModificationEvent(user, flavors);
RaiseLocalEvent(user, ev, true);
return FlavorsToFlavorMessage(flavors);
}
private string FlavorsToFlavorMessage(HashSet<string> flavorSet)
{
var flavors = new List<FlavorPrototype>();
foreach (var flavor in flavorSet)
{
if (string.IsNullOrEmpty(flavor) || !_prototypeManager.TryIndex<FlavorPrototype>(flavor, out var flavorPrototype))
{
continue;
}
flavors.Add(flavorPrototype);
}
flavors.Sort((a, b) => a.FlavorType.CompareTo(b.FlavorType));
if (flavors.Count == 1 && !string.IsNullOrEmpty(flavors[0].FlavorDescription))
{
return Loc.GetString("flavor-profile", ("flavor", Loc.GetString(flavors[0].FlavorDescription)));
}
if (flavors.Count > 1)
{
var lastFlavor = Loc.GetString(flavors[^1].FlavorDescription);
var allFlavors = string.Join(", ", flavors.GetRange(0, flavors.Count - 1).Select(i => Loc.GetString(i.FlavorDescription)));
return Loc.GetString("flavor-profile-multiple", ("flavors", allFlavors), ("lastFlavor", lastFlavor));
}
return Loc.GetString(BackupFlavorMessage);
}
private HashSet<string> GetFlavorsFromReagents(Solution solution, int desiredAmount, HashSet<string>? toIgnore = null)
{
var flavors = new HashSet<string>();
foreach (var (reagent, quantity) in solution.GetReagentPrototypes(_prototypeManager))
{
if (toIgnore != null && toIgnore.Contains(reagent.ID))
{
continue;
}
if (flavors.Count == desiredAmount)
{
break;
}
// don't care if the quantity is negligible
if (quantity < reagent.FlavorMinimum)
{
continue;
}
if (reagent.Flavor != null)
flavors.Add(reagent.Flavor);
}
return flavors;
}
}
public sealed class FlavorProfileModificationEvent : EntityEventArgs
{
public FlavorProfileModificationEvent(EntityUid user, HashSet<string> flavors)
{
User = user;
Flavors = flavors;
}
public EntityUid User { get; }
public HashSet<string> Flavors { get; }
}