Skip to content
Open
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
15 changes: 13 additions & 2 deletions Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections;
using System.Linq;
using System.Runtime.CompilerServices;
using Content.Server.Atmos.Reactions;
Expand Down Expand Up @@ -278,13 +279,23 @@ public GasCompareResult CompareExchange(GasMixture sample, GasMixture otherSampl
}

[PublicAPI]
// Goobstation - Added override method without gasesToReact parameter to ensure inherence from shared system
public override ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder)
{
// Goobstation - Sends list of standard reactions to react
var standardReactions = GasReactions.Where(x => x.IsStandardReaction);
return React(mixture, holder, standardReactions);
}

// Goobstation - Added gasesToReact parameter to add specific set of reactions to react
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, IEnumerable<GasReactionPrototype> gasesToReact)
{
var reaction = ReactionResult.NoReaction;
var temperature = mixture.Temperature;
var energy = GetThermalEnergy(mixture);

foreach (var prototype in GasReactions)
// Goobstation - Added check for standard reactions
foreach (var prototype in gasesToReact)
{
if (energy < prototype.MinimumEnergyRequirement ||
temperature < prototype.MinimumTemperatureRequirement ||
Expand All @@ -307,7 +318,7 @@ public override ReactionResult React(GasMixture mixture, IGasMixtureHolder? hold
continue;

reaction = prototype.React(mixture, holder, this, HeatScale);
if(reaction.HasFlag(ReactionResult.StopReactions))
if (reaction.HasFlag(ReactionResult.StopReactions))
break;
}

Expand Down
7 changes: 7 additions & 0 deletions Content.Server/Atmos/Reactions/GasReactionPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ public sealed partial class GasReactionPrototype : IPrototype
[DataField("priority")]
public int Priority { get; private set; } = int.MinValue;

/// <summary>
/// Goobstation:
/// True if it's standard reaction that happens in atmosphere and not require conditions to try React.
/// </summary>
[DataField]
public bool IsStandardReaction { get; private set; } = true;

/// <summary>
/// A list of effects this will produce.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Content.Goobstation.Common.Atmos;

/// <summary>
/// Allows entity to devour nearby gases and put them inside GasMixtureHolderComponent
/// </summary>
[RegisterComponent]
public sealed partial class GasDevourerComponent : Component
{
/// <summary>
/// Devouring speed in L/s
/// </summary>
[DataField]
public float TransferRate = 100;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Content.Server.Atmos.Reactions;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;

namespace Content.Goobstation.Server.Atmos;

/// <summary>
/// Gas chamber that allows only specific gas reactions inside it
/// </summary>
[RegisterComponent]
public sealed partial class GasReactionChamberComponent : Component
{
/// <summary>
/// List of allowed reactions. Reactions are not allowed if empty.
/// </summary>
[DataField(customTypeSerializer: typeof(PrototypeIdHashSetSerializer<GasReactionPrototype>))]
public HashSet<string>? Reactions = null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Content.Goobstation.Common.Atmos;
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Unary.EntitySystems;
using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Robust.Server.GameObjects;

namespace Content.Goobstation.Server.Atmos;

public sealed partial class GasDevourerSystem : EntitySystem
{
[Dependency] private EntityQuery<GasMixtureHolderComponent> _gasHolderQuery = default!;

[Dependency] private AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private GasVentScrubberSystem _scrubberSystem = default!;
[Dependency] private TransformSystem _transformSystem = default!;

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

SubscribeLocalEvent<GasDevourerComponent, AtmosDeviceUpdateEvent>(OnAtmosUpdated);
}

private void OnAtmosUpdated(Entity<GasDevourerComponent> devourer, ref AtmosDeviceUpdateEvent args)
{
// Return if entity cannot hold gas or we are not on grid
if (!_gasHolderQuery.TryComp(devourer, out var gasHolder) || args.Grid is not { } grid)
return;

var position = _transformSystem.GetGridTilePositionOrDefault(devourer.Owner);
var gasEnumerator = _atmosphereSystem.GetAdjacentTileMixtures(grid, position, false, true);

while (gasEnumerator.MoveNext(out var tileMixture))
{
_scrubberSystem.Scrub(args.dt, devourer.Comp.TransferRate * _atmosphereSystem.PumpSpeedup(),
ScrubberPumpDirection.Siphoning, [], tileMixture, gasHolder.Air);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.Collections.Frozen;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.GameTicking;
using Content.Shared.Atmos.Prototypes;
using Robust.Shared.Prototypes;

/// <summary>
/// System that creates and store entities of specific gases just to allow gases work with components
/// </summary>
public sealed partial class GasEntitySystem : EntitySystem
{
[Dependency] private IPrototypeManager _protoMan = default!;
private FrozenDictionary<ProtoId<GasPrototype>, EntityUid> _gasesDict = default!;

public override void Initialize()
{
SubscribeLocalEvent<PostGameMapLoad>(AfterMapLoad);
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReload);
}

private void AfterMapLoad(PostGameMapLoad args)
{
if (_gasesDict == null || _gasesDict.Count == 0)
FillGasesDictionary();
}

private void OnPrototypesReload(PrototypesReloadedEventArgs args)
{
FillGasesDictionary();
}

private void FillGasesDictionary()
{
var gases = _protoMan.EnumeratePrototypes<GasPrototype>();
Dictionary<ProtoId<GasPrototype>, EntityUid> gasesDict = [];

foreach (var gas in gases)
{
if (!_protoMan.TryIndex<EntityPrototype>(gas.ID, out var gasEntProto))
{
Log.Error($"GasPrototype «{gas.ID}» does not have correlation entity prototype with same ID.");
continue;
}

// Spawn gas entity with same gas ID and put it in dictionary
var gasEnt = Spawn(gasEntProto.ID);
gasesDict.Add(gas.ID, gasEnt);
}

_gasesDict = gasesDict.ToFrozenDictionary();
}

public bool TryGetGasEntity(string gasId, [NotNullWhen(true)] out EntityUid? gasEnt)
{
if (_gasesDict.TryGetValue(gasId, out var outValue))
{
gasEnt = outValue;
return true;
}
gasEnt = null;
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Linq;
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Reactions;
using Content.Shared.Atmos.Components;
using Robust.Shared.Prototypes;

namespace Content.Goobstation.Server.Atmos;

public sealed partial class GasReactionChamberSystem : EntitySystem
{
[Dependency] private AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private IPrototypeManager _prototypeMan = default!;
[Dependency] private EntityQuery<GasMixtureHolderComponent> _gasHolderQuery = default!;

private GasReactionPrototype[] _gasReactions = [];

/// <summary>
/// List of gas reactions ordered by priority.
/// </summary>
public IEnumerable<GasReactionPrototype> GasReactions => _gasReactions;

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

SubscribeLocalEvent<GasReactionChamberComponent, AtmosDeviceUpdateEvent>(OnAtmosUpdate);

_gasReactions = _prototypeMan.EnumeratePrototypes<GasReactionPrototype>().ToArray();
Array.Sort(_gasReactions, (a, b) => b.Priority.CompareTo(a.Priority));
}

private void OnAtmosUpdate(Entity<GasReactionChamberComponent> chamber, ref AtmosDeviceUpdateEvent args)
{
if (chamber.Comp.Reactions is null || !_gasHolderQuery.TryComp(chamber, out var gasHolderComp))
return;

var reactGases = GasReactions.Where(x => chamber.Comp.Reactions.Contains(x.ID));

_atmosphereSystem.React(gasHolderComp.Air, gasHolderComp, reactGases);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#Contains the entity objects of gases
- type: entity
id: BaseGas
name: gas
description: Just a gas!

- type: entity
parent: BaseGas
id: Oxygen
name: oxygen gas

- type: entity
parent: BaseGas
id: Nitrogen
name: nitrogen gas

- type: entity
parent: BaseGas
id: Frezon
name: frezon gas

- type: entity
parent: BaseGas
id: NitrousOxide
name: nitrous oxide gas

- type: entity
parent: BaseGas
id: Plasma
name: plasma gas

- type: entity
parent: BaseGas
id: Ammonia
name: ammonia gas

- type: entity
parent: BaseGas
id: Tritium
name: tritium gas

- type: entity
parent: BaseGas
id: CarbonDioxide
name: carbon dioxide gas

- type: entity
parent: BaseGas
id: WaterVapor
name: water vapor gas
Loading