grindable/juiceable stacks (#4391)

* grindable/juiceable stacks

reagent grinder now takes stacks into account
added ScaleSolution that allows easy scaling of solution contents

* grindable/juiceable stacks revision

grinder/juicer stack fix now ECS
added JuiceableScalingEvent

* Update Content.Server/Kitchen/EntitySystems/ReagentGrinderSystem.cs

Co-authored-by: mirrorcult <lunarautomaton6@gmail.com>

* Update Content.Server/Kitchen/EntitySystems/ReagentGrinderSystem.cs

Co-authored-by: mirrorcult <lunarautomaton6@gmail.com>
Co-authored-by: Vera Aguilera Puerto <6766154+Zumorica@users.noreply.github.com>
This commit is contained in:
plinyvic
2021-07-31 08:06:24 -04:00
committed by GitHub
parent 8aa4f998de
commit e5956566f5
3 changed files with 74 additions and 14 deletions

View File

@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Content.Server.Chemistry.Components; using Content.Server.Chemistry.Components;
@@ -6,7 +6,9 @@ using Content.Server.Hands.Components;
using Content.Server.Items; using Content.Server.Items;
using Content.Server.Kitchen.Components; using Content.Server.Kitchen.Components;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Server.Stack;
using Content.Server.UserInterface; using Content.Server.UserInterface;
using Content.Server.Kitchen.Events;
using Content.Shared.Chemistry.Solution; using Content.Shared.Chemistry.Solution;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Kitchen.Components; using Content.Shared.Kitchen.Components;
@@ -30,7 +32,7 @@ namespace Content.Server.Kitchen.EntitySystems
{ {
[Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!;
private Queue<ReagentGrinderComponent> _uiUpdateQueue = new (); private Queue<ReagentGrinderComponent> _uiUpdateQueue = new();
public override void Initialize() public override void Initialize()
{ {
@@ -40,11 +42,17 @@ namespace Content.Server.Kitchen.EntitySystems
SubscribeLocalEvent<ReagentGrinderComponent, PowerChangedEvent>((_, component, _) => EnqueueUiUpdate(component)); SubscribeLocalEvent<ReagentGrinderComponent, PowerChangedEvent>((_, component, _) => EnqueueUiUpdate(component));
SubscribeLocalEvent<ReagentGrinderComponent, InteractHandEvent>(OnInteractHand); SubscribeLocalEvent<ReagentGrinderComponent, InteractHandEvent>(OnInteractHand);
SubscribeLocalEvent<ReagentGrinderComponent, InteractUsingEvent>(OnInteractUsing); SubscribeLocalEvent<ReagentGrinderComponent, InteractUsingEvent>(OnInteractUsing);
SubscribeLocalEvent<StackComponent, JuiceableScalingEvent>(JuiceableScaling);
}
private void JuiceableScaling(EntityUid uid, StackComponent component, JuiceableScalingEvent args)
{
args.Scalar *= component.Count; // multiply scalar by amount of items in stack
} }
private void OnInteractUsing(EntityUid uid, ReagentGrinderComponent component, InteractUsingEvent args) private void OnInteractUsing(EntityUid uid, ReagentGrinderComponent component, InteractUsingEvent args)
{ {
if(args.Handled) return; if (args.Handled) return;
if (!args.User.TryGetComponent(out IHandsComponent? hands)) if (!args.User.TryGetComponent(out IHandsComponent? hands))
{ {
@@ -58,7 +66,7 @@ namespace Content.Server.Kitchen.EntitySystems
//First, check if user is trying to insert a beaker. //First, check if user is trying to insert a beaker.
//No promise it will be a beaker right now, but whatever. //No promise it will be a beaker right now, but whatever.
//Maybe this should whitelist "beaker" in the prototype id of heldEnt? //Maybe this should whitelist "beaker" in the prototype id of heldEnt?
if(heldEnt.TryGetComponent(out SolutionContainerComponent? beaker) && beaker.Capabilities.HasFlag(SolutionContainerCaps.FitsInDispenser)) if (heldEnt.TryGetComponent(out SolutionContainerComponent? beaker) && beaker.Capabilities.HasFlag(SolutionContainerCaps.FitsInDispenser))
{ {
component.BeakerContainer.Insert(heldEnt); component.BeakerContainer.Insert(heldEnt);
component.HeldBeaker = beaker; component.HeldBeaker = beaker;
@@ -74,7 +82,7 @@ namespace Content.Server.Kitchen.EntitySystems
} }
//Next, see if the user is trying to insert something they want to be ground/juiced. //Next, see if the user is trying to insert something they want to be ground/juiced.
if(!heldEnt.HasTag("Grindable") && !heldEnt.TryGetComponent(out JuiceableComponent? juice)) if (!heldEnt.HasTag("Grindable") && !heldEnt.TryGetComponent(out JuiceableComponent? juice))
{ {
//Entity did NOT pass the whitelist for grind/juice. //Entity did NOT pass the whitelist for grind/juice.
//Wouldn't want the clown grinding up the Captain's ID card now would you? //Wouldn't want the clown grinding up the Captain's ID card now would you?
@@ -113,7 +121,7 @@ namespace Content.Server.Kitchen.EntitySystems
private void EnqueueUiUpdate(ReagentGrinderComponent component) private void EnqueueUiUpdate(ReagentGrinderComponent component)
{ {
if(!_uiUpdateQueue.Contains(component)) _uiUpdateQueue.Enqueue(component); if (!_uiUpdateQueue.Contains(component)) _uiUpdateQueue.Enqueue(component);
} }
private void OnComponentInit(EntityUid uid, ReagentGrinderComponent component, ComponentInit args) private void OnComponentInit(EntityUid uid, ReagentGrinderComponent component, ComponentInit args)
@@ -138,12 +146,12 @@ namespace Content.Server.Kitchen.EntitySystems
private void OnUIMessageReceived(EntityUid uid, ReagentGrinderComponent component, private void OnUIMessageReceived(EntityUid uid, ReagentGrinderComponent component,
ServerBoundUserInterfaceMessage message) ServerBoundUserInterfaceMessage message)
{ {
if(component.Busy) if (component.Busy)
{ {
return; return;
} }
switch(message.Message) switch (message.Message)
{ {
case SharedReagentGrinderComponent.ReagentGrinderGrindStartMessage msg: case SharedReagentGrinderComponent.ReagentGrinderGrindStartMessage msg:
if (!component.Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || !receiver.Powered) break; if (!component.Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || !receiver.Powered) break;
@@ -158,7 +166,7 @@ namespace Content.Server.Kitchen.EntitySystems
break; break;
case SharedReagentGrinderComponent.ReagentGrinderEjectChamberAllMessage msg: case SharedReagentGrinderComponent.ReagentGrinderEjectChamberAllMessage msg:
if(component.Chamber.ContainedEntities.Count > 0) if (component.Chamber.ContainedEntities.Count > 0)
{ {
ClickSound(component); ClickSound(component);
for (var i = component.Chamber.ContainedEntities.Count - 1; i >= 0; i--) for (var i = component.Chamber.ContainedEntities.Count - 1; i >= 0; i--)
@@ -234,7 +242,7 @@ namespace Content.Server.Kitchen.EntitySystems
return; return;
var beaker = component.BeakerContainer.ContainedEntity; var beaker = component.BeakerContainer.ContainedEntity;
if(beaker is null) if (beaker is null)
return; return;
component.BeakerContainer.Remove(beaker); component.BeakerContainer.Remove(beaker);
@@ -258,7 +266,7 @@ namespace Content.Server.Kitchen.EntitySystems
private void DoWork(ReagentGrinderComponent component, IEntity user, SharedReagentGrinderComponent.GrinderProgram program) private void DoWork(ReagentGrinderComponent component, IEntity user, SharedReagentGrinderComponent.GrinderProgram program)
{ {
//Have power, are we busy, chamber has anything to grind, a beaker for the grounds to go? //Have power, are we busy, chamber has anything to grind, a beaker for the grounds to go?
if(!component.Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || !receiver.Powered || component.Busy || component.Chamber.ContainedEntities.Count <= 0 || component.BeakerContainer.ContainedEntity == null || component.HeldBeaker == null) if (!component.Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || !receiver.Powered || component.Busy || component.Chamber.ContainedEntities.Count <= 0 || component.BeakerContainer.ContainedEntity == null || component.HeldBeaker == null)
{ {
return; return;
} }
@@ -278,12 +286,14 @@ namespace Content.Server.Kitchen.EntitySystems
{ {
if (!item.HasTag("Grindable")) continue; if (!item.HasTag("Grindable")) continue;
if (!item.TryGetComponent<SolutionContainerComponent>(out var solution)) continue; if (!item.TryGetComponent<SolutionContainerComponent>(out var solution)) continue;
if (component.HeldBeaker.CurrentVolume + solution.CurrentVolume > component.HeldBeaker.MaxVolume) continue; var juiceEvent = new JuiceableScalingEvent(); // default of scalar is always 1.0
RaiseLocalEvent<JuiceableScalingEvent>(item.Uid, juiceEvent, false);
if (component.HeldBeaker.CurrentVolume + solution.CurrentVolume * juiceEvent.Scalar > component.HeldBeaker.MaxVolume) continue;
solution.Solution.ScaleSolution(juiceEvent.Scalar);
component.HeldBeaker.TryAddSolution(solution.Solution); component.HeldBeaker.TryAddSolution(solution.Solution);
solution.RemoveAllSolution(); solution.RemoveAllSolution();
item.Delete(); item.Delete();
} }
component.Busy = false; component.Busy = false;
EnqueueUiUpdate(component); EnqueueUiUpdate(component);
bui?.SendMessage(new SharedReagentGrinderComponent.ReagentGrinderWorkCompleteMessage()); bui?.SendMessage(new SharedReagentGrinderComponent.ReagentGrinderWorkCompleteMessage());
@@ -297,7 +307,13 @@ namespace Content.Server.Kitchen.EntitySystems
foreach (var item in component.Chamber.ContainedEntities.ToList()) foreach (var item in component.Chamber.ContainedEntities.ToList())
{ {
if (!item.TryGetComponent<JuiceableComponent>(out var juiceMe)) continue; if (!item.TryGetComponent<JuiceableComponent>(out var juiceMe)) continue;
if (component.HeldBeaker.CurrentVolume + juiceMe.JuiceResultSolution.TotalVolume > component.HeldBeaker.MaxVolume) continue; var juiceEvent = new JuiceableScalingEvent(); // default of scalar is always 1.0
if (item.HasComponent<StackComponent>())
{
RaiseLocalEvent<JuiceableScalingEvent>(item.Uid, juiceEvent);
}
if (component.HeldBeaker.CurrentVolume + juiceMe.JuiceResultSolution.TotalVolume * juiceEvent.Scalar > component.HeldBeaker.MaxVolume) continue;
juiceMe.JuiceResultSolution.ScaleSolution(juiceEvent.Scalar);
component.HeldBeaker.TryAddSolution(juiceMe.JuiceResultSolution); component.HeldBeaker.TryAddSolution(juiceMe.JuiceResultSolution);
item.Delete(); item.Delete();
} }

View File

@@ -0,0 +1,23 @@
using Robust.Shared.GameObjects;
namespace Content.Server.Kitchen.Events
{
/// <summary>
/// Used in scaling amount of solution to extract in juicing
/// </summary>
public class JuiceableScalingEvent : EntityEventArgs
{
public JuiceableScalingEvent()
{
Scalar = 1f;
}
public float Scalar
{
get;
set;
}
}
}

View File

@@ -115,6 +115,27 @@ namespace Content.Shared.Chemistry.Solution
TotalVolume += quantity; TotalVolume += quantity;
} }
/// <summary>
/// Scales the amount of solution.
/// </summary>
/// <param name="scale">The scalar to modify the solution by.</param>
public void ScaleSolution(float scale)
{
if (scale == 1) return;
var tempContents = new List<ReagentQuantity>(_contents);
foreach(ReagentQuantity current in tempContents)
{
if(scale > 1)
{
AddReagent(current.ReagentId, current.Quantity * scale - current.Quantity);
}
else
{
RemoveReagent(current.ReagentId, current.Quantity - current.Quantity * scale);
}
}
}
/// <summary> /// <summary>
/// Returns the amount of a single reagent inside the solution. /// Returns the amount of a single reagent inside the solution.
/// </summary> /// </summary>