forked from phenom/healer-man
Update Healer Man server
This commit is contained in:
1 parent
4c768fbec6
commit
b16821e92e
330 files changed
+35406
-1760
No files matched your search
@@ -140,13 +140,19 @@ export interface AbilityAmountScaling {
|
||||
readonly bonusPowerCoefficient?: number;
|
||||
readonly attackPowerCoefficient?: number;
|
||||
readonly rangedAttackPowerCoefficient?: number;
|
||||
/** Add a fraction of the source character's Intelligence to the resolved amount. */
|
||||
readonly intellectCoefficient?: number;
|
||||
readonly spiritCoefficient?: number;
|
||||
/** Add a fraction of the source character's Stamina to the resolved amount. */
|
||||
readonly staminaCoefficient?: number;
|
||||
/** Add main-hand weapon DPS multiplied by this value to the resolved amount. */
|
||||
readonly weaponDpsCoefficient?: number;
|
||||
readonly sourceLevel?: number;
|
||||
readonly maxScalingLevel?: number;
|
||||
}
|
||||
|
||||
export interface AbilityHealingRecipients {
|
||||
readonly recipient?: "caster" | "ability-target";
|
||||
readonly recipient?: "caster" | "ability-target" | "pet";
|
||||
readonly scope?: "party";
|
||||
readonly center?: "caster" | "ability-target";
|
||||
readonly radius?: number;
|
||||
@@ -170,7 +176,7 @@ export type AbilityEffect =
|
||||
/** Optional stack-based payload used by poison-consuming finishers. */
|
||||
readonly poison?: import("./roguePoison").RoguePoisonFinisherScaling;
|
||||
}
|
||||
| ({ readonly kind: "heal"; readonly coefficient: number; readonly percentMaxHealth?: number; readonly percentOfDamage?: number } & AbilityAmountScaling & AbilityHealingRecipients)
|
||||
| ({ readonly kind: "heal"; readonly coefficient: number; readonly percentMaxHealth?: number; readonly percentOfDamage?: number; readonly requiresLandedHit?: boolean } & AbilityAmountScaling & AbilityHealingRecipients)
|
||||
| ({ readonly kind: "shield"; readonly coefficient: number; readonly durationMs: number } & AbilityAmountScaling & AbilityHealingRecipients)
|
||||
| ({ readonly kind: "dot"; readonly coefficient: number; readonly school?: DamageSchool; readonly ticks: number; readonly intervalMs: number; readonly startsImmediately?: boolean; readonly tag?: string } & AbilityAmountScaling & AbilityDamageResource)
|
||||
| ({ readonly kind: "hot"; readonly coefficient: number; readonly ticks: number; readonly intervalMs: number; readonly percentMaxHealth?: number } & AbilityAmountScaling & AbilityHealingRecipients)
|
||||
@@ -185,7 +191,14 @@ export type AbilityEffect =
|
||||
/** Source-defined party absorb area carried by a stationary Death Knight zone. */
|
||||
readonly antiMagicZone?: { readonly radius: number; readonly capacityBase: number; readonly capacityPerAttackPower: number; readonly absorbFraction: number; readonly intervalMs: number };
|
||||
}
|
||||
| { readonly kind: "resource"; readonly amount: number; readonly resource?: ResourceType; readonly percentage?: boolean }
|
||||
| {
|
||||
readonly kind: "resource";
|
||||
readonly amount: number;
|
||||
readonly resource?: ResourceType;
|
||||
readonly percentage?: boolean;
|
||||
/** Party-scoped resource effects use the ability's radius and targeting shape. */
|
||||
readonly scope?: "target" | "party";
|
||||
}
|
||||
| { readonly kind: "combo"; readonly amount: number }
|
||||
| { readonly kind: "taunt"; readonly durationMs: number; readonly maxTargets?: number }
|
||||
| { readonly kind: "status"; readonly status: MobStatusKind; readonly durationMs: number; readonly magnitude?: number; readonly maxTargets?: number; readonly breakOnDamage?: boolean }
|
||||
@@ -196,6 +209,8 @@ export type AbilityEffect =
|
||||
readonly recipient?: "ability-target" | "caster" | "pet";
|
||||
/** Party/raid area auras are applied to the player and every active party member. */
|
||||
readonly scope?: "target" | "party";
|
||||
/** Optional range for a party aura sourced by a nearby-target proc. */
|
||||
readonly radius?: number;
|
||||
/** Some party effects benefit allies but exclude the caster. */
|
||||
readonly excludeCaster?: boolean;
|
||||
readonly control?: AbilityAuraControl;
|
||||
@@ -203,6 +218,10 @@ export type AbilityEffect =
|
||||
readonly sourceAuraType: number;
|
||||
readonly miscValue: number;
|
||||
readonly triggerSpellId: number;
|
||||
/** Resolve this rider only if the cast landed at least one direct hit. */
|
||||
readonly requiresLandedHit?: boolean;
|
||||
/** Resolve this rider only if the cast landed at least one direct critical hit. */
|
||||
readonly requiresCriticalHit?: boolean;
|
||||
}
|
||||
| {
|
||||
readonly kind: "dispel";
|
||||
@@ -227,6 +246,8 @@ export type AbilityEffect =
|
||||
readonly kind: "movement";
|
||||
readonly movement: "teleport" | "leap" | "charge" | "knockback" | "sanctuary";
|
||||
readonly toward: "target" | "destination" | "away";
|
||||
/** Source row movement distance in yards when the spell supplies one. */
|
||||
readonly distance?: number;
|
||||
}
|
||||
| { readonly kind: "dispel-mechanic"; readonly mechanic: number; readonly maxCount: number }
|
||||
| { readonly kind: "pet"; readonly action: "summon" | "call" | "recall" | "dismiss" | "resurrect" | "feed" | "tame"; readonly creatureId?: number }
|
||||
@@ -340,6 +361,15 @@ export interface AbilityDefinition {
|
||||
readonly talentNodeId?: string;
|
||||
/** Legacy CoA source identifier; `abilityTalentNodeId` normalizes it. */
|
||||
readonly talentEntryId?: number;
|
||||
/** A pair-only upgrade applied after its source passive unlock level. */
|
||||
readonly buildUpgrade?: AbilityBuildUpgrade;
|
||||
}
|
||||
|
||||
export interface AbilityBuildUpgrade {
|
||||
readonly unlockLevel: number;
|
||||
readonly values: Partial<Pick<AbilityDefinition,
|
||||
"description" | "target" | "castMode" | "castTimeMs" | "cooldownMs" | "cost" | "costs" | "effects"
|
||||
>>;
|
||||
}
|
||||
|
||||
export interface ClassResourceProfile {
|
||||
@@ -1063,7 +1093,37 @@ export function abilitiesForCharacter(
|
||||
ability.romSkillGroup === "general" || (ability.romSkillGroup === "passive" && ability.id.includes("-general-"))
|
||||
));
|
||||
const elites = romEliteAbilities.filter((ability) => ability.classId === classId && ability.secondaryClassId === secondaryClassId);
|
||||
return [...primary, ...secondaryGeneral, ...elites];
|
||||
const characterAbilities = [...primary, ...secondaryGeneral, ...elites];
|
||||
if (classId !== "rom-warlock" || secondaryClassId !== "rom-priest") return characterAbilities;
|
||||
return characterAbilities.map((ability) => {
|
||||
if (ability.classId === "rom-priest" && ability.dbcSpellId === 490256) {
|
||||
return {
|
||||
...ability,
|
||||
buildUpgrade: {
|
||||
unlockLevel: 30,
|
||||
values: {
|
||||
castMode: "instant",
|
||||
castTimeMs: 0,
|
||||
cooldownMs: 5_000,
|
||||
description: "Instant cast with a 5-second cooldown. Restores 1 Psi. A critical hit activates Healing Fortune. The simulator cannot redirect an ally-targeted cast to that ally's hostile target.",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
if (ability.classId === "rom-warlock" && ability.dbcSpellId === 497958) {
|
||||
return {
|
||||
...ability,
|
||||
buildUpgrade: {
|
||||
unlockLevel: 15,
|
||||
values: {
|
||||
target: "any",
|
||||
description: "Can target a hostile enemy to deal damage or a friendly ally to heal them when Healing Fortune is learned. Ally-target redirection is not modeled.",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
return ability;
|
||||
});
|
||||
}
|
||||
|
||||
/** Return the RuneWaker Nature Power cap granted by the learned Brilliance passive. */
|
||||
@@ -1140,6 +1200,12 @@ export function learnedAbilityForBuild(
|
||||
return abilityAtLevel(ability, playerLevel, ability.talentEntryId === undefined ? undefined : learnedRank);
|
||||
}
|
||||
|
||||
function applyBuildUpgradeAtLevel(ability: AbilityDefinition, playerLevel: number): AbilityDefinition {
|
||||
return ability.buildUpgrade && playerLevel >= ability.buildUpgrade.unlockLevel
|
||||
? { ...ability, ...ability.buildUpgrade.values }
|
||||
: ability;
|
||||
}
|
||||
|
||||
export function abilityAtLevel(
|
||||
ability: AbilityDefinition,
|
||||
playerLevel: number,
|
||||
@@ -1148,8 +1214,8 @@ export function abilityAtLevel(
|
||||
const rank = abilityRankForLevel(ability, playerLevel, learnedTalentRank);
|
||||
const effects = rank?.effects ?? ability.effects;
|
||||
const target = effects.length > 0 && effects.every((effect) => effect.kind === "dispel" && effect.relationship === "target" && effect.mode === "cleanse") ? "any" : ability.target;
|
||||
if (!rank) return target === ability.target ? ability : { ...ability, target };
|
||||
return {
|
||||
if (!rank) return applyBuildUpgradeAtLevel(target === ability.target ? ability : { ...ability, target }, playerLevel);
|
||||
return applyBuildUpgradeAtLevel({
|
||||
...ability,
|
||||
target,
|
||||
dbcSpellId: rank.spellId,
|
||||
@@ -1167,7 +1233,7 @@ export function abilityAtLevel(
|
||||
targeting: rank.targeting ?? ability.targeting,
|
||||
castRules: rank.castRules ?? ability.castRules,
|
||||
runeCost: rank.runeCost ?? ability.runeCost,
|
||||
};
|
||||
}, playerLevel);
|
||||
}
|
||||
|
||||
export function isAbilityUnlocked(ability: AbilityDefinition, playerLevel: number): boolean {
|
||||
|
||||
Reference in new issue
Block a user