Release Healer Man 0.1.53

This commit is contained in:
phenom committed 2026-09-18 12:32:51 -04:00
1 parent d0a02487db
commit d6976e6ef6
17 files changed
+555 -69

No files matched your search

+41 -23
View File
@@ -18,7 +18,7 @@ import {
} from "./abilityRules";
import type { MobCombatState } from "./combatStore";
import { useCombatStore } from "./combatStore";
import { memberFromCompanionActor } from "./combatActorAuthority";
import { companionResourceMaximum, memberFromCompanionActor } from "./combatActorAuthority";
import type { MobVector3 } from "./mobPopulation";
import { requireDungeonDefinition } from "./dungeonRegistry";
import { getMobPosition } from "./mobRuntimeRegistry";
@@ -713,9 +713,13 @@ function advancePartyWeaponAttack(member: PartyMember, targetId: string, now: nu
targetActorId: targetId, abilityId, name: "Auto Attack", source: "fallback", school: "physical",
delivery: baseClassFor(member.classId) === "hunter" ? "projectile" : identity.delivery, origin, targetPosition, instantCast: true });
}
if (member.resourceType !== "rage" || result.amount <= 0) return member;
const resource = Math.min(member.maxResource, member.resource + 6);
return { ...member, resource, resourcePools: { ...member.resourcePools, rage: resource } };
if (member.resourcePools.rage === undefined || result.amount <= 0) return member;
const rage = Math.min(companionResourceMaximum(member, "rage"), member.resourcePools.rage + 6);
return {
...member,
resource: member.resourceType === "rage" ? rage : member.resource,
resourcePools: { ...member.resourcePools, rage },
};
}
function partyFriendlyPosition(actorId: string): MobVector3 | null {
@@ -1207,26 +1211,37 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
);
members = members.map((member) => {
const profile = resourceProfileForClass(member.classId);
const regeneration = (profile.type === "rage" || profile.type === "runic-power")
? 0
: profile.regenerationPerSecond + member.gearStats.mp5 / 5 + member.gearStats.spirit * 0.02;
const pool = advanceCombatResourcePool(normalizeActorResourcePool(
member.resourceType,
member.resource,
member.maxResource,
regeneration,
member.lastResourceSpentAt[member.resourceType] ?? 0,
), {
inCombat: Boolean(targetId),
actorLevel: member.level,
now,
deltaSeconds,
manaSpiritRegenerationPerSecond: member.gearStats.spirit * 0.02,
});
const passiveRates: Partial<Record<ResourceType, number>> = {
mana: 4,
rage: 0,
energy: 10,
focus: 6,
"runic-power": 0,
};
const resourcePools: Partial<Record<ResourceType, number>> = { ...member.resourcePools };
for (const type of Object.keys(resourcePools) as ResourceType[]) {
const manaRegeneration = member.gearStats.mp5 / 5 + member.gearStats.spirit * 0.02;
const regeneration = type === member.resourceType
? (profile.type === "rage" || profile.type === "runic-power" ? 0 : profile.regenerationPerSecond + manaRegeneration)
: (passiveRates[type] ?? 0) + (type === "mana" ? manaRegeneration : 0);
resourcePools[type] = advanceCombatResourcePool(normalizeActorResourcePool(
type,
resourcePools[type] ?? 0,
companionResourceMaximum(member, type),
regeneration,
member.lastResourceSpentAt[type] ?? 0,
), {
inCombat: Boolean(targetId),
actorLevel: member.level,
now,
deltaSeconds,
manaSpiritRegenerationPerSecond: type === "mana" ? member.gearStats.spirit * 0.02 : 0,
}).current;
}
return {
...member,
resource: pool.current,
resourcePools: { ...member.resourcePools, [member.resourceType]: pool.current },
resource: resourcePools[member.resourceType] ?? member.resource,
resourcePools,
cooldowns: Object.fromEntries(Object.entries(member.cooldowns).filter(([, readyAt]) => readyAt > now)),
schoolLockedUntil: Object.fromEntries(Object.entries(member.schoolLockedUntil).filter(([, readyAt]) => (readyAt ?? 0) > now)),
};
@@ -1291,7 +1306,10 @@ export function advanceDungeonPartyCombat(now = Date.now()): void {
const currentCombat = useCombatStore.getState();
if (member.activeCast) {
const activeCast = member.activeCast;
const castingAbility = abilityById(member.activeCast.abilityId);
const catalogAbility = abilityById(member.activeCast.abilityId);
const castingAbility = catalogAbility
? learnedAbilityForBuild(catalogAbility, member.level, member.talentRanks)
: null;
const castTargetId = member.activeCastTargetId;
if (!castingAbility || !castTargetId) {
nextMembers[index] = { ...member, activeCast: null, activeCastTargetId: null };