You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
3.6 KiB
94 lines
3.6 KiB
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;
|
|
}
|
|
|