diff --git a/Content.Server/Electrocution/Components/ElectrifiedComponent.cs b/Content.Server/Electrocution/Components/ElectrifiedComponent.cs index d551aa1541..2f3def6e06 100644 --- a/Content.Server/Electrocution/Components/ElectrifiedComponent.cs +++ b/Content.Server/Electrocution/Components/ElectrifiedComponent.cs @@ -41,18 +41,6 @@ public sealed partial class ElectrifiedComponent : Component [DataField("lowVoltageNode")] public string? LowVoltageNode; - [DataField("highVoltageDamageMultiplier")] - public float HighVoltageDamageMultiplier = 3f; - - [DataField("highVoltageTimeMultiplier")] - public float HighVoltageTimeMultiplier = 1.5f; - - [DataField("mediumVoltageDamageMultiplier")] - public float MediumVoltageDamageMultiplier = 2f; - - [DataField("mediumVoltageTimeMultiplier")] - public float MediumVoltageTimeMultiplier = 1.25f; - [DataField("shockDamage")] public int ShockDamage = 20; diff --git a/Content.Server/Electrocution/Components/ElectrocutionComponent.cs b/Content.Server/Electrocution/Components/ElectrocutionComponent.cs index 2534544f6c..9da78c9134 100644 --- a/Content.Server/Electrocution/Components/ElectrocutionComponent.cs +++ b/Content.Server/Electrocution/Components/ElectrocutionComponent.cs @@ -7,15 +7,18 @@ [Access(typeof(ElectrocutionSystem))] public sealed partial class ElectrocutionComponent : Component { - [DataField("timeLeft")] - public float TimeLeft; - [DataField("electrocuting")] public EntityUid Electrocuting; + [DataField("source")] + public EntityUid Source; + + [DataField("timeLeft")] + public float TimeLeft; + [DataField("accumDamage")] public float AccumulatedDamage; - [DataField("source")] - public EntityUid Source; + [DataField("baseDamage")] + public float BaseDamage = 20f; } diff --git a/Content.Server/Electrocution/ElectrocutionSystem.cs b/Content.Server/Electrocution/ElectrocutionSystem.cs index 48415c3953..6c96266740 100644 --- a/Content.Server/Electrocution/ElectrocutionSystem.cs +++ b/Content.Server/Electrocution/ElectrocutionSystem.cs @@ -17,6 +17,7 @@ using Content.Shared.Interaction; using Content.Shared.Inventory; using Content.Shared.Jittering; using Content.Shared.Maps; +using Content.Shared.Mobs; using Content.Shared.Popups; using Content.Shared.Pulling.Components; using Content.Shared.Speech.EntitySystems; @@ -61,7 +62,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem private const string DamageType = "Shock"; // Yes, this is absurdly small for a reason. - private const float ElectrifiedDamagePerWatt = 0.0015f; + private const float ElectrifiedScalePerWatt = 1E-6f; private const float RecursiveDamageMultiplier = 0.75f; private const float RecursiveTimeMultiplier = 0.8f; @@ -102,7 +103,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem var timePassed = Math.Min(frameTime, electrocution.TimeLeft); electrocution.TimeLeft -= timePassed; - electrocution.AccumulatedDamage += consumer.ReceivedPower * ElectrifiedDamagePerWatt * timePassed; + electrocution.AccumulatedDamage += electrocution.BaseDamage * (consumer.ReceivedPower / consumer.DrawRate) * timePassed; if (!MathHelper.CloseTo(electrocution.TimeLeft, 0)) continue; @@ -117,7 +118,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem if (actual != null) { _adminLogger.Add(LogType.Electrocution, - $"{ToPrettyString(electrocution.Electrocuting):entity} received {actual.Total:damage} powered electrocution damage from {ToPrettyString(electrocution.Source):source}"); + $"{ToPrettyString(electrocution.Electrocuting):entity} received {actual.GetTotal():damage} powered electrocution damage from {ToPrettyString(electrocution.Source):source}"); } } QueueDel(uid); @@ -257,15 +258,17 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem } var node = PoweredNode(uid, electrified, nodeContainer); - if (node == null) + if (node?.NodeGroup is not IBasePowerNet powerNet) return false; - var (damageMult, timeMult) = node.NodeGroupID switch - { - NodeGroupID.HVPower => (electrified.HighVoltageDamageMultiplier, electrified.HighVoltageTimeMultiplier), - NodeGroupID.MVPower => (electrified.MediumVoltageDamageMultiplier, electrified.MediumVoltageTimeMultiplier), - _ => (1f, 1f) - }; + var net = powerNet.NetworkNode; + var supp = net.LastCombinedSupply; + + if (supp <= 0f) + return false; + + // Initial damage scales off of the available supply on the principle that the victim has shorted the entire powernet through their body. + var damageScale = supp * ElectrifiedScalePerWatt; { var lastRet = true; @@ -276,8 +279,8 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem entity, uid, node, - (int) (electrified.ShockDamage * MathF.Pow(RecursiveDamageMultiplier, depth) * damageMult), - TimeSpan.FromSeconds(electrified.ShockTime * MathF.Pow(RecursiveTimeMultiplier, depth) * timeMult), + (int) (electrified.ShockDamage * damageScale * MathF.Pow(RecursiveDamageMultiplier, depth)), + TimeSpan.FromSeconds(electrified.ShockTime * MathF.Min(1f + MathF.Log2(1f + damageScale), 3f) * MathF.Pow(RecursiveTimeMultiplier, depth)), true, electrified.SiemensCoefficient); } @@ -304,18 +307,18 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem } } - /// - public override bool TryDoElectrocution( - EntityUid uid, EntityUid? sourceUid, int shockDamage, TimeSpan time, bool refresh, float siemensCoefficient = 1f, - StatusEffectsComponent? statusEffects = null, bool ignoreInsulation = false) - { - if (!DoCommonElectrocutionAttempt(uid, sourceUid, ref siemensCoefficient, ignoreInsulation) - || !DoCommonElectrocution(uid, sourceUid, shockDamage, time, refresh, siemensCoefficient, statusEffects)) - return false; + /// + public override bool TryDoElectrocution( + EntityUid uid, EntityUid? sourceUid, int shockDamage, TimeSpan time, bool refresh, float siemensCoefficient = 1f, + StatusEffectsComponent? statusEffects = null, bool ignoreInsulation = false) + { + if (!DoCommonElectrocutionAttempt(uid, sourceUid, ref siemensCoefficient, ignoreInsulation) + || !DoCommonElectrocution(uid, sourceUid, shockDamage, time, refresh, siemensCoefficient, statusEffects)) + return false; - RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient), true); - return true; - } + RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient), true); + return true; + } private bool TryDoElectrocutionPowered( EntityUid uid, @@ -331,12 +334,12 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem if (!DoCommonElectrocutionAttempt(uid, sourceUid, ref siemensCoefficient)) return false; + if (!DoCommonElectrocution(uid, sourceUid, shockDamage, time, refresh, siemensCoefficient, statusEffects)) + return false; + // Coefficient needs to be higher than this to do a powered electrocution! if (siemensCoefficient <= 0.5f) - return DoCommonElectrocution(uid, sourceUid, shockDamage, time, refresh, siemensCoefficient, statusEffects); - - if (!DoCommonElectrocution(uid, sourceUid, null, time, refresh, siemensCoefficient, statusEffects)) - return false; + return true; if (!Resolve(sourceUid, ref sourceTransform)) // This shouldn't really happen, but just in case... return true; @@ -422,7 +425,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem if (actual != null) { _adminLogger.Add(LogType.Electrocution, - $"{ToPrettyString(uid):entity} received {actual.Total:damage} powered electrocution damage{(sourceUid != null ? " from " + ToPrettyString(sourceUid.Value) : ""):source}"); + $"{ToPrettyString(uid):entity} received {actual.GetTotal():damage} powered electrocution damage{(sourceUid != null ? " from " + ToPrettyString(sourceUid.Value) : ""):source}"); } } diff --git a/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs b/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs index e2399d8f77..d0c0a297b4 100644 --- a/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs +++ b/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs @@ -170,6 +170,7 @@ namespace Content.Server.Power.Pow3r } } + network.LastCombinedLoad = demand; network.LastCombinedSupply = totalSupply + totalBatterySupply; network.LastCombinedMaxSupply = totalMaxSupply + totalMaxBatterySupply; diff --git a/Content.Server/Power/Pow3r/PowerState.cs b/Content.Server/Power/Pow3r/PowerState.cs index 2b94af97b2..78ba97bb22 100644 --- a/Content.Server/Power/Pow3r/PowerState.cs +++ b/Content.Server/Power/Pow3r/PowerState.cs @@ -488,6 +488,11 @@ namespace Content.Server.Power.Pow3r /// [ViewVariables] public List BatterySupplies = new(); + /// + /// The total load on the power network as of last tick. + /// + [ViewVariables] public float LastCombinedLoad = 0f; + /// /// Available supply, including both normal supplies and batteries. ///