Solution rejig (#12428)

This commit is contained in:
Leon Friedrich
2023-01-12 16:41:40 +13:00
committed by GitHub
parent 38504f6412
commit 466384b081
61 changed files with 873 additions and 619 deletions

View File

@@ -1,4 +1,4 @@
using Content.Server.Body.Components;
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Server.Chemistry.EntitySystems;
using Content.Shared.Administration.Logs;
@@ -6,6 +6,7 @@ using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Foam;
using Content.Shared.Inventory;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.Components
{
@@ -14,6 +15,7 @@ namespace Content.Server.Chemistry.Components
public sealed class FoamSolutionAreaEffectComponent : SolutionAreaEffectComponent
{
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
public new const string SolutionName = "solutionArea";
@@ -25,7 +27,7 @@ namespace Content.Server.Chemistry.Components
if (_entMan.TryGetComponent(Owner, out AppearanceComponent? appearance) &&
EntitySystem.Get<SolutionContainerSystem>().TryGetSolution(Owner, SolutionName, out var solution))
{
appearance.SetData(FoamVisuals.Color, solution.Color.WithAlpha(0.80f));
appearance.SetData(FoamVisuals.Color, solution.GetColor(_proto).WithAlpha(0.80f));
}
}
@@ -60,7 +62,7 @@ namespace Content.Server.Chemistry.Components
var bloodstreamSys = EntitySystem.Get<BloodstreamSystem>();
var cloneSolution = solution.Clone();
var transferAmount = FixedPoint2.Min(cloneSolution.TotalVolume * solutionFraction * (1 - protection),
var transferAmount = FixedPoint2.Min(cloneSolution.Volume * solutionFraction * (1 - protection),
bloodstream.ChemicalSolution.AvailableVolume);
var transferSolution = cloneSolution.SplitSolution(transferAmount);

View File

@@ -25,7 +25,7 @@ namespace Content.Server.Chemistry.Components
{
var solutionSys = _entMan.EntitySysManager.GetEntitySystem<SolutionContainerSystem>();
return solutionSys.TryGetSolution(Owner, SolutionName, out var solution)
? new HyposprayComponentState(solution.CurrentVolume, solution.MaxVolume)
? new HyposprayComponentState(solution.Volume, solution.MaxVolume)
: new HyposprayComponentState(FixedPoint2.Zero, FixedPoint2.Zero);
}
}

View File

@@ -1,4 +1,4 @@
using Content.Server.Body.Components;
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Server.Chemistry.EntitySystems;
using Content.Shared.Administration.Logs;
@@ -7,6 +7,7 @@ using Content.Shared.Chemistry.Reagent;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Smoking;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.Components
{
@@ -15,6 +16,7 @@ namespace Content.Server.Chemistry.Components
public sealed class SmokeSolutionAreaEffectComponent : SolutionAreaEffectComponent
{
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
public new const string SolutionName = "solutionArea";
@@ -24,7 +26,7 @@ namespace Content.Server.Chemistry.Components
if (_entMan.TryGetComponent(Owner, out AppearanceComponent? appearance) &&
EntitySystem.Get<SolutionContainerSystem>().TryGetSolution(Owner, SolutionName, out var solution))
{
appearance.SetData(SmokeVisuals.Color, solution.Color);
appearance.SetData(SmokeVisuals.Color, solution.GetColor(_proto));
}
}
@@ -42,7 +44,7 @@ namespace Content.Server.Chemistry.Components
var chemistry = EntitySystem.Get<ReactiveSystem>();
var cloneSolution = solution.Clone();
var transferAmount = FixedPoint2.Min(cloneSolution.TotalVolume * solutionFraction, bloodstream.ChemicalSolution.AvailableVolume);
var transferAmount = FixedPoint2.Min(cloneSolution.Volume * solutionFraction, bloodstream.ChemicalSolution.AvailableVolume);
var transferSolution = cloneSolution.SplitSolution(transferAmount);
foreach (var reagentQuantity in transferSolution.Contents.ToArray())

View File

@@ -194,14 +194,14 @@ namespace Content.Server.Chemistry.Components
public void TryAddSolution(Solution solution)
{
if (solution.TotalVolume == 0)
if (solution.Volume == 0)
return;
if (!EntitySystem.Get<SolutionContainerSystem>().TryGetSolution(Owner, SolutionName, out var solutionArea))
return;
var addSolution =
solution.SplitSolution(FixedPoint2.Min(solution.TotalVolume, solutionArea.AvailableVolume));
solution.SplitSolution(FixedPoint2.Min(solution.Volume, solutionArea.AvailableVolume));
EntitySystem.Get<SolutionContainerSystem>().TryAddSolution(Owner, solutionArea, addSolution);

View File

@@ -66,7 +66,7 @@ namespace Content.Server.Chemistry.EntitySystems
var outputContainer = _itemSlotsSystem.GetItemOrNull(chemMaster.Owner, SharedChemMaster.OutputSlotName);
var bufferReagents = bufferSolution.Contents;
var bufferCurrentVolume = bufferSolution.CurrentVolume;
var bufferCurrentVolume = bufferSolution.Volume;
var state = new ChemMasterBoundUserInterfaceState(
chemMaster.Mode, BuildInputContainerInfo(inputContainer), BuildOutputContainerInfo(outputContainer),
@@ -288,7 +288,7 @@ namespace Content.Server.Chemistry.EntitySystems
return false;
}
if (solution.TotalVolume == 0)
if (solution.Volume == 0)
{
if (user.HasValue)
_popupSystem.PopupCursor(Loc.GetString("chem-master-window-buffer-empty-text"), user.Value);
@@ -296,7 +296,7 @@ namespace Content.Server.Chemistry.EntitySystems
}
// ReSharper disable once InvertIf
if (neededVolume > solution.CurrentVolume)
if (neededVolume > solution.Volume)
{
if (user.HasValue)
_popupSystem.PopupCursor(Loc.GetString("chem-master-window-buffer-low-text"), user.Value);
@@ -343,12 +343,12 @@ namespace Content.Server.Chemistry.EntitySystems
if (!TryComp(container, out ServerStorageComponent? storage))
return null;
var pills = storage.Storage?.ContainedEntities.Select(pill =>
var pills = storage.Storage?.ContainedEntities.Select((Func<EntityUid, (string, FixedPoint2 quantity)>) (pill =>
{
_solutionContainerSystem.TryGetSolution(pill, SharedChemMaster.PillSolutionName, out var solution);
var quantity = solution?.CurrentVolume ?? FixedPoint2.Zero;
return (Name(pill), quantity);
}).ToList();
var quantity = solution?.Volume ?? FixedPoint2.Zero;
return ((string, FixedPoint2 quantity))(Name(pill), quantity:(FixedPoint2) quantity);
})).ToList();
return pills is null
? null
@@ -360,7 +360,7 @@ namespace Content.Server.Chemistry.EntitySystems
var reagents = solution.Contents
.Select(reagent => (reagent.ReagentId, reagent.Quantity)).ToList();
return new ContainerInfo(name, true, solution.CurrentVolume, solution.MaxVolume, reagents);
return new ContainerInfo(name, true, solution.Volume, solution.MaxVolume, reagents);
}
}
}

View File

@@ -145,7 +145,7 @@ public sealed partial class ChemistrySystem
{
_solutions.TryGetSolution(uid, InjectorComponent.SolutionName, out var solution);
var currentVolume = solution?.CurrentVolume ?? FixedPoint2.Zero;
var currentVolume = solution?.Volume ?? FixedPoint2.Zero;
var maxVolume = solution?.MaxVolume ?? FixedPoint2.Zero;
args.State = new SharedInjectorComponent.InjectorComponentState(currentVolume, maxVolume, component.ToggleState);
@@ -323,7 +323,7 @@ public sealed partial class ChemistrySystem
removedSolution.DoEntityReaction(targetBloodstream.Owner, ReactionMethod.Injection);
_popup.PopupEntity(Loc.GetString("injector-component-inject-success-message",
("amount", removedSolution.TotalVolume),
("amount", removedSolution.Volume),
("target", Identity.Entity(targetBloodstream.Owner, EntityManager))), component.Owner, user);
Dirty(component);
@@ -333,7 +333,7 @@ public sealed partial class ChemistrySystem
private void TryInject(InjectorComponent component, EntityUid targetEntity, Solution targetSolution, EntityUid user, bool asRefill)
{
if (!_solutions.TryGetSolution(component.Owner, InjectorComponent.SolutionName, out var solution)
|| solution.CurrentVolume == 0)
|| solution.Volume == 0)
{
return;
}
@@ -363,7 +363,7 @@ public sealed partial class ChemistrySystem
}
_popup.PopupEntity(Loc.GetString("injector-component-transfer-success-message",
("amount", removedSolution.TotalVolume),
("amount", removedSolution.Volume),
("target", Identity.Entity(targetEntity, EntityManager))), component.Owner, user);
Dirty(component);
@@ -374,7 +374,7 @@ public sealed partial class ChemistrySystem
{
// Automatically set syringe to draw after completely draining it.
if (_solutions.TryGetSolution(component.Owner, InjectorComponent.SolutionName, out var solution)
&& solution.CurrentVolume == 0)
&& solution.Volume == 0)
{
component.ToggleState = SharedInjectorComponent.InjectorToggleMode.Draw;
}
@@ -399,7 +399,7 @@ public sealed partial class ChemistrySystem
}
// Get transfer amount. May be smaller than _transferAmount if not enough room, also make sure there's room in the injector
var realTransferAmount = FixedPoint2.Min(component.TransferAmount, targetSolution.DrawAvailable, solution.AvailableVolume);
var realTransferAmount = FixedPoint2.Min(component.TransferAmount, targetSolution.Volume, solution.AvailableVolume);
if (realTransferAmount <= 0)
{
@@ -424,7 +424,7 @@ public sealed partial class ChemistrySystem
}
_popup.PopupEntity(Loc.GetString("injector-component-draw-success-message",
("amount", removedSolution.TotalVolume),
("amount", removedSolution.Volume),
("target", Identity.Entity(targetEntity, EntityManager))), component.Owner, user);
Dirty(component);
@@ -436,7 +436,7 @@ public sealed partial class ChemistrySystem
var drawAmount = (float) transferAmount;
var bloodAmount = drawAmount;
var chemAmount = 0f;
if (stream.ChemicalSolution.CurrentVolume > 0f) // If they have stuff in their chem stream, we'll draw some of that
if (stream.ChemicalSolution.Volume > 0f) // If they have stuff in their chem stream, we'll draw some of that
{
bloodAmount = drawAmount * 0.85f;
chemAmount = drawAmount * 0.15f;

View File

@@ -77,7 +77,7 @@ namespace Content.Server.Chemistry.EntitySystems
_solutions.TryGetSolution(uid, component.SolutionName, out var hypoSpraySolution);
if (hypoSpraySolution == null || hypoSpraySolution.CurrentVolume == 0)
if (hypoSpraySolution == null || hypoSpraySolution.Volume == 0)
{
_popup.PopupCursor(Loc.GetString("hypospray-component-empty-message"), user);
return true;

View File

@@ -6,6 +6,7 @@ using Content.Shared.Chemistry.Dispenser;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Database;
using Content.Shared.Emag.Systems;
using Content.Shared.FixedPoint;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
@@ -62,7 +63,7 @@ namespace Content.Server.Chemistry.EntitySystems
if (_solutionContainerSystem.TryGetFitsInDispenser(container.Value, out var solution))
{
var reagents = solution.Contents.Select(reagent => (reagent.ReagentId, reagent.Quantity)).ToList();
return new ContainerInfo(Name(container.Value), true, solution.CurrentVolume, solution.MaxVolume, reagents);
return new ContainerInfo(Name(container.Value), true, solution.Volume, solution.MaxVolume, reagents);
}
return null;

View File

@@ -110,7 +110,7 @@ public sealed partial class SolutionContainerSystem
{
return !TryGetDrainableSolution(uid, out var solution)
? FixedPoint2.Zero
: solution.CurrentVolume;
: solution.Volume;
}
public float PercentFull(EntityUid uid)
@@ -118,7 +118,7 @@ public sealed partial class SolutionContainerSystem
if (!TryGetDrainableSolution(uid, out var solution) || solution.MaxVolume.Equals(FixedPoint2.Zero))
return 0;
return ((solution.CurrentVolume.Float() / solution.MaxVolume.Float()) * 100);
return solution.FillFraction * 100;
}
public bool TryGetFitsInDispenser(EntityUid owner,

View File

@@ -51,13 +51,7 @@ public sealed partial class SolutionContainerSystem : EntitySystem
foreach (var (name, solutionHolder) in component.Solutions)
{
solutionHolder.Name = name;
if (solutionHolder.MaxVolume == FixedPoint2.Zero)
{
solutionHolder.MaxVolume = solutionHolder.TotalVolume > solutionHolder.InitialMaxVolume
? solutionHolder.TotalVolume
: solutionHolder.InitialMaxVolume;
}
solutionHolder.ValidateSolution();
UpdateAppearance(uid, solutionHolder);
}
}
@@ -70,14 +64,14 @@ public sealed partial class SolutionContainerSystem : EntitySystem
|| !solutionsManager.Solutions.TryGetValue(examinableComponent.Solution, out var solutionHolder))
return;
if (solutionHolder.Contents.Count == 0)
var primaryReagent = solutionHolder.GetPrimaryReagentId();
if (string.IsNullOrEmpty(primaryReagent))
{
args.PushText(Loc.GetString("shared-solution-container-component-on-examine-empty-container"));
return;
}
var primaryReagent = solutionHolder.GetPrimaryReagentId();
if (!_prototypeManager.TryIndex(primaryReagent, out ReagentPrototype? proto))
{
Logger.Error(
@@ -85,7 +79,7 @@ public sealed partial class SolutionContainerSystem : EntitySystem
return;
}
var colorHex = solutionHolder.Color
var colorHex = solutionHolder.GetColor(_prototypeManager)
.ToHexNoAlpha(); //TODO: If the chem has a dark color, the examine text becomes black on a black background, which is unreadable.
var messageString = "shared-solution-container-component-on-examine-main-text";
@@ -104,9 +98,9 @@ public sealed partial class SolutionContainerSystem : EntitySystem
|| !Resolve(uid, ref appearanceComponent, false))
return;
var filledVolumePercent = Math.Min(1.0f, solution.CurrentVolume.Float() / solution.MaxVolume.Float());
var filledVolumePercent = solution.FillFraction * 100;
appearanceComponent.SetData(SolutionContainerVisuals.VisualState,
new SolutionContainerVisualState(solution.Color, filledVolumePercent));
new SolutionContainerVisualState(solution.GetColor(_prototypeManager), filledVolumePercent));
}
/// <summary>
@@ -139,7 +133,7 @@ public sealed partial class SolutionContainerSystem : EntitySystem
public void RemoveAllSolution(EntityUid uid, Solution solutionHolder)
{
if (solutionHolder.CurrentVolume == 0)
if (solutionHolder.Volume == 0)
return;
solutionHolder.RemoveAllSolution();
@@ -169,8 +163,8 @@ public sealed partial class SolutionContainerSystem : EntitySystem
return;
targetSolution.MaxVolume = capacity;
if (capacity < targetSolution.CurrentVolume)
targetSolution.RemoveSolution(targetSolution.CurrentVolume - capacity);
if (capacity < targetSolution.Volume)
targetSolution.RemoveSolution(targetSolution.Volume - capacity);
UpdateChemicals(targetUid, targetSolution);
}
@@ -188,14 +182,20 @@ public sealed partial class SolutionContainerSystem : EntitySystem
out FixedPoint2 acceptedQuantity, float? temperature = null)
{
acceptedQuantity = targetSolution.AvailableVolume > quantity ? quantity : targetSolution.AvailableVolume;
targetSolution.AddReagent(reagentId, acceptedQuantity, temperature);
if (acceptedQuantity > 0)
UpdateChemicals(targetUid, targetSolution, true);
if (acceptedQuantity <= 0)
return quantity == 0;
if (temperature == null)
targetSolution.AddReagent(reagentId, acceptedQuantity);
else
targetSolution.AddReagent(_prototypeManager.Index<ReagentPrototype>(reagentId), acceptedQuantity, temperature.Value, _prototypeManager);
UpdateChemicals(targetUid, targetSolution, true);
return acceptedQuantity == quantity;
}
/// <summary>
/// Removes reagent of an Id to the container.
/// </summary>
@@ -224,10 +224,10 @@ public sealed partial class SolutionContainerSystem : EntitySystem
public bool TryAddSolution(EntityUid targetUid, Solution? targetSolution, Solution addedSolution)
{
if (targetSolution == null
|| !targetSolution.CanAddSolution(addedSolution) || addedSolution.TotalVolume == 0)
|| !targetSolution.CanAddSolution(addedSolution) || addedSolution.Volume == 0)
return false;
targetSolution.AddSolution(addedSolution);
targetSolution.AddSolution(addedSolution, _prototypeManager);
UpdateChemicals(targetUid, targetSolution, true);
return true;
}
@@ -245,13 +245,13 @@ public sealed partial class SolutionContainerSystem : EntitySystem
if (quantity < 0)
return TryTransferSolution(targetUid, sourceUid, target, source, -quantity);
quantity = FixedPoint2.Min(quantity, target.AvailableVolume, source.CurrentVolume);
quantity = FixedPoint2.Min(quantity, target.AvailableVolume, source.Volume);
if (quantity == 0)
return false;
// TODO after #12428 is merged, this should be made into a function that directly transfers reagents.
// currently this is quite inefficient.
target.AddSolution(source.SplitSolution(quantity));
// TODO This should be made into a function that directly transfers reagents. currently this is quite
// inefficient.
target.AddSolution(source.SplitSolution(quantity), _prototypeManager);
UpdateChemicals(sourceUid, source, false);
UpdateChemicals(targetUid, target, true);
@@ -294,16 +294,16 @@ public sealed partial class SolutionContainerSystem : EntitySystem
FixedPoint2 overflowThreshold,
[NotNullWhen(true)] out Solution? overflowingSolution)
{
if (addedSolution.TotalVolume == 0 || overflowThreshold > targetSolution.MaxVolume)
if (addedSolution.Volume == 0 || overflowThreshold > targetSolution.MaxVolume)
{
overflowingSolution = null;
return false;
}
targetSolution.AddSolution(addedSolution);
targetSolution.AddSolution(addedSolution, _prototypeManager);
UpdateChemicals(targetUid, targetSolution, true);
overflowingSolution = targetSolution.SplitSolution(FixedPoint2.Max(FixedPoint2.Zero,
targetSolution.CurrentVolume - overflowThreshold));
targetSolution.Volume - overflowThreshold));
return true;
}
@@ -320,14 +320,16 @@ public sealed partial class SolutionContainerSystem : EntitySystem
return solutionsMgr.Solutions.TryGetValue(name, out solution);
}
/// <summary>
/// Will ensure a solution is added to given entity even if it's missing solutionContainerManager
/// </summary>
/// <param name="uid">EntityUid to which to add solution</param>
/// <param name="name">name for the solution</param>
/// <param name="solutionsMgr">solution components used in resolves</param>
/// <param name="existed">true if the solution already existed</param>
/// <returns>solution</returns>
public Solution EnsureSolution(EntityUid uid, string name,
public Solution EnsureSolution(EntityUid uid, string name, out bool existed,
SolutionContainerManagerComponent? solutionsMgr = null)
{
if (!Resolve(uid, ref solutionsMgr, false))
@@ -335,15 +337,76 @@ public sealed partial class SolutionContainerSystem : EntitySystem
solutionsMgr = EntityManager.EnsureComponent<SolutionContainerManagerComponent>(uid);
}
if (!solutionsMgr.Solutions.ContainsKey(name))
if (!solutionsMgr.Solutions.TryGetValue(name, out var existing))
{
var newSolution = new Solution() { Name = name };
solutionsMgr.Solutions.Add(name, newSolution);
existed = false;
return newSolution;
}
return solutionsMgr.Solutions[name];
existed = true;
return existing;
}
/// <summary>
/// Will ensure a solution is added to given entity even if it's missing solutionContainerManager
/// </summary>
/// <param name="uid">EntityUid to which to add solution</param>
/// <param name="name">name for the solution</param>
/// <param name="solutionsMgr">solution components used in resolves</param>
/// <returns>solution</returns>
public Solution EnsureSolution(EntityUid uid, string name, SolutionContainerManagerComponent? solutionsMgr = null)
=> EnsureSolution(uid, name, out _, solutionsMgr);
/// <summary>
/// Will ensure a solution is added to given entity even if it's missing solutionContainerManager
/// </summary>
/// <param name="uid">EntityUid to which to add solution</param>
/// <param name="name">name for the solution</param>
/// <param name="minVol">Ensures that the solution's maximum volume is larger than this value./param>
/// <param name="solutionsMgr">solution components used in resolves</param>
/// <returns>solution</returns>
public Solution EnsureSolution(EntityUid uid, string name, FixedPoint2 minVol, out bool existed,
SolutionContainerManagerComponent? solutionsMgr = null)
{
if (!Resolve(uid, ref solutionsMgr, false))
{
solutionsMgr = EntityManager.EnsureComponent<SolutionContainerManagerComponent>(uid);
}
if (!solutionsMgr.Solutions.TryGetValue(name, out var existing))
{
var newSolution = new Solution() { Name = name };
solutionsMgr.Solutions.Add(name, newSolution);
existed = false;
newSolution.MaxVolume = minVol;
return newSolution;
}
existed = true;
existing.MaxVolume = FixedPoint2.Max(existing.MaxVolume, minVol);
return existing;
}
public Solution EnsureSolution(EntityUid uid, string name,
IEnumerable<Solution.ReagentQuantity> reagents,
bool setMaxVol = true,
SolutionContainerManagerComponent? solutionsMgr = null)
{
if (!Resolve(uid, ref solutionsMgr, false))
solutionsMgr = EntityManager.EnsureComponent<SolutionContainerManagerComponent>(uid);
if (!solutionsMgr.Solutions.TryGetValue(name, out var existing))
{
var newSolution = new Solution(reagents, setMaxVol);
solutionsMgr.Solutions.Add(name, newSolution);
return newSolution;
}
existing.SetContents(reagents, setMaxVol);
return existing;
}
/// <summary>
/// Removes an amount from all reagents in a solution, adding it to a new solution.
/// </summary>
@@ -446,10 +509,8 @@ public sealed partial class SolutionContainerSystem : EntitySystem
/// <param name="thermalEnergy">The new value to set the thermal energy to.</param>
public void SetThermalEnergy(EntityUid owner, Solution solution, float thermalEnergy)
{
if (thermalEnergy == solution.ThermalEnergy)
return;
solution.ThermalEnergy = thermalEnergy;
var heatCap = solution.GetHeatCapacity(_prototypeManager);
solution.Temperature = heatCap == 0 ? 0 : thermalEnergy / heatCap;
UpdateChemicals(owner, solution, true);
}
@@ -464,7 +525,8 @@ public sealed partial class SolutionContainerSystem : EntitySystem
if (thermalEnergy == 0.0f)
return;
solution.ThermalEnergy += thermalEnergy;
var heatCap = solution.GetHeatCapacity(_prototypeManager);
solution.Temperature += heatCap == 0 ? 0 : thermalEnergy / heatCap;
UpdateChemicals(owner, solution, true);
}

