forked from phenom/healer-man
Update Healer Man server
This commit is contained in:
1 parent
39458d5de6
commit
6cc1b9217f
203 files changed
+133929
-31271
No files matched your search
@@ -0,0 +1,119 @@
|
||||
export const WOW335_ROGUE_KILLING_SPREE_DURATION_MS = 2_000;
|
||||
export const WOW335_ROGUE_KILLING_SPREE_INTERVAL_MS = 500;
|
||||
export const WOW335_ROGUE_KILLING_SPREE_ASSAULTS = 5;
|
||||
|
||||
export interface Wow335KillingSpreeWeaponSnapshot {
|
||||
readonly hand: "main-hand" | "off-hand";
|
||||
readonly weaponType?: string;
|
||||
readonly damageMin: number;
|
||||
readonly damageMax: number;
|
||||
readonly speedMs: number;
|
||||
}
|
||||
|
||||
export interface Wow335KillingSpreeHit {
|
||||
readonly hand: "main-hand" | "off-hand";
|
||||
readonly damage: number;
|
||||
readonly speedMs: number;
|
||||
readonly dbcSpellId: 57841 | 57842;
|
||||
}
|
||||
|
||||
export interface Wow335KillingSpreeWindow {
|
||||
readonly ownerActorId: string;
|
||||
readonly abilityId: string;
|
||||
readonly role: import("./partyRoles").PartyRole;
|
||||
readonly startedAt: number;
|
||||
readonly endsAt: number;
|
||||
readonly nextAssaultAt: number;
|
||||
readonly completedAssaults: number;
|
||||
readonly targetIds: readonly string[];
|
||||
readonly hits: readonly Wow335KillingSpreeHit[];
|
||||
}
|
||||
|
||||
export interface Wow335KillingSpreeAssault {
|
||||
readonly at: number;
|
||||
readonly index: number;
|
||||
readonly targetIds: readonly string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* The source's 51690 dummy aura has a 500-ms period, a 2-second duration,
|
||||
* and EXTRA_INITIAL_PERIOD, yielding an immediate tick plus four 500-ms ticks.
|
||||
*/
|
||||
export function createWow335KillingSpreeWindow(input: {
|
||||
readonly ownerActorId: string;
|
||||
readonly abilityId: string;
|
||||
readonly role: import("./partyRoles").PartyRole;
|
||||
readonly now: number;
|
||||
readonly targetIds: readonly string[];
|
||||
readonly hands: readonly Wow335KillingSpreeWeaponSnapshot[];
|
||||
readonly attackPower: number;
|
||||
readonly fallbackDamage: number;
|
||||
}): Wow335KillingSpreeWindow {
|
||||
const hands = input.hands.length > 0 ? input.hands : [{
|
||||
hand: "main-hand" as const,
|
||||
damageMin: 0,
|
||||
damageMax: 0,
|
||||
speedMs: 2_000,
|
||||
}];
|
||||
const hits = hands.map((weapon): Wow335KillingSpreeHit => {
|
||||
const hasWeaponDamage = weapon.damageMin > 0 || weapon.damageMax > 0;
|
||||
const coefficient = weapon.weaponType === "dagger" ? 1.95 : 1.3;
|
||||
const damage = hasWeaponDamage
|
||||
? Math.max(1, Math.round(((weapon.damageMin + weapon.damageMax) / 2
|
||||
+ input.attackPower / 14 * weapon.speedMs / 1_000) * coefficient))
|
||||
: Math.max(1, Math.round(input.fallbackDamage));
|
||||
return {
|
||||
hand: weapon.hand,
|
||||
damage,
|
||||
speedMs: weapon.speedMs,
|
||||
dbcSpellId: weapon.hand === "off-hand" ? 57842 : 57841,
|
||||
};
|
||||
});
|
||||
const uniqueTargetIds = [...new Set(input.targetIds)];
|
||||
return {
|
||||
ownerActorId: input.ownerActorId,
|
||||
abilityId: input.abilityId,
|
||||
role: input.role,
|
||||
startedAt: input.now,
|
||||
endsAt: input.now + WOW335_ROGUE_KILLING_SPREE_DURATION_MS,
|
||||
nextAssaultAt: input.now,
|
||||
completedAssaults: 0,
|
||||
targetIds: uniqueTargetIds,
|
||||
hits,
|
||||
};
|
||||
}
|
||||
|
||||
/** Advance one scheduled assault and retain its cast-time target list. */
|
||||
export function advanceWow335KillingSpreeAssault(
|
||||
window: Wow335KillingSpreeWindow,
|
||||
targetIds: readonly string[],
|
||||
): { readonly assault: Wow335KillingSpreeAssault; readonly window: Wow335KillingSpreeWindow | null } | null {
|
||||
if (window.completedAssaults >= WOW335_ROGUE_KILLING_SPREE_ASSAULTS) return null;
|
||||
const assault: Wow335KillingSpreeAssault = {
|
||||
at: window.nextAssaultAt,
|
||||
index: window.completedAssaults,
|
||||
targetIds,
|
||||
};
|
||||
const completedAssaults = window.completedAssaults + 1;
|
||||
return {
|
||||
assault,
|
||||
window: completedAssaults >= WOW335_ROGUE_KILLING_SPREE_ASSAULTS
|
||||
? null
|
||||
: {
|
||||
...window,
|
||||
targetIds,
|
||||
completedAssaults,
|
||||
nextAssaultAt: window.nextAssaultAt + WOW335_ROGUE_KILLING_SPREE_INTERVAL_MS,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** Source retains successful targets, so selection is with replacement. */
|
||||
export function selectWow335KillingSpreeTarget(
|
||||
targetIds: readonly string[],
|
||||
roll: number,
|
||||
): string | null {
|
||||
if (targetIds.length === 0) return null;
|
||||
const normalizedRoll = Number.isFinite(roll) ? Math.max(0, Math.min(0.999_999_999, roll)) : 0;
|
||||
return targetIds[Math.floor(normalizedRoll * targetIds.length)] ?? null;
|
||||
}
|
||||
Reference in new issue
Block a user