Update Healer Man server
This commit is contained in:
1 parent
6cc1b9217f
commit
6114a2295f
67 files changed
+6241
-347
No files matched your search
@@ -0,0 +1,187 @@
|
||||
import type { AbilityDefinition, ResourceType } from "./abilityCatalog";
|
||||
import type { ActiveAura } from "./combatAuras";
|
||||
|
||||
export const ROM_SCOUT_BLOOD_ARROW_ABILITY_ID = "rom-scout-general-4";
|
||||
export const ROM_SCOUT_BLOOD_ARROW_SOURCE_SKILL_ID = 490434;
|
||||
export const ROM_SCOUT_BLOOD_ARROW_AURA_TAG = "rom-self-health-drain";
|
||||
export const ROM_SCOUT_BLOOD_ARROW_DEACTIVATION_COOLDOWN_MS = 10_000;
|
||||
|
||||
export interface RomBloodArrowOwnerBuild {
|
||||
readonly classId: string;
|
||||
readonly secondaryClassId?: string | null;
|
||||
}
|
||||
|
||||
export function isRomScoutBloodArrowAbility(ability: AbilityDefinition): boolean {
|
||||
return ability.source === "runewaker"
|
||||
&& ability.id === ROM_SCOUT_BLOOD_ARROW_ABILITY_ID
|
||||
&& ability.classId === "rom-scout"
|
||||
&& ability.secondaryClassId === undefined
|
||||
&& ability.dbcSpellId === ROM_SCOUT_BLOOD_ARROW_SOURCE_SKILL_ID;
|
||||
}
|
||||
|
||||
export function isRomKnightScoutBloodArrowOwner(owner: RomBloodArrowOwnerBuild): boolean {
|
||||
return owner.classId === "rom-knight" && owner.secondaryClassId === "rom-scout";
|
||||
}
|
||||
|
||||
export function isRomScoutRogueBloodArrowOwner(owner: RomBloodArrowOwnerBuild): boolean {
|
||||
return owner.classId === "rom-scout" && owner.secondaryClassId === "rom-rogue";
|
||||
}
|
||||
|
||||
export function isRomBloodArrowOwner(owner: RomBloodArrowOwnerBuild): boolean {
|
||||
return isRomKnightScoutBloodArrowOwner(owner) || isRomScoutRogueBloodArrowOwner(owner);
|
||||
}
|
||||
|
||||
function bloodArrowDescriptionForOwner(owner: RomBloodArrowOwnerBuild): string {
|
||||
if (isRomKnightScoutBloodArrowOwner(owner)) {
|
||||
return "Activates Blood Arrow and increases ranged weapon damage. Each offensive ranged weapon skill costs 2.0% HP and 1.0% MP. Right-click the buff icon or use the skill again to deactivate; the skill enters a 10-second cooldown after deactivation.";
|
||||
}
|
||||
if (isRomScoutRogueBloodArrowOwner(owner)) {
|
||||
return "Activates Blood Arrow and increases physical ranged weapon damage. Ranged attacks cost 2.0% HP each. Right-click the buff icon or use the skill again to deactivate; the skill enters a 10-second cooldown after deactivation.";
|
||||
}
|
||||
return "Activates Blood Arrow and increases physical ranged weapon damage. Right-click the buff icon or use the skill again to deactivate; the skill enters a 10-second cooldown after deactivation.";
|
||||
}
|
||||
|
||||
function indefiniteBloodArrowEffects(effects: AbilityDefinition["effects"]): AbilityDefinition["effects"] {
|
||||
const auraEffect = effects.find((effect) => effect.kind === "apply-aura" && effect.recipient === "caster");
|
||||
if (auraEffect?.kind !== "apply-aura") return effects;
|
||||
return [{
|
||||
...auraEffect,
|
||||
aura: {
|
||||
...auraEffect.aura,
|
||||
durationMs: null,
|
||||
utilityTags: auraEffect.aura.utilityTags?.includes(ROM_SCOUT_BLOOD_ARROW_AURA_TAG)
|
||||
? auraEffect.aura.utilityTags
|
||||
: [...(auraEffect.aura.utilityTags ?? []), ROM_SCOUT_BLOOD_ARROW_AURA_TAG],
|
||||
},
|
||||
}];
|
||||
}
|
||||
|
||||
export function romBloodArrowAbilityForOwner(
|
||||
ability: AbilityDefinition,
|
||||
owner: RomBloodArrowOwnerBuild,
|
||||
): AbilityDefinition {
|
||||
if (!isRomScoutBloodArrowAbility(ability) || !isRomBloodArrowOwner(owner)) return ability;
|
||||
const description = bloodArrowDescriptionForOwner(owner);
|
||||
return {
|
||||
...ability,
|
||||
description,
|
||||
cooldownMs: 0,
|
||||
effects: indefiniteBloodArrowEffects(ability.effects),
|
||||
ranks: ability.ranks?.map((rank) => ({
|
||||
...rank,
|
||||
description,
|
||||
cooldownMs: 0,
|
||||
effects: indefiniteBloodArrowEffects(rank.effects),
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
export function isRomKnightScoutOffensiveRangedWeaponSkill(
|
||||
ability: AbilityDefinition,
|
||||
owner: RomBloodArrowOwnerBuild,
|
||||
): boolean {
|
||||
if (!isRomKnightScoutBloodArrowOwner(owner)
|
||||
|| ability.source !== "runewaker"
|
||||
|| ability.passive
|
||||
|| ability.dbcSpellId === ROM_SCOUT_BLOOD_ARROW_SOURCE_SKILL_ID
|
||||
|| ability.dbcSpellId === 492589 // Autoshot is an ongoing mode, not a cast trigger.
|
||||
|| ability.sourceAttackKind === "melee"
|
||||
|| !ability.effects.some((effect) => effect.kind === "damage" || effect.kind === "dot")) return false;
|
||||
|
||||
const scoutSkill = ability.classId === "rom-scout"
|
||||
&& ability.secondaryClassId === undefined
|
||||
&& ability.romSkillGroup === "general";
|
||||
const knightScoutElite = ability.classId === "rom-knight" && ability.secondaryClassId === "rom-scout";
|
||||
return (scoutSkill || knightScoutElite)
|
||||
&& (/ranged weapon DPS/i.test(ability.description) || ability.dbcSpellId === 490420);
|
||||
}
|
||||
|
||||
export function isRomScoutRogueRangedAttackSkill(
|
||||
ability: AbilityDefinition,
|
||||
owner: RomBloodArrowOwnerBuild,
|
||||
): boolean {
|
||||
if (!isRomScoutRogueBloodArrowOwner(owner)
|
||||
|| ability.source !== "runewaker"
|
||||
|| ability.passive
|
||||
|| ability.dbcSpellId === ROM_SCOUT_BLOOD_ARROW_SOURCE_SKILL_ID
|
||||
|| ability.dbcSpellId === 492589 // Autoshot is an ongoing mode, not a cast trigger.
|
||||
|| ability.sourceAttackKind === "melee"
|
||||
|| !ability.effects.some((effect) => effect.kind === "damage" || effect.kind === "dot")) return false;
|
||||
|
||||
const scoutGeneralSkill = ability.classId === "rom-scout"
|
||||
&& ability.secondaryClassId === undefined
|
||||
&& (ability.romSkillGroup === "general" || ability.romSkillGroup === "primary");
|
||||
return scoutGeneralSkill
|
||||
&& (/ranged weapon DPS/i.test(ability.description) || ability.dbcSpellId === 490420);
|
||||
}
|
||||
|
||||
export function romBloodArrowCastCosts(
|
||||
ability: AbilityDefinition,
|
||||
owner: RomBloodArrowOwnerBuild,
|
||||
auras: readonly ActiveAura[],
|
||||
ownerId: string,
|
||||
maxHealth: number,
|
||||
maxMana: number,
|
||||
now?: number,
|
||||
): readonly { readonly resource: ResourceType; readonly amount: number }[] {
|
||||
if (!isRomBloodArrowOwner(owner)
|
||||
|| !auras.some((aura) => aura.sourceId === ownerId
|
||||
&& aura.targetId === ownerId
|
||||
&& (now === undefined || aura.expiresAt === null || aura.expiresAt > now)
|
||||
&& aura.definition.utilityTags?.includes(ROM_SCOUT_BLOOD_ARROW_AURA_TAG))) return [];
|
||||
|
||||
if (isRomKnightScoutBloodArrowOwner(owner)
|
||||
&& isRomKnightScoutOffensiveRangedWeaponSkill(ability, owner)) {
|
||||
return [
|
||||
{ resource: "health", amount: Math.max(0, Math.round(maxHealth * 0.02)) },
|
||||
{ resource: "mana", amount: Math.max(0, Math.round(maxMana * 0.01)) },
|
||||
];
|
||||
}
|
||||
|
||||
if (isRomScoutRogueBloodArrowOwner(owner)
|
||||
&& isRomScoutRogueRangedAttackSkill(ability, owner)) {
|
||||
return [{ resource: "health", amount: Math.max(0, Math.round(maxHealth * 0.02)) }];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
export function romScoutRogueBloodArrowRangedAutoAttackCost(
|
||||
owner: RomBloodArrowOwnerBuild,
|
||||
auras: readonly ActiveAura[],
|
||||
ownerId: string,
|
||||
maxHealth: number,
|
||||
now: number,
|
||||
): number {
|
||||
return isRomScoutRogueBloodArrowOwner(owner)
|
||||
&& hasOwnedRomScoutBloodArrow(auras, ownerId, now)
|
||||
? Math.max(0, Math.round(maxHealth * 0.02))
|
||||
: 0;
|
||||
}
|
||||
|
||||
export function hasOwnedRomScoutBloodArrow(
|
||||
auras: readonly ActiveAura[],
|
||||
ownerId: string,
|
||||
now: number,
|
||||
): boolean {
|
||||
return auras.some((aura) => aura.sourceId === ownerId
|
||||
&& aura.targetId === ownerId
|
||||
&& (aura.expiresAt === null || aura.expiresAt > now)
|
||||
&& aura.definition.utilityTags?.includes(ROM_SCOUT_BLOOD_ARROW_AURA_TAG));
|
||||
}
|
||||
|
||||
export function isOwnedRomScoutBloodArrowAura(aura: ActiveAura, ownerId: string): boolean {
|
||||
return aura.sourceId === ownerId
|
||||
&& aura.targetId === ownerId
|
||||
&& aura.definition.utilityTags?.includes(ROM_SCOUT_BLOOD_ARROW_AURA_TAG) === true;
|
||||
}
|
||||
|
||||
export function deactivateRomBloodArrowFromAuraContextMenu(
|
||||
aura: ActiveAura,
|
||||
ownerId: string,
|
||||
deactivate: (ownerId: string, now?: number) => boolean,
|
||||
now?: number,
|
||||
): boolean {
|
||||
return isOwnedRomScoutBloodArrowAura(aura, ownerId)
|
||||
&& deactivate(ownerId, now);
|
||||
}
|
||||
Reference in new issue
Block a user