View File

@@ -52,7 +52,7 @@ namespace Content.Server.Chemistry.EntitySystems
}
var solRemoved = solution.SplitSolution(component.TransferAmount);
var solRemovedVol = solRemoved.TotalVolume;
var solRemovedVol = solRemoved.Volume;
var solToInject = solRemoved.SplitSolution(solRemovedVol * component.TransferEfficiency);

View File

@@ -54,7 +54,7 @@ public sealed class SolutionSpikableSystem : EntitySystem
return;
}
if (targetSolution.CurrentVolume == 0 && !spikableSource.IgnoreEmpty)
if (targetSolution.Volume == 0 && !spikableSource.IgnoreEmpty)
{
_popupSystem.PopupEntity(Loc.GetString(spikableSource.PopupEmpty, ("spiked-entity", target), ("spike-entity", source)), user, user);
return;
@@ -66,7 +66,7 @@ public sealed class SolutionSpikableSystem : EntitySystem
targetSolution.MaxVolume,
out var overflow))
{
if (overflow.TotalVolume > 0)
if (overflow.Volume > 0)
{
RaiseLocalEvent(target, new SolutionSpikeOverflowEvent(overflow));
}

View File

@@ -156,7 +156,7 @@ namespace Content.Server.Chemistry.EntitySystems
return FixedPoint2.Zero;
}
if (source.DrainAvailable == 0)
if (source.Volume == 0)
{
sourceEntity.PopupMessage(user,
Loc.GetString("comp-solution-transfer-is-empty", ("target", sourceEntity)));
@@ -178,7 +178,7 @@ namespace Content.Server.Chemistry.EntitySystems
return FixedPoint2.Zero;
}
var actualAmount = FixedPoint2.Min(amount, FixedPoint2.Min(source.DrainAvailable, target.AvailableVolume));
var actualAmount = FixedPoint2.Min(amount, FixedPoint2.Min(source.Volume, target.AvailableVolume));
var solutionSystem = Get<SolutionContainerSystem>();
var solution = solutionSystem.Drain(sourceEntity, source, actualAmount);

