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.
 
 
 
 
AdLike2048/assets/script/battle/skill/YudiConfig.ts

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;
}