Update class mechanics, stat rulesets, and CoA reference catalogs

This commit is contained in:
phenom committed 2026-10-04 12:56:30 -04:00
1 parent b16821e92e
commit 39458d5de6
221 files changed
+2584962 -568

No files matched your search

+36 -7
View File
@@ -48,6 +48,7 @@ import {
import { romPriestChampionCooldownOverride } from "./romPriestChampionOverrides";
import { applyTalentModifierValue, talentModifiersForRanks } from "./talentModifiers";
import { romWarlockMageSoulBrandStingHasWillpowerBladeState } from "./romWarlockMageSoulBrandSting";
import { EMPTY_ITEM_STATS } from "./itemStats";
export interface PartyAbilityContext {
readonly now: number;
@@ -279,8 +280,16 @@ export function partyAbilityCosts(member: PartyMember, ability: AbilityDefinitio
aura.definition.utilityTags?.includes(WOW335_MAGE_ARCANE_CONCENTRATION_TAG)
));
return (adjustedAbility.costs?.length ? adjustedAbility.costs : [adjustedAbility.cost]).map((cost) => {
const baseMana = cost.percentageBasis === "base-mana"
? adjustedAbility.source === "runewaker" && member.statRuleset === "rom"
? deriveCharacterStats(
member.classId, member.level, EMPTY_ITEM_STATS, member.raceId, {}, member.secondaryClassId,
member.gender, "rom",
).mana
: baseResourcesFor(member.classId, member.level).mana
: 0;
const maximum = cost.percentageBasis === "base-mana"
? baseResourcesFor(member.classId, member.level).mana
? baseMana
: cost.resource === "health" ? member.maxHealth : companionResourceMaximum(member, cost.resource);
const baseAmount = cost.percentage ? cost.amount / 100 * maximum : cost.amount;
const adjusted = resolveResourceValue(
@@ -393,6 +402,21 @@ export function choosePartyRotationDecision(
.map((resource) => [resource, companionResourceMaximum(member, resource)]),
);
const learned = learnedAbilities(member);
const readyAbilities = learned.filter((ability) => partyAbilityIsReady(
member,
ability,
context.now,
Boolean(context.nextHealingSpellFree && ability.effects.some((effect) => effect.kind === "heal")),
));
const linkedKnightPunishment = member.classId === "rom-knight" && member.secondaryClassId === "rom-rogue"
? readyAbilities.find((ability) => ability.source === "runewaker"
&& ability.classId === "rom-knight" && ability.secondaryClassId === "rom-rogue"
&& ability.dbcSpellId === 499909
&& (context.canUseAbility?.(ability) ?? true))
: null;
const rotationAbilities = linkedKnightPunishment
? readyAbilities.filter((ability) => ability.dbcSpellId !== 490151)
: readyAbilities;
const reapingRank = member.classId === "death-knight"
? Math.max(0, Math.trunc(member.talentRanks["talent-2001"] ?? 0))
: 0;
@@ -442,12 +466,7 @@ export function choosePartyRotationDecision(
comboTargetId: member.comboTargetId,
runes: member.runes,
deathKnightReapingRank: reapingRank,
abilities: learned.filter((ability) => partyAbilityIsReady(
member,
ability,
context.now,
Boolean(context.nextHealingSpellFree && ability.effects.some((effect) => effect.kind === "heal")),
)),
abilities: rotationAbilities,
knownDamagingAbilityNames: new Set(learned.filter((ability) => {
const categories = aiHintsForAbility(ability).categories;
return categories.includes("damage") || categories.includes("execute");
@@ -555,6 +574,8 @@ export function partyAbilityAmount(
member.raceId,
{},
member.secondaryClassId,
member.gender,
member.statRuleset ?? "wow",
).intellect;
if (effect.kind === "finisher-damage" && effect.poison) {
const consumedDoses = Math.max(0, Math.min(
@@ -574,6 +595,10 @@ export function partyAbilityAmount(
ability,
0,
sourceIntellect,
member.raceId,
member.gender,
member.statRuleset ?? "wow",
member.secondaryClassId,
);
}
const coefficient = "coefficient" in effect
@@ -589,6 +614,10 @@ export function partyAbilityAmount(
ability,
0,
sourceIntellect,
member.raceId,
member.gender,
member.statRuleset ?? "wow",
member.secondaryClassId,
) + (effect.kind === "damage" ? effect.bonusFlat ?? 0 : 0);
if (member.classId === "druid" && (effect.kind === "damage" || effect.kind === "dot")) {
return applyTalentModifierValue(