Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace BlockSolutionAccessComponent with an attempt event #26988

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 0 additions & 29 deletions Content.Server/Fluids/EntitySystems/PuddleSystem.Spillable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ protected override void InitializeSpillable()
SubscribeLocalEvent<SpillableComponent, LandEvent>(SpillOnLand);
// Openable handles the event if it's closed
SubscribeLocalEvent<SpillableComponent, MeleeHitEvent>(SplashOnMeleeHit, after: [typeof(OpenableSystem)]);
SubscribeLocalEvent<SpillableComponent, ClothingGotEquippedEvent>(OnGotEquipped);
SubscribeLocalEvent<SpillableComponent, ClothingGotUnequippedEvent>(OnGotUnequipped);
SubscribeLocalEvent<SpillableComponent, SolutionContainerOverflowEvent>(OnOverflow);
SubscribeLocalEvent<SpillableComponent, SpillDoAfterEvent>(OnDoAfter);
SubscribeLocalEvent<SpillableComponent, AttemptPacifiedThrowEvent>(OnAttemptPacifiedThrow);
Expand Down Expand Up @@ -97,33 +95,6 @@ private void SplashOnMeleeHit(Entity<SpillableComponent> entity, ref MeleeHitEve
}
}

private void OnGotEquipped(Entity<SpillableComponent> entity, ref ClothingGotEquippedEvent args)
{
if (!entity.Comp.SpillWorn)
return;

if (!_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.SolutionName, out var soln, out var solution))
return;

// block access to the solution while worn
AddComp<BlockSolutionAccessComponent>(entity);

if (solution.Volume == 0)
return;

// spill all solution on the player
var drainedSolution = _solutionContainerSystem.Drain(entity.Owner, soln.Value, solution.Volume);
TrySplashSpillAt(entity.Owner, Transform(args.Wearer).Coordinates, drainedSolution, out _);
}

private void OnGotUnequipped(Entity<SpillableComponent> entity, ref ClothingGotUnequippedEvent args)
{
if (!entity.Comp.SpillWorn)
return;

RemCompDeferred<BlockSolutionAccessComponent>(entity);
}

private void SpillOnLand(Entity<SpillableComponent> entity, ref LandEvent args)
{
if (!_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.SolutionName, out var soln, out var solution))
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ public partial record struct SolutionOverflowEvent(Entity<SolutionComponent> Sol
public bool Handled = false;
}

[ByRefEvent]
public partial record struct SolutionAccessAttemptEvent(string SolutionName)
{
public bool Cancelled;
}