View File

@@ -71,7 +71,7 @@ namespace Content.Server.Chemistry.EntitySystems
internal bool TryAddSolution(VaporComponent vapor, Solution solution)
{
if (solution.TotalVolume == 0)
if (solution.Volume == 0)
{
return false;
}
@@ -120,7 +120,7 @@ namespace Content.Server.Chemistry.EntitySystems
}
}
if (contents.CurrentVolume == 0)
if (contents.Volume == 0)
{
// Delete this
EntityManager.QueueDeleteEntity(entity);

View File

@@ -77,7 +77,7 @@ namespace Content.Server.Chemistry.ReactionEffects
if (args.Source == null)
return;
var splitSolution = EntitySystem.Get<SolutionContainerSystem>().SplitSolution(args.SolutionEntity, args.Source, args.Source.MaxVolume);
var splitSolution = EntitySystem.Get<SolutionContainerSystem>().SplitSolution(args.SolutionEntity, args.Source, args.Source.Volume);
// We take the square root so it becomes harder to reach higher amount values
var amount = (int) Math.Round(_rangeConstant + _rangeMultiplier*Math.Sqrt(args.Quantity.Float()));
amount = Math.Min(amount, _maxRange);
@@ -90,7 +90,7 @@ namespace Content.Server.Chemistry.ReactionEffects
// Weird formulas here but basically when amount increases, solutionFraction gets closer to 0 in a reciprocal manner
// _reagentDilutionFactor defines how fast solutionFraction gets closer to 0
float solutionFraction = 1 / (_reagentDilutionFactor*(amount) + 1);
splitSolution.RemoveSolution(splitSolution.TotalVolume * (1 - solutionFraction));
splitSolution.RemoveSolution(splitSolution.Volume * (1 - solutionFraction));
}
var transform = args.EntityManager.GetComponent<TransformComponent>(args.SolutionEntity);

