import type { EntityId } from 'db://assets/mx/module/ecs'; import { AtkHookComp, EntityTag, TagComp } from 'db://assets/mx/module/battle'; import { SkillPresentationEnv } from './SkillPresentationEnv'; import { YU_DI_WEAPON1_ID, WANG_MU_WEAPON1_ID } from '../heros/HeroActorRes'; export const YUDI_WEAPON1_ID = YU_DI_WEAPON1_ID; /** 共掌天庭:王母 Hero.id */ export const YUDI_GROUP2_PARTNER_ID = WANG_MU_WEAPON1_ID; export interface YudiLightningBallConfig { count: number; damageScale: number; } export interface YudiPercentMaxHpConfig { normalWan: number; bossWan: number; } function parseUltAfterType7(raws: readonly string[]): YudiLightningBallConfig | null { let count = 0; let damageScale = 1; for (const raw of raws) { for (const seg of raw.split(';')) { const part = seg.trim(); if (!part) continue; const p = part.split(',').map(Number); if (p[0] !== 7) continue; count += Math.max(0, Math.floor(p[1] ?? 0)); if (p[2] != null && p[2] > 0) damageScale = p[2]; } } if (count <= 0) return null; return { count, damageScale }; } function parseSkillSpecial15(raws: readonly string[]): YudiPercentMaxHpConfig | null { for (const raw of raws) { for (const seg of raw.split(';')) { const part = seg.trim(); if (!part) continue; const p = part.split(',').map(Number); if (p[0] !== 15) continue; return { normalWan: p[1] ?? 0, bossWan: p[2] ?? p[1] ?? 0, }; } } return null; } /** group2 伙伴在场时效果数值 ×2 */ function applyGroup2Double(effectValue: number, group2HeroId: number, caster: EntityId): number { if (!group2HeroId || effectValue === 0) return effectValue; if (!SkillPresentationEnv.isGroup2PartnerActive(caster, group2HeroId)) return effectValue; return effectValue * 2; } /** 大招 ultAfter type7 → 闪电球数量与伤害倍数(含 group2 翻倍) */ export function readYudiLightningBallConfig(caster: EntityId): YudiLightningBallConfig | null { const session = SkillPresentationEnv.getBattleSession(); if (!session?.world.isAlive(caster)) return null; const hook = session.world.getComponent(caster, AtkHookComp); if (!hook?.ultAfter?.length) return null; const base = parseUltAfterType7(hook.ultAfter); if (!base) return null; const g2 = SkillPresentationEnv.isGroup2PartnerActive(caster, YUDI_GROUP2_PARTNER_ID) ? 2 : 1; return { count: base.count * g2, damageScale: base.damageScale, }; } /** skill_special type15 → 最大生命百分比伤害(含 group2 翻倍) */ export function readYudiPercentMaxHpConfig(caster: EntityId): YudiPercentMaxHpConfig | null { const session = SkillPresentationEnv.getBattleSession(); if (!session?.world.isAlive(caster)) return null; const hook = session.world.getComponent(caster, AtkHookComp); if (!hook?.specials?.length) return null; const base = parseSkillSpecial15(hook.specials); if (!base) return null; return { normalWan: applyGroup2Double(base.normalWan, YUDI_GROUP2_PARTNER_ID, caster), bossWan: applyGroup2Double(base.bossWan, YUDI_GROUP2_PARTNER_ID, caster), }; } export function resolvePercentMaxHpWan(targetId: EntityId, cfg: YudiPercentMaxHpConfig): number { const session = SkillPresentationEnv.getBattleSession(); if (!session) return cfg.normalWan; const isBoss = !!session.world.getComponent(targetId, TagComp)?.tags.includes(EntityTag.Boss); return isBoss ? cfg.bossWan : cfg.normalWan; }