/// <summary>
/// Part of Chemistry system deal with SolutionContainers
/// </summary>
Expand Down Expand Up @@ -156,12 +162,6 @@ public bool TryGetSolution(
[NotNullWhen(true)] out Entity<SolutionComponent>? entity,
bool errorOnMissing = false)
{
if (TryComp(container, out BlockSolutionAccessComponent? blocker))
{
entity = null;
return false;
}

EntityUid uid;
if (name is null)
uid = container;
Expand All @@ -170,7 +170,18 @@ public bool TryGetSolution(
solutionContainer is ContainerSlot solutionSlot &&
solutionSlot.ContainedEntity is { } containedSolution
)
{
var attemptEv = new SolutionAccessAttemptEvent(name);
RaiseLocalEvent(container, ref attemptEv);

if (attemptEv.Cancelled)
{
entity = null;
return false;
}

uid = containedSolution;
}
else
{
entity = null;
Expand Down Expand Up @@ -218,11 +229,14 @@ public bool TryGetSolution(SolutionContainerManagerComponent container,
if (!Resolve(container, ref container.Comp, logMissing: false))
yield break;

if (HasComp<BlockSolutionAccessComponent>(container))
yield break;

foreach (var name in container.Comp.Containers)
{
var attemptEv = new SolutionAccessAttemptEvent(name);
RaiseLocalEvent(container, ref attemptEv);

if (attemptEv.Cancelled)
continue;

if (ContainerSystem.GetContainer(container, $"solution@{name}") is ContainerSlot slot && slot.ContainedEntity is { } solutionId)
yield return (name, (solutionId, Comp<SolutionComponent>(solutionId)));
}
Expand Down
24 changes: 24 additions & 0 deletions Content.Shared/Fluids/Components/SpillWhenWornComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Robust.Shared.GameStates;

namespace Content.Shared.Fluids.Components;

/// <summary>
/// This entity will spill its contained solution onto the wearer when worn, and its
/// (empty) contents will be inaccessible while still worn.
/// </summary>
[RegisterComponent]
[NetworkedComponent, AutoGenerateComponentState]
public sealed partial class SpillWhenWornComponent : Component
{
/// <summary>
/// Name of the solution to spill.
/// </summary>
[DataField]
public string Solution = "default";

/// <summary>
/// Tracks if this item is currently being worn.
/// </summary>
[DataField, AutoNetworkedField]
public bool IsWorn;
}
7 changes: 0 additions & 7 deletions Content.Shared/Fluids/Components/SpillableComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@ public sealed partial class SpillableComponent : Component
[DataField("solution")]
public string SolutionName = "puddle";

/// <summary>
/// Should this item be spilled when worn as clothing?
/// Doesn't count for pockets or hands.
/// </summary>
[DataField]
public bool SpillWorn = true;

[DataField]
public float? SpillDelay;

Expand Down
55 changes: 55 additions & 0 deletions Content.Shared/Fluids/EntitySystems/SpillWhenWornSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Clothing;
using Content.Shared.Fluids.Components;

namespace Content.Shared.Fluids.EntitySystems;

/// <inheritdoc cref="SpillWhenWornComponent"/>
public sealed class SpillWhenWornSystem : EntitySystem
{
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
[Dependency] private readonly SharedPuddleSystem _puddle = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<SpillWhenWornComponent, ClothingGotEquippedEvent>(OnGotEquipped);
SubscribeLocalEvent<SpillWhenWornComponent, ClothingGotUnequippedEvent>(OnGotUnequipped);
SubscribeLocalEvent<SpillWhenWornComponent, SolutionAccessAttemptEvent>(OnSolutionAccessAttempt);
}

private void OnGotEquipped(Entity<SpillWhenWornComponent> ent, ref ClothingGotEquippedEvent args)
{
if (_solutionContainer.TryGetSolution(ent.Owner, ent.Comp.Solution, out var soln, out var solution)
&& solution.Volume > 0)
{
// Spill all solution on the player
var drainedSolution = _solutionContainer.Drain(ent.Owner, soln.Value, solution.Volume);
_puddle.TrySplashSpillAt(ent.Owner, Transform(args.Wearer).Coordinates, drainedSolution, out _);
}

// Flag as worn after draining, otherwise we'll block ourself from accessing!
ent.Comp.IsWorn = true;
Dirty(ent);
}

private void OnGotUnequipped(Entity<SpillWhenWornComponent> ent, ref ClothingGotUnequippedEvent args)
{
ent.Comp.IsWorn = false;
Dirty(ent);
}

private void OnSolutionAccessAttempt(Entity<SpillWhenWornComponent> ent, ref SolutionAccessAttemptEvent args)
{
// If we're not being worn right now, we don't care
if (!ent.Comp.IsWorn)
return;

// Make sure it's the right solution
if (ent.Comp.Solution != args.SolutionName)
return;

args.Cancelled = true;
}
}
2 changes: 2 additions & 0 deletions Resources/Prototypes/Entities/Objects/Tools/bucket.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
Blunt: 0
- type: Spillable
solution: bucket
- type: SpillWhenWorn
solution: bucket
- type: DrawableSolution
solution: bucket
- type: RefillableSolution
Expand Down
Loading