using System.Linq;
using Content.Server.Botany.Components;
using Content.Server.Materials.Components;
using Content.Server.Power.EntitySystems;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Storage;
using Content.Shared.Storage.Components;
using Robust.Server.Audio;
namespace Content.Server.Materials;
public sealed class ProduceMaterialExtractorSystem : EntitySystem
{
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly MaterialStorageSystem _materialStorage = default!;
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
///
public override void Initialize()
{
SubscribeLocalEvent(OnInteractUsing);
}
private void OnInteractUsing(Entity ent, ref AfterInteractUsingEvent args)
{
if (args.Handled)
return;
if (!this.IsPowered(ent, EntityManager))
return;
bool success = false;
// Handle using bags (mainly plant bags)
if (ExtractFromStorage(ent, args.Used))
success = true;
// Handle using produce directly
if (ExtractFromProduce(ent, args.Used))
success = true;
// TODO: What if a bag is also a plant?
if (success)
{
_audio.PlayPvs(ent.Comp.ExtractSound, ent);
args.Handled = true;
}
}
private bool ExtractFromProduce(Entity ent, EntityUid used)
{
if (!TryComp(used, out var produce))
return false;
if (!_solutionContainer.TryGetSolution(used, produce.SolutionName, out var solution))
return false;
// Can produce even have fractional amounts? Does it matter if they do?
// Questions man was never meant to answer.
var matAmount = solution.Value.Comp.Solution.Contents
.Where(r => ent.Comp.ExtractionReagents.Contains(r.Reagent.Prototype))
.Sum(r => r.Quantity.Float());
var changed = (int)matAmount;
if (changed == 0)
{
_popup.PopupEntity(Loc.GetString("material-extractor-comp-wrongreagent", ("used", used)), ent);
return false;
}
_materialStorage.TryChangeMaterialAmount(ent, ent.Comp.ExtractedMaterial, changed);
QueueDel(used);
return true;
}
private bool ExtractFromStorage(Entity ent, EntityUid used)
{
if (!TryComp(used, out var storage))
return false;
bool success = false;
foreach (var (item, _location) in storage.StoredItems)
if (ExtractFromProduce(ent, item))
success = true;
return success;
}
}