| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- using System.Diagnostics.CodeAnalysis;
- using System.Linq;
- using Content.Shared.Emag.Systems;
- using Content.Shared.Examine;
- using Content.Shared.Lathe.Prototypes;
- using Content.Shared.Localizations;
- using Content.Shared.Materials;
- using Content.Shared.Research.Prototypes;
- using JetBrains.Annotations;
- using Robust.Shared.Prototypes;
- using Robust.Shared.Utility;
- namespace Content.Shared.Lathe;
- /// <summary>
- /// This handles...
- /// </summary>
- public abstract class SharedLatheSystem : EntitySystem
- {
- [Dependency] private readonly IPrototypeManager _proto = default!;
- [Dependency] private readonly SharedMaterialStorageSystem _materialStorage = default!;
- [Dependency] private readonly EmagSystem _emag = default!;
- public readonly Dictionary<string, List<LatheRecipePrototype>> InverseRecipes = new();
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<EmagLatheRecipesComponent, GotEmaggedEvent>(OnEmagged);
- SubscribeLocalEvent<LatheComponent, ExaminedEvent>(OnExamined);
- SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
- BuildInverseRecipeDictionary();
- }
- /// <summary>
- /// Add every recipe in the list of recipe packs to a single hashset.
- /// </summary>
- public void AddRecipesFromPacks(HashSet<ProtoId<LatheRecipePrototype>> recipes, IEnumerable<ProtoId<LatheRecipePackPrototype>> packs)
- {
- foreach (var id in packs)
- {
- var pack = _proto.Index(id);
- recipes.UnionWith(pack.Recipes);
- }
- }
- private void OnExamined(Entity<LatheComponent> ent, ref ExaminedEvent args)
- {
- if (!args.IsInDetailsRange)
- return;
- if (ent.Comp.ReagentOutputSlotId != null)
- args.PushMarkup(Loc.GetString("lathe-menu-reagent-slot-examine"));
- }
- [PublicAPI]
- public bool CanProduce(EntityUid uid, string recipe, int amount = 1, LatheComponent? component = null)
- {
- return _proto.TryIndex<LatheRecipePrototype>(recipe, out var proto) && CanProduce(uid, proto, amount, component);
- }
- public bool CanProduce(EntityUid uid, LatheRecipePrototype recipe, int amount = 1, LatheComponent? component = null)
- {
- if (!Resolve(uid, ref component))
- return false;
- if (!HasRecipe(uid, recipe, component))
- return false;
- foreach (var (material, needed) in recipe.Materials)
- {
- var adjustedAmount = AdjustMaterial(needed, recipe.ApplyMaterialDiscount, component.MaterialUseMultiplier);
- if (_materialStorage.GetMaterialAmount(uid, material) < adjustedAmount * amount)
- return false;
- }
- return true;
- }
- private void OnEmagged(EntityUid uid, EmagLatheRecipesComponent component, ref GotEmaggedEvent args)
- {
- if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
- return;
- if (_emag.CheckFlag(uid, EmagType.Interaction))
- return;
- args.Handled = true;
- }
- public static int AdjustMaterial(int original, bool reduce, float multiplier)
- => reduce ? (int) MathF.Ceiling(original * multiplier) : original;
- protected abstract bool HasRecipe(EntityUid uid, LatheRecipePrototype recipe, LatheComponent component);
- private void OnPrototypesReloaded(PrototypesReloadedEventArgs obj)
- {
- if (!obj.WasModified<LatheRecipePrototype>())
- return;
- BuildInverseRecipeDictionary();
- }
- private void BuildInverseRecipeDictionary()
- {
- InverseRecipes.Clear();
- foreach (var latheRecipe in _proto.EnumeratePrototypes<LatheRecipePrototype>())
- {
- if (latheRecipe.Result is not {} result)
- continue;
- InverseRecipes.GetOrNew(result).Add(latheRecipe);
- }
- }
- public bool TryGetRecipesFromEntity(string prototype, [NotNullWhen(true)] out List<LatheRecipePrototype>? recipes)
- {
- recipes = new();
- if (InverseRecipes.TryGetValue(prototype, out var r))
- recipes.AddRange(r);
- return recipes.Count != 0;
- }
- public string GetRecipeName(ProtoId<LatheRecipePrototype> proto)
- {
- return GetRecipeName(_proto.Index(proto));
- }
- public string GetRecipeName(LatheRecipePrototype proto)
- {
- if (!string.IsNullOrWhiteSpace(proto.Name))
- return Loc.GetString(proto.Name);
- if (proto.Result is {} result)
- {
- return _proto.Index(result).Name;
- }
- if (proto.ResultReagents is { } resultReagents)
- {
- return ContentLocalizationManager.FormatList(resultReagents
- .Select(p => Loc.GetString("lathe-menu-result-reagent-display", ("reagent", _proto.Index(p.Key).LocalizedName), ("amount", p.Value)))
- .ToList());
- }
- return string.Empty;
- }
- [PublicAPI]
- public string GetRecipeDescription(ProtoId<LatheRecipePrototype> proto)
- {
- return GetRecipeDescription(_proto.Index(proto));
- }
- public string GetRecipeDescription(LatheRecipePrototype proto)
- {
- if (!string.IsNullOrWhiteSpace(proto.Description))
- return Loc.GetString(proto.Description);
- if (proto.Result is {} result)
- {
- return _proto.Index(result).Description;
- }
- if (proto.ResultReagents is { } resultReagents)
- {
- // We only use the first one for the description since these descriptions don't combine very well.
- var reagent = resultReagents.First().Key;
- return _proto.Index(reagent).LocalizedDescription;
- }
- return string.Empty;
- }
- }
|