Fix CryostasisBeaker grenade exploit by limiting solution temperature (#2987)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: VigersRay <60344369+VigersRay@users.noreply.github.com> Co-authored-by: Vigers Ray <vigersray@gmail.com>
This commit is contained in:
parent
020ba143df
commit
5bbcd98f99
4 changed files with 142 additions and 0 deletions
|
|
@ -0,0 +1,84 @@
|
|||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.FixedPoint;
|
||||
|
||||
namespace Content.IntegrationTests.Tests._Sunrise.Chemistry;
|
||||
|
||||
[TestFixture]
|
||||
[TestOf(typeof(CryostasisBeakerSystem))]
|
||||
public sealed class CryostasisBeakerTests
|
||||
{
|
||||
[TestPrototypes]
|
||||
private const string Prototypes = @"
|
||||
- type: entity
|
||||
id: TestCryostasisBeaker
|
||||
components:
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
beaker:
|
||||
maxVol: 50
|
||||
canReact: false
|
||||
- type: CryostasisBeaker
|
||||
maxTemperature: 293.15
|
||||
|
||||
- type: reagent
|
||||
id: TestReagent
|
||||
name: reagent-name-nothing
|
||||
desc: reagent-desc-nothing
|
||||
physicalDesc: reagent-physical-desc-nothing
|
||||
";
|
||||
|
||||
[Test]
|
||||
public async Task CryostasisBeakerPreventsHeating()
|
||||
{
|
||||
await using var pair = await PoolManager.GetServerClient();
|
||||
var server = pair.Server;
|
||||
|
||||
var testMap = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var solutionSystem = server.System<SharedSolutionContainerSystem>();
|
||||
|
||||
var beaker = server.EntMan.SpawnEntity("TestCryostasisBeaker", testMap.GridCoords);
|
||||
|
||||
Assert.That(solutionSystem.TryGetSolution(beaker, "beaker", out var solutionEntity, out var solution));
|
||||
|
||||
solutionSystem.TryAddReagent(solutionEntity.Value, "TestReagent", FixedPoint2.New(10));
|
||||
|
||||
solutionSystem.SetTemperature(solutionEntity.Value, 500.0f);
|
||||
|
||||
Assert.That(solution!.Temperature, Is.LessThanOrEqualTo(293.15f));
|
||||
|
||||
solutionSystem.AddThermalEnergy(solutionEntity.Value, 10000.0f);
|
||||
|
||||
Assert.That(solution.Temperature, Is.LessThanOrEqualTo(293.15f));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task NormalBeakerAllowsHeating()
|
||||
{
|
||||
await using var pair = await PoolManager.GetServerClient();
|
||||
var server = pair.Server;
|
||||
|
||||
var testMap = await pair.CreateTestMap();
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var solutionSystem = server.System<SharedSolutionContainerSystem>();
|
||||
|
||||
var beaker = server.EntMan.SpawnEntity("TestCryostasisBeaker", testMap.GridCoords);
|
||||
if (server.EntMan.HasComponent<CryostasisBeakerComponent>(beaker))
|
||||
server.EntMan.RemoveComponent<CryostasisBeakerComponent>(beaker);
|
||||
|
||||
Assert.That(solutionSystem.TryGetSolution(beaker, "beaker", out var solutionEntity, out var solution));
|
||||
|
||||
solutionSystem.TryAddReagent(solutionEntity.Value, "TestReagent", FixedPoint2.New(10));
|
||||
|
||||
solutionSystem.SetTemperature(solutionEntity.Value, 500.0f);
|
||||
|
||||
Assert.That(solution!.Temperature, Is.EqualTo(500.0f));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
namespace Content.Shared.Chemistry.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Component that marks a beaker as a cryostasis beaker, which prevents solutions inside from being heated.
|
||||
/// Solutions in cryostasis beakers will remain at or below room temperature (293.15K).
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class CryostasisBeakerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Maximum temperature that solutions in this beaker can reach.
|
||||
/// Default is room temperature (293.15K).
|
||||
/// </summary>
|
||||
[DataField("maxTemperature")]
|
||||
public float MaxTemperature = 293.15f;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Chemistry.Components.SolutionManager;
|
||||
|
||||
namespace Content.Shared.Chemistry.EntitySystems;
|
||||
|
||||
/// <summary>
|
||||
/// System that prevents solutions in cryostasis beakers from being heated above room temperature.
|
||||
/// </summary>
|
||||
public sealed class CryostasisBeakerSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<SolutionComponent, SolutionChangedEvent>(OnSolutionChanged);
|
||||
}
|
||||
|
||||
private void OnSolutionChanged(EntityUid solutionEntity, SolutionComponent solutionComp, ref SolutionChangedEvent args)
|
||||
{
|
||||
// Get the container that holds this solution
|
||||
if (!TryComp<ContainedSolutionComponent>(solutionEntity, out var containedSolution))
|
||||
return;
|
||||
|
||||
var containerEntity = containedSolution.Container;
|
||||
|
||||
// Check if the container is a CryostasisBeaker
|
||||
if (!TryComp<CryostasisBeakerComponent>(containerEntity, out var cryostasisBeaker))
|
||||
return;
|
||||
|
||||
var solution = solutionComp.Solution;
|
||||
|
||||
// If the solution temperature is above the maximum allowed, cool it down
|
||||
if (solution.Temperature > cryostasisBeaker.MaxTemperature)
|
||||
{
|
||||
solution.Temperature = cryostasisBeaker.MaxTemperature;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -245,6 +245,10 @@
|
|||
beaker:
|
||||
maxVol: 60
|
||||
canReact: false
|
||||
# Sunrise-Start
|
||||
- type: CryostasisBeaker
|
||||
maxTemperature: 293.15
|
||||
# Sunrise-End
|
||||
|
||||
- type: entity
|
||||
name: bluespace beaker
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue