Skip to content

Commit

Permalink
AnnoucesAndIntegrity
Browse files Browse the repository at this point in the history
  • Loading branch information
Alwayswannahunt committed Aug 8, 2024
1 parent 357ec46 commit 15b1326
Show file tree
Hide file tree
Showing 15 changed files with 336 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
namespace Content.Client.SS220.SuperMatterCrystalUIs;

public sealed class SuperMatterObserverBUI : BoundUserInterface
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt -->
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow;
using System.Numerics;
using Robust.Client.AutoGenerated;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Client.Resources;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface;
Expand Down Expand Up @@ -83,6 +84,8 @@ private void DrawAxis(DrawingHandleScreen handle, float maxY, float xWidth)
handle.DrawString(_font, CorrectVector(AxisBorderPosition + 2 * SerifSize, AxisBorderPosition), $"{-xWidth:0.}");
// here goes labels
handle.DrawString(_font, CorrectVector(AxisBorderPosition + SerifSize, PixelHeight), $"{_plotPoints.YLabel}");
// !!!TODO: Add title!!!
// !!!TODO: Make it it centered and below graph!!!
if (_plotPoints.XLabel != null)
handle.DrawString(_font, CorrectVector(PixelWidth - _plotPoints.XLabel.Length * FontSize, AxisBorderPosition), $"{_plotPoints.XLabel}");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Linq;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,41 @@ namespace Content.Server.SS220.SuperMatterCrystal.Components;
[RegisterComponent, AutoGenerateComponentPause]
public sealed partial class SuperMatterComponent : Component
{
/// <summary> The SM will only cycle if activated. </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public bool Activated = false;
/// <summary> Super flag for freezing all SM interaction.
/// Only changing it to true will invoke base SM logic </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public bool DisabledByAdmin = false;


// Accumulators
[ViewVariables(VVAccess.ReadOnly)]
public float IntegrityDamageAccumulator = 0f;

[DataField, ViewVariables(VVAccess.ReadOnly)]
public float AccumulatedZapEnergy = 0f;
[DataField, ViewVariables(VVAccess.ReadOnly)]
public float AccumulatedRadiationEnergy = 0f;

/// <summary> Current Value set to 4.1f cause for Arcs where is no point in lesser </summary>
[DataField]
public TimeSpan OutputEnergySourceUpdateDelay = TimeSpan.FromSeconds(4.1f);
[DataField, ViewVariables(VVAccess.ReadOnly)]
// TimeSpans
/// <summary> Current Value set to 3.5f cause for Arcs where is no point in lesser </summary>
[ViewVariables(VVAccess.ReadOnly)]
public TimeSpan OutputEnergySourceUpdateDelay = TimeSpan.FromSeconds(3.5f);
[ViewVariables(VVAccess.ReadOnly)]
[AutoPausedField]
public TimeSpan NextOutputEnergySourceUpdate = default!;
[DataField, ViewVariables(VVAccess.ReadOnly)]
[ViewVariables(VVAccess.ReadOnly)]
[AutoPausedField]
public TimeSpan NextDamageImplementTime = default!;
[ViewVariables(VVAccess.ReadOnly)]
[AutoPausedField]
public TimeSpan NextDamageStationAnnouncement = default!;

// SM params

[ViewVariables(VVAccess.ReadOnly)]
public float Integrity = 100f;
public float Temperature = Atmospherics.T20C;
[DataField, ViewVariables(VVAccess.ReadOnly)]
public float Matter = 200 * SuperMatterSystem.MatterNondimensionalization; // To wrap it in own VAR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ namespace Content.Server.SS220.SuperMatterCrystal.Components;
public sealed partial class SuperMatterSpecificConsumableComponent : Component
{
[DataField]
public float AdditionalEnergyOnConsumption = 0f;
public float AdditionalMatterOnConsumption = 0f;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Content.Shared.Atmos;

namespace Content.Server.SS220.SuperMatterCrystal;
/// <summary> TODO DESC </summary>

public static class SuperMatterInternalProcess
{
private const float TriplePointTemperature = SuperMatterPhaseDiagram.SuperMatterTriplePointTemperature;
Expand Down Expand Up @@ -72,12 +72,10 @@ public static float GetZapToRadiationRatio(float temperature, float pressure, Su
private const float O2ToPlasmaFloatRatio = 1.7f;
private const float RatioValueOffset = 0.44f;
private const float SqrtOfMaxRatioValue = 1.2f;
/// <summary> MADE IT! </summary>
/// <returns></returns>
public static float GetOxygenToPlasmaRatio(float temperature, float pressure, SuperMatterPhaseState smState)
{
var ratio = GetZapToRadiationRatio(temperature, pressure, smState);
return (O2ToPlasmaBaseRatio + O2ToPlasmaFloatRatio * MathF.Sqrt(ratio+RatioValueOffset))
return (O2ToPlasmaBaseRatio + O2ToPlasmaFloatRatio * MathF.Sqrt(ratio + RatioValueOffset))
/ (O2ToPlasmaBaseRatio + O2ToPlasmaFloatRatio * SqrtOfMaxRatioValue);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using System.Diagnostics.CodeAnalysis;
using Content.Server.Chat.Managers;
using Content.Server.Chat.Systems;
using Content.Server.SS220.SuperMatterCrystal.Components;
using Content.Shared.Radio;
using Robust.Shared.Prototypes;

namespace Content.Server.SS220.SuperMatterCrystal;

public sealed partial class SuperMatterSystem : EntitySystem
{
[Dependency] IChatManager _chatManager = default!;
[Dependency] ChatSystem _chatSystem = default!;
[Dependency] IPrototypeManager _prototypeManager = default!;
private ProtoId<RadioChannelPrototype> _engineerRadio = "Engineering";
private ProtoId<RadioChannelPrototype> _commonRadio = "Common";
private char _engineerRadioKey = '\0';
private char _commonRadioKey = '\0';


private void InitializeAnnouncement()
{
_engineerRadioKey = _prototypeManager.Index(_engineerRadio).KeyCode;
_commonRadioKey = _prototypeManager.Index(_commonRadio).KeyCode;
}

public void RadioAnnounceIntegrity(Entity<SuperMatterComponent> crystal, AnnounceIntegrityTypeEnum announceType)
{
if (announceType == AnnounceIntegrityTypeEnum.None)
return;
var integrity = GetIntegrity(crystal.Comp);
var localePath = "supermatter-" + announceType.ToString().ToLower();
var message = Loc.GetString(localePath, ("integrity", integrity));
if (TryGetChannelKey(announceType, out var channelKey))
message = channelKey + message;
RadioAnnouncement(crystal.Owner, message);
}
public void StationAnnounceIntegrity(Entity<SuperMatterComponent> crystal, AnnounceIntegrityTypeEnum announceType)
{
if (!(announceType == AnnounceIntegrityTypeEnum.DelaminationStopped
|| announceType == AnnounceIntegrityTypeEnum.Delamination))
return;
var integrity = GetIntegrity(crystal.Comp);
var localePath = "supermatter-" + announceType.ToString().ToLower();
var message = Loc.GetString(localePath, ("integrity", integrity));
}

private void SendAdminChatAlert(Entity<SuperMatterComponent> crystal, string msg, string? whom = null)
{
var startString = $"SuperMatter {crystal} Alert! ";
var endString = "";
if (whom != null)
endString = $" caused by {whom}.";
_chatManager.SendAdminAlert(startString + msg + endString);
}
private void SendStationAnnouncement(EntityUid uid, string message, string? sender = null)
{
var localizedSender = GetLocalizedSender(sender);

_chatSystem.DispatchStationAnnouncement(uid, message, localizedSender, colorOverride: Color.FromHex("#deb63d"));
return;
}
private void RadioAnnouncement(EntityUid uid, string message)
{
_chatSystem.TrySendInGameICMessage(uid, message, InGameICChatType.Speak, false, checkRadioPrefix: true);
}
private string GetLocalizedSender(string? sender)
{
var resultSender = sender ?? "supermatter-announcer";
if (!Loc.TryGetString(resultSender, out var localizedSender))
localizedSender = resultSender;
return localizedSender;
}
/// <summary> Gets announce type, do it before zeroing AccumulatedDamage </summary>
/// <param name="smComp"></param>
/// <returns></returns>
private AnnounceIntegrityTypeEnum GetAnnounceIntegrityType(SuperMatterComponent smComp)
{
var type = AnnounceIntegrityTypeEnum.Error;
if (smComp.IntegrityDamageAccumulator > 0)
type = smComp.Integrity switch
{
< 15f => AnnounceIntegrityTypeEnum.Delamination,
< 35f => AnnounceIntegrityTypeEnum.Danger,
< 80f => AnnounceIntegrityTypeEnum.Warning,
_ => AnnounceIntegrityTypeEnum.None
};
else type = smComp.Integrity switch
{
< 15f => AnnounceIntegrityTypeEnum.DelaminationStopped,
< 35f => AnnounceIntegrityTypeEnum.DangerRecovering,
< 80f => AnnounceIntegrityTypeEnum.WarningRecovering,
_ => AnnounceIntegrityTypeEnum.None
};

return type;
}
private bool TryGetChannelKey(AnnounceIntegrityTypeEnum announceType, [NotNullWhen(true)] out char? channelKey)
{
channelKey = announceType switch
{
AnnounceIntegrityTypeEnum.DangerRecovering => _commonRadioKey,
AnnounceIntegrityTypeEnum.Danger => _commonRadioKey,
AnnounceIntegrityTypeEnum.Delamination => _commonRadioKey,
AnnounceIntegrityTypeEnum.DelaminationStopped => _commonRadioKey,
AnnounceIntegrityTypeEnum.Warning => _engineerRadioKey,
AnnounceIntegrityTypeEnum.WarningRecovering => _engineerRadioKey,
_ => null
};
return channelKey is not null;
}
}

public enum AnnounceIntegrityTypeEnum
{
Error = -1,
None,
Warning,
Danger,
WarningRecovering,
DangerRecovering,
Delamination,
DelaminationStopped
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Server.SS220.SuperMatterCrystal.Components;

namespace Content.Server.SS220.SuperMatterCrystal;

public sealed partial class SuperMatterSystem : EntitySystem
{
/// <summary> !TODO IT! </summary>
private void MarkAsLaminated(Entity<SuperMatterComponent> crystal)
{
// TODO
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.Atmos;
using Content.Server.SS220.SuperMatterCrystal.Components;

namespace Content.Server.SS220.SuperMatterCrystal;

public sealed partial class SuperMatterSystem : EntitySystem
{
/// <summary> Based lie, negative damage = heal, no exception will thrown </summary>
/// <returns> if positive - damage, if negative - heal </returns>
public float GetIntegrityDamage(SuperMatterComponent smComp)
{
var (internalEnergy, matter, temperature) = (smComp.InternalEnergy, smComp.Matter, smComp.Temperature);
var damageFromDelta = GetInternalEnergyToMatterDamageFactor(internalEnergy, matter);
var temperatureFactor = TemperatureDamageFactorFunction(temperature);
var damage = damageFromDelta > 0 ? damageFromDelta * temperatureFactor : damageFromDelta;
return damage;
}
public float GetInternalEnergyToMatterDamageFactor(float internalEnergy, float matter)
{
var safeInternalEnergy = GetSafeInternalEnergyToMatterValue(matter);
var delta = internalEnergy - safeInternalEnergy;
var damageFromDelta = EnergyToMatterDamageFactorFunction(delta);
return damageFromDelta;
}
public float GetSafeInternalEnergyToMatterValue(float matter)
{
var normalizedMatter = matter / MatterNondimensionalization;
return SafeInternalEnergyToMatterFunction(normalizedMatter);
}
public void AddIntegrityDamage(SuperMatterComponent smComp, float damage)
{
smComp.IntegrityDamageAccumulator += damage;
}
public float GetIntegrity(SuperMatterComponent smComp)
{
return MathF.Round(smComp.Integrity, 2);
}

private const float MaxDamagePerSecond = 1.5f;
private const float MaxRegenerationPerSecond = 1.5f;
/// <summary> Based lie, negative damage = heal, no exception will thrown </summary>
/// <returns> Return false only if SM integrity WILL fall below zero, but wont set it to zero </returns>
private bool TryImplementIntegrityDamage(SuperMatterComponent smComp)
{
var resultIntegrityDamage = Math.Clamp(smComp.IntegrityDamageAccumulator, -MaxDamagePerSecond, MaxRegenerationPerSecond);
if (smComp.Integrity + resultIntegrityDamage < 0f)
return false;
if (smComp.Integrity + resultIntegrityDamage < 100f)
{
smComp.Integrity += resultIntegrityDamage;
return true;
}
if (smComp.Integrity != 100f)
smComp.Integrity = 100f;
return true;
}

private const float EnergyToMatterDamageFactorSlowerOffset = 1000f;
private const float EnergyToMatterDamageFactorDeltaOffset = 1000f;
private float EnergyToMatterDamageFactorFunction(float delta)
{
var offsetedDelta = delta - EnergyToMatterDamageFactorDeltaOffset;
return offsetedDelta / (MathF.Abs(offsetedDelta) + EnergyToMatterDamageFactorSlowerOffset);
}

private const float SafeInternalEnergyToMatterCoeff = 800f;
private const float SafeInternalEnergyToMatterSlowerOffset = 50f;
private float SafeInternalEnergyToMatterFunction(float normalizedMatter)
{
return SafeInternalEnergyToMatterCoeff * MathF.Pow(normalizedMatter, 1.5f)
/ (normalizedMatter + SafeInternalEnergyToMatterSlowerOffset);
}

private const float TemperatureDamageFactorCoeff = 3f;
private const float TemperatureDamageFactorSlowerOffset = 20f;
private float TemperatureDamageFactorFunction(float normalizedTemperature)
{
var normalizedMaxTemperature = Atmospherics.Tmax / SuperMatterPhaseDiagram.SuperMatterTriplePointTemperature;
var maxFuncValue = MathF.Pow(normalizedMaxTemperature, 1.5f) /
(normalizedMaxTemperature - TemperatureDamageFactorSlowerOffset);

return TemperatureDamageFactorCoeff * (MathF.Pow(normalizedTemperature, 1.5f) /
(normalizedTemperature - TemperatureDamageFactorSlowerOffset)) / maxFuncValue;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Robust.Shared.Physics;
using Robust.Shared.Physics.Events;
using Content.Server.SS220.SuperMatterCrystal.Components;
using Content.Shared.Interaction;
using Content.Shared.Projectiles;

namespace Content.Server.SS220.SuperMatterCrystal;

public sealed partial class SuperMatterSystem : EntitySystem
{
private void InitializeInteractions()
{
// subscribe Events
SubscribeLocalEvent<SuperMatterComponent, InteractHandEvent>(OnHandInteract);
SubscribeLocalEvent<SuperMatterComponent, InteractUsingEvent>(OnItemInteract);
SubscribeLocalEvent<SuperMatterComponent, StartCollideEvent>(OnCollideEvent);
}
private void OnHandInteract(Entity<SuperMatterComponent> entity, ref InteractHandEvent args)
{
entity.Comp.Matter += MatterNondimensionalization;
ConsumeObject(args.User, entity.Comp);
}
private void OnItemInteract(Entity<SuperMatterComponent> entity, ref InteractUsingEvent args)
{
entity.Comp.Matter += MatterNondimensionalization / 4;
ConsumeObject(args.User, entity.Comp);
}
private void OnCollideEvent(Entity<SuperMatterComponent> entity, ref StartCollideEvent args)
{
if (args.OtherBody.BodyType == BodyType.Static)
return;
if (TryComp<ProjectileComponent>(args.OtherEntity, out var projectile))
entity.Comp.InternalEnergy += CHEMISTRY_POTENTIAL_BASE * MathF.Max((float) projectile.Damage.GetTotal(), 0f);
entity.Comp.Matter += MatterNondimensionalization / 4;
ConsumeObject(args.OtherEntity, entity.Comp);
}
private void ConsumeObject(EntityUid uid, SuperMatterComponent smComp)
{
if (smComp.DisabledByAdmin)
return;
if (HasComp<SuperMatterImmuneComponent>(uid))
return;
if (!smComp.Activated)
smComp.Activated = true;
if (TryComp<SuperMatterSpecificConsumableComponent>(uid, out var consumableComponent))
smComp.Matter += consumableComponent.AdditionalMatterOnConsumption;
// TODO: Spawn Ash & make sound/popup
EntityManager.QueueDeleteEntity(uid);
}
}
Loading

0 comments on commit 15b1326

Please sign in to comment.