Complete RoM pair elite mechanics and creature family rules

This commit is contained in:
phenom committed 2026-09-23 19:38:13 -04:00
1 parent c8b3a3d95a
commit 0206fda9e2
21 files changed
+1082 -134

No files matched your search

+63 -1
View File
@@ -82,6 +82,9 @@ import {
ROGUE_ENVENOM_BUFF_TAG,
} from "./roguePoison";
import { romAbilityNeedsShield, romEffectsForCast, romSelfDrainPercent, romTargetBleedCount } from "./romCombatMechanics";
import { romCreatureFamilyTargetTags } from "./romCreatureFamilies";
import { romScoutRogueWhirlwindBonusEffect } from "./romScoutRogueOverrides";
import { ROM_FIRE_LIGHTNING_BURST_RESET_GUARD_TAG, romFireLightningBurstReset } from "./romMageWarlockOverrides";
const OUT_OF_COMBAT_REGEN_FRACTION = 0.06;
const ATTACK_ACQUISITION_RANGE = 30;
@@ -768,9 +771,17 @@ function partyAbilityTargetIsValid(
&& aura.definition.disposition === "buff" && aura.definition.dispelCategory === "enrage"
&& !aura.definition.name.startsWith("Enraged Regeneration"))) return false;
if (ability.source === "runewaker") {
if (ability.dbcSpellId === 491613 && mob?.creatureFamily === "living"
&& !(member.classId === "rom-knight" && member.secondaryClassId === "rom-scout" && member.level >= 60)) return false;
if (ability.dbcSpellId === 490347 && mob?.creatureFamily === "undead") return false;
if (ability.dbcSpellId === 490151 && (member.comboTargetId !== targetId || member.comboPoints <= 0)) return false;
if (ability.dbcSpellId === 490347 && !combat.auras.some((aura) => aura.targetId === member.id
&& aura.definition.utilityTags?.includes("rom-poisonous"))) return false;
if (ability.dbcSpellId === 493017 && !combat.auras.some((aura) => aura.targetId === member.id
&& aura.definition.utilityTags?.includes("rom-poisonous"))) return false;
if (ability.dbcSpellId === 492920 && !combat.effects.some((effect) => effect.kind === "dot"
&& effect.targetId === targetId && effect.remainingTicks > 0
&& effect.sourceAbilityId === "rom-rogue-rom-warrior-elite-35")) return false;
if (ability.dbcSpellId === 491171 && !combat.auras.some((aura) => aura.targetId === member.id
&& aura.definition.utilityTags?.includes("rom-charged"))) return false;
if (ability.dbcSpellId === 491172 && !combat.auras.some((aura) => aura.targetId === member.id
@@ -1225,10 +1236,19 @@ function executePartyAbility(
),
targetTags: combat.auras.filter((aura) => aura.targetId === targetId)
.flatMap((aura) => aura.definition.utilityTags ?? []).concat(
romCreatureFamilyTargetTags(combat.mobs[targetId]?.creatureFamily ?? "unknown"),
combat.effects.filter((effect) => effect.targetId === targetId && effect.remainingTicks > 0)
.flatMap((effect) => effect.tag ? [effect.tag] : []),
),
});
if (ability.dbcSpellId === 492920 && castEffects.some((effect) => effect.kind === "dot"
&& effect.tag === "rom-622992")) {
useCombatStore.setState((state) => ({
effects: state.effects.filter((effect) => !(effect.kind === "dot"
&& effect.targetId === targetId
&& effect.sourceAbilityId === "rom-rogue-rom-warrior-elite-35")),
}));
}
for (const effect of castEffects) {
if (ability.name === "Penance" && combat.mobs[targetId]
&& (effect.kind === "heal" || effect.kind === "hot")) continue;
@@ -1272,6 +1292,20 @@ function executePartyAbility(
} : undefined,
);
effectiveAmount += result.amount;
if (effect.kind === "damage" && ability.dbcSpellId === 490133) {
const currentCombat = useCombatStore.getState();
const bonus = romScoutRogueWhirlwindBonusEffect(
ability,
currentCombat.auras.filter((aura) => aura.targetId === member.id)
.flatMap((aura) => aura.definition.utilityTags ?? []),
currentCombat.effects.filter((active) => active.targetId === hostileTargetId && active.remainingTicks > 0)
.flatMap((active) => active.tag ? [active.tag] : []),
);
if (bonus) effectiveAmount += currentCombat.damageMob(
hostileTargetId, partyAbilityAmount(runtimeMember, ability, bonus), now,
{ actorId: member.id, role: member.role, abilityId: ability.id }, "physical",
).amount;
}
if (
result.amount > 0
&& effect.kind === "damage"
@@ -1383,7 +1417,7 @@ function executePartyAbility(
: effect.recipient === "caster"
? [member.id]
: combat.mobs[targetId] ? hostileTargets : friendlyTargets;
for (const recipientId of recipients) {
for (const recipientId of recipients.filter((id) => !effect.excludeCaster || id !== member.id)) {
const appliedEffect = ability.name === "Rupture"
? { ...effect, aura: { ...effect.aura, durationMs: Math.max(4, Math.min(8, 3 + runtimeMember.comboPoints)) * 2_000 } }
: ability.name === "Envenom"
@@ -1563,6 +1597,34 @@ function executePartyAbility(
if (consumesColdBlood) useCombatStore.getState().consumeActorAuraTag(member.id, "next-offensive-critical");
if (ability.dbcSpellId === 491171) useCombatStore.getState().consumeActorAuraTag(member.id, "rom-charged");
if (ability.dbcSpellId === 491172) useCombatStore.getState().consumeActorAuraTag(member.id, "rom-static-field-charge");
if (ability.dbcSpellId === 498759) {
const currentCombat = useCombatStore.getState();
const reset = romFireLightningBurstReset(
ability,
Boolean(currentCombat.mobs[targetId] && !currentCombat.mobs[targetId].dead
&& currentCombat.mobs[targetId].health > 0),
currentCombat.auras.some((aura) => aura.targetId === member.id
&& aura.definition.utilityTags?.includes(ROM_FIRE_LIGHTNING_BURST_RESET_GUARD_TAG)),
);
if (reset.reset) {
useCombatStore.getState().applyActorAura(member.id, member.id, ability, {
kind: "apply-aura",
recipient: "caster",
sourceEffectType: -1,
sourceAuraType: -1,
miscValue: 0,
triggerSpellId: 621514,
aura: {
id: "rom-fire-lightning-burst-reset-guard",
name: "Fire Lightning Burst reset guard",
disposition: "buff",
durationMs: reset.guardDurationMs,
utilityTags: [ROM_FIRE_LIGHTNING_BURST_RESET_GUARD_TAG],
},
}, now);
runtimeMember = { ...runtimeMember, cooldowns: { ...runtimeMember.cooldowns, [ability.id]: 0 } };
}
}
emitPartyAbility(member, ability, targetId, "release", now, !castStartAlreadyEmitted);
emitPartyAbility(member, ability, targetId, "impact", now, !castStartAlreadyEmitted);
if (effectiveAmount > 0 && ability.effects.some((effect) => ["heal", "hot", "shield", "resurrection"].includes(effect.kind))) {