namespace Aeshnidae.Healing; /// /// Heals that keep up with the vital they heal (Tom, 2026-09-29: "Can we flip all this stuff to be /// percentage based ... If health ever gets into the thousands those healing spells become useless"; /// "Let's not touch harm yet. But definitely healing/stam kits/spells"). /// /// Every heal this covers is its retail amount times max(1, the target's maximum of that vital / /// the reference for it) - "retail or a percentage, whichever is larger". At or below the reference /// nothing changes from retail; above it, the heal grows with the vital, so the same kit or spell /// always restores the same share of it. The references sit just above a fully buffed level-275 /// character (live shard, 2026-09-29: Endurance 250, Self 200-290, 196 ranks in each vital - about /// 350-420 health, ~500 stamina, ~550 mana), so every character playing today heals exactly as in /// retail; the heal only grows once a pool passes that. `/healing` lists every online player's pools. /// /// Enabled the switch; off = every heal is retail /// ReferenceHealth the maximum health at which a heal is its retail amount /// ReferenceStamina the same for stamina (kits and Revitalize) /// ReferenceMana the same for mana, if ScaleMana /// ScaleKits healing and stamina kits (Healer): the amount, and the success check /// measured against the scaled-down missing vital so the odds stay retail /// ScaleSpells Heal / Revitalize spells (positive Boost spells); harm and drain never /// ScaleMana mana kits and Mana Boost spells too (Tom asked health and stamina) /// ScaleMonsterHeals heals landing on a monster or NPC, whoever casts them - off: tier-scaled /// monsters keep retail self-heals, and a player healing a monster heals it retail /// MaxFactor the most a heal is ever multiplied by; 0 = no limit /// public class Settings { public const string FileName = "Settings.json"; public bool Enabled { get; set; } = true; public double ReferenceHealth { get; set; } = 400; public double ReferenceStamina { get; set; } = 500; public double ReferenceMana { get; set; } = 500; public bool ScaleKits { get; set; } = true; public bool ScaleSpells { get; set; } = true; public bool ScaleMana { get; set; } public bool ScaleMonsterHeals { get; set; } public double MaxFactor { get; set; } private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true, ReadCommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true, }; public static Settings Load(string modPath) { var path = Path.Combine(modPath, FileName); try { if (File.Exists(path)) return JsonSerializer.Deserialize(File.ReadAllText(path), JsonOptions) ?? new Settings(); var defaults = new Settings(); defaults.Save(modPath); ModManager.Log($"[{Mod.Name}] wrote default settings to {path}"); return defaults; } catch (Exception ex) { ModManager.Log($"[{Mod.Name}] could not read {path}, using defaults: {ex.Message}", ModManager.LogLevel.Warn); return new Settings(); } } public void Save(string modPath) { try { File.WriteAllText(Path.Combine(modPath, FileName), JsonSerializer.Serialize(this, JsonOptions)); } catch (Exception ex) { ModManager.Log($"[{Mod.Name}] could not save settings: {ex.Message}", ModManager.LogLevel.Error); } } }