Compare commits
3 Commits
4388a1ed3a
...
22bd377275
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22bd377275 | ||
|
|
f2dbd30470 | ||
|
|
aec84d169f |
@@ -28,7 +28,7 @@
|
||||
* - SkillDescSet:结构化描述模板
|
||||
* - FieldSkillSet(驻场技能)、BuffList(计时 buff 默认值兜底)、Attrs(属性枚举)
|
||||
*/
|
||||
import { SkillTriggerName, SkillTriggerType, TriggerGrouped, LvTriggerEntry, LvFieldEntry, LvReviveEntry, LvBonusEntry, FieldEntry, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, getTriggerSkillName, HGrowType, calcGrowBonus } from "./heroSet";
|
||||
import { SkillTriggerName, SkillTriggerType, TriggerGrouped, LvTriggerEntry, LvFieldEntry, LvReviveEntry, LvBonusEntry, FieldEntry, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, resolveSkillOverrides, getTriggerSkillName, HGrowType, calcGrowBonus, HSkillInfo } from "./heroSet";
|
||||
import { FieldSkillSet, mergeSkillParams, SkillConfig, SkillKind, SkillOverrides, SkillSet, TGroup } from "./SkillSet";
|
||||
import { FieldDescSet, FieldValueFmt, SkillDescSet } from "./SkillDescSet";
|
||||
import { BuffList } from "./BuffSet";
|
||||
@@ -42,6 +42,8 @@ import { CardConfig } from "./CardSet";
|
||||
export interface ISkillDescSource {
|
||||
/** 当前等级(用于 resolve 触发技能/光环/复活取档;静态 heroInfo 恒为 1) */
|
||||
lv?: number;
|
||||
/** 携带技能(普攻技能,支持 lv_entries 按等级分档 resolve) */
|
||||
skills?: Record<number, HSkillInfo>;
|
||||
call?: TriggerGrouped;
|
||||
dead?: TriggerGrouped;
|
||||
fstart?: TriggerGrouped;
|
||||
@@ -368,6 +370,24 @@ function buildSkillLines(source: ISkillDescSource, showName: boolean = true, sho
|
||||
const lines: ISkillLine[] = [];
|
||||
const lv = Math.max(1, source.lv ?? 1);
|
||||
|
||||
// ---- 普攻技能(skills):按英雄等级 resolve 分档 overrides ----
|
||||
if (source.skills) {
|
||||
for (const key in source.skills) {
|
||||
const hSkill = source.skills[key];
|
||||
if (!hSkill) continue;
|
||||
const base = SkillSet[hSkill.uuid];
|
||||
if (!base) continue;
|
||||
const overrides = resolveSkillOverrides(hSkill, lv);
|
||||
const skill = mergeSkillParams(base, overrides);
|
||||
// 技能等级展示:lv_entries 有档时取档位 s_lv,否则用运行时 lv
|
||||
const sLv = hSkill.lv_entries?.length
|
||||
? (hSkill.lv_entries.filter(e => e.lv <= lv).pop()?.s_lv ?? hSkill.lv)
|
||||
: hSkill.lv;
|
||||
const nameSeg = showName ? `「${base.name}」 ` : "";
|
||||
lines.push(buildEffectLine(`Lv${sLv}: ${nameSeg}`, skill));
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 6 种标准触发技能 ----
|
||||
for (const key of TRIGGER_KEYS) {
|
||||
const grouped = source[key] as TriggerGrouped | undefined;
|
||||
@@ -569,6 +589,24 @@ export function buildSkillDescMoreRich(source: ISkillDescSource, showName: boole
|
||||
return highlightDuration(text);
|
||||
};
|
||||
|
||||
// ---- 普攻技能(skills):按英雄等级 resolve 分档 overrides,展示当前生效档 ----
|
||||
if (source.skills) {
|
||||
for (const key in source.skills) {
|
||||
const hSkill = source.skills[key];
|
||||
if (!hSkill) continue;
|
||||
const base = SkillSet[hSkill.uuid];
|
||||
if (!base) continue;
|
||||
const overrides = resolveSkillOverrides(hSkill, lv);
|
||||
const skill = mergeSkillParams(base, overrides);
|
||||
// 技能等级展示:lv_entries 有档时取档位 s_lv,否则用运行时 lv
|
||||
const sLv = hSkill.lv_entries?.length
|
||||
? (hSkill.lv_entries.filter(e => e.lv <= lv).pop()?.s_lv ?? hSkill.lv)
|
||||
: hSkill.lv;
|
||||
const head = showName ? `「${base.name}」 Lv.${sLv}: ` : `Lv.${sLv}: `;
|
||||
lines.push(effectRich(buildEffectLine(head, skill)));
|
||||
}
|
||||
}
|
||||
|
||||
for (const key of TRIGGER_KEYS) {
|
||||
const grouped = source[key] as TriggerGrouped | undefined;
|
||||
if (!grouped) continue;
|
||||
|
||||
@@ -60,7 +60,6 @@ const SkillCardData: SkillCardRaw[] = [
|
||||
{ uuid: 8202, skill: 6102, card_lv: 2, icon: "Stat_Mana", name: "飓风卷轴", info: "召唤飓风攻击敌人,造成攻击力200%的伤害,30%击晕,可命中2个目标", is_inst: false, t_times: 3, t_inv: 5, trigger_type: CardTriggerType.Interval, overrides: { ap: 200, stun: 30 } },
|
||||
|
||||
// ==================== card_lv 3 · 高阶范围(ap:250,群体附加) ====================
|
||||
{ uuid: 8301, skill: 6201, card_lv: 3, icon: "Stat_SplashDamage", name: "陨石雨卷轴", info: "召唤陨石雨攻击敌人,一次释放3发,每发造成攻击力250%的范围伤害,40%击晕", is_inst: false, t_times: 4, t_inv: 4, trigger_type: CardTriggerType.Interval, overrides: { ap: 250, stun: 40, num: 2 } },
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -160,12 +160,8 @@ export const SkillDescSet: Record<number, SkillDescConfig> = {
|
||||
templPerm: "造成攻击力{value}{unit}的伤害",
|
||||
},
|
||||
|
||||
// ==================== 技能商店范围攻击卡(6201-6206):ap = 单段伤害 ====================
|
||||
// ==================== 技能商店范围攻击卡(6202-6206):ap = 单段伤害 ====================
|
||||
// 注:暴击/冰冻/击晕/击退等附加概率由 buildCardDescRich 扫描 crt/frz/stun/bck 动态追加,不在模板写死
|
||||
6201: {
|
||||
verb: "", unit: "", permField: "ap",
|
||||
templPerm: "每段造成{value}点伤害",
|
||||
},
|
||||
6202: {
|
||||
verb: "", unit: "", permField: "ap",
|
||||
templPerm: "每段造成{value}点伤害",
|
||||
|
||||
@@ -336,17 +336,17 @@ export const SkillSet: Record<number, SkillConfig> = {
|
||||
RType: RType.bezier, EType: EType.collision, info: "对周围的敌人造成攻击力150%的伤害",//英雄配置技能的时候,可以疲惫触发6013闪电术
|
||||
},
|
||||
6107: {
|
||||
uuid: 6201, name: "万剑朝宗", sp_name: "range3", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max1",
|
||||
uuid: 6107, name: "万剑朝宗", sp_name: "range3", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max1",
|
||||
DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.fixed, EType: EType.animationEnd, info: "召唤6把冰剑攻击敌人",//可以附加冰冻增强
|
||||
},
|
||||
6108: {
|
||||
uuid: 6201, name: "开山斧", sp_name: "range2", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max0",
|
||||
uuid: 6108, name: "开山斧", sp_name: "range2", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max0",
|
||||
DTType: DTType.aoe_grid, stun: 0, ap: 300, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.fixed, EType: EType.animationEnd, info: "召唤巨斧劈向前方敌人",//可以附加击晕增强
|
||||
},
|
||||
6109: {
|
||||
uuid: 6019, name: "万箭齐发.冰", sp_name: "maxa1", icon: "Stat_RangedAttack", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
uuid: 6109, name: "万箭齐发.冰", sp_name: "maxa1", icon: "Stat_RangedAttack", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, ap: 100, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.bezier, EType: EType.collision, bezier_start_y: 20, bezier_mid_y: 140, bezier_arc: 1.05, info: "造成攻击力100%的伤害",
|
||||
},
|
||||
@@ -356,12 +356,6 @@ export const SkillSet: Record<number, SkillConfig> = {
|
||||
RType: RType.bezier, EType: EType.collision, bezier_start_y: 20, bezier_mid_y: 140, bezier_arc: 1.05, info: "造成攻击力100%的伤害",
|
||||
},
|
||||
|
||||
6201: {
|
||||
uuid: 6201, name: "陨石术", sp_name: "fb-3", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max1",
|
||||
DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.fixed, EType: EType.animationEnd, info: "召唤陨石范围攻击敌人, 有概率击晕",
|
||||
},
|
||||
|
||||
//============================= ====== 辅助技能 回合技能 ====== ==========================
|
||||
6301: {
|
||||
uuid: 6301, name: "护盾", sp_name: "buff_wind", icon: "Stat_Defense", TGroup: TGroup.Self, readyAnm: "up_blue", endAnm: "", act: "atk",
|
||||
|
||||
@@ -316,7 +316,18 @@ export interface HSkillInfo {
|
||||
lv: number; // 技能等级
|
||||
cd: number; // 技能cd
|
||||
ccd: number; // 占位当前cd,用于cd计时
|
||||
overrides?: SkillOverrides; // 角色专属参数覆盖
|
||||
overrides?: SkillOverrides; // 角色专属参数覆盖(全等级生效,作为底)
|
||||
lv_entries?: LvSkillEntry[]; // 按英雄等级分档(按 lv 升序,运行时取 ≤英雄等级 的最大档)
|
||||
}
|
||||
|
||||
/**
|
||||
* 普攻技能分档配置:达到 lv 级英雄时此档 overrides 生效(与基础 overrides 浅合并,档位优先)。
|
||||
* s_lv 标注此档对应的技能等级(SkillLv 枚举),便于面板显示"技能Lv.x"。
|
||||
*/
|
||||
export interface LvSkillEntry {
|
||||
lv: number; // 达到该英雄等级时此档生效
|
||||
s_lv?: SkillLv; // 此档对应的技能等级(标注用)
|
||||
overrides: SkillOverrides; // 此档注入的效果
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,7 +435,18 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
// 5004 破晓先知 — fstart 全队攻击
|
||||
5004: {
|
||||
uuid: 5004, name: "破晓先知", path: "hm1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: 143, ap: 32,
|
||||
skills: { 6014: { uuid: 6014, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 80, timed_buff_id: 7003 } } },
|
||||
skills: {
|
||||
6014: { uuid: 6014, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 80, timed_buff_id: 7003 } },
|
||||
// 大招:火焰喷射,独立 cd,按英雄等级分档成长(5级双发)
|
||||
6101: {
|
||||
uuid: 6101, lv: 1, cd: 8, ccd: 0,
|
||||
overrides: { ap: 100 },
|
||||
lv_entries: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150 } },
|
||||
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 200, num: 1 } },
|
||||
],
|
||||
},
|
||||
},
|
||||
fstart: {
|
||||
6401: [
|
||||
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
||||
@@ -974,6 +996,21 @@ export function resolveTriggerByLv(grouped: TriggerGrouped | undefined, lv: numb
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析普攻技能在目标英雄等级下的有效 overrides。
|
||||
* 取 lv_entries 中 ≤hero_lv 的最大档,与基础 overrides 浅合并(档位字段优先)。
|
||||
* Why: 普攻技能与触发技能对齐"英雄等级驱动成长"语义,且下游读取 skills[uuid].overrides 无需感知分档。
|
||||
*/
|
||||
export function resolveSkillOverrides(skill: HSkillInfo, hero_lv: number): SkillOverrides | undefined {
|
||||
if (!skill.lv_entries || skill.lv_entries.length === 0) return skill.overrides;
|
||||
let pick: LvSkillEntry | undefined;
|
||||
for (const e of skill.lv_entries) {
|
||||
if (e.lv <= hero_lv && (!pick || e.lv > pick.lv)) pick = e;
|
||||
}
|
||||
if (!pick) return skill.overrides;
|
||||
return { ...skill.overrides, ...pick.overrides };
|
||||
}
|
||||
|
||||
/** 解析驻场光环在目标等级下的有效词条列表(取 ≤lv 的最大档) */
|
||||
export function resolveFieldByLv(field: LvFieldEntry[] | undefined, lv: number): FieldEntry[] {
|
||||
if (!field || field.length === 0) return [];
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
```typescript
|
||||
[SkillTriggerType.Atking]: {
|
||||
// 普攻触发 360% 范围伤害 + 击退
|
||||
6201: [{ lv: 1, t_num: 1, overrides: { ap: 150, bck: 30 } }],
|
||||
6107: [{ lv: 1, t_num: 1, overrides: { ap: 150, bck: 30 } }],
|
||||
// 普攻吸血 35%
|
||||
6302: [{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Self, ap: 35 } }],
|
||||
},
|
||||
@@ -201,7 +201,7 @@
|
||||
```typescript
|
||||
[SkillTriggerType.Atking]: {
|
||||
// 范围伤害 + 群体击退
|
||||
6201: [{ lv: 1, t_num: 1, overrides: { ap: 200, bck: 50, hit_count: 6 } }],
|
||||
6108: [{ lv: 1, t_num: 1, overrides: { ap: 200, bck: 50, hit_count: 6 } }],
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { smc } from "../common/SingletonModuleComp";
|
||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { BoxSet, FacSet, FightSet, IndexSet } from "../common/config/GameSet";
|
||||
import { HeroInfo, resolveFormationTargetX, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, calcGrowBonus, HeroDisVal } from "../common/config/heroSet";
|
||||
import { HeroInfo, resolveFormationTargetX, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, resolveSkillOverrides, calcGrowBonus, HeroDisVal } from "../common/config/heroSet";
|
||||
import { GameEvent } from "../common/config/GameEvent";
|
||||
import { SkillTriggerType, HType } from "../common/config/heroSet";
|
||||
import { SkillTriggerHelper } from "./SkillTriggerHelper";
|
||||
@@ -158,13 +158,13 @@ export class Hero extends ecs.Entity {
|
||||
|
||||
model.speed = hero.speed ?? 200;
|
||||
|
||||
// 构建技能表并注入运行时冷却字段 ccd
|
||||
// 构建技能表并注入运行时冷却字段 ccd;overrides 按英雄等级 resolve 分档(下游无感知)
|
||||
model.skills = {};
|
||||
for (const key in hero.skills) {
|
||||
const skill = hero.skills[key];
|
||||
if (!skill) continue;
|
||||
// 最终技能等级 = 初始技能等级 + 英雄等级增量,下限 0、上限封顶(无限升级下技能不涨过上限)
|
||||
model.skills[skill.uuid] = { ...skill, lv: Math.min(FightSet.HERO_SKILL_MAX_LV, Math.max(0, skill.lv + hero_lv - 2)), ccd: 0 };
|
||||
model.skills[skill.uuid] = { ...skill, lv: Math.min(FightSet.HERO_SKILL_MAX_LV, Math.max(0, skill.lv + hero_lv - 2)), ccd: 0, overrides: resolveSkillOverrides(skill, hero_lv) };
|
||||
}
|
||||
|
||||
// 按当前英雄等级 resolve 触发技能/光环/复活到运行时缓存,供 SkillTriggerHelper 消费
|
||||
|
||||
@@ -3,7 +3,7 @@ import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/O
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { BoxSet, FacSet, FightSet, IndexSet } from "../common/config/GameSet";
|
||||
import { HeroInfo, resolveTriggerByLv, resolveReviveByLv, HeroDisVal } from "../common/config/heroSet";
|
||||
import { HeroInfo, resolveTriggerByLv, resolveReviveByLv, resolveSkillOverrides, HeroDisVal } from "../common/config/heroSet";
|
||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { MoveComp } from "./MoveComp";
|
||||
@@ -201,8 +201,8 @@ export class Monster extends ecs.Entity {
|
||||
for (const key in hero.skills) {
|
||||
const skill = hero.skills[key];
|
||||
if (!skill) continue;
|
||||
// 最终技能等级 = 初始技能等级 + 怪物等级增量,且下限为 0
|
||||
model.skills[skill.uuid] = { ...skill, lv: Math.max(0, skill.lv + mon_lv - 2), ccd: 0 };
|
||||
// 最终技能等级 = 初始技能等级 + 怪物等级增量,且下限为 0;overrides 按怪物等级 resolve 分档
|
||||
model.skills[skill.uuid] = { ...skill, lv: Math.max(0, skill.lv + mon_lv - 2), ccd: 0, overrides: resolveSkillOverrides(skill, mon_lv) };
|
||||
}
|
||||
// 【测试模式专属】如果有覆盖技能配置则应用
|
||||
const testSkills = (this as any)._testSkills;
|
||||
|
||||
@@ -475,6 +475,7 @@ export class CHeroComp extends CCComp {
|
||||
private buildHeroDescSource(hero: typeof HeroInfo[number]): ISkillDescSource {
|
||||
return {
|
||||
lv: 5,
|
||||
skills: hero.skills,
|
||||
call: hero.call,
|
||||
dead: hero.dead,
|
||||
fstart: hero.fstart,
|
||||
|
||||
@@ -214,6 +214,7 @@ export class HeroBoxComp extends CCComp {
|
||||
|
||||
const buildSource = (lv: number): ISkillDescSource => ({
|
||||
lv: lv,
|
||||
skills: hero.skills,
|
||||
call: hero.call,
|
||||
dead: hero.dead,
|
||||
fstart: hero.fstart,
|
||||
|
||||
@@ -52,7 +52,7 @@ import { MissSkillsComp } from "./MissSkillsComp";
|
||||
import { oops } from "db://oops-framework/core/Oops";
|
||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { HeroInfo, HType, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, calcGrowBonus } from "../common/config/heroSet";
|
||||
import { HeroInfo, HType, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, resolveSkillOverrides, calcGrowBonus } from "../common/config/heroSet";
|
||||
import { HeroViewComp } from "../hero/HeroViewComp";
|
||||
import { FacSet, FightSet } from "../common/config/GameSet";
|
||||
import { MissionEconomy } from "./MissionEconomy";
|
||||
@@ -2273,7 +2273,8 @@ export class MissionCardComp extends CCComp {
|
||||
for (const key in hero.skills) {
|
||||
const skill = hero.skills[key];
|
||||
if (!skill) continue;
|
||||
model.skills[skill.uuid] = { ...skill, lv: Math.min(FightSet.HERO_SKILL_MAX_LV, Math.max(0, skill.lv + nextLv - 2)), ccd: 0 };
|
||||
// 升级后按 nextLv 重新 resolve 分档 overrides(与 Hero.load 对齐)
|
||||
model.skills[skill.uuid] = { ...skill, lv: Math.min(FightSet.HERO_SKILL_MAX_LV, Math.max(0, skill.lv + nextLv - 2)), ccd: 0, overrides: resolveSkillOverrides(skill, nextLv) };
|
||||
}
|
||||
model.updateSkillDistanceCache();
|
||||
model.dirty_hp = true;
|
||||
|
||||
Reference in New Issue
Block a user