Flavor profiles (#10991)
* flavor profiles
TODO: every single flavor! yeah!!!
* adds basic localization, and flavors/lastFlavor values for when you get the flavor profile message
* multiple and single flavor messages
* start on flavor localization, multiple flavors in localized flavors
* flavor prototypes
* a few more flavors, descriptions on what each section of the flavor file should be doing
* localization for flavor profiles in drink/food system
* adds an event that allows a flavor profile list to be transformed base on the user entity
* raises it on the food entity too
* changes a field in flavor, adds some more flavors, starts adding flavor prototypes
* adds basic flavors to several entities, and consumable drinks, renames flavor field to 'flavors'
* changes call ordering in flavorprofile, adds flavor to ignored components server-side
flavor is really just a popup message, and those are all processed server-side
* fixes where food tried to get the flavor of the user instead of the food
* single flavors will now get the localized string
* getting the flavor message now ensures that flavors are deduplicated
* makes flavor processing more strictly unique bu making everything hashsets
* yeah, that could just not have distinctby now
* adds flavorprofile directly to food base instead for generic food taste
* FlavorProfileModificationEvent now passes a hashset of strings and not flavorprototypes
* flavorprofilesystem now broadcasts the flavor profile modification event
* adds more flavors to the flavor profile loc file
* skips a flavor, if the flavor string is null/empty
* adds some more flavors, adds generic medicine flavor to medicinal chemicals
* more food flavors, adds flavors to swallowing
* adds some cocktails to the set of flavor profiles
* regenerates flavor prototypes
* adds flavor type to all flavors, adds whitespace between variants
* adds more flavors, adds flavors to several chemicals and food items
this is the part that took the longest
* changes backup flavor message
* spelling mistake
* more flavors, and flavors on food
* readds all the type fields, whoops
* fixes localization strings for forcefeeding food/drink
* fixes multiple flavor profile
* adds flavor limit for flavors
* makes that fetch the cvardef instead
2022-09-08 16:14:49 -07:00
|
|
|
using Content.Server.Nutrition.Components;
|
|
|
|
|
using Content.Shared.CCVar;
|
|
|
|
|
using Content.Shared.Chemistry.Components;
|
2023-08-06 14:47:45 +12:00
|
|
|
using Content.Shared.Nutrition;
|
Flavor profiles (#10991)
* flavor profiles
TODO: every single flavor! yeah!!!
* adds basic localization, and flavors/lastFlavor values for when you get the flavor profile message
* multiple and single flavor messages
* start on flavor localization, multiple flavors in localized flavors
* flavor prototypes
* a few more flavors, descriptions on what each section of the flavor file should be doing
* localization for flavor profiles in drink/food system
* adds an event that allows a flavor profile list to be transformed base on the user entity
* raises it on the food entity too
* changes a field in flavor, adds some more flavors, starts adding flavor prototypes
* adds basic flavors to several entities, and consumable drinks, renames flavor field to 'flavors'
* changes call ordering in flavorprofile, adds flavor to ignored components server-side
flavor is really just a popup message, and those are all processed server-side
* fixes where food tried to get the flavor of the user instead of the food
* single flavors will now get the localized string
* getting the flavor message now ensures that flavors are deduplicated
* makes flavor processing more strictly unique bu making everything hashsets
* yeah, that could just not have distinctby now
* adds flavorprofile directly to food base instead for generic food taste
* FlavorProfileModificationEvent now passes a hashset of strings and not flavorprototypes
* flavorprofilesystem now broadcasts the flavor profile modification event
* adds more flavors to the flavor profile loc file
* skips a flavor, if the flavor string is null/empty
* adds some more flavors, adds generic medicine flavor to medicinal chemicals
* more food flavors, adds flavors to swallowing
* adds some cocktails to the set of flavor profiles
* regenerates flavor prototypes
* adds flavor type to all flavors, adds whitespace between variants
* adds more flavors, adds flavors to several chemicals and food items
this is the part that took the longest
* changes backup flavor message
* spelling mistake
* more flavors, and flavors on food
* readds all the type fields, whoops
* fixes localization strings for forcefeeding food/drink
* fixes multiple flavor profile
* adds flavor limit for flavors
* makes that fetch the cvardef instead
2022-09-08 16:14:49 -07:00
|
|
|
using Robust.Shared.Configuration;
|
|
|
|
|
using Robust.Shared.Prototypes;
|
2023-12-29 04:47:43 -08:00
|
|
|
using System.Linq;
|
Flavor profiles (#10991)
* flavor profiles
TODO: every single flavor! yeah!!!
* adds basic localization, and flavors/lastFlavor values for when you get the flavor profile message
* multiple and single flavor messages
* start on flavor localization, multiple flavors in localized flavors
* flavor prototypes
* a few more flavors, descriptions on what each section of the flavor file should be doing
* localization for flavor profiles in drink/food system
* adds an event that allows a flavor profile list to be transformed base on the user entity
* raises it on the food entity too
* changes a field in flavor, adds some more flavors, starts adding flavor prototypes
* adds basic flavors to several entities, and consumable drinks, renames flavor field to 'flavors'
* changes call ordering in flavorprofile, adds flavor to ignored components server-side
flavor is really just a popup message, and those are all processed server-side
* fixes where food tried to get the flavor of the user instead of the food
* single flavors will now get the localized string
* getting the flavor message now ensures that flavors are deduplicated
* makes flavor processing more strictly unique bu making everything hashsets
* yeah, that could just not have distinctby now
* adds flavorprofile directly to food base instead for generic food taste
* FlavorProfileModificationEvent now passes a hashset of strings and not flavorprototypes
* flavorprofilesystem now broadcasts the flavor profile modification event
* adds more flavors to the flavor profile loc file
* skips a flavor, if the flavor string is null/empty
* adds some more flavors, adds generic medicine flavor to medicinal chemicals
* more food flavors, adds flavors to swallowing
* adds some cocktails to the set of flavor profiles
* regenerates flavor prototypes
* adds flavor type to all flavors, adds whitespace between variants
* adds more flavors, adds flavors to several chemicals and food items
this is the part that took the longest
* changes backup flavor message
* spelling mistake
* more flavors, and flavors on food
* readds all the type fields, whoops
* fixes localization strings for forcefeeding food/drink
* fixes multiple flavor profile
* adds flavor limit for flavors
* makes that fetch the cvardef instead
2022-09-08 16:14:49 -07:00
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2022-09-14 19:09:15 +12:00
|
|
|
if (!Resolve(uid, ref flavorProfile, false))
|
Flavor profiles (#10991)
* flavor profiles
TODO: every single flavor! yeah!!!
* adds basic localization, and flavors/lastFlavor values for when you get the flavor profile message
* multiple and single flavor messages
* start on flavor localization, multiple flavors in localized flavors
* flavor prototypes
* a few more flavors, descriptions on what each section of the flavor file should be doing
* localization for flavor profiles in drink/food system
* adds an event that allows a flavor profile list to be transformed base on the user entity
* raises it on the food entity too
* changes a field in flavor, adds some more flavors, starts adding flavor prototypes
* adds basic flavors to several entities, and consumable drinks, renames flavor field to 'flavors'
* changes call ordering in flavorprofile, adds flavor to ignored components server-side
flavor is really just a popup message, and those are all processed server-side
* fixes where food tried to get the flavor of the user instead of the food
* single flavors will now get the localized string
* getting the flavor message now ensures that flavors are deduplicated
* makes flavor processing more strictly unique bu making everything hashsets
* yeah, that could just not have distinctby now
* adds flavorprofile directly to food base instead for generic food taste
* FlavorProfileModificationEvent now passes a hashset of strings and not flavorprototypes
* flavorprofilesystem now broadcasts the flavor profile modification event
* adds more flavors to the flavor profile loc file
* skips a flavor, if the flavor string is null/empty
* adds some more flavors, adds generic medicine flavor to medicinal chemicals
* more food flavors, adds flavors to swallowing
* adds some cocktails to the set of flavor profiles
* regenerates flavor prototypes
* adds flavor type to all flavors, adds whitespace between variants
* adds more flavors, adds flavors to several chemicals and food items
this is the part that took the longest
* changes backup flavor message
* spelling mistake
* more flavors, and flavors on food
* readds all the type fields, whoops
* fixes localization strings for forcefeeding food/drink
* fixes multiple flavor profile
* adds flavor limit for flavors
* makes that fetch the cvardef instead
2022-09-08 16:14:49 -07:00
|
|
|
{
|
|
|
|
|
return Loc.GetString(BackupFlavorMessage);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-07 04:29:23 +00:00
|
|
|
var flavors = new HashSet<string>(flavorProfile.Flavors);
|
Flavor profiles (#10991)
* flavor profiles
TODO: every single flavor! yeah!!!
* adds basic localization, and flavors/lastFlavor values for when you get the flavor profile message
* multiple and single flavor messages
* start on flavor localization, multiple flavors in localized flavors
* flavor prototypes
* a few more flavors, descriptions on what each section of the flavor file should be doing
* localization for flavor profiles in drink/food system
* adds an event that allows a flavor profile list to be transformed base on the user entity
* raises it on the food entity too
* changes a field in flavor, adds some more flavors, starts adding flavor prototypes
* adds basic flavors to several entities, and consumable drinks, renames flavor field to 'flavors'
* changes call ordering in flavorprofile, adds flavor to ignored components server-side
flavor is really just a popup message, and those are all processed server-side
* fixes where food tried to get the flavor of the user instead of the food
* single flavors will now get the localized string
* getting the flavor message now ensures that flavors are deduplicated
* makes flavor processing more strictly unique bu making everything hashsets
* yeah, that could just not have distinctby now
* adds flavorprofile directly to food base instead for generic food taste
* FlavorProfileModificationEvent now passes a hashset of strings and not flavorprototypes
* flavorprofilesystem now broadcasts the flavor profile modification event
* adds more flavors to the flavor profile loc file
* skips a flavor, if the flavor string is null/empty
* adds some more flavors, adds generic medicine flavor to medicinal chemicals
* more food flavors, adds flavors to swallowing
* adds some cocktails to the set of flavor profiles
* regenerates flavor prototypes
* adds flavor type to all flavors, adds whitespace between variants
* adds more flavors, adds flavors to several chemicals and food items
this is the part that took the longest
* changes backup flavor message
* spelling mistake
* more flavors, and flavors on food
* readds all the type fields, whoops
* fixes localization strings for forcefeeding food/drink
* fixes multiple flavor profile
* adds flavor limit for flavors
* makes that fetch the cvardef instead
2022-09-08 16:14:49 -07:00
|
|
|
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>();
|
2023-09-05 09:55:10 +12:00
|
|
|
foreach (var (reagent, quantity) in solution.GetReagentPrototypes(_prototypeManager))
|
Flavor profiles (#10991)
* flavor profiles
TODO: every single flavor! yeah!!!
* adds basic localization, and flavors/lastFlavor values for when you get the flavor profile message
* multiple and single flavor messages
* start on flavor localization, multiple flavors in localized flavors
* flavor prototypes
* a few more flavors, descriptions on what each section of the flavor file should be doing
* localization for flavor profiles in drink/food system
* adds an event that allows a flavor profile list to be transformed base on the user entity
* raises it on the food entity too
* changes a field in flavor, adds some more flavors, starts adding flavor prototypes
* adds basic flavors to several entities, and consumable drinks, renames flavor field to 'flavors'
* changes call ordering in flavorprofile, adds flavor to ignored components server-side
flavor is really just a popup message, and those are all processed server-side
* fixes where food tried to get the flavor of the user instead of the food
* single flavors will now get the localized string
* getting the flavor message now ensures that flavors are deduplicated
* makes flavor processing more strictly unique bu making everything hashsets
* yeah, that could just not have distinctby now
* adds flavorprofile directly to food base instead for generic food taste
* FlavorProfileModificationEvent now passes a hashset of strings and not flavorprototypes
* flavorprofilesystem now broadcasts the flavor profile modification event
* adds more flavors to the flavor profile loc file
* skips a flavor, if the flavor string is null/empty
* adds some more flavors, adds generic medicine flavor to medicinal chemicals
* more food flavors, adds flavors to swallowing
* adds some cocktails to the set of flavor profiles
* regenerates flavor prototypes
* adds flavor type to all flavors, adds whitespace between variants
* adds more flavors, adds flavors to several chemicals and food items
this is the part that took the longest
* changes backup flavor message
* spelling mistake
* more flavors, and flavors on food
* readds all the type fields, whoops
* fixes localization strings for forcefeeding food/drink
* fixes multiple flavor profile
* adds flavor limit for flavors
* makes that fetch the cvardef instead
2022-09-08 16:14:49 -07:00
|
|
|
{
|
2023-09-05 09:55:10 +12:00
|
|
|
if (toIgnore != null && toIgnore.Contains(reagent.ID))
|
Flavor profiles (#10991)
* flavor profiles
TODO: every single flavor! yeah!!!
* adds basic localization, and flavors/lastFlavor values for when you get the flavor profile message
* multiple and single flavor messages
* start on flavor localization, multiple flavors in localized flavors
* flavor prototypes
* a few more flavors, descriptions on what each section of the flavor file should be doing
* localization for flavor profiles in drink/food system
* adds an event that allows a flavor profile list to be transformed base on the user entity
* raises it on the food entity too
* changes a field in flavor, adds some more flavors, starts adding flavor prototypes
* adds basic flavors to several entities, and consumable drinks, renames flavor field to 'flavors'
* changes call ordering in flavorprofile, adds flavor to ignored components server-side
flavor is really just a popup message, and those are all processed server-side
* fixes where food tried to get the flavor of the user instead of the food
* single flavors will now get the localized string
* getting the flavor message now ensures that flavors are deduplicated
* makes flavor processing more strictly unique bu making everything hashsets
* yeah, that could just not have distinctby now
* adds flavorprofile directly to food base instead for generic food taste
* FlavorProfileModificationEvent now passes a hashset of strings and not flavorprototypes
* flavorprofilesystem now broadcasts the flavor profile modification event
* adds more flavors to the flavor profile loc file
* skips a flavor, if the flavor string is null/empty
* adds some more flavors, adds generic medicine flavor to medicinal chemicals
* more food flavors, adds flavors to swallowing
* adds some cocktails to the set of flavor profiles
* regenerates flavor prototypes
* adds flavor type to all flavors, adds whitespace between variants
* adds more flavors, adds flavors to several chemicals and food items
this is the part that took the longest
* changes backup flavor message
* spelling mistake
* more flavors, and flavors on food
* readds all the type fields, whoops
* fixes localization strings for forcefeeding food/drink
* fixes multiple flavor profile
* adds flavor limit for flavors
* makes that fetch the cvardef instead
2022-09-08 16:14:49 -07:00
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (flavors.Count == desiredAmount)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-07 04:29:23 +00:00
|
|
|
// don't care if the quantity is negligible
|
2023-09-05 09:55:10 +12:00
|
|
|
if (quantity < reagent.FlavorMinimum)
|
2023-06-07 04:29:23 +00:00
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 09:55:10 +12:00
|
|
|
if (reagent.Flavor != null)
|
|
|
|
|
flavors.Add(reagent.Flavor);
|
Flavor profiles (#10991)
* flavor profiles
TODO: every single flavor! yeah!!!
* adds basic localization, and flavors/lastFlavor values for when you get the flavor profile message
* multiple and single flavor messages
* start on flavor localization, multiple flavors in localized flavors
* flavor prototypes
* a few more flavors, descriptions on what each section of the flavor file should be doing
* localization for flavor profiles in drink/food system
* adds an event that allows a flavor profile list to be transformed base on the user entity
* raises it on the food entity too
* changes a field in flavor, adds some more flavors, starts adding flavor prototypes
* adds basic flavors to several entities, and consumable drinks, renames flavor field to 'flavors'
* changes call ordering in flavorprofile, adds flavor to ignored components server-side
flavor is really just a popup message, and those are all processed server-side
* fixes where food tried to get the flavor of the user instead of the food
* single flavors will now get the localized string
* getting the flavor message now ensures that flavors are deduplicated
* makes flavor processing more strictly unique bu making everything hashsets
* yeah, that could just not have distinctby now
* adds flavorprofile directly to food base instead for generic food taste
* FlavorProfileModificationEvent now passes a hashset of strings and not flavorprototypes
* flavorprofilesystem now broadcasts the flavor profile modification event
* adds more flavors to the flavor profile loc file
* skips a flavor, if the flavor string is null/empty
* adds some more flavors, adds generic medicine flavor to medicinal chemicals
* more food flavors, adds flavors to swallowing
* adds some cocktails to the set of flavor profiles
* regenerates flavor prototypes
* adds flavor type to all flavors, adds whitespace between variants
* adds more flavors, adds flavors to several chemicals and food items
this is the part that took the longest
* changes backup flavor message
* spelling mistake
* more flavors, and flavors on food
* readds all the type fields, whoops
* fixes localization strings for forcefeeding food/drink
* fixes multiple flavor profile
* adds flavor limit for flavors
* makes that fetch the cvardef instead
2022-09-08 16:14:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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; }
|
|
|
|
|
}
|