mirror of
https://github.com/wega-team/ss14-wega.git
synced 2026-02-14 19:30:01 +01:00
fix solution contents duplication on spill behavior (#33231)
* I’M SCREAMING INTO THE VOID AND IT’S NOT LISTENING * review * explodes pancakes with mind * graaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa * Meteors RAAAAAAAAAAH * I'm so tired of solutions * whhop * revert --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
This commit is contained in:
@@ -73,7 +73,19 @@ public sealed class PuddleSystem : SharedPuddleSystem
|
||||
// Maybe someday we'll have clientside prediction for entity spawning, but not today.
|
||||
// Until then, these methods do nothing on the client.
|
||||
/// <inheritdoc/>
|
||||
public override bool TrySplashSpillAt(EntityUid uid, EntityCoordinates coordinates, Solution solution, out EntityUid puddleUid, bool sound = true, EntityUid? user = null)
|
||||
public override bool TrySplashSpillAt(Entity<SpillableComponent?> entity, EntityCoordinates coordinates, out EntityUid puddleUid, out Solution solution, bool sound = true, EntityUid? user = null)
|
||||
{
|
||||
puddleUid = EntityUid.Invalid;
|
||||
solution = new Solution();
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool TrySplashSpillAt(EntityUid entity,
|
||||
EntityCoordinates coordinates,
|
||||
Solution spilled,
|
||||
out EntityUid puddleUid,
|
||||
bool sound = true,
|
||||
EntityUid? user = null)
|
||||
{
|
||||
puddleUid = EntityUid.Invalid;
|
||||
return false;
|
||||
|
||||
@@ -1,42 +1,38 @@
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Shared.Fluids.Components;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Server.Destructible.Thresholds.Behaviors
|
||||
namespace Content.Server.Destructible.Thresholds.Behaviors;
|
||||
|
||||
[UsedImplicitly]
|
||||
[DataDefinition]
|
||||
public sealed partial class SpillBehavior : IThresholdBehavior
|
||||
{
|
||||
[UsedImplicitly]
|
||||
[DataDefinition]
|
||||
public sealed partial class SpillBehavior : IThresholdBehavior
|
||||
/// <summary>
|
||||
/// Optional fallback solution name if SpillableComponent is not present.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string? Solution;
|
||||
|
||||
/// <summary>
|
||||
/// When triggered, spills the entity's solution onto the ground.
|
||||
/// Will first try to use the solution from a SpillableComponent if present,
|
||||
/// otherwise falls back to the solution specified in the behavior's data fields.
|
||||
/// The solution is properly drained/split before spilling to prevent double-spilling with other behaviors.
|
||||
/// </summary>
|
||||
/// <param name="owner">Entity whose solution will be spilled</param>
|
||||
/// <param name="system">System calling this behavior</param>
|
||||
/// <param name="cause">Optional entity that caused this behavior to trigger</param>
|
||||
public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
|
||||
{
|
||||
[DataField]
|
||||
public string? Solution;
|
||||
var puddleSystem = system.EntityManager.System<PuddleSystem>();
|
||||
var solutionContainer = system.EntityManager.System<SharedSolutionContainerSystem>();
|
||||
var coordinates = system.EntityManager.GetComponent<TransformComponent>(owner).Coordinates;
|
||||
|
||||
/// <summary>
|
||||
/// If there is a SpillableComponent on EntityUidowner use it to create a puddle/smear.
|
||||
/// Or whatever solution is specified in the behavior itself.
|
||||
/// If none are available do nothing.
|
||||
/// </summary>
|
||||
/// <param name="owner">Entity on which behavior is executed</param>
|
||||
/// <param name="system">system calling the behavior</param>
|
||||
/// <param name="cause"></param>
|
||||
public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
|
||||
{
|
||||
var solutionContainerSystem = system.EntityManager.System<SharedSolutionContainerSystem>();
|
||||
var spillableSystem = system.EntityManager.System<PuddleSystem>();
|
||||
|
||||
var coordinates = system.EntityManager.GetComponent<TransformComponent>(owner).Coordinates;
|
||||
|
||||
if (system.EntityManager.TryGetComponent(owner, out SpillableComponent? spillableComponent) &&
|
||||
solutionContainerSystem.TryGetSolution(owner, spillableComponent.SolutionName, out _, out var compSolution))
|
||||
{
|
||||
spillableSystem.TrySplashSpillAt(owner, coordinates, compSolution, out _, false, user: cause);
|
||||
}
|
||||
else if (Solution != null &&
|
||||
solutionContainerSystem.TryGetSolution(owner, Solution, out _, out var behaviorSolution))
|
||||
{
|
||||
spillableSystem.TrySplashSpillAt(owner, coordinates, behaviorSolution, out _, user: cause);
|
||||
}
|
||||
}
|
||||
// Spill the solution that was drained/split
|
||||
if (solutionContainer.TryGetSolution(owner, Solution, out _, out var solution))
|
||||
puddleSystem.TrySplashSpillAt(owner, coordinates, solution, out _, false, cause);
|
||||
else
|
||||
puddleSystem.TrySplashSpillAt(owner, coordinates, out _, out _, false, cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,23 +29,14 @@ public sealed partial class PuddleSystem
|
||||
|
||||
private void SpillOnLand(Entity<SpillableComponent> entity, ref LandEvent args)
|
||||
{
|
||||
if (!_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.SolutionName, out var soln, out var solution))
|
||||
if (!entity.Comp.SpillWhenThrown || Openable.IsClosed(entity.Owner))
|
||||
return;
|
||||
|
||||
if (Openable.IsClosed(entity.Owner))
|
||||
return;
|
||||
|
||||
if (!entity.Comp.SpillWhenThrown)
|
||||
return;
|
||||
|
||||
if (args.User != null)
|
||||
if (TrySplashSpillAt(entity.Owner, Transform(entity).Coordinates, out _, out var solution) && args.User != null)
|
||||
{
|
||||
AdminLogger.Add(LogType.Landed,
|
||||
$"{ToPrettyString(entity.Owner):entity} spilled a solution {SharedSolutionContainerSystem.ToPrettyString(solution):solution} on landing");
|
||||
}
|
||||
|
||||
var drainedSolution = _solutionContainerSystem.Drain(entity.Owner, soln.Value, solution.Volume);
|
||||
TrySplashSpillAt(entity.Owner, Transform(entity).Coordinates, drainedSolution, out _);
|
||||
}
|
||||
|
||||
private void OnDoAfter(Entity<SpillableComponent> entity, ref SpillDoAfterEvent args)
|
||||
|
||||
@@ -369,16 +369,37 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
|
||||
|
||||
// TODO: This can be predicted once https://github.com/space-wizards/RobustToolbox/pull/5849 is merged
|
||||
/// <inheritdoc/>
|
||||
public override bool TrySplashSpillAt(EntityUid uid,
|
||||
public override bool TrySplashSpillAt(Entity<SpillableComponent?> entity,
|
||||
EntityCoordinates coordinates,
|
||||
Solution solution,
|
||||
out EntityUid puddleUid,
|
||||
out Solution spilled,
|
||||
bool sound = true,
|
||||
EntityUid? user = null)
|
||||
{
|
||||
puddleUid = EntityUid.Invalid;
|
||||
spilled = new Solution();
|
||||
|
||||
if (!Resolve(entity, ref entity.Comp))
|
||||
return false;
|
||||
|
||||
if (!_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.SolutionName, out var solution))
|
||||
return false;
|
||||
|
||||
spilled = solution.Value.Comp.Solution;
|
||||
|
||||
return TrySplashSpillAt(entity, coordinates, spilled, out puddleUid, sound, user);
|
||||
}
|
||||
|
||||
public override bool TrySplashSpillAt(EntityUid entity,
|
||||
EntityCoordinates coordinates,
|
||||
Solution spilled,
|
||||
out EntityUid puddleUid,
|
||||
bool sound = true,
|
||||
EntityUid? user = null)
|
||||
{
|
||||
puddleUid = EntityUid.Invalid;
|
||||
|
||||
if (solution.Volume == 0)
|
||||
if (spilled.Volume == 0)
|
||||
return false;
|
||||
|
||||
var targets = new List<EntityUid>();
|
||||
@@ -392,26 +413,28 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
|
||||
var owner = ent.Owner;
|
||||
|
||||
// between 5 and 30%
|
||||
var splitAmount = solution.Volume * _random.NextFloat(0.05f, 0.30f);
|
||||
var splitSolution = solution.SplitSolution(splitAmount);
|
||||
var splitAmount = spilled.Volume * _random.NextFloat(0.05f, 0.30f);
|
||||
var splitSolution = spilled.SplitSolution(splitAmount);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
AdminLogger.Add(LogType.Landed,
|
||||
$"{ToPrettyString(user.Value):user} threw {ToPrettyString(uid):entity} which splashed a solution {SharedSolutionContainerSystem.ToPrettyString(solution):solution} onto {ToPrettyString(owner):target}");
|
||||
$"{ToPrettyString(user.Value):user} threw {ToPrettyString(entity):entity} which splashed a solution {SharedSolutionContainerSystem.ToPrettyString(spilled):solution} onto {ToPrettyString(owner):target}");
|
||||
}
|
||||
|
||||
targets.Add(owner);
|
||||
Reactive.DoEntityReaction(owner, splitSolution, ReactionMethod.Touch);
|
||||
Popups.PopupEntity(
|
||||
Loc.GetString("spill-land-spilled-on-other", ("spillable", uid),
|
||||
("target", Identity.Entity(owner, EntityManager))), owner, PopupType.SmallCaution);
|
||||
Popups.PopupEntity(Loc.GetString("spill-land-spilled-on-other",
|
||||
("spillable", entity),
|
||||
("target", Identity.Entity(owner, EntityManager))),
|
||||
owner,
|
||||
PopupType.SmallCaution);
|
||||
}
|
||||
|
||||
_color.RaiseEffect(solution.GetColor(_prototypeManager), targets,
|
||||
Filter.Pvs(uid, entityManager: EntityManager));
|
||||
_color.RaiseEffect(spilled.GetColor(_prototypeManager), targets,
|
||||
Filter.Pvs(entity, entityManager: EntityManager));
|
||||
|
||||
return TrySpillAt(coordinates, solution, out puddleUid, sound);
|
||||
return TrySpillAt(coordinates, spilled, out puddleUid, sound);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -354,6 +354,15 @@ public abstract partial class SharedPuddleSystem : EntitySystem
|
||||
}
|
||||
|
||||
#region Spill
|
||||
|
||||
/// <inheritdoc cref="TrySplashSpillAt(EntityUid,EntityCoordinates,Solution,out EntityUid,bool,EntityUid?)"/>
|
||||
public abstract bool TrySplashSpillAt(Entity<SpillableComponent?> entity,
|
||||
EntityCoordinates coordinates,
|
||||
out EntityUid puddleUid,
|
||||
out Solution spilled,
|
||||
bool sound = true,
|
||||
EntityUid? user = null);
|
||||
|
||||
// These methods are in Shared to make it easier to interact with PuddleSystem in Shared code.
|
||||
// Note that they always fail when run on the client, not creating a puddle and returning false.
|
||||
// Adding proper prediction to this system would require spawning temporary puddle entities on the
|
||||
@@ -367,9 +376,9 @@ public abstract partial class SharedPuddleSystem : EntitySystem
|
||||
/// <remarks>
|
||||
/// On the client, this will always set <paramref name="puddleUid"/> to <see cref="EntityUid.Invalid"/> and return false.
|
||||
/// </remarks>
|
||||
public abstract bool TrySplashSpillAt(EntityUid uid,
|
||||
public abstract bool TrySplashSpillAt(EntityUid entity,
|
||||
EntityCoordinates coordinates,
|
||||
Solution solution,
|
||||
Solution spilled,
|
||||
out EntityUid puddleUid,
|
||||
bool sound = true,
|
||||
EntityUid? user = null);
|
||||
|
||||
@@ -179,8 +179,8 @@ public sealed partial class PressurizedSolutionSystem : EntitySystem
|
||||
var solution = _solutionContainer.SplitSolution(soln.Value, interactions.Volume);
|
||||
|
||||
// Spray the solution onto the ground and anyone nearby
|
||||
if (TryComp(entity, out TransformComponent? transform))
|
||||
_puddle.TrySplashSpillAt(entity, transform.Coordinates, solution, out _, sound: false);
|
||||
var coordinates = Transform(entity).Coordinates;
|
||||
_puddle.TrySplashSpillAt(entity.Owner, coordinates, out _, out _, sound: false);
|
||||
|
||||
var drinkName = Identity.Entity(entity, EntityManager);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user