* Add random products datafield to the reaciton prototype. One of the items in the list will be used as additional products as a result of the reaction and will be persistent per round. Resolves #245 * Another try Add getter and setter for the reaction products field and add random products there. * There is no such product as CP14BasicEffectHealHeat * Try to visualize random products in the guidebook * experimental recipes * fix * file restructurization * Guidebook alchemy update * Update Alchemy.xml * fix * Update mixing_simple.yml --------- Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
105 lines
3.6 KiB
C#
105 lines
3.6 KiB
C#
using Content.Shared.Chemistry.Components;
|
|
using Content.Shared.Chemistry.Components.SolutionManager;
|
|
using Content.Shared.Chemistry.EntitySystems;
|
|
using Content.Shared.FixedPoint;
|
|
using Content.Shared.Interaction;
|
|
using Content.Shared.Kitchen.Components;
|
|
using Content.Shared.Stacks;
|
|
using Robust.Shared.Audio.Systems;
|
|
using Robust.Shared.Containers;
|
|
using Robust.Shared.Random;
|
|
|
|
namespace Content.Server._CP14.Alchemy;
|
|
|
|
public sealed partial class CP14AlchemyExtractionSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
|
[Dependency] private readonly SharedContainerSystem _container = default!;
|
|
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
|
|
[Dependency] private readonly IRobustRandom _random = default!;
|
|
[Dependency] private readonly SharedStackSystem _stackSystem = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<CP14MortarComponent, InteractUsingEvent>(OnInteractUsing);
|
|
}
|
|
|
|
private void OnInteractUsing(Entity<CP14MortarComponent> mortar, ref InteractUsingEvent args)
|
|
{
|
|
if (!TryComp<CP14PestleComponent>(args.Used, out var pestle))
|
|
return;
|
|
|
|
_audio.PlayPvs(pestle.HitSound, mortar);
|
|
|
|
var ev = new PestleGrindingEvent()
|
|
{
|
|
User = args.User,
|
|
Target = args.Target,
|
|
};
|
|
RaiseLocalEvent(args.Used, ev);
|
|
|
|
if (!_random.Prob(pestle.Probability))
|
|
return;
|
|
|
|
if (!TryComp<SolutionContainerManagerComponent>(mortar, out var solutionManagerComp))
|
|
return;
|
|
var solutionManager = new Entity<SolutionContainerManagerComponent?>(mortar, solutionManagerComp);
|
|
|
|
if (!_solutionContainer.TryGetSolution(solutionManager, mortar.Comp.Solution, out var solutionEnt, out var solution))
|
|
return;
|
|
|
|
if (!_container.TryGetContainer(mortar, mortar.Comp.ContainerId, out var container))
|
|
return;
|
|
|
|
if (container.ContainedEntities.Count == 0)
|
|
return;
|
|
|
|
var ent = _random.Pick(container.ContainedEntities);
|
|
|
|
var juiceSolution = CompOrNull<ExtractableComponent>(ent)?.JuiceSolution;
|
|
if (juiceSolution is null)
|
|
return;
|
|
|
|
if (TryComp<StackComponent>(ent, out var stack))
|
|
{
|
|
var totalVolume = juiceSolution.Volume * stack.Count;
|
|
if (totalVolume <= 0)
|
|
return;
|
|
|
|
// Maximum number of items we can process in the stack without going over AvailableVolume
|
|
// We add a small tolerance, because floats are inaccurate.
|
|
var fitsCount = (int) (stack.Count * FixedPoint2.Min(solution.AvailableVolume / totalVolume + 0.01, 1));
|
|
if (fitsCount <= 0)
|
|
return;
|
|
|
|
// Make a copy of the solution to scale
|
|
// Otherwise we'll actually change the volume of the remaining stack too
|
|
var scaledSolution = new Solution(juiceSolution);
|
|
scaledSolution.ScaleSolution(fitsCount);
|
|
juiceSolution = scaledSolution;
|
|
|
|
_stackSystem.SetCount(ent, stack.Count - fitsCount); // Setting to 0 will QueueDel
|
|
}
|
|
else
|
|
{
|
|
if (juiceSolution.Volume > solution.AvailableVolume)
|
|
return;
|
|
|
|
QueueDel(ent);
|
|
}
|
|
|
|
_solutionContainer.TryAddSolution(solutionEnt.Value, juiceSolution);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// is triggered on the pestle when the player uses it to grind something.
|
|
/// </summary>
|
|
public sealed class PestleGrindingEvent : EntityEventArgs
|
|
{
|
|
public EntityUid User;
|
|
public EntityUid Target;
|
|
}
|