diff --git a/EpicLoot/EpicLoot.cs b/EpicLoot/EpicLoot.cs index 252ab1f70..c0ff30631 100644 --- a/EpicLoot/EpicLoot.cs +++ b/EpicLoot/EpicLoot.cs @@ -151,6 +151,7 @@ private static void RegisterMagicEffectEvents() { MagicItemEffects.Shards.LuckyLoot.RegisterDisplayValues(); MagicItemEffects.Shards.Bloodrage.RegisterDisplayValues(); MagicItemEffects.Shards.MeteorSummoner.RegisterDisplayValues(); + MagicItemEffects.Shards.EikthyrShockingCharge.RegisterDisplayValues(); MagicItemEffects.Shards.BlockAsDodgeAsBlock.RegisterDisplayValues(); MagicItemEffects.Shards.BlockAsWoodCuttingAndPickaxes.RegisterDisplayValues(); diff --git a/EpicLoot/config/shardstones.json b/EpicLoot/config/shardstones.json index 7053f4331..d14e2a38a 100644 --- a/EpicLoot/config/shardstones.json +++ b/EpicLoot/config/shardstones.json @@ -2407,6 +2407,7 @@ "Config": { "MaxCharges": 15, "DamageFraction": 0.3, + "ValueReference": 15, "ConeLength": 4, "ConeMaxWidth": 4, "DischargeIgnoreWindow": 0.3 diff --git a/EpicLoot/localizations/English.json b/EpicLoot/localizations/English.json index 3dc4100ec..7427ec0ad 100644 --- a/EpicLoot/localizations/English.json +++ b/EpicLoot/localizations/English.json @@ -656,7 +656,7 @@ "mod_epicloot_me_stormrider_display": "+{0}% Movement Speed in Storms", "mod_epicloot_me_stormrider_desc": "+{0}% movement speed while a storm rages.", - "mod_epicloot_me_shockingcharge_display": "Shocking Charge", + "mod_epicloot_me_shockingcharge_display": "Shocking Charge: {0:0.#}% Banked Damage after {1} Hits", "mod_epicloot_me_shockingcharge_desc": "Your combat hits build charges. At max charge, the next hit unleashes a forward lightning shockwave that deals a portion of your previous hits' damage.", "mod_epicloot_me_forestsaid_display": "Forest's Aid", "mod_epicloot_me_forestsaid_desc": "When you are hit, ensnaring roots erupt and immobilize nearby enemies.", @@ -2179,4 +2179,4 @@ "mod_epicloot_criticalsuccess": "Critical Success", "mod_epicloot_criticalfail": "Critical Fail", "mod_epicloot_temper": "Temper" -} \ No newline at end of file +} diff --git a/EpicLoot/src/Magic/MagicItemEffects/Shards/EikthyrShockingCharge.cs b/EpicLoot/src/Magic/MagicItemEffects/Shards/EikthyrShockingCharge.cs index 15eb6c430..8af7bdb23 100644 --- a/EpicLoot/src/Magic/MagicItemEffects/Shards/EikthyrShockingCharge.cs +++ b/EpicLoot/src/Magic/MagicItemEffects/Shards/EikthyrShockingCharge.cs @@ -7,19 +7,23 @@ namespace EpicLoot.MagicItemEffects.Shards { public static class EikthyrShockingCharge { // All tunable in this effect's Config block in config/shardstones.json, under these key names. // - // Hits required to trigger a discharge, and the portion of the banked combat damage the shockwave - // delivers. Cone geometry: reach straight ahead, and the full width of the cone at that reach -- + // Hits required to trigger a discharge, the portion of the banked combat damage the Epic shard + // delivers, and the shard value that represents that reference rarity. Other rarities scale the + // damage fraction in direct proportion to their value. Cone geometry: reach straight ahead, and + // the full width of the cone at that reach -- // the half-width grows linearly from 0 at the player to (ConeMaxWidth / 2) at ConeLength. The // ignore window is how long after a discharge the shockwave's own hits are kept from rebuilding // the charge. public const int DefaultMaxCharges = 15; public const float DefaultDamageFraction = 0.3f; + public const float DefaultValueReference = 15f; public const float DefaultConeLength = 4f; public const float DefaultConeMaxWidth = 4f; public const float DefaultDischargeIgnoreWindow = 0.3f; private const string MaxChargesKey = "MaxCharges"; private const string DamageFractionKey = "DamageFraction"; + private const string ValueReferenceKey = "ValueReference"; private const string ConeLengthKey = "ConeLength"; private const string ConeMaxWidthKey = "ConeMaxWidth"; private const string DischargeIgnoreWindowKey = "DischargeIgnoreWindow"; @@ -27,11 +31,17 @@ public static class EikthyrShockingCharge { public static readonly Dictionary DefaultConfig = new Dictionary { { MaxChargesKey, DefaultMaxCharges }, { DamageFractionKey, DefaultDamageFraction }, + { ValueReferenceKey, DefaultValueReference }, { ConeLengthKey, DefaultConeLength }, { ConeMaxWidthKey, DefaultConeMaxWidth }, { DischargeIgnoreWindowKey, DefaultDischargeIgnoreWindow }, }; + public static void RegisterDisplayValues() { + MagicItem.RegisterDisplayValues(MagicEffectType.ShockingCharge, + value => new object[] { GetDamageFraction(value) * 100f, (float)GetMaxCharges() }); + } + // Clamped to at least 1 so a misconfiguration can't discharge on every hit through a zero threshold. private static int GetMaxCharges() { return EffectConfig.GetIntAtLeast(MagicEffectType.ShockingCharge, @@ -44,6 +54,16 @@ private static float GetConeLength() { EffectConfig.Get(MagicEffectType.ShockingCharge, ConeLengthKey, DefaultConeLength)); } + // The configured fraction is the Epic baseline. Keeping the reference value configurable preserves + // that balance when a server replaces the default rarity ramp. + private static float GetDamageFraction(float value) { + float referenceValue = Mathf.Max(0.1f, EffectConfig.Get(MagicEffectType.ShockingCharge, + ValueReferenceKey, DefaultValueReference)); + float baseFraction = Mathf.Max(0f, EffectConfig.Get(MagicEffectType.ShockingCharge, + DamageFractionKey, DefaultDamageFraction)); + return baseFraction * value / referenceValue; + } + private const string ShockwaveFx = "fx_eikthyr_forwardshockwave"; private static int _charges; @@ -101,8 +121,7 @@ public static void OnDamageDealt(Character __instance, HitData hit, Character at _charges = 0; _ignoreUntil = Time.time + EffectConfig.Get(MagicEffectType.ShockingCharge, DischargeIgnoreWindowKey, DefaultDischargeIgnoreWindow); - var shotDamage = _bankedDamage * EffectConfig.Get(MagicEffectType.ShockingCharge, - DamageFractionKey, DefaultDamageFraction); + float shotDamage = _bankedDamage * GetDamageFraction(value); _bankedDamage = 0f; FireShockwave(player, hit.m_dir, shotDamage); }