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.
73 lines
2.6 KiB
73 lines
2.6 KiB
|
3 weeks ago
|
import type { EntityId } from 'db://assets/mx/module/ecs';
|
||
|
|
import { TableNames } from '../../game/ConfigTableData';
|
||
|
|
import { getTowerLoadoutService } from '../combat/TowerLoadoutService';
|
||
|
|
import { getMonsterStatusText } from '../view/MonsterStatusText';
|
||
|
|
import { SkillPresentationEnv } from './SkillPresentationEnv';
|
||
|
|
|
||
|
|
/** 大招名飘字后、实际释放大招的通用延迟(秒) */
|
||
|
|
export const ULT_SKILL_RELEASE_DELAY_SEC = 0.5;
|
||
|
|
/** 技能名飘字字号 */
|
||
|
|
const SKILL_NAME_FONT_SIZE = 28;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 神将主动技能名飘字:读 Skill 表 name,在组合中心用 battleText 播放。
|
||
|
|
*/
|
||
|
|
export class SkillNameFloater {
|
||
|
|
/**
|
||
|
|
* 播放技能名飘字。
|
||
|
|
* @param caster 施法实体
|
||
|
|
* @param abilityId 可选;用于解析 Skill 表 id
|
||
|
|
*/
|
||
|
|
static play(caster: EntityId, abilityId?: string): void {
|
||
|
|
const skillName = SkillNameFloater.resolveDisplayName(caster, abilityId);
|
||
|
|
if (!skillName) return;
|
||
|
|
|
||
|
|
const worldCenter = SkillPresentationEnv.getCompositionWorldCenter(caster);
|
||
|
|
if (!worldCenter) {
|
||
|
|
console.log('[SkillNameFloater] 无组合中心', caster);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
getMonsterStatusText().playAtWorld(worldCenter, skillName, SKILL_NAME_FONT_SIZE);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 从 Skill 表解析展示名(lang)。
|
||
|
|
* @param caster 施法实体
|
||
|
|
* @param abilityId 主动技能 Ability id
|
||
|
|
*/
|
||
|
|
private static resolveDisplayName(caster: EntityId, abilityId?: string): string | null {
|
||
|
|
let skillId = SkillNameFloater.parseSkillId(abilityId);
|
||
|
|
if (!(skillId > 0)) {
|
||
|
|
skillId = getTowerLoadoutService().getLoadout(caster)?.activeSkillBaseAtkId ?? 0;
|
||
|
|
}
|
||
|
|
if (!(skillId > 0)) {
|
||
|
|
console.log('[SkillNameFloater] 无主动技能 id', caster, abilityId);
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const row = gg.data.table.getTableData<ITableSkill>(TableNames.Skill, skillId);
|
||
|
|
if (!row) {
|
||
|
|
console.log('[SkillNameFloater] Skill 缺失', skillId);
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const name = String(gg.lang.get(row.name) ?? '').trim();
|
||
|
|
if (!name) {
|
||
|
|
console.log('[SkillNameFloater] Skill.name 为空', skillId);
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return name;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 从 ability_hero_/ability_ult_/ability_weapon_ id 解析 Skill 表 id。
|
||
|
|
* @param abilityId Ability id
|
||
|
|
*/
|
||
|
|
private static parseSkillId(abilityId?: string): number {
|
||
|
|
if (!abilityId) return 0;
|
||
|
|
const m = /^ability_(?:ult|hero|weapon)_(\d+)(?:_e\d+)?$/.exec(abilityId);
|
||
|
|
return m ? Number(m[1]) : 0;
|
||
|
|
}
|
||
|
|
}
|