Files
wwdpublic/Content.Shared/_EE/Supermatter/Components/SupermatterComponent.cs
Spatison c564778c08 [Fix] Supermatter Console (#559)
* tgaziki

* format
2025-06-11 11:07:27 +03:00

482 lines
13 KiB
C#

using Content.Shared._EE.Supermatter.Monitor;
using Content.Shared.Atmos;
using Content.Shared.DoAfter;
using Content.Shared.Radio;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared._EE.Supermatter.Components;
[RegisterComponent, NetworkedComponent]
public sealed partial class SupermatterComponent : Component
{
#region Base
/// <summary>
/// The SM will only cycle if activated.
/// </summary>
[DataField]
public bool Activated;
/// <summary>
/// The current status of the singularity, used for alert sounds and the monitoring console
/// </summary>
[DataField]
public SupermatterStatusType Status = SupermatterStatusType.Inactive;
[DataField]
public string SliverPrototype = "SupermatterSliver";
/// <summary>
/// Affects delamination timer.
/// If removed - delamination timer is divided by 2.
/// </summary>
[DataField]
public bool SliverRemoved;
public string[] LightningPrototypes =
{
"SupermatterLightning",
"SupermatterLightningCharged",
"SupermatterLightningSupercharged"
};
[DataField]
public string SingularitySpawnPrototype = "Singularity";
[DataField]
public string TeslaSpawnPrototype = "TeslaEnergyBall";
[DataField]
public string KudzuSpawnPrototype = "SupermatterKudzu";
/// <summary>
/// What spawns in the place of an unfortunate entity that got removed by the SM.
/// </summary>
[DataField]
public string CollisionResultPrototype = "Ash";
#endregion
#region Sounds
[DataField]
public SoundSpecifier DustSound = new SoundPathSpecifier("/Audio/_EE/Supermatter/supermatter.ogg");
[DataField]
public SoundSpecifier DistortSound = new SoundPathSpecifier("/Audio/_EE/Supermatter/distort.ogg");
[DataField]
public SoundSpecifier CalmLoopSound = new SoundPathSpecifier("/Audio/_EE/Supermatter/calm.ogg");
[DataField]
public SoundSpecifier DelamLoopSound = new SoundPathSpecifier("/Audio/_EE/Supermatter/delamming.ogg");
[DataField]
public SoundSpecifier CurrentSoundLoop = new SoundPathSpecifier("/Audio/_EE/Supermatter/calm.ogg");
[DataField]
public SoundSpecifier CalmAccent = new SoundCollectionSpecifier("SupermatterAccentNormal");
[DataField]
public SoundSpecifier DelamAccent = new SoundCollectionSpecifier("SupermatterAccentDelam");
[DataField]
public string StatusWarningSound = "SupermatterWarning";
[DataField]
public string StatusDangerSound = "SupermatterDanger";
[DataField]
public string StatusEmergencySound = "SupermatterEmergency";
[DataField]
public string StatusDelamSound = "SupermatterDelaminating";
[DataField]
public string? StatusCurrentSound;
#endregion
#region Processing
[DataField]
public float Power;
[DataField]
public float Temperature;
[DataField]
public float WasteMultiplier;
[DataField]
public float MatterPower;
[DataField]
public float MatterPowerConversion = 10f;
/// <summary>
/// The portion of the gasmix we're on
/// </summary>
[DataField]
public float GasEfficiency = 0.15f;
/// <summary>
/// Based on CO2 percentage, this slowly moves between 0 and 1.
/// We use it to calculate the powerloss_inhibitor.
/// </summary>
[DataField]
public float PowerlossDynamicScaling;
/// <summary>
/// Affects the amount of damage and minimum point at which the SM takes heat damage
/// </summary>
[DataField]
public float DynamicHeatResistance = 1;
/// <summary>
/// Multiplier on damage the core takes from absorbing hot gas.
/// Default is ~1/350.
/// </summary>
[DataField]
public float MoleHeatPenalty = 0.00286f;
/// <summary>
/// Inverse of <see cref="MoleHeatPenalty" />
/// </summary>
[DataField]
public float MoleHeatThreshold = 350f;
/// <summary>
/// Multiplier on power generated by nuclear reactions
/// </summary>
[DataField]
public float ReactionPowerModifier = 0.55f;
/// <summary>
/// Acts as a multiplier on the amount that nuclear reactions increase the supermatter core temperature
/// </summary>
[DataField]
public float ThermalReleaseModifier = 0.2f;
/// <summary>
/// Multiplier on how much plasma is released during supermatter reactions
/// Default is ~1/750
/// </summary>
[DataField]
public float PlasmaReleaseModifier = 0.001333f;
/// <summary>
/// Multiplier on how much oxygen is released during supermatter reactions.
/// Default is ~1/325
/// </summary>
[DataField]
public float OxygenReleaseEfficiencyModifier = 0.0031f;
/// <summary>
/// The chance for supermatter lightning to strike random coordinates instead of an entity
/// </summary>
[DataField]
public float ZapHitCoordinatesChance = 0.75f;
#endregion
#region Timing
/// <summary>
/// We yell if over 50 damage every YellTimer Seconds
/// </summary>
[DataField]
public TimeSpan YellTimer = TimeSpan.Zero;
/// <summary>
/// Last time the supermatter's damage was announced
/// </summary>
[DataField]
public TimeSpan YellLast = TimeSpan.Zero;
/// <summary>
/// Time when the delamination will occuer
/// </summary>
[DataField]
public TimeSpan DelamEndTime;
/// <summary>
/// How long it takes in seconds for the supermatter to delaminate after reaching zero integrity
/// </summary>
[DataField]
public float DelamTimer = 30f;
/// <summary>
/// Last time a supermatter accent sound was triggered
/// </summary>
[DataField]
public TimeSpan AccentLastTime = TimeSpan.Zero;
/// <summary>
/// Minimum time in seconds between supermatter accent sounds
/// </summary>
[DataField]
public float AccentMinCooldown = 2f;
[DataField]
public TimeSpan ZapLast = TimeSpan.Zero;
#endregion
#region Thresholds
/// <summary>
/// The heat threshold in Kelvin, after which the supermatter begins taking damage.
/// </summary>
[DataField]
public float HeatThreshold = 2500f;
/// <summary>
/// Percentage of inhibitor gas needed before the charge inertia chain reaction effect starts.
/// </summary>
[DataField]
public float PowerlossInhibitionGasThreshold = 0.20f;
/// <summary>
/// Moles of the gas needed before the charge inertia chain reaction effect starts.
/// Scales powerloss inhibition down until this amount of moles is reached.
/// </summary>
[DataField]
public float PowerlossInhibitionMoleThreshold = 20f;
/// <summary>
/// Bonus powerloss inhibition boost if this amount of moles is reached
/// </summary>
[DataField]
public float PowerlossInhibitionMoleBoostThreshold = 500f;
/// <summary>
/// Above this value we can get lord singulo and independent mol damage, below it we can heal damage
/// </summary>
[DataField]
public float MolePenaltyThreshold = 1800f;
/// <summary>
/// More moles of gases are harder to heat than fewer, so let's scale heat damage around them
/// </summary>
[DataField]
public float MoleHeatPenaltyThreshold;
/// <summary>
/// The cutoff on power properly doing damage, pulling shit around,
/// and delamming into a tesla. Low chance of pyro anomalies, +2 bolts of electricity
/// </summary>
[DataField]
public float PowerPenaltyThreshold = 5000f;
/// <summary>
/// +1 bolt of electricity, TODO: anomaly spawning
/// </summary>
[DataField]
public float SeverePowerPenaltyThreshold = 7000f;
/// <summary>
/// +1 bolt of electricity
/// </summary>
[DataField]
public float CriticalPowerPenaltyThreshold = 9000f;
/// <summary>
/// Maximum safe operational temperature in degrees Celsius.
/// Supermatter begins taking damage above this temperature.
/// </summary>
[DataField]
public float HeatPenaltyThreshold = 40f;
#endregion
#region Damage
/// <summary>
/// The amount of damage taken
/// </summary>
[DataField]
public float Damage;
/// <summary>
/// The damage from before this cycle.
/// Used to limit the damage we can take each cycle, and for safe alert.
/// </summary>
[DataField]
public float DamageArchived;
/// <summary>
/// Is multiplied by ExplosionPoint to cap evironmental damage per cycle
/// </summary>
[DataField]
public float DamageHardcap = 0.002f;
/// <summary>
/// Environmental damage is scaled by this
/// </summary>
[DataField]
public float DamageIncreaseMultiplier = 0.25f;
/// <summary>
/// Max space damage the SM will take per cycle
/// </summary>
[DataField]
public float MaxSpaceExposureDamage = 2;
/// <summary>
/// The point at which we should start sending radio messages about the damage.
/// </summary>
[DataField]
public float DamageWarningThreshold = 50;
/// <summary>
/// The point at which we start sending station announcements about the damage.
/// </summary>
[DataField]
public float DamageEmergencyThreshold = 500;
/// <summary>
/// The point at which the SM begins shooting lightning.
/// </summary>
[DataField]
public int DamagePenaltyPoint = 550;
/// <summary>
/// The point at which the SM begins delaminating.
/// </summary>
[DataField]
public int DamageDelaminationPoint = 900;
/// <summary>
/// The point at which the SM begins showing warning signs.
/// </summary>
[DataField]
public int DamageDelamAlertPoint = 300;
[DataField]
public bool Delamming;
[DataField]
public DelamType PreferredDelamType = DelamType.Explosion;
#endregion
#region Announcements
[DataField]
public bool DelamAnnounced;
[DataField]
public ProtoId<RadioChannelPrototype> Channel = "Engineering";
[DataField]
public ProtoId<RadioChannelPrototype> ChannelGlobal = "Common";
#endregion
#region Gases
/// <summary>
/// How much gas is in the SM
/// </summary>
[DataField]
public Dictionary<Gas, float> GasStorage = new Dictionary<Gas, float>()
{
{ Gas.Oxygen, 0f },
{ Gas.Nitrogen, 0f },
{ Gas.CarbonDioxide, 0f },
{ Gas.Plasma, 0f },
{ Gas.Tritium, 0f },
{ Gas.WaterVapor, 0f },
{ Gas.Frezon, 0f },
{ Gas.Ammonia, 0f },
{ Gas.NitrousOxide, 0f },
// WD EDIT START
{ Gas.BZ, 0f },
{ Gas.Pluoxium, 0f },
{ Gas.Hydrogen, 0f },
{ Gas.Nitrium, 0f },
{ Gas.Healium, 0f },
{ Gas.HyperNoblium, 0f },
{ Gas.ProtoNitrate, 0f },
{ Gas.Zauker, 0f },
{ Gas.Halon, 0f },
{ Gas.Helium, 0f },
{ Gas.AntiNoblium, 0f },
// WD EDIT END
};
/// <summary>
/// Stores information about how every gas interacts with the SM
/// </summary>
//TODO: Replace this with serializable GasFact array something
public readonly Dictionary<Gas, (float TransmitModifier, float HeatPenalty, float PowerMixRatio)> GasDataFields = new()
{
{ Gas.Oxygen, (1.5f, 1f, 1f) },
{ Gas.Nitrogen, (0f, -1.5f, -1f) },
{ Gas.CarbonDioxide, (0f, 0.1f, 1f) },
{ Gas.Plasma, (4f, 15f, 1f) },
{ Gas.Tritium, (30f, 10f, 1f) },
{ Gas.WaterVapor, (2f, 12f, 1f) },
{ Gas.Frezon, (3f, -10f, -1f) },
{ Gas.Ammonia, (0f, .5f, 1f) },
{ Gas.NitrousOxide, (0f, -5f, -1f) },
// WD EDIT START
{ Gas.BZ, (0f, 5f, 1f) },
{ Gas.Pluoxium, (0f, -3f, -1.5f) },
{ Gas.Hydrogen, (15f, 5f, 1f) },
{ Gas.Nitrium, (1.5f, 1f, 1f) },
{ Gas.Healium, (2f, 3f, 1f) },
{ Gas.HyperNoblium, (0f, 2f, 1f) },
{ Gas.ProtoNitrate, (0f, 0.1f, 2f) },
{ Gas.Zauker, (2f, 2f, 1f) },
{ Gas.Halon, (0f, 0f, 0f) },
{ Gas.Helium, (0f, 0f, 0f) },
{ Gas.AntiNoblium, (.1f, .01f, 1f) },
// WD EDIT END
};
#endregion
}
public enum SupermatterSound : sbyte
{
Aggressive = 0,
Delam = 1
}
public enum DelamType : int
{
Explosion = 0,
Singulo = 1,
Tesla = 2,
Cascade = 3
}
[Serializable, DataDefinition]
public sealed partial class GasFact
{
[DataField]
public float TransmitModifier;
[DataField]
public float HeatPenalty;
[DataField]
public float PowerMixRatio;
public GasFact(float transmitModifier, float heatPenalty, float powerMixRatio)
{
TransmitModifier = transmitModifier;
HeatPenalty = heatPenalty;
PowerMixRatio = powerMixRatio;
}
}
[Serializable, NetSerializable]
public sealed partial class SupermatterDoAfterEvent : SimpleDoAfterEvent { }