Release Healer Man 0.1.14

This commit is contained in:
phenom committed 2026-09-05 11:40:50 -04:00
1 parent 67d7a8ebe7
commit 7b41b102fa
147 files changed
+169892 -1342

No files matched your search

+40
View File
@@ -83,12 +83,14 @@ import {
} from "./talentModifiers";
import {
getMobPosition,
getMobRuntimeTransform,
mobRuntimeDistanceSquared,
nearbyMobRuntimeIds,
removeMobPosition,
setMobPosition,
type CombatPosition,
} from "./mobRuntimeRegistry";
import { enemyTelegraphContainsPosition } from "./enemyTelegraphGeometry";
import {
getPartyRuntimePosition,
partyRuntimeDistanceSquared,
@@ -299,6 +301,9 @@ export interface EnemyActiveCast {
readonly school: EnemyDamageSchool;
readonly interruptible: boolean;
readonly targetActorId: AggroActorId | null;
readonly sourcePosition: CombatPosition;
readonly targetPosition: CombatPosition;
readonly sourceYaw: number;
readonly startedAt: number;
readonly completesAt: number;
}
@@ -6163,6 +6168,7 @@ export const useCombatStore = create<CombatState>((set, get) => ({
);
if (selectedAttack && startingEnemyCast) {
const attack = selectedAttack;
const sourceTransform = getMobRuntimeTransform(id);
enemyActiveCast = {
attackId: attack.id,
name: attack.name,
@@ -6170,6 +6176,10 @@ export const useCombatStore = create<CombatState>((set, get) => ({
school: attack.school,
interruptible: attack.interruptible !== false,
targetActorId: resolution.targetActorId,
sourcePosition: [...position],
targetPosition: [...targetPosition],
sourceYaw: sourceTransform?.yaw
?? Math.atan2(targetPosition[0] - position[0], targetPosition[2] - position[2]),
startedAt: now,
completesAt: now + (attack.castTimeMs ?? 0),
};
@@ -6187,6 +6197,7 @@ export const useCombatStore = create<CombatState>((set, get) => ({
);
} else if (selectedAttack && !cannotAttack) {
const attack = selectedAttack!;
const resolvedEnemyCast = enemyActiveCast;
enemyActiveCast = null;
const effect = attack.effect ?? {
kind: "damage" as const,
@@ -6198,10 +6209,24 @@ export const useCombatStore = create<CombatState>((set, get) => ({
stableCombatUnit(`${id}:${attack.id}:${attackRevision}:target`) * eligibleActors.length,
)]
: resolution.targetActorId;
const telegraphPlacement = resolvedEnemyCast
? {
sourcePosition: resolvedEnemyCast.sourcePosition,
targetPosition: resolvedEnemyCast.targetPosition,
sourceYaw: resolvedEnemyCast.sourceYaw,
}
: {
sourcePosition: position,
targetPosition,
sourceYaw: Math.atan2(targetPosition[0] - position[0], targetPosition[2] - position[2]),
};
const unvalidatedTargets = attack.target === "nearby-party"
? eligibleActors.filter((actorId) => {
const candidate = actorPosition(runtimeState, actorId);
if (!candidate) return false;
if (attack.telegraph) {
return enemyTelegraphContainsPosition(attack.telegraph, telegraphPlacement, candidate);
}
const radius = attack.radius ?? Math.max(1, attack.range * 0.35);
const targetDx = candidate[0] - position[0];
const targetDy = candidate[1] - position[1];
@@ -6298,6 +6323,21 @@ export const useCombatStore = create<CombatState>((set, get) => ({
targetId: id,
now,
}).auras];
} else if (effect.kind === "target-aura") {
for (const actorId of targets) {
namedAuras = [...applyCombatAura(namedAuras, {
definition: {
id: `enemy-debuff:${id}:${attack.id}:${effect.aura}`,
name: `${attack.name}: ${effect.aura}`,
disposition: "debuff",
durationMs: effect.durationMs > 0 ? effect.durationMs : null,
dispelCategory: "magic",
},
sourceId: id,
targetId: actorId,
now,
}).auras];
}
} else if (effect.kind === "control") {
for (const actorId of targets) {
if (hasControlImmunity(namedAuras, actorId, effect.mechanic)) continue;