Release Healer Man 0.1.24

This commit is contained in:
phenom committed 2026-09-09 16:43:37 -04:00
1 parent c4346751a9
commit bac0da9300
118 files changed
+857 -289

No files matched your search

+9
View File
@@ -57,6 +57,15 @@ describe("dual-screen party commands", () => {
expect(useCombatStore.getState().cooldowns["priest-psychic-scream"]).toBeGreaterThan(0);
});
it("publishes the active fixed spell-rank cost instead of the catalog's first rank", () => {
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 32 });
const pain = currentCompanionSnapshot().game.abilities
.find((ability) => ability.id === "priest-shadow-word-pain");
expect(pain).toMatchObject({ resourceCost: 133, resourceLabel: "Mana" });
});
it("executes all three party commands from the companion channel", () => {
for (const command of ["attack", "stop", "defend"] as const) {
executeCompanionCommand({ name: "setPartyCommand", command });
+23 -7
View File
@@ -1,7 +1,7 @@
import { classById, type GenderId, type RaceId } from "../app/characterCatalog";
import { useGameStore } from "../game/store";
import type { GameMode, GameOverlay } from "../game/store";
import { useCombatStore } from "../game/combatStore";
import { resolvedAbilityCosts, useCombatStore } from "../game/combatStore";
import { activePartyBossObjectives } from "../game/partyRuntime";
import { requireDungeonDefinition } from "../game/dungeonRegistry";
import {
@@ -20,7 +20,7 @@ import {
type ActionBindingControl,
type ActionBindingLayer,
} from "../game/actionBindings";
import type { AbilityTarget } from "../game/abilityCatalog";
import { abilityAtLevel, resourceProfileForClass, type AbilityTarget } from "../game/abilityCatalog";
import type { DungeonId } from "../game/dungeonCatalog";
import { useManastormStore } from "../game/manastormStore";
import { resolveStagePresentation } from "../game/manastormStagePresentation";
@@ -190,10 +190,24 @@ export function currentCompanionSnapshot(): CompanionSnapshot {
const selectedTarget = combat.selectedTargetId ? combat.mobs[combat.selectedTargetId] ?? null : null;
const globalCooldownRemaining = Math.max(0, combat.globalCooldownEndsAt - now);
const classColor = classById(combat.classId).color;
const activeResourceType = resourceProfileForClass(combat.classId).type;
const abilities = ACTION_CONTROLS.flatMap((control): CompanionAbilitySnapshot[] => {
const abilityId = combat.actionBindings[actionBindingId(game.actionLayer, control)];
const ability = abilityId ? combat.abilities.find((candidate) => candidate.id === abilityId) ?? null : null;
if (!ability) return [];
const catalogAbility = abilityId
? combat.abilities.find((candidate) => candidate.id === abilityId) ?? null
: null;
if (!catalogAbility) return [];
const learnedTalentRank = catalogAbility.talentEntryId === undefined
? undefined
: combat.talentRanks[`coa-entry-${catalogAbility.talentEntryId}`] ?? 0;
const ability = abilityAtLevel(catalogAbility, combat.level, learnedTalentRank);
const costs = resolvedAbilityCosts(ability, combat.talentModifiers, combat);
const displayCost = costs[0] ?? { resource: ability.cost.resource, amount: 0 };
const cannotPay = costs.some((cost) => cost.resource === "health"
? combat.health <= cost.amount
: (cost.resource === activeResourceType
? combat.resource
: combat.resourcePools[cost.resource] ?? 0) < cost.amount);
const personalCooldownRemaining = Math.max(0, (combat.cooldowns[ability.id] ?? 0) - now);
const remainingMs = Math.max(personalCooldownRemaining, globalCooldownRemaining);
const durationMs = personalCooldownRemaining >= globalCooldownRemaining
@@ -207,8 +221,10 @@ export function currentCompanionSnapshot(): CompanionSnapshot {
description: ability.description,
icon: ability.icon,
color: classColor,
resourceCost: ability.cost.amount,
resourceLabel: combat.resourceName,
resourceCost: displayCost.amount,
resourceLabel: displayCost.resource === activeResourceType
? combat.resourceName
: displayCost.resource.replace("-", " "),
cooldownRemaining: remainingMs / 1_000,
cooldownDuration: durationMs / 1_000,
lockedUntilLevel: combat.level < ability.unlockLevel ? ability.unlockLevel : undefined,
@@ -218,7 +234,7 @@ export function currentCompanionSnapshot(): CompanionSnapshot {
|| combat.health <= 0
|| combat.activeCast !== null
|| remainingMs > 0
|| ability.cost.amount > combat.resource,
|| cannotPay,
target: ability.target,
}];
});