View File

@@ -1,5 +1,7 @@
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
using static Robust.Shared.Physics.DynamicTree;
namespace Content.Server.Chemistry.ReactionEffects
{
@@ -28,13 +30,12 @@ namespace Content.Server.Chemistry.ReactionEffects
/// Adjusts the temperature of the solution involved in the reaction.
/// </summary>
[DataDefinition]
[Virtual]
public class AdjustSolutionTemperatureEffect : ReagentEffect
public sealed class AdjustSolutionTemperatureEffect : ReagentEffect
{
/// <summary>
/// The total change in the thermal energy of the solution.
/// The change in temperature.
/// </summary>
[DataField("delta", required: true)] protected float Delta;
[DataField("delta", required: true)] private float _delta;
/// <summary>
/// The minimum temperature this effect can reach.
@@ -51,47 +52,62 @@ namespace Content.Server.Chemistry.ReactionEffects
/// </summary>
[DataField("scaled")] private bool _scaled;
/// <summary>
///
/// </summary>
/// <param name="solution"></param>
/// <returns></returns>
protected virtual float GetDeltaT(Solution solution) => Delta;
public override void Effect(ReagentEffectArgs args)
{
var solution = args.Source;
if (solution == null)
if (solution == null || solution.Volume == 0)
return;
var deltaT = GetDeltaT(solution);
if (_scaled)
deltaT = deltaT * (float) args.Quantity;
if (deltaT == 0.0d)
return;
if (deltaT > 0.0d && solution.Temperature >= _maxTemp)
return;
if (deltaT < 0.0d && solution.Temperature <= _minTemp)
return;
solution.Temperature = MathF.Max(MathF.Min(solution.Temperature + deltaT, _minTemp), _maxTemp);
var deltaT = _scaled ? _delta * (float) args.Quantity : _delta;
solution.Temperature = Math.Clamp(solution.Temperature + deltaT, _minTemp, _maxTemp);
}
}
/// <summary>
/// Adjusts the thermal energy of the solution involved in the reaction.
/// </summary>
public sealed class AdjustSolutionThermalEnergyEffect : AdjustSolutionTemperatureEffect
public sealed class AdjustSolutionThermalEnergyEffect : ReagentEffect
{
protected override float GetDeltaT(Solution solution)
/// <summary>
/// The change in energy.
/// </summary>
[DataField("delta", required: true)] private float _delta;
/// <summary>
/// The minimum temperature this effect can reach.
/// </summary>
[DataField("minTemp")] private float _minTemp = 0.0f;
/// <summary>
/// The maximum temperature this effect can reach.
/// </summary>
[DataField("maxTemp")] private float _maxTemp = float.PositiveInfinity;
/// <summary>
/// If true, then scale ranges by intensity. If not, the ranges are the same regardless of reactant amount.
/// </summary>
[DataField("scaled")] private bool _scaled;
public override void Effect(ReagentEffectArgs args)
{
var heatCapacity = solution.HeatCapacity;
if (heatCapacity == 0.0f)
return 0.0f;
return Delta / heatCapacity;
var solution = args.Source;
if (solution == null || solution.Volume == 0)
return;
if (_delta > 0 && solution.Temperature >= _maxTemp)
return;
if (_delta < 0 && solution.Temperature <= _minTemp)
return;
var heatCap = solution.GetHeatCapacity(null);
var deltaT = _scaled
? _delta / heatCap * (float) args.Quantity
: _delta / heatCap;
solution.Temperature = Math.Clamp(solution.Temperature + deltaT, _minTemp, _maxTemp);
}
}
}

View File

@@ -1,28 +0,0 @@
using Content.Shared.Chemistry.Reagent;
namespace Content.Server.Chemistry.ReagentEffectConditions
{
/// <summary>
/// Requires the solution to be above or below a certain thermal energy.
/// Used for things like explosives.
/// </summary>
public sealed class SolutionThermalEnergy : ReagentEffectCondition
{
[DataField("min")]
public float Min = 0.0f;
[DataField("max")]
public float Max = float.PositiveInfinity;
public override bool Condition(ReagentEffectArgs args)
{
if (args.Source == null)
return false;
if (args.Source.ThermalEnergy < Min)
return false;
if (args.Source.ThermalEnergy > Max)
return false;
return true;
}
}
}