6
2026-01-24 12:49:55 +03:00

91 lines
3.1 KiB
C#

using System.Linq;
using Content.Client.Chemistry.EntitySystems;
using Content.Server.Medical.Components;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Damage;
using Content.Shared.Kitchen;
using Robust.Server.Player;
using Robust.Shared.Enums;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server._NF.Medical.EntitySystems;
public sealed class MedicalRecipeDataSystem : SharedMedicalGuideDataSystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly IComponentFactory _componentFactory = default!;
private Dictionary<string, List<MedicalRecipeData>> _sources = new();
public override void Initialize()
{
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
_player.PlayerStatusChanged += OnPlayerStatusChanged;
ReloadRecipes();
}
private void OnPrototypesReloaded(PrototypesReloadedEventArgs args)
{
if (!args.WasModified<EntityPrototype>()
&& !args.WasModified<FoodRecipePrototype>()
)
return;
ReloadRecipes();
}
public void ReloadRecipes()
{
_sources.Clear();
// Recipes
foreach (var recipe in _protoMan.EnumeratePrototypes<FoodRecipePrototype>())
{
if (recipe.HideInGuidebook)
continue;
MicrowaveRecipeType recipeType = (MicrowaveRecipeType)recipe.RecipeType;
if (recipeType.HasFlag(MicrowaveRecipeType.MedicalAssembler))
{
_sources.GetOrNew(recipe.Result).Add(new MedicalRecipeData(recipe));
}
}
Registry.Clear();
foreach (var (result, sources) in _sources)
{
var proto = _protoMan.Index<EntityPrototype>(result);
ReagentQuantity[] reagents = [];
// Hack: assume there is only one solution in the result
if (proto.TryGetComponent<SolutionContainerManagerComponent>(out var manager, _componentFactory))
reagents = manager?.Solutions?.FirstOrNull()?.Value?.Contents?.ToArray() ?? [];
DamageSpecifier? damage = null;
if (proto.TryGetComponent<HealingComponent>(out var healing, _componentFactory))
damage = healing.Damage;
// Limit the number of sources to 10 - shouldn't be an issue for medical recipes, but just in case.
var distinctSources = sources.DistinctBy(it => it.Identitier).Take(10);
var entry = new MedicalGuideEntry(result, proto.Name, distinctSources.ToArray(), reagents, damage);
Registry.Add(entry);
}
RaiseNetworkEvent(new MedicalGuideRegistryChangedEvent(Registry));
}
private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs args)
{
if (args.NewStatus != SessionStatus.Connected)
return;
RaiseNetworkEvent(new MedicalGuideRegistryChangedEvent(Registry), args.Session);
}
}