feat: resolve spell \$o1 periodic totals from base points × ticks

Spell descriptions now substitute \$o1/\$o2/\$o3 with the total
periodic damage/healing: base_per_tick × (duration / 3sec).

Example: SW:Pain with base=4 (5 per tick), duration=18sec (6 ticks):
  Before: "Causes X Shadow damage over 18 sec"
  After:  "Causes 30 Shadow damage over 18 sec"

Combined with \$s1 (per-tick/instant) and \$d (duration), the three
most common spell template variables are now fully resolved. This
covers the vast majority of spell tooltips.
This commit is contained in:
Kelsi 2026-03-23 01:02:31 -07:00
parent 11ecc475c8
commit b8c33c7d9b

View file

@ -1649,8 +1649,24 @@ static std::string cleanSpellDescription(const std::string& raw, const int32_t e
result += 'X';
}
while (i + 1 < raw.size() && raw[i + 1] >= '0' && raw[i + 1] <= '9') ++i;
} else if (next == 'o' || next == 'O' ||
next == 'e' || next == 'E' || next == 't' || next == 'T' ||
} else if (next == 'o' || next == 'O') {
// $o1 = periodic total (base * ticks). Ticks = duration / 3sec for most spells
i += 1;
int idx = 0;
if (i + 1 < raw.size() && raw[i + 1] >= '1' && raw[i + 1] <= '3') {
idx = raw[i + 1] - '1';
++i;
}
if (effectBase && effectBase[idx] != 0 && durationSec > 0.0f) {
int32_t perTick = std::abs(effectBase[idx]) + 1;
int ticks = static_cast<int>(durationSec / 3.0f);
if (ticks < 1) ticks = 1;
result += std::to_string(perTick * ticks);
} else {
result += 'X';
}
while (i + 1 < raw.size() && raw[i + 1] >= '0' && raw[i + 1] <= '9') ++i;
} else if (next == 'e' || next == 'E' || next == 't' || next == 'T' ||
next == 'h' || next == 'H' || next == 'u' || next == 'U') {
// Other variables — insert "X" placeholder
result += 'X';