CleanTileReaction.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using Content.Shared.Chemistry.EntitySystems;
  2. using Content.Shared.Chemistry.Components;
  3. using Content.Shared.Chemistry.Reaction;
  4. using Content.Shared.Chemistry.Reagent;
  5. using Content.Shared.FixedPoint;
  6. using Content.Shared.Fluids.Components;
  7. using Robust.Shared.Map;
  8. using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
  9. using System.Linq;
  10. namespace Content.Server.Chemistry.TileReactions;
  11. /// <summary>
  12. /// Turns all of the reagents on a puddle into water.
  13. /// </summary>
  14. [DataDefinition]
  15. public sealed partial class CleanTileReaction : ITileReaction
  16. {
  17. /// <summary>
  18. /// How much it costs to clean 1 unit of reagent.
  19. /// </summary>
  20. /// <remarks>
  21. /// In terms of space cleaner can clean 1 average puddle per 5 units.
  22. /// </remarks>
  23. [DataField("cleanCost")]
  24. public float CleanAmountMultiplier { get; private set; } = 0.25f;
  25. /// <summary>
  26. /// What reagent to replace the tile conents with.
  27. /// </summary>
  28. [DataField("reagent", customTypeSerializer: typeof(PrototypeIdSerializer<ReagentPrototype>))]
  29. public string ReplacementReagent = "Water";
  30. FixedPoint2 ITileReaction.TileReact(TileRef tile,
  31. ReagentPrototype reagent,
  32. FixedPoint2 reactVolume,
  33. IEntityManager entityManager
  34. , List<ReagentData>? data)
  35. {
  36. var entities = entityManager.System<EntityLookupSystem>().GetLocalEntitiesIntersecting(tile, 0f).ToArray();
  37. var puddleQuery = entityManager.GetEntityQuery<PuddleComponent>();
  38. var solutionContainerSystem = entityManager.System<SharedSolutionContainerSystem>();
  39. // Multiply as the amount we can actually purge is higher than the react amount.
  40. var purgeAmount = reactVolume / CleanAmountMultiplier;
  41. foreach (var entity in entities)
  42. {
  43. if (!puddleQuery.TryGetComponent(entity, out var puddle) ||
  44. !solutionContainerSystem.TryGetSolution(entity, puddle.SolutionName, out var puddleSolution, out _))
  45. {
  46. continue;
  47. }
  48. var purgeable = solutionContainerSystem.SplitSolutionWithout(puddleSolution.Value, purgeAmount, ReplacementReagent, reagent.ID);
  49. purgeAmount -= purgeable.Volume;
  50. solutionContainerSystem.TryAddSolution(puddleSolution.Value, new Solution(ReplacementReagent, purgeable.Volume));
  51. if (purgeable.Volume <= FixedPoint2.Zero)
  52. break;
  53. }
  54. return (reactVolume / CleanAmountMultiplier - purgeAmount) * CleanAmountMultiplier;
  55. }
  56. }