Update Healer Man server
This commit is contained in:
1 parent
ab1434a3b8
commit
e284f4fc76
60 files changed
+2704
-118
No files matched your search
+32
-15
@@ -19,6 +19,8 @@ import {
|
||||
} from "./abilityRules";
|
||||
import type { MobCombatState } from "./combatStore";
|
||||
import { useCombatStore } from "./combatStore";
|
||||
import { raceAffixHasteMultiplier } from "./dungeonRaceAffixBuffs";
|
||||
import { activeRaceOrbId } from "./dungeonRaceAffixRuntime";
|
||||
import { companionResourceMaximum, memberFromCompanionActor } from "./combatActorAuthority";
|
||||
import type { MobVector3 } from "./mobPopulation";
|
||||
import { requireDungeonDefinition } from "./dungeonRegistry";
|
||||
@@ -48,6 +50,7 @@ import { useWailingEncounterStore } from "./wailingCavernsEncounter";
|
||||
import { resolvedEquipmentLoadout } from "./heirloomEquipment";
|
||||
import {
|
||||
emitCombatPresentation,
|
||||
penancePulseVisualSpellId,
|
||||
presentationDeliveryForAbility,
|
||||
presentationSchoolForAbility,
|
||||
type CombatPresentationDelivery,
|
||||
@@ -664,7 +667,7 @@ function memberSwingMs(member: PartyMember): number {
|
||||
|| member.specialization === "Feral (Cat)"
|
||||
? 1_550
|
||||
: 1_900;
|
||||
return hastedDuration(
|
||||
return Math.round(hastedDuration(
|
||||
base,
|
||||
ratingPercent(
|
||||
member.gearStats.hasteRating,
|
||||
@@ -675,7 +678,7 @@ function memberSwingMs(member: PartyMember): number {
|
||||
member.classId,
|
||||
),
|
||||
500,
|
||||
);
|
||||
) / raceAffixHasteMultiplier());
|
||||
}
|
||||
|
||||
function emitPartyAbility(
|
||||
@@ -686,25 +689,33 @@ function emitPartyAbility(
|
||||
now: number,
|
||||
instantCast = false,
|
||||
): void {
|
||||
const penancePulse = ability.id === "wow335-priest-penance"
|
||||
&& ability.effects.some((effect) => effect.kind === "heal" || effect.kind === "damage")
|
||||
&& (phase === "release" || phase === "impact");
|
||||
if (ability.id === "wow335-priest-penance" && phase === "impact" && !penancePulse) return;
|
||||
const origin = getPartyRuntimePosition(member.id) ?? useCombatStore.getState().playerPosition;
|
||||
const targetPosition = targetId === PLAYER_AGGRO_ID
|
||||
? useCombatStore.getState().playerPosition
|
||||
: getMobPosition(targetId) ?? getPartyRuntimePosition(targetId) ?? origin;
|
||||
emitCombatPresentation({
|
||||
occurredAt: now,
|
||||
phase,
|
||||
phase: penancePulse && phase === "release" ? "tick" : phase,
|
||||
actorGroup: "party",
|
||||
sourceActorId: member.id,
|
||||
targetActorId: targetId,
|
||||
abilityId: ability.id,
|
||||
sourceSpellId: ability.dbcSpellId,
|
||||
sourceSpellId: penancePulse
|
||||
? penancePulseVisualSpellId(Boolean(useCombatStore.getState().mobs[targetId]))
|
||||
: ability.dbcSpellId,
|
||||
name: ability.name,
|
||||
source: ability.source === "runewaker" ? "runewaker" : ability.source?.startsWith("coa") ? "ascension" : "wow335",
|
||||
school: presentationSchoolForAbility(ability),
|
||||
delivery: presentationDeliveryForAbility(ability),
|
||||
delivery: penancePulse ? "projectile" : presentationDeliveryForAbility(ability),
|
||||
origin,
|
||||
targetPosition,
|
||||
...(ability.radius === undefined ? {} : { radius: ability.radius }),
|
||||
...(ability.id === "wow335-priest-penance" && phase === "cast-start"
|
||||
? { durationMs: ability.castTimeMs } : {}),
|
||||
...(instantCast ? { instantCast: true } : {}),
|
||||
});
|
||||
}
|
||||
@@ -1686,6 +1697,7 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
|
||||
party.activeMobId,
|
||||
partyOrigin,
|
||||
);
|
||||
if (!targetId && party.command !== "stop") targetId = activeRaceOrbId();
|
||||
members = members.map((member) => {
|
||||
const profile = resourceProfileForClass(member.classId);
|
||||
const passiveRates: Partial<Record<ResourceType, number>> = {
|
||||
@@ -1867,7 +1879,7 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
|
||||
status: desiredStatus,
|
||||
nextActionAt: activeCast.mode === "channel"
|
||||
? Math.max(now + 250, execution.member.globalCooldownEndsAt)
|
||||
: now + Math.max(250, castingAbility.gcdMs),
|
||||
: now + Math.max(250, Math.round(castingAbility.gcdMs / raceAffixHasteMultiplier(now))),
|
||||
};
|
||||
} else {
|
||||
nextMembers[index] = {
|
||||
@@ -1900,6 +1912,7 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
|
||||
const instantOutOfCombatResurrection = !targetId
|
||||
&& supportIntent.ability.effects.some((effect) => effect.kind === "resurrection");
|
||||
if (supportIntent.ability.castTimeMs > 0 && !instantOutOfCombatResurrection) {
|
||||
const castTimeMs = Math.round(supportIntent.ability.castTimeMs / raceAffixHasteMultiplier(now));
|
||||
const castOrigin = getPartyRuntimePosition(member.id) ?? currentCombat.playerPosition;
|
||||
nextMembers[index] = {
|
||||
...committed,
|
||||
@@ -1909,14 +1922,14 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
|
||||
school: presentationSchoolForAbility(supportIntent.ability),
|
||||
mode: supportIntent.ability.castMode === "channel" ? "channel" : "cast",
|
||||
startedAt: now,
|
||||
completesAt: now + supportIntent.ability.castTimeMs,
|
||||
originalDurationMs: supportIntent.ability.castTimeMs,
|
||||
completesAt: now + castTimeMs,
|
||||
originalDurationMs: castTimeMs,
|
||||
pushbackHits: 0,
|
||||
origin: castOrigin,
|
||||
targetId: supportIntent.targetId,
|
||||
},
|
||||
activeCastTargetId: supportIntent.targetId,
|
||||
nextActionAt: now + supportIntent.ability.castTimeMs,
|
||||
nextActionAt: now + castTimeMs,
|
||||
};
|
||||
emitPartyAbility(member, supportIntent.ability, supportIntent.targetId, "cast-start", now);
|
||||
} else {
|
||||
@@ -1930,7 +1943,7 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
|
||||
nextMembers[index] = {
|
||||
...execution.member,
|
||||
status: "healing",
|
||||
nextActionAt: now + Math.max(250, supportIntent.ability.gcdMs),
|
||||
nextActionAt: now + Math.max(250, Math.round(supportIntent.ability.gcdMs / raceAffixHasteMultiplier(now))),
|
||||
};
|
||||
}
|
||||
continue;
|
||||
@@ -1942,6 +1955,7 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
|
||||
targetId,
|
||||
partyOrigin,
|
||||
);
|
||||
if (!targetId && party.command !== "stop") targetId = activeRaceOrbId();
|
||||
if (!targetId) {
|
||||
nextMembers[index] = member.status === "ready" && member.nextActionAt === 0
|
||||
? member
|
||||
@@ -1950,7 +1964,9 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
|
||||
}
|
||||
const desiredStatus = member.role === "tank" ? "guarding" : "attacking";
|
||||
const memberPosition = getPartyRuntimePosition(member.id) ?? currentCombat.playerPosition;
|
||||
const memberTargetId = member.role === "tank"
|
||||
const memberTargetId = member.role === "damage" && party.command !== "stop" && activeRaceOrbId()
|
||||
? activeRaceOrbId()
|
||||
: member.role === "tank"
|
||||
? tankPriorityTargetId(
|
||||
currentCombat.mobs,
|
||||
nextMembers,
|
||||
@@ -2115,6 +2131,7 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
|
||||
});
|
||||
}
|
||||
if (selectedAbility.castTimeMs > 0) {
|
||||
const castTimeMs = Math.round(selectedAbility.castTimeMs / raceAffixHasteMultiplier(now));
|
||||
nextMembers[index] = {
|
||||
...committed,
|
||||
status: desiredStatus,
|
||||
@@ -2123,14 +2140,14 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
|
||||
school: presentationSchoolForAbility(selectedAbility),
|
||||
mode: selectedAbility.castMode === "channel" ? "channel" : "cast",
|
||||
startedAt: now,
|
||||
completesAt: now + selectedAbility.castTimeMs,
|
||||
originalDurationMs: selectedAbility.castTimeMs,
|
||||
completesAt: now + castTimeMs,
|
||||
originalDurationMs: castTimeMs,
|
||||
pushbackHits: 0,
|
||||
origin: memberPosition,
|
||||
targetId: abilityTargetId,
|
||||
},
|
||||
activeCastTargetId: abilityTargetId,
|
||||
nextActionAt: now + selectedAbility.castTimeMs,
|
||||
nextActionAt: now + castTimeMs,
|
||||
};
|
||||
emitPartyAbility(member, selectedAbility, abilityTargetId, "cast-start", now);
|
||||
} else {
|
||||
@@ -2138,7 +2155,7 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
|
||||
nextMembers[index] = {
|
||||
...execution.member,
|
||||
status: desiredStatus,
|
||||
nextActionAt: now + Math.max(250, selectedAbility.gcdMs),
|
||||
nextActionAt: now + Math.max(250, Math.round(selectedAbility.gcdMs / raceAffixHasteMultiplier(now))),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user