forked from phenom/healer-man
Update Healer Man server
This commit is contained in:
1 parent
9d7e0e2f9e
commit
35dfdaed61
94 files changed
+17034
-418
No files matched your search
+45
-12
@@ -149,7 +149,9 @@ export interface AbilityHealingRecipients {
|
||||
readonly center?: "caster" | "ability-target";
|
||||
readonly radius?: number;
|
||||
readonly maximumTargets?: number;
|
||||
readonly selection?: "random";
|
||||
readonly falloffPerJump?: number;
|
||||
readonly selection?: "random" | "lowest-max-health";
|
||||
readonly excludeCaster?: boolean;
|
||||
}
|
||||
|
||||
export interface AbilityDamageResource {
|
||||
@@ -166,12 +168,21 @@ 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 } & AbilityAmountScaling & AbilityHealingRecipients)
|
||||
| ({ readonly kind: "heal"; readonly coefficient: number; readonly percentMaxHealth?: number; readonly percentOfDamage?: number } & 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 } & AbilityAmountScaling & AbilityHealingRecipients)
|
||||
| { readonly kind: "resurrection"; readonly percentMaxHealth: number }
|
||||
| { readonly kind: "summon"; readonly creatureId: number; readonly coefficient: number; readonly durationMs: number }
|
||||
| ({ readonly kind: "hot"; readonly coefficient: number; readonly ticks: number; readonly intervalMs: number; readonly percentMaxHealth?: number } & AbilityAmountScaling & AbilityHealingRecipients)
|
||||
| { readonly kind: "resurrection"; readonly percentMaxHealth: number; readonly flatHealth?: number }
|
||||
| {
|
||||
readonly kind: "summon";
|
||||
readonly creatureId: number;
|
||||
readonly coefficient: number;
|
||||
readonly durationMs: number;
|
||||
/** Source-defined pulse for stationary healing totems. */
|
||||
readonly healingPulse?: { readonly amount: number; readonly intervalMs: number; readonly radius: number };
|
||||
/** 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: "combo"; readonly amount: number }
|
||||
| { readonly kind: "taunt"; readonly durationMs: number; readonly maxTargets?: number }
|
||||
@@ -180,7 +191,7 @@ export type AbilityEffect =
|
||||
readonly kind: "apply-aura";
|
||||
readonly aura: AuraDefinition;
|
||||
/** Some hostile spells apply their beneficial rider to the caster. */
|
||||
readonly recipient?: "ability-target" | "caster";
|
||||
readonly recipient?: "ability-target" | "caster" | "pet";
|
||||
/** Party/raid area auras are applied to the player and every active party member. */
|
||||
readonly scope?: "target" | "party";
|
||||
/** Some party effects benefit allies but exclude the caster. */
|
||||
@@ -218,11 +229,18 @@ export type AbilityEffect =
|
||||
| { 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 }
|
||||
| { readonly kind: "totem"; readonly action: "destroy-all" }
|
||||
| { readonly kind: "rune"; readonly action: "activate"; readonly count: number }
|
||||
| {
|
||||
readonly kind: "rune";
|
||||
readonly action: "activate";
|
||||
readonly count: number;
|
||||
readonly runeType?: "blood" | "frost" | "unholy";
|
||||
readonly convertToDeathMs?: number;
|
||||
}
|
||||
| {
|
||||
readonly kind: "cooldown-reset";
|
||||
readonly mode: "reset" | "reduce";
|
||||
readonly abilityName?: string;
|
||||
readonly excludeAbilityNames?: readonly string[];
|
||||
readonly amountMs?: number;
|
||||
/** Fraction of the target ability's remaining cooldown removed at execution time. */
|
||||
readonly amountPercent?: number;
|
||||
@@ -907,7 +925,7 @@ const abilityCatalog: Record<string, AbilityDefinition> = {};
|
||||
let romEliteAbilities: readonly AbilityDefinition[] = [];
|
||||
let romTriggeredAbilityResolver: ((spellId: number) => AbilityDefinition | null) | null = null;
|
||||
const coaTriggeredAbilities = new Map<number, AbilityDefinition>();
|
||||
const classicChannelTriggeredAbilities = new Map<number, AbilityDefinition>();
|
||||
const classicTriggeredAbilities = new Map<number, AbilityDefinition>();
|
||||
let classicLoad: Promise<void> | null = null;
|
||||
let romLoad: Promise<void> | null = null;
|
||||
const coaLoads = new Map<CoaClassId, Promise<void>>();
|
||||
@@ -950,7 +968,7 @@ async function preloadClassicAbilityCatalog(): Promise<void> {
|
||||
if (classicLoad) return classicLoad;
|
||||
classicLoad = import("./wow335AbilityCatalog").then(({
|
||||
WOW335_ABILITIES_BY_CLASS,
|
||||
WOW335_CHANNEL_TRIGGERED_ABILITIES_BY_SPELL_ID,
|
||||
WOW335_TRIGGERED_ABILITIES_BY_SPELL_ID,
|
||||
}) => {
|
||||
for (const classId of BASE_CLASS_IDS) {
|
||||
registerClassAbilities(
|
||||
@@ -958,8 +976,8 @@ async function preloadClassicAbilityCatalog(): Promise<void> {
|
||||
mergeWow335ClassicAbilities(CLASSIC_CORE_ABILITIES[classId], WOW335_ABILITIES_BY_CLASS[classId]),
|
||||
);
|
||||
}
|
||||
for (const [spellId, ability] of Object.entries(WOW335_CHANNEL_TRIGGERED_ABILITIES_BY_SPELL_ID)) {
|
||||
classicChannelTriggeredAbilities.set(Number(spellId), ability);
|
||||
for (const [spellId, ability] of Object.entries(WOW335_TRIGGERED_ABILITIES_BY_SPELL_ID)) {
|
||||
classicTriggeredAbilities.set(Number(spellId), ability);
|
||||
}
|
||||
}).catch((error: unknown) => {
|
||||
classicLoad = null;
|
||||
@@ -1026,7 +1044,7 @@ export function triggeredAbilityBySpellId(
|
||||
includeCoa = true,
|
||||
): AbilityDefinition | null {
|
||||
return romTriggeredAbilityResolver?.(spellId)
|
||||
?? classicChannelTriggeredAbilities.get(spellId)
|
||||
?? classicTriggeredAbilities.get(spellId)
|
||||
?? (includeCoa ? coaTriggeredAbilities.get(spellId) : undefined)
|
||||
?? null;
|
||||
}
|
||||
@@ -1048,6 +1066,21 @@ export function abilitiesForCharacter(
|
||||
return [...primary, ...secondaryGeneral, ...elites];
|
||||
}
|
||||
|
||||
/** Return the RuneWaker Nature Power cap granted by the learned Brilliance passive. */
|
||||
export function naturePowerMaximumForCharacter(
|
||||
classId: ClassId,
|
||||
secondaryClassId: ClassId | null | undefined,
|
||||
level: number,
|
||||
): number {
|
||||
const hasBrillianceOfNature = abilitiesForCharacter(classId, secondaryClassId).some((ability) => (
|
||||
ability.source === "runewaker"
|
||||
&& ability.dbcSpellId === 494931
|
||||
&& ability.passive
|
||||
&& level >= ability.unlockLevel
|
||||
));
|
||||
return hasBrillianceOfNature ? 15 : 10;
|
||||
}
|
||||
|
||||
export function abilityRankForLevel(
|
||||
ability: AbilityDefinition,
|
||||
playerLevel: number,
|
||||
|
||||
Reference in new issue
Block a user