Compare commits
15 Commits
c96eac9bac
...
5cacfee288
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cacfee288 | ||
|
|
92836c14b6 | ||
|
|
f49831bf9e | ||
|
|
9f6f09dbd3 | ||
|
|
8a485bb6e6 | ||
|
|
a2b5bbc39d | ||
|
|
268c6e155a | ||
|
|
23db51df12 | ||
|
|
de67e36590 | ||
|
|
0b59f601d8 | ||
|
|
cb53417ea8 | ||
|
|
9eccca7e2a | ||
|
|
fce7646de6 | ||
|
|
88d7bdae47 | ||
|
|
eae62f245a |
@@ -0,0 +1,49 @@
|
||||
# 技能配置重构实施计划
|
||||
|
||||
## 1. 探索阶段总结 (Current State Analysis)
|
||||
经过对代码库的探索,当前技能触发系统及相关配置状态如下:
|
||||
- `SkillSet.ts` 包含了所有技能的基座配置 `SkillConfig` 和技能字典 `SkillSet`。
|
||||
- `heroSet.ts` 中的 `HeroInfo` 存放英雄和怪物的配置,目前 `call`, `dead`, `fstart`, `fend` 被定义为 `number[]`,而 `atking` 和 `atked` 被定义为 `{s_uuid: number, t_num: number}[]`。
|
||||
- `HeroAttrsComp.ts` 内部存储了与配置一致的触发技能结构。
|
||||
- `SkillTriggerHelper.ts` 负责判定并向外派发 `GameEvent.TriggerSkill` 事件,由 `SCastSystem.ts` 监听并执行 `forceCastTriggerSkill`。
|
||||
- 目前 `SCastSystem.ts` 在收集技能目标和施放技能时,都是直接从 `SkillSet[s_uuid]` 读取 `config`,没有针对具体角色的差异化机制。
|
||||
|
||||
## 2. 拟议变更 (Proposed Changes)
|
||||
|
||||
### 2.1 修改 `SkillSet.ts`
|
||||
- **新增接口**:定义 `SkillOverrides` 接口,包含所有可被角色覆盖的技能参数(如 `TGroup`, `ap`, `hit_count`, `buffs` 等,全部为可选字段)。
|
||||
- **新增函数**:编写 `mergeSkillParams(config, overrides?)` 函数,将基座 `config` 和角色覆盖 `overrides` 进行合并,返回一个新的 `SkillConfig` 对象。
|
||||
|
||||
### 2.2 修改 `heroSet.ts`
|
||||
- **扩展接口**:
|
||||
- 在 `HSkillInfo` 接口中增加 `overrides?: SkillOverrides;`。
|
||||
- 将 `heroInfo` 接口中的触发字段 `call`, `dead`, `fstart`, `fend`, `atking`, `atked` 统一更新为 `{ s_uuid: number; t_num: number; overrides?: SkillOverrides }[]` 结构。
|
||||
- **更新配置示例**:按照设计文档更新英雄 `5001`, `5002`, `5301`, `5302` 的配置,为特定的触发技能添加 `overrides` 字段(如盾骑士 5002 全队护盾覆盖)。
|
||||
|
||||
### 2.3 修改 `HeroAttrsComp.ts`
|
||||
- **同步类型**:将 `call`, `dead`, `fstart`, `fend`, `atking`, `atked` 的类型同步改为与 `heroInfo` 一致的 `{ s_uuid: number; t_num: number; overrides?: SkillOverrides }[]`。
|
||||
|
||||
### 2.4 修改 `SkillTriggerHelper.ts`
|
||||
- **派发支持**:
|
||||
- 更新 `dispatchSingle` 方法签名,增加 `overrides?: SkillOverrides` 参数,并在 `oops.message.dispatchEvent(GameEvent.TriggerSkill, {...})` 中将其传入。
|
||||
- 更新 `handleCall`, `handleDead`, `handleArrayTrigger` 处理逻辑,将原先对 `number[]` 的处理改为对 `{s_uuid, t_num, overrides}` 对象数组的处理,并提取 `overrides` 传递给 `dispatchArray`。
|
||||
- 更新 `handleAtking`, `handleAtked` 中的 `dispatchSingle` 调用,传入 `atkConfig.overrides`。
|
||||
|
||||
### 2.5 修改 `SCastSystem.ts` (关键运行时逻辑)
|
||||
- **事件监听更新**:在 `onTriggerSkill` 方法的 `args` 参数定义中补充 `overrides?: SkillOverrides`,并传递给 `forceCastTriggerSkill`。
|
||||
- **合并逻辑上移(架构优化)**:
|
||||
- 在 `forceCastTriggerSkill` 和 `castSkill` 的**方法入口处**(而非 `applyFriendlySkillEffects` 内部),第一时间调用 `mergeSkillParams(config, overrides)` 获取 `effective` 技能配置。
|
||||
- 将后续所有关于阵营判定(如 `effective.TGroup`)、目标收集、以及传递给 `applyFriendlySkillEffects` / `applyEnemySkillEffects` 的参数全部替换为 `effective`。
|
||||
- **为何如此设计**:如果在原设计中仅在 `applyFriendlySkillEffects` 入口处合并,那么前置的**目标选择逻辑**(依赖 `TGroup` 判定是 `Self` 还是 `Team`)将会使用未合并的基础配置,导致类似“自己加盾变为全队加盾”的 `TGroup` 覆盖无法生效。将合并操作前置可以彻底解决这一问题。
|
||||
- **主动技能支持**:在 `pickCastSkill` 中,读取 `heroAttrs.skills[s_uuid]?.overrides` 并进行合并判定,同时将 `overrides` 放入返回的 `castPlan` 中,以便 `castSkill` 使用。
|
||||
|
||||
## 3. 假设与决策 (Assumptions & Decisions)
|
||||
- **统一触发结构**:虽然 `call`, `dead`, `fstart`, `fend` 不严格需要 `t_num`,但为了类型统一并完全遵守设计规范,统一采用了包含 `t_num` 的对象结构。
|
||||
- **合并前置决策**:如上所述,坚决在施放方法入口处进行 `mergeSkillParams` 以保证目标收集逻辑能够感知到 `TGroup` 的变化。这比设计规范中要求的修改范围略有扩大,但对于系统功能的正确实现是必须的。
|
||||
- **卡牌技能影响**:卡牌技能(`forceCastCardSkill`)当前没有绑定角色的 `overrides`,因此维持读取基础 `SkillSet` 逻辑不变。
|
||||
|
||||
## 4. 验证步骤 (Verification steps)
|
||||
1. 编译 TypeScript 代码,确保 `HeroAttrsComp`, `heroSet`, `SCastSystem` 等修改后的接口和类型无报错。
|
||||
2. 启动游戏或运行测试,确认 `5001` (见习战士) 触发的基础护盾只对自己生效。
|
||||
3. 确认 `5002` (盾骑士) 受击触发的护盾技能,正确地为全队附加护盾,并且护盾值(ap)与次数(hit_count)符合 `overrides` 配置。
|
||||
4. 确认所有旧版英雄技能在无 `overrides` 时能够正确回退到 `SkillSet` 的默认配置,游戏运转正常无异常日志。
|
||||
289
assets/resources/game/skill/buff/gold.prefab
Normal file
289
assets/resources/game/skill/buff/gold.prefab
Normal file
@@ -0,0 +1,289 @@
|
||||
[
|
||||
{
|
||||
"__type__": "cc.Prefab",
|
||||
"_name": "gold",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_native": "",
|
||||
"data": {
|
||||
"__id__": 1
|
||||
},
|
||||
"optimizationPolicy": 0,
|
||||
"persistent": false
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "gold",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": null,
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 2
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 8
|
||||
},
|
||||
{
|
||||
"__id__": 10
|
||||
},
|
||||
{
|
||||
"__id__": 12
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 14
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 6.112,
|
||||
"y": 45.573,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Node",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 3
|
||||
},
|
||||
{
|
||||
"__id__": 5
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 7
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 4
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 127,
|
||||
"height": 127
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "ddhDbko4FLmKZGY46brX7z"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 6
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
"_dstBlendFactor": 4,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": null,
|
||||
"_type": 0,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 1,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_useGrayscale": false,
|
||||
"_atlas": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "c3vPZUzCRINL3sICnCZKIr"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "feOW1uSctLKYCw3esMiuox",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 9
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 104,
|
||||
"height": 75
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "a7pn5tzA1BSI1AfdpVsHh7"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Animation",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 11
|
||||
},
|
||||
"playOnLoad": true,
|
||||
"_clips": [
|
||||
{
|
||||
"__uuid__": "a2e59563-ef5b-4535-a9b3-1b19c5253489",
|
||||
"__expectedType__": "cc.AnimationClip"
|
||||
}
|
||||
],
|
||||
"_defaultClip": {
|
||||
"__uuid__": "a2e59563-ef5b-4535-a9b3-1b19c5253489",
|
||||
"__expectedType__": "cc.AnimationClip"
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "63z5ZyjTNKYbn+kEVB1s3W"
|
||||
},
|
||||
{
|
||||
"__type__": "0f3c4JhFbFO2rEFqBJJ7hFv",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 13
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "32SLcINL1JHZ+vIyextzaC"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "cfqCWnxbFLNoQMedQXsav3",
|
||||
"instance": null,
|
||||
"targetOverrides": null
|
||||
}
|
||||
]
|
||||
1
assets/resources/game/skill/buff/gold.prefab.meta
Normal file
1
assets/resources/game/skill/buff/gold.prefab.meta
Normal file
@@ -0,0 +1 @@
|
||||
{"ver":"1.1.50","importer":"prefab","imported":true,"uuid":"e8d41546-4291-4505-8d72-fec141f76309","files":[".json"],"subMetas":{},"userData":{"syncNodeName":"gold"}}
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as exp from "constants"
|
||||
import { HeroInfo, HType } from "./heroSet"
|
||||
import { HeroInfo, HeroList, HType } from "./heroSet"
|
||||
import { FightSet } from "./GameSet"
|
||||
import { oops } from "db://oops-framework/core/Oops"
|
||||
|
||||
@@ -70,7 +70,7 @@ export const CardsUpSet: Record<number, number> = {
|
||||
}
|
||||
|
||||
/**初始coin数 */
|
||||
export const CardInitCoins = 11
|
||||
export const CardInitCoins = 10
|
||||
/** 卡池升级每波减免金额 */
|
||||
export const CARD_POOL_UPGRADE_DISCOUNT_PER_WAVE = 10
|
||||
/** 卡池默认初始等级 */
|
||||
@@ -81,44 +81,58 @@ export const CARD_POOL_MAX_LEVEL = CardLV.LV3
|
||||
export const CARD_HERO_MAX_LEVEL = 1
|
||||
/** 基础卡池(英雄、技能、功能) */
|
||||
|
||||
export const CardPoolList: CardConfig[] = [
|
||||
{ uuid: 5001, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5002, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5003, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5004, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5005, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
export const CardPoolList: CardConfig[] = [];
|
||||
|
||||
{ uuid: 5101, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5102, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5103, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5104, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5105, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
// 动态生成英雄卡池
|
||||
HeroList.forEach(uuid => {
|
||||
const hero = HeroInfo[uuid];
|
||||
if (!hero) return;
|
||||
|
||||
{ uuid: 5201, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5202, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5203, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5204, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
|
||||
{ uuid: 5301, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5302, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
const basePoolLv = hero.pool_lv || 1;
|
||||
const baseHeroLv = hero.lv || 1;
|
||||
const baseCost = 5;
|
||||
const baseWeight = 25;
|
||||
|
||||
{ uuid: 5401, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
{ uuid: 5402, type: CardType.Hero, cost: 10, weight: 25, pool_lv: 1, kind: CKind.Hero, hero_lv: 1 },
|
||||
// 生成从 basePoolLv 到 CARD_POOL_MAX_LEVEL 的卡牌
|
||||
for (let pLv = basePoolLv; pLv <= CARD_POOL_MAX_LEVEL; pLv++) {
|
||||
const offset = pLv - basePoolLv;
|
||||
const targetHeroLv = baseHeroLv + offset;
|
||||
|
||||
// 英雄的最高等级 是MERGE_MAX-1
|
||||
if (targetHeroLv > FightSet.MERGE_MAX - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
// cost = baseCost * 3^(lv-1): Lv1=5, Lv2=15, Lv3=45
|
||||
let cost = baseCost;
|
||||
if (targetHeroLv > 1) {
|
||||
cost = baseCost * Math.pow(FightSet.MERGE_NEED, targetHeroLv - 1);
|
||||
}
|
||||
|
||||
CardPoolList.push({
|
||||
uuid: hero.uuid,
|
||||
type: CardType.Hero,
|
||||
cost: cost,
|
||||
weight: baseWeight,
|
||||
pool_lv: pLv as CardLV,
|
||||
kind: CKind.Hero,
|
||||
hero_lv: targetHeroLv
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 添加非英雄卡牌 (技能、功能卡)
|
||||
CardPoolList.push(
|
||||
// 技能卡牌 (以增益/辅助为主,因为在备战期没有敌人)
|
||||
{ uuid: 6401, type: CardType.Skill, cost: 10, weight: 20, pool_lv: 1, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6401"), info: t("skill_info_6401"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6402, type: CardType.Skill, cost: 10, weight: 20, pool_lv: 1, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6402"), info: t("skill_info_6402"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6403, type: CardType.Skill, cost: 10, weight: 20, pool_lv: 1, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6403"), info: t("skill_info_6403"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6404, type: CardType.Skill, cost: 10, weight: 20, pool_lv: 1, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6404"), info: t("skill_info_6404"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6405, type: CardType.Skill, cost: 10, weight: 20, pool_lv: 2, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6405"), info: t("skill_info_6405"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6406, type: CardType.Skill, cost: 10, weight: 20, pool_lv: 2, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6406"), info: t("skill_info_6406"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6304, type: CardType.Skill, cost: 10, weight: 20, pool_lv: 3, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6304"), info: t("skill_info_6304"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6305, type: CardType.Skill, cost: 10, weight: 20, pool_lv: 3, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6305"), info: t("skill_info_6305"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
|
||||
// { uuid: 7101, type: CardType.SpecialRefresh, cost: 1, weight: 12, pool_lv: 1 ,kind: CKind.Card },
|
||||
// { uuid: 7102, type: CardType.SpecialRefresh, cost: 1, weight: 12, pool_lv: 1 ,kind: CKind.Card },
|
||||
// { uuid: 7103, type: CardType.SpecialRefresh, cost: 1, weight: 12, pool_lv: 1 ,kind: CKind.Card },
|
||||
]
|
||||
{ uuid: 6401, type: CardType.Skill, cost: 8, weight: 20, pool_lv: 1, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6401"), info: t("skill_info_6401"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6402, type: CardType.Skill, cost: 8, weight: 20, pool_lv: 1, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6402"), info: t("skill_info_6402"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6403, type: CardType.Skill, cost: 8, weight: 20, pool_lv: 1, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6403"), info: t("skill_info_6403"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6404, type: CardType.Skill, cost: 8, weight: 20, pool_lv: 1, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6404"), info: t("skill_info_6404"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6405, type: CardType.Skill, cost: 8, weight: 20, pool_lv: 2, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6405"), info: t("skill_info_6405"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6406, type: CardType.Skill, cost: 8, weight: 20, pool_lv: 2, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6406"), info: t("skill_info_6406"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6304, type: CardType.Skill, cost: 8, weight: 20, pool_lv: 3, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6304"), info: t("skill_info_6304"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
{ uuid: 6305, type: CardType.Skill, cost: 8, weight: 20, pool_lv: 3, kind: CKind.Skill, card_lv: 1, name: t("skill_name_6305"), info: t("skill_info_6305"), is_inst: true, t_times: 1, t_inv: 0 },
|
||||
);
|
||||
|
||||
|
||||
export enum SpecialRefreshHeroType {
|
||||
@@ -148,22 +162,22 @@ export interface SpecialRefreshCardConfig extends CardConfig {
|
||||
|
||||
|
||||
export const SpecialUpgradeCardList: Record<number, SpecialUpgradeCardConfig> = {
|
||||
7001: { uuid: 7001,type: CardType.SpecialUpgrade,cost: 6,weight: 16,pool_lv: CardLV.LV1,kind:CKind.Card,name:t("scard_name_7001"),info:t("scard_info_7001"),
|
||||
7001: { uuid: 7001,type: CardType.SpecialUpgrade,cost: 10,weight: 16,pool_lv: CardLV.LV1,kind:CKind.Card,name:t("scard_name_7001"),info:t("scard_info_7001"),
|
||||
currentLv: 1, targetLv: 2,
|
||||
},
|
||||
7002: { uuid: 7002,type: CardType.SpecialUpgrade,cost: 6,weight: 14,pool_lv: CardLV.LV2,kind:CKind.Card,name:t("scard_name_7002"),info:t("scard_info_7002"),
|
||||
7002: { uuid: 7002,type: CardType.SpecialUpgrade,cost: 28,weight: 14,pool_lv: CardLV.LV2,kind:CKind.Card,name:t("scard_name_7002"),info:t("scard_info_7002"),
|
||||
currentLv: 2, targetLv: 3,
|
||||
},
|
||||
}
|
||||
|
||||
export const SpecialRefreshCardList: Record<number, SpecialRefreshCardConfig> = {
|
||||
7101: { uuid: 7101,type: CardType.SpecialRefresh,cost: 4,weight: 14,pool_lv: CardLV.LV1,kind:CKind.Card,name:t("scard_name_7101"),info:t("scard_info_7101"),
|
||||
7101: { uuid: 7101,type: CardType.SpecialRefresh,cost: 3,weight: 14,pool_lv: CardLV.LV1,kind:CKind.Card,name:t("scard_name_7101"),info:t("scard_info_7101"),
|
||||
refreshLv: 0, refreshHeroType: SpecialRefreshHeroType.Melee,
|
||||
},
|
||||
7102: { uuid: 7102,type: CardType.SpecialRefresh,cost: 4,weight: 14,pool_lv: CardLV.LV1,kind:CKind.Card,name:t("scard_name_7102"),info:t("scard_info_7102"),
|
||||
7102: { uuid: 7102,type: CardType.SpecialRefresh,cost: 3,weight: 14,pool_lv: CardLV.LV1,kind:CKind.Card,name:t("scard_name_7102"),info:t("scard_info_7102"),
|
||||
refreshLv: 0, refreshHeroType: SpecialRefreshHeroType.Ranged,
|
||||
},
|
||||
7103: { uuid: 7103,type: CardType.SpecialRefresh,cost: 5,weight: 12,pool_lv: CardLV.LV2,kind:CKind.Card,name:t("scard_name_7103"),info:t("scard_info_7103"),
|
||||
7103: { uuid: 7103,type: CardType.SpecialRefresh,cost: 4,weight: 12,pool_lv: CardLV.LV2,kind:CKind.Card,name:t("scard_name_7103"),info:t("scard_info_7103"),
|
||||
refreshLv: 3, refreshHeroType: SpecialRefreshHeroType.Any,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ export enum FightSet {
|
||||
CSKILL_START_Y=30,
|
||||
SHIELD_MAX=5,
|
||||
WAVE_HEAL_RATE=0.5, // 回合结束时所有英雄恢复最大生命值的比例
|
||||
PUNCTURE_DOWN=50,
|
||||
}
|
||||
|
||||
export const laneIdx = {
|
||||
|
||||
@@ -33,7 +33,7 @@ export enum Attrs {
|
||||
knockback_distance = "knockback_distance", // 击退距离强化
|
||||
knockback_res = "knockback_res", // 击退抗性
|
||||
invincible_time = "invincible_time",// 无敌时间
|
||||
puncture = "puncture", // 穿刺次数
|
||||
puncture_chance = "puncture_chance", // 穿透概率
|
||||
wfuny = "wfuny", // 风怒
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ export enum SkillKind {
|
||||
Damage = 0,
|
||||
Heal = 1,
|
||||
Shield = 2,
|
||||
Support = 3
|
||||
Support = 3,
|
||||
Gold = 4
|
||||
}
|
||||
|
||||
|
||||
@@ -101,11 +102,7 @@ export enum IType {
|
||||
export const HeroSkillList = [6001,6001,6001,6001,6001,6001]
|
||||
|
||||
// Debuff配置接口
|
||||
|
||||
export interface BuffConf {
|
||||
buff:Attrs;
|
||||
value:number; // 效果值
|
||||
}
|
||||
// (已被废弃,采用平铺字段 buff_type 和 buff_value 代替)
|
||||
|
||||
interface IReady {
|
||||
uuid:number,
|
||||
@@ -133,6 +130,7 @@ export interface SkillConfig {
|
||||
act:string, // 角色执行的动画
|
||||
DTType:DTType, // 伤害类型(单体/范围)
|
||||
ap:number, // 伤害/治疗技能为攻击百分比,护盾技能为免疫次数
|
||||
gold?:number, // 获取金币技能的金币值
|
||||
hit_count:number, // 可命中次数
|
||||
hitcd:number, // 持续伤害的伤害间隔(秒)
|
||||
speed:number, // 移动速度
|
||||
@@ -153,11 +151,37 @@ export interface SkillConfig {
|
||||
crt?:number, // 额外暴击率
|
||||
frz?:number, // 额外冰冻概率
|
||||
bck?:number, // 额外击退概率
|
||||
buffs:BuffConf[], // 对目标应用的 buff 配置列表
|
||||
buff_type?:Attrs, // Buff 类型 (单一职责)
|
||||
call_hero?:number, // 召唤技能召唤英雄id(可选)
|
||||
info:string, // 技能描述
|
||||
}
|
||||
|
||||
export interface SkillOverrides {
|
||||
TGroup?: TGroup;
|
||||
ap?: number;
|
||||
gold?: number;
|
||||
hit_count?: number;
|
||||
hitcd?: number;
|
||||
crt?: number;
|
||||
frz?: number;
|
||||
bck?: number;
|
||||
buff_type?: Attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将覆盖参数合并到基础技能配置中
|
||||
* @param config 基础技能配置
|
||||
* @param overrides 技能覆盖参数
|
||||
* @returns 合并后的新技能配置
|
||||
*/
|
||||
export function mergeSkillParams(config: SkillConfig, overrides?: SkillOverrides): SkillConfig {
|
||||
if (!overrides) return config;
|
||||
return {
|
||||
...config,
|
||||
...overrides
|
||||
};
|
||||
}
|
||||
|
||||
export const SkillUpList = {
|
||||
1001:{ap:0,hit_count:0,buff_ap:0,buff_hp:0,bck:0,frz:0,crt:0,num:0}
|
||||
}
|
||||
@@ -174,153 +198,158 @@ export const SkillSet: Record<number, SkillConfig> = {
|
||||
6001: {
|
||||
uuid:6001,name:"普通攻击",sp_name:"atk",icon:"1026",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.Melee,
|
||||
RType:RType.linear,EType:EType.collision,buffs:[],info:"造成攻击力100%的伤害",
|
||||
RType:RType.linear,EType:EType.collision,info:"造成攻击力100%的伤害",
|
||||
},
|
||||
6002: {
|
||||
uuid:6002,name:"光箭蓝",sp_name:"atk_c1",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.bezier,EType:EType.collision,buffs:[],info:"近战普通攻击技能",
|
||||
RType:RType.bezier,EType:EType.collision,info:"近战普通攻击技能",
|
||||
},
|
||||
6003: {
|
||||
uuid:6003,name:"光箭红",sp_name:"atk_c2",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.bezier,EType:EType.collision,buffs:[],info:"一定几率暴击",
|
||||
RType:RType.bezier,EType:EType.collision,info:"一定几率暴击",
|
||||
},
|
||||
6004: {
|
||||
uuid:6004,name:"光箭绿",sp_name:"atk_c3",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.bezier,EType:EType.collision,buffs:[],info:"一定几率击退目标",
|
||||
RType:RType.bezier,EType:EType.collision,info:"一定几率击退目标",
|
||||
},
|
||||
//怪物战士类型统一使用 6005
|
||||
6005: {
|
||||
uuid:6005,name:"光箭深红",sp_name:"atk_c4",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.bezier,EType:EType.collision,buffs:[],info:"一定几率击退目标",
|
||||
RType:RType.bezier,EType:EType.collision,info:"一定几率击退目标",
|
||||
},
|
||||
6006: {
|
||||
uuid:6006,name:"光箭灰白",sp_name:"atk_c5",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.bezier,EType:EType.collision,buffs:[],info:"一定几率击退目标",
|
||||
RType:RType.bezier,EType:EType.collision,info:"一定几率击退目标",
|
||||
},
|
||||
6007: {
|
||||
uuid:6007,name:"水球",sp_name:"ball_water",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.bezier,EType:EType.collision,buffs:[],info:"一定几率冰冻目标",
|
||||
RType:RType.bezier,EType:EType.collision,info:"一定几率冰冻目标",
|
||||
},
|
||||
6008: {
|
||||
uuid:6008,name:"箭矢",sp_name:"arrow",icon:"1135",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,buffs:[],info:"造成攻击力100%的伤害",
|
||||
RType:RType.bezier,EType:EType.collision,bezier_start_y:20,bezier_mid_y:140,bezier_arc:1.05,info:"造成攻击力100%的伤害",
|
||||
},
|
||||
6009: {
|
||||
uuid:6009,name:"箭矢蓝",sp_name:"arrow_blue",icon:"1135",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,buffs:[],info:"造成攻击力100%的伤害",
|
||||
RType:RType.bezier,EType:EType.collision,bezier_start_y:20,bezier_mid_y:140,bezier_arc:1.05,info:"造成攻击力100%的伤害",
|
||||
},
|
||||
6010: {
|
||||
uuid:6010,name:"箭矢红",sp_name:"arrow_red",icon:"1135",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,buffs:[],info:"造成攻击力100%的伤害",
|
||||
RType:RType.bezier,EType:EType.collision,bezier_start_y:20,bezier_mid_y:140,bezier_arc:1.05,info:"造成攻击力100%的伤害",
|
||||
},
|
||||
|
||||
6101: {
|
||||
uuid:6101,name:"火球",sp_name:"ball_fire",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,frz:0,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.linear,EType:EType.collision,buffs:[],info:"造成攻击力100%的伤害,一定几率暴击,高阶技能",
|
||||
RType:RType.linear,EType:EType.collision,info:"造成攻击力100%的伤害,一定几率暴击,高阶技能",
|
||||
},
|
||||
6102: {
|
||||
uuid:6102,name:"龙卷风",sp_name:"ball_winds",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.linear,EType:EType.collision,buffs:[],info:"造成攻击力100%的伤害,一定几率击退目标,高阶技能",
|
||||
RType:RType.linear,EType:EType.collision,info:"造成攻击力100%的伤害,一定几率击退目标,高阶技能",
|
||||
},
|
||||
//怪物法师统一使用 暗影球
|
||||
6103: {
|
||||
uuid:6103,name:"暗影球",sp_name:"ball_zi",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.linear,EType:EType.collision,buffs:[],info:"造成攻击力100%的伤害,一定几率上毒(后期加入),高阶技能 ",
|
||||
RType:RType.linear,EType:EType.collision,info:"造成攻击力100%的伤害,一定几率上毒(后期加入),高阶技能 ",
|
||||
},
|
||||
6104: {
|
||||
uuid:6104,name:"穿云箭",sp_name:"arrow_big_yellow",icon:"1135",TGroup:TGroup.Enemy,readyAnm:"yellow",endAnm:"",act:"max",
|
||||
DTType:DTType.single,crt:20,ap:100,hit_count:6,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.linear,EType:EType.collision,buffs:[],info:"射出强力箭矢,最多穿透6个敌人,附带20%额外暴击率",
|
||||
RType:RType.linear,EType:EType.collision,info:"射出强力箭矢,最多穿透6个敌人,附带20%额外暴击率",
|
||||
},
|
||||
6105: {
|
||||
uuid:6105,name:"冰刺",sp_name:"ice_up",icon:"1173",TGroup:TGroup.Enemy,readyAnm:"blues",endAnm:"",act:"max",
|
||||
DTType:DTType.range,frz:0,ap:150,hit_count:6,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.fixedEnd,EType:EType.animationEnd,buffs:[],info:"召唤冰刺攻击一排的敌人,有概率冰冻",
|
||||
RType:RType.fixedEnd,EType:EType.animationEnd,info:"召唤冰刺攻击一排的敌人,有概率冰冻",
|
||||
},
|
||||
6106: {
|
||||
uuid:6106,name:"冰推",sp_name:"ice_t",icon:"1173",TGroup:TGroup.Enemy,readyAnm:"blues",endAnm:"",act:"max",
|
||||
DTType:DTType.range,frz: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,buffs:[],info:"召唤冰墙阻挡敌人,有概率冰冻,100%击退",
|
||||
RType:RType.fixed,EType:EType.animationEnd,info:"召唤冰墙阻挡敌人,有概率冰冻,100%击退",
|
||||
},
|
||||
6107: {
|
||||
uuid:6107,name:"陨石",sp_name:"fire_yuns",icon:"1173",TGroup:TGroup.Enemy,readyAnm:"reds",endAnm:"",act:"max",
|
||||
DTType:DTType.range,crt:20,ap:150,hit_count:6,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote,
|
||||
RType:RType.fixedEnd,EType:EType.animationEnd,buffs:[],info:"召唤攻击敌人,造成攻击力150%的范围伤害,附带20%额外暴击率",
|
||||
RType:RType.fixedEnd,EType:EType.animationEnd,info:"召唤攻击敌人,造成攻击力150%的范围伤害,附带20%额外暴击率",
|
||||
},
|
||||
|
||||
//============================= ====== 辅助技能 ====== ==========================
|
||||
6301:{
|
||||
uuid:6301,name:"护盾",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Self,readyAnm:"up_blue",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Shield,ap:3,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[],info:"为自己添加护盾,可抵挡3次伤害",
|
||||
RType:RType.fixed,EType:EType.animationEnd,info:"为伙伴/自己添加护盾,可抵挡3次伤害",
|
||||
},
|
||||
6302: {
|
||||
uuid:6302,name:"群体治疗",sp_name:"buff_wind",icon:"1292",TGroup:TGroup.Team,readyAnm:"up_green",endAnm:"",act:"atk",
|
||||
uuid:6302,name:"治疗",sp_name:"buff_wind",icon:"1292",TGroup:TGroup.Team,readyAnm:"up_green",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Heal,ap:300,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[],info:"为全体友方恢复攻击力300%的生命值",
|
||||
RType:RType.fixed,EType:EType.animationEnd,info:"治疗伙伴/自己",
|
||||
},
|
||||
6303:{
|
||||
uuid:6303,name:"强化护盾",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Self,readyAnm:"up_blue",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Shield,ap:3,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[],info:"为自己添加强化护盾,可抵挡3次伤害",
|
||||
},
|
||||
6304: {
|
||||
uuid:6304,name:"持续恢复",sp_name:"buff_wind",icon:"1292",TGroup:TGroup.Team,readyAnm:"up_green",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Heal,ap:200,hit_count:3,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[],info:"为全体友方持续恢复,共3次,每次恢复攻击力200%的生命值",
|
||||
},
|
||||
6305:{
|
||||
uuid:6305,name:"团队护盾",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_blue",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Shield,ap:2,hit_count:3,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[],info:"为全体友方添加护盾,每人可抵挡2次伤害,持续3次",
|
||||
6303: {
|
||||
uuid:6303,name:"获取金币",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Self,readyAnm:"up_blue",endAnm:"gold",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Gold,ap:0,gold:10,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,info:"增加一定数量的金币",
|
||||
},
|
||||
//==========================buff 技能=====================
|
||||
6401:{
|
||||
uuid:6401,name:"攻击强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_ap",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:0,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[{buff:Attrs.ap,value:5}],info:"全体友方攻击力提升5点,持续1次",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:5,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buff_type:Attrs.ap,info:"全体友方攻击力提升5点,持续1次",
|
||||
},
|
||||
6402:{
|
||||
uuid:6402,name:"生命强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_hp",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:0,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[{buff:Attrs.hp_max,value:20}],info:"全体友方最大生命值提升20点,持续1次",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:20,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buff_type:Attrs.hp_max,info:"全体友方最大生命值提升20点,持续1次",
|
||||
},
|
||||
6403:{
|
||||
uuid:6403,name:"全面强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_hp",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:0,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[{buff:Attrs.ap,value:5},{buff:Attrs.hp_max,value:20}],info:"全体友方攻击力提升5点,最大生命值提升20点,持续1次",
|
||||
uuid:6403,name:"暴击强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_ap",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:1,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buff_type:Attrs.critical,info:"全体友方暴击率提升10%,持续1次",
|
||||
},
|
||||
6404:{
|
||||
uuid:6404,name:"持续攻击强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_ap",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:0,hit_count:3,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[{buff:Attrs.ap,value:2}],info:"全体友方攻击力提升2点,持续3次",
|
||||
uuid:6404,name:"暴伤强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_ap",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:1,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buff_type:Attrs.critical_damage,info:"全体友方暴击伤害提升20%,持续1次",
|
||||
},
|
||||
6405:{
|
||||
uuid:6405,name:"持续生命强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_hp",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:0,hit_count:3,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[{buff:Attrs.hp_max,value:10}],info:"全体友方最大生命值提升10点,持续3次",
|
||||
uuid:6405,name:"冰冻强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_blue",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:1,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buff_type:Attrs.freeze_chance,info:"全体友方冰冻概率提升10%,持续1次",
|
||||
},
|
||||
6406:{
|
||||
uuid:6406,name:"持续全面强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_ap",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:0,hit_count:3,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[{buff:Attrs.ap,value:2},{buff:Attrs.hp_max,value:10}],info:"全体友方攻击力提升2点,最大生命值提升10点,持续3次",
|
||||
uuid:6406,name:"击退强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_blue",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:1,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buff_type:Attrs.knockback_chance,info:"全体友方击退概率提升10%,持续1次",
|
||||
},
|
||||
6407:{
|
||||
uuid:6407,name:"距推强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_blue",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:1,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buff_type:Attrs.knockback_distance,info:"全体友方击退距离提升20点,持续1次",
|
||||
},
|
||||
6408:{
|
||||
uuid:6408,name:"穿刺强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_ap",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:20,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buff_type:Attrs.puncture_chance,info:"全体友方穿透概率提升20%,持续1次",
|
||||
},
|
||||
6409:{
|
||||
uuid:6409,name:"风怒强化",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Team,readyAnm:"up_ap",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:1,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buff_type:Attrs.wfuny,info:"全体友方风怒次数提升1次,持续1次",
|
||||
},
|
||||
6501:{
|
||||
uuid:6501,name:"复活",sp_name:"buff_wind",icon:"1255",TGroup:TGroup.Self,readyAnm:"up_ap",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,kind:SkillKind.Support,ap:50,hit_count:3,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.support,
|
||||
RType:RType.fixed,EType:EType.animationEnd,buffs:[],info:"ap 代表复活的生命值百分比",
|
||||
RType:RType.fixed,EType:EType.animationEnd,info:"ap 代表复活的生命值百分比",
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { v3 } from "cc"
|
||||
import { BoxSet, FacSet } from "./GameSet"
|
||||
import { SkillOverrides, TGroup } from "./SkillSet"
|
||||
|
||||
export enum HType {
|
||||
Melee = 0,
|
||||
@@ -83,100 +84,328 @@ export interface heroInfo {
|
||||
fac: FacSet; // 阵营(FacSet.HERO 或 FacSet.MON)
|
||||
kind?: number; // 未使用
|
||||
lv: number; // 英雄等级
|
||||
cards_lv?: number; // 卡片等级
|
||||
pool_lv?: number; // 卡片等级
|
||||
type: HType; // 攻击定位(近战/中程/远程)
|
||||
hp: number; // 生命值上限
|
||||
ap: number; // 攻击力
|
||||
call?:number[]; // 召唤后触发的技能uuid列表
|
||||
dead?:number[]; // 死亡后触发的技能uuid列表
|
||||
fstart?:number[]; // 战斗开始时释放的技能uuid列表
|
||||
fend?:number[]; // 战斗结束时释放的技能uuid列表
|
||||
call?:{s_uuid:number, t_num:number, overrides?: SkillOverrides}[]; // 召唤后触发的技能配置
|
||||
dead?:{s_uuid:number, t_num:number, overrides?: SkillOverrides}[]; // 死亡后触发的技能配置
|
||||
fstart?:{s_uuid:number, t_num:number, overrides?: SkillOverrides}[]; // 战斗开始时释放的技能配置
|
||||
fend?:{s_uuid:number, t_num:number, overrides?: SkillOverrides}[]; // 战斗结束时释放的技能配置
|
||||
field?:number[]; // 驻场技能uuid列表,英雄在场时对全局生效
|
||||
atking?:{s_uuid:number, t_num:number}[]; // 普通攻击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的普攻次数
|
||||
atked?:{s_uuid:number, t_num:number}[]; // 受击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的受击次数
|
||||
atking?:{s_uuid:number, t_num:number, overrides?: SkillOverrides}[]; // 普通攻击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的普攻次数
|
||||
atked?:{s_uuid:number, t_num:number, overrides?: SkillOverrides}[]; // 受击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的受击次数
|
||||
revive?:{s_uuid:number,r_num:number,upr:number}; // 复活技能配置,s_uuid: 技能id, r_num: 触发所需的复活次数, upr 等级对复活次数的影响
|
||||
dis?: number; // 攻击距离(像素)
|
||||
dis?: number; // 攻击距离(像素)
|
||||
speed?: number; // 移动速度(像素/秒)
|
||||
skills: Record<number, HSkillInfo> ; // 携带技能ID列表
|
||||
info: string; // 描述文案
|
||||
}
|
||||
/**
|
||||
* 英雄/怪物基础信息接口
|
||||
* 技能基础信息接口
|
||||
*/
|
||||
export interface HSkillInfo {
|
||||
uuid: number; // 唯一标识(英雄5000段,怪物5200段)
|
||||
uuid: number; // 唯一标识(技能6000段等)
|
||||
lv:number; // 技能等级
|
||||
cd:number; // 技能cd
|
||||
ccd:number; // 占位当前cd,用于cd计时
|
||||
overrides?: SkillOverrides; // 角色专属参数覆盖
|
||||
}
|
||||
/*
|
||||
*=============英雄配置列表================
|
||||
* 英雄规则设定
|
||||
* 战士 专注 受攻击触发技能
|
||||
* 射手 专注 施法触发技能
|
||||
* 法师 专注 战斗开始触发技能
|
||||
* 辅助 专注 战斗结束触发技能
|
||||
*
|
||||
*=============英雄配置列表================
|
||||
* 职业触发规则 (v3)
|
||||
* 战士 专注 atked(受击) + dead(死亡) 触发 — 承伤坦克定位
|
||||
* 刺客 专注 atking(攻击) + dead(死亡) 触发 — 高风险高回报近战
|
||||
* 射手 专注 atking(攻击) + fstart(战前) 触发 — 稳定远程输出
|
||||
* 法师 专注 atking(攻击) + field(驻场) 触发 — 魔法输出+被动光环
|
||||
* 辅助 专注 atking(攻击) + revive(复活) 触发 — 战斗支援
|
||||
*
|
||||
* 设定中的英雄都是1级,最高可以升级到3级(不在列表内提现,升级在游戏内进行)
|
||||
* skills[0]是普通攻击技能
|
||||
* skills[1]是等级2时的技能,skills[2]是等级3时的技能
|
||||
*
|
||||
* 属性基准(cards_lv:1,lv:1) : SPEED:800, AP:30 | HP:300 | skills[0].cd = 1.0 (普通)
|
||||
* 坦克(cards_lv:1,lv:1) : SPEED:800, AP:25 | HP:450 | skills[0].cd = 2.3 或 2.8 (很慢+/很慢) - 突出沉重感与承伤定位
|
||||
* 近战dps(cards_lv:1,lv:1) : SPEED:800, AP:50 | HP:250 | skills[0].cd = 0.3 或 0.5 (极速/快速+) - 强化割草连击爽感
|
||||
* 远程dps(cards_lv:1,lv:1) : SPEED:800, AP:60 | HP:150 | skills[0].cd = 0.7 或 0.9 (快速/普通+) - 稳定持续的物理输出节奏
|
||||
*远程法dps(cards_lv:1,lv:1) : SPEED:800, AP:60 | HP:150 | skills[0].cd = 1.5 或 1.8 (慢+/慢) - 强调施法前摇与单发爆发
|
||||
* 远程辅助(cards_lv:1,lv:1) : SPEED:800, AP:20 | HP:150 | skills[0].cd = 1.1 (普通) - 贴近基准,动作不急不躁,侧重技能
|
||||
*
|
||||
* 属性基准(pool_lv:1,lv:1) : SPEED:800, AP:30 | HP:300 | skills[0].cd = 1.0 (普通)
|
||||
* 坦克(pool_lv:1,lv:1) : SPEED:800, AP:25 | HP:450 | skills[0].cd = 2.3 或 2.8 (很慢+/很慢) - 突出沉重感与承伤定位
|
||||
* 近战dps(pool_lv:1,lv:1) : SPEED:800, AP:50 | HP:250 | skills[0].cd = 0.3 或 0.5 (极速/快速+) - 强化割草连击爽感
|
||||
* 远程dps(pool_lv:1,lv:1) : SPEED:800, AP:60 | HP:150 | skills[0].cd = 0.7 或 0.9 (快速/普通+) - 稳定持续的物理输出节奏
|
||||
*远程法dps(pool_lv:1,lv:1) : SPEED:800, AP:60 | HP:150 | skills[0].cd = 1.5 或 1.8 (慢+/慢) - 强调施法前摇与单发爆发
|
||||
* 远程辅助(pool_lv:1,lv:1) : SPEED:800, AP:20 | HP:150 | skills[0].cd = 1.1 (普通) - 贴近基准,动作不急不躁,侧重技能
|
||||
*/
|
||||
|
||||
export const HeroInfo: Record<number, heroInfo> = {
|
||||
// ========== 近战英雄 ==========
|
||||
5001:{uuid:5001,name:"见习战士",path:"hk2", fac:FacSet.HERO,cards_lv:1,lv:1,type:HType.Melee,hp:150,ap:25,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:1.5,ccd:0}},atking:[{s_uuid:6301,t_num:2}],info:" "},
|
||||
5002:{uuid:5002,name:"盾骑士",path:"hk1", fac:FacSet.HERO,cards_lv:3,lv:1,type:HType.Melee,hp:150,ap:75,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:1.5,ccd:0}},atked:[{s_uuid:6301,t_num:2}],info:" "},
|
||||
5003:{uuid:5003,name:"战士3",path:"hk3", fac:FacSet.HERO,cards_lv:2,lv:1,type:HType.Melee,hp:100,ap:100,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:1.5,ccd:0}},info:" "},
|
||||
5004:{uuid:5004,name:"战士4",path:"hk4", fac:FacSet.HERO,cards_lv:4,lv:1,type:HType.Melee,hp:100,ap:200,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:0.7,ccd:0}},info:" "},
|
||||
5005:{uuid:5005,name:"战士5",path:"hk5", fac:FacSet.HERO,cards_lv:4,lv:1,type:HType.Melee,hp:100,ap:200,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:1.5,ccd:0}},info:" "},
|
||||
// ========== 铁壁反伤流 (保留原有 5001, 5002) ==========
|
||||
5001:{uuid:5001,name:"见习战士",path:"hk2", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Melee,hp:150,ap:25,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:1.5,ccd:0}},
|
||||
atked:[{s_uuid:6301,t_num:2}],
|
||||
info:" "},
|
||||
5002:{uuid:5002,name:"盾骑士",path:"hk1", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Melee,hp:150,ap:75,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:1.5,ccd:0}},
|
||||
atked:[{s_uuid:6301,t_num:2,overrides:{TGroup:TGroup.Team,ap:2,hit_count:3}}],
|
||||
info:" "},
|
||||
|
||||
/*
|
||||
// 废弃旧英雄
|
||||
5003:{uuid:5003,name:"战士3",path:"hk3", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Melee,hp:100,ap:100,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:1.5,ccd:0}},
|
||||
info:" "},
|
||||
5004:{uuid:5004,name:"战士4",path:"hk4", fac:FacSet.HERO,pool_lv:4,lv:1,type:HType.Melee,hp:100,ap:200,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:0.7,ccd:0}},
|
||||
info:" "},
|
||||
5005:{uuid:5005,name:"战士5",path:"hk5", fac:FacSet.HERO,pool_lv:4,lv:1,type:HType.Melee,hp:100,ap:200,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:1.5,ccd:0}},
|
||||
info:" "},
|
||||
*/
|
||||
|
||||
// ========== 法师英雄 ==========
|
||||
5101:{uuid:5101,name:"奥术法师",path:"hm2", fac:FacSet.HERO,cards_lv:1,lv:1,type:HType.Long,hp:150,ap:60,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1,ccd:0}},revive:{s_uuid:6501,r_num:1,upr:0.5},info:""},
|
||||
5102:{uuid:5102,name:"火焰法师",path:"hm1", fac:FacSet.HERO,cards_lv:2,lv:1,type:HType.Long,hp:130,ap:120,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1,ccd:0}},info:""},
|
||||
5103:{uuid:5103,name:"冰法法师",path:"hm3", fac:FacSet.HERO,cards_lv:3,lv:1,type:HType.Long,hp:145,ap:180,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1,ccd:0}},info:""},
|
||||
5104:{uuid:5104,name:"寒霜术士",path:"hm5", fac:FacSet.HERO,cards_lv:4,lv:1,type:HType.Long,hp:160,ap:240,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1,ccd:0}},info:""},
|
||||
5105:{uuid:5105,name:"炎爆法师",path:"hm4", fac:FacSet.HERO,cards_lv:5,lv:1,type:HType.Long,hp:175,ap:300,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1,ccd:0}},info:"" },
|
||||
|
||||
// ========== 远程英雄 ==========
|
||||
5201:{uuid:5201,name:"射手",path:"ha1", fac:FacSet.HERO,cards_lv:1,lv:1,type:HType.Long,hp:115,ap:60,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.9,ccd:0}},info:""},
|
||||
5202:{uuid:5202,name:"游侠2",path:"ha2", fac:FacSet.HERO,cards_lv:3,lv:1,type:HType.Long,hp:145,ap:180,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.9,ccd:0}},info:""},
|
||||
5203:{uuid:5203,name:"游侠3",path:"ha3", fac:FacSet.HERO,cards_lv:3,lv:1,type:HType.Long,hp:145,ap:180,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.9,ccd:0}},info:""},
|
||||
5204:{uuid:5204,name:"游侠4",path:"ha4", fac:FacSet.HERO,cards_lv:3,lv:1,type:HType.Long,hp:145,ap:180,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.9,ccd:0}},info:""},
|
||||
|
||||
// ========== 辅助英雄 ==========
|
||||
5301:{uuid:5301,name:"牧师",path:"hh1", fac:FacSet.HERO,cards_lv:1,lv:1,type:HType.Long,hp:115,ap:50,
|
||||
skills:{6004:{uuid:6004,lv:1,cd:1.2,ccd:0}},atking:[{s_uuid:6302,t_num:2}],info:"" },
|
||||
5302:{uuid:5302,name:"医师",path:"hh2", fac:FacSet.HERO,cards_lv:2,lv:1,type:HType.Long,hp:130,ap:50,
|
||||
skills:{6004:{uuid:6004,lv:1,cd:1.2,ccd:0}}, atking:[{s_uuid:6304,t_num:2}],info:""},
|
||||
// ========== 攻速叠伤流 ==========
|
||||
5006:{uuid:5006,name:"疾风刺客",path:"hk3", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Melee,
|
||||
hp:200,ap:35,
|
||||
skills:{6001:{uuid:6001,lv:1,cd:0.3,ccd:0}},
|
||||
atking:[{s_uuid:6401,t_num:1,overrides:{TGroup:TGroup.Self,ap:5}}],
|
||||
dead:[{s_uuid:6401,t_num:1,overrides:{TGroup:TGroup.Team,ap:8}}],
|
||||
info:"极速攻速近战,每次攻击给自己叠攻击,死亡时把力量传给全队"},
|
||||
|
||||
5205:{uuid:5205,name:"暴风射手",path:"ha3", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Long,
|
||||
hp:180,ap:55,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:0.5,ccd:0}},
|
||||
atking:[{s_uuid:6403,t_num:2}],
|
||||
info:"远程快速射击,每2次攻击为全队叠加暴击率"},
|
||||
|
||||
// ========== 辅助英雄 ==========
|
||||
5401:{uuid:5401,name:"刺客1",path:"hc1", fac:FacSet.HERO,cards_lv:1,lv:1,type:HType.Long,hp:115,ap:50,
|
||||
skills:{6006:{uuid:6006,lv:1,cd:1.2,ccd:0}},atking:[{s_uuid:6302,t_num:2}],info:"" },
|
||||
5402:{uuid:5402,name:"刺客2",path:"hc2", fac:FacSet.HERO,cards_lv:2,lv:1,type:HType.Long,hp:130,ap:50,
|
||||
skills:{6006:{uuid:6006,lv:1,cd:1.2,ccd:0}},atking:[{s_uuid:6304,t_num:2}],info:""},
|
||||
5403:{uuid:5403,name:"嗜血剑圣",path:"hc1", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Melee,
|
||||
hp:280,ap:90,
|
||||
skills:{6001:{uuid:6001,lv:1,cd:0.7,ccd:0}},
|
||||
atking:[{s_uuid:6401,t_num:1,overrides:{TGroup:TGroup.Self,ap:8}}],
|
||||
dead:[{s_uuid:6401,t_num:1,overrides:{TGroup:TGroup.Team,ap:10}}],
|
||||
info:"每次攻击给自己叠攻击,死亡时把力量传给全队"},
|
||||
|
||||
// ========== 铁壁反伤流 (新加) ==========
|
||||
5007:{uuid:5007,name:"盾卫",path:"hk1", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Melee,
|
||||
hp:450,ap:25,
|
||||
skills:{6001:{uuid:6001,lv:1,cd:2.3,ccd:0}},
|
||||
atked:[{s_uuid:6301,t_num:2}],
|
||||
info:"高血量坦克,受击2次自动加护盾"},
|
||||
|
||||
5008:{uuid:5008,name:"守护骑士",path:"hk2", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Melee,
|
||||
hp:500,ap:20,
|
||||
skills:{6001:{uuid:6001,lv:1,cd:2.3,ccd:0}},
|
||||
atked:[{s_uuid:6301,t_num:2,overrides:{TGroup:TGroup.Team,ap:2,hit_count:2}}],
|
||||
info:"受击时为全队加护盾,越被围殴全队越安全"},
|
||||
|
||||
5009:{uuid:5009,name:"不屈战神",path:"hk4", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Melee,
|
||||
hp:600,ap:30,
|
||||
skills:{6001:{uuid:6001,lv:1,cd:2.8,ccd:0}},
|
||||
atked:[
|
||||
{s_uuid:6301,t_num:1,overrides:{TGroup:TGroup.Self,ap:4}},
|
||||
{s_uuid:6402,t_num:3}
|
||||
],
|
||||
dead:[{s_uuid:6402,t_num:1,overrides:{ap:40}}],
|
||||
info:"血量最厚的前排,受击加盾+全队加血,死亡时给全队巨额生命强化"},
|
||||
|
||||
|
||||
// ========== 法师英雄 (保留 5101) ==========
|
||||
5101:{uuid:5101,name:"奥术法师",path:"hm2", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Long,hp:150,ap:60,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1,ccd:0}},
|
||||
field:[6401],
|
||||
atking:[{s_uuid:6401,t_num:2,overrides:{ap:3}}],
|
||||
info:"驻场提供攻击力光环,每2次攻击为全队叠加攻击力"},
|
||||
/*
|
||||
// 废弃旧英雄
|
||||
5102:{uuid:5102,name:"火焰法师",path:"hm1", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Long,hp:130,ap:120,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1,ccd:0}},
|
||||
info:""},
|
||||
5103:{uuid:5103,name:"冰法法师",path:"hm3", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Long,hp:145,ap:180,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1,ccd:0}},
|
||||
info:""},
|
||||
5104:{uuid:5104,name:"寒霜术士",path:"hm5", fac:FacSet.HERO,pool_lv:4,lv:1,type:HType.Long,hp:160,ap:240,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1,ccd:0}},
|
||||
info:""},
|
||||
5105:{uuid:5105,name:"炎爆法师",path:"hm4", fac:FacSet.HERO,pool_lv:5,lv:1,type:HType.Long,hp:175,ap:300,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1,ccd:0}},
|
||||
info:"" },
|
||||
*/
|
||||
|
||||
// ========== 冰冻控制流 (新加) ==========
|
||||
5106:{uuid:5106,name:"寒冰学徒",path:"hm3", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Long,
|
||||
hp:130,ap:50,
|
||||
skills:{6007:{uuid:6007,lv:1,cd:1.5,ccd:0}},
|
||||
field:[6405],
|
||||
atking:[{s_uuid:6405,t_num:2}],
|
||||
info:"驻场提供冰冻光环,每2次普攻叠加冰冻概率"},
|
||||
|
||||
5107:{uuid:5107,name:"霜寒法师",path:"hm5", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Long,
|
||||
hp:160,ap:80,
|
||||
skills:{6007:{uuid:6007,lv:1,cd:1.0,ccd:0}},
|
||||
field:[6405],
|
||||
atking:[{s_uuid:6105,t_num:2,overrides:{ap:120,frz:25}}],
|
||||
info:"驻场冰冻光环,每2次攻击触发冰刺AOE,25%冰冻概率冻住一排敌人"},
|
||||
|
||||
5108:{uuid:5108,name:"永冬贤者",path:"hm4", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Long,
|
||||
hp:250,ap:110,
|
||||
skills:{6007:{uuid:6007,lv:1,cd:1.8,ccd:0}},
|
||||
field:[6405],
|
||||
atking:[{s_uuid:6105,t_num:1,overrides:{ap:150,frz:35,hit_count:8}}],
|
||||
info:"驻场强力冰冻光环,每次攻击释放冰刺,35%冰冻概率"},
|
||||
|
||||
/*
|
||||
// ========== 远程英雄 (旧) ==========
|
||||
5201:{uuid:5201,name:"射手",path:"ha1", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Long,hp:115,ap:60,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.9,ccd:0}},
|
||||
info:""},
|
||||
5202:{uuid:5202,name:"游侠2",path:"ha2", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Long,hp:145,ap:180,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.9,ccd:0}},
|
||||
info:""},
|
||||
5203:{uuid:5203,name:"游侠3",path:"ha3", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Long,hp:145,ap:180,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.9,ccd:0}},
|
||||
info:""},
|
||||
5204:{uuid:5204,name:"游侠4",path:"ha4", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Long,hp:145,ap:180,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.9,ccd:0}},
|
||||
info:""},
|
||||
*/
|
||||
|
||||
// ========== 辅助英雄 (保留 5301, 5302) ==========
|
||||
5301:{uuid:5301,name:"牧师",path:"hh1", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Long,hp:115,ap:50,
|
||||
skills:{6004:{uuid:6004,lv:1,cd:1.2,ccd:0}},
|
||||
atking:[{s_uuid:6302,t_num:2}],
|
||||
info:"" },
|
||||
5302:{uuid:5302,name:"医师",path:"hh2", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Long,hp:130,ap:50,
|
||||
skills:{6004:{uuid:6004,lv:1,cd:1.2,ccd:0}},
|
||||
atking:[{s_uuid:6302,t_num:2,overrides:{hit_count:3,ap:200}}],
|
||||
info:""},
|
||||
|
||||
// ========== 治疗续航流 (新加) ==========
|
||||
5303:{uuid:5303,name:"见习牧师",path:"hh1", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Long,
|
||||
hp:120,ap:40,
|
||||
skills:{6004:{uuid:6004,lv:1,cd:1.1,ccd:0}},
|
||||
atking:[{s_uuid:6302,t_num:2}],
|
||||
info:"每2次普攻后治疗全队,恢复攻击力300%的生命值"},
|
||||
|
||||
5304:{uuid:5304,name:"神圣医师",path:"hh2", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Long,
|
||||
hp:150,ap:50,
|
||||
skills:{6004:{uuid:6004,lv:1,cd:0.9,ccd:0}},
|
||||
atking:[{s_uuid:6302,t_num:2,overrides:{hit_count:3,ap:200}}],
|
||||
revive:{s_uuid:6501,r_num:1,upr:0.3},
|
||||
info:"持续治疗,每2次普攻触发3次群体治疗,死后可复活一次继续治疗"},
|
||||
|
||||
5305:{uuid:5305,name:"生命贤者",path:"hh3", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Long,
|
||||
hp:200,ap:70,
|
||||
skills:{6004:{uuid:6004,lv:1,cd:1.0,ccd:0}},
|
||||
atking:[{s_uuid:6302,t_num:1,overrides:{ap:250}}],
|
||||
revive:{s_uuid:6501,r_num:1,upr:0.5},
|
||||
info:"每次普攻后全队治疗250%攻击力,死后复活一次继续治疗"},
|
||||
|
||||
/*
|
||||
// ========== 刺客英雄 (旧) ==========
|
||||
5401:{uuid:5401,name:"刺客1",path:"hc1", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Long,hp:115,ap:50,
|
||||
skills:{6006:{uuid:6006,lv:1,cd:1.2,ccd:0}},
|
||||
atking:[{s_uuid:6302,t_num:2}],
|
||||
info:"" },
|
||||
5402:{uuid:5402,name:"刺客2",path:"hc2", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Long,hp:130,ap:50,
|
||||
skills:{6006:{uuid:6006,lv:1,cd:1.2,ccd:0}},
|
||||
atking:[{s_uuid:6304,t_num:2}],
|
||||
info:""},
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// ========== 击退推拉流 ==========
|
||||
5209:{uuid:5209,name:"风弓手",path:"ha2", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Long,
|
||||
hp:140,ap:45,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.7,ccd:0}},
|
||||
atking:[{s_uuid:6406,t_num:2}],
|
||||
info:"快速射击,每2次攻击为全队叠加击退概率"},
|
||||
|
||||
5210:{uuid:5210,name:"龙卷猎手",path:"ha3", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Long,
|
||||
hp:170,ap:70,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.9,ccd:0}},
|
||||
atking:[{s_uuid:6102,t_num:2,overrides:{bck:30,hit_count:3}}],
|
||||
info:"每2次攻击释放龙卷风,30%击退概率推开一排敌人"},
|
||||
|
||||
5404:{uuid:5404,name:"风暴刺客",path:"hc2", fac:FacSet.HERO,pool_lv:4,lv:1,type:HType.Melee,
|
||||
hp:250,ap:100,
|
||||
skills:{6001:{uuid:6001,lv:1,cd:0.5,ccd:0}},
|
||||
atking:[
|
||||
{s_uuid:6407,t_num:1},
|
||||
{s_uuid:6102,t_num:3,overrides:{bck:50,hit_count:5,ap:120}}
|
||||
],
|
||||
dead:[{s_uuid:6406,t_num:1}],
|
||||
info:"极速近战,每次攻击给全队加击退距离,每3次攻击释放龙卷风,死后全队永久击退率加成"},
|
||||
|
||||
// ========== 暴击爆发流 ==========
|
||||
5211:{uuid:5211,name:"猎鹰射手",path:"ha4", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Long,
|
||||
hp:130,ap:55,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:0.9,ccd:0}},
|
||||
atking:[{s_uuid:6403,t_num:2}],
|
||||
info:"稳定输出,每2次攻击为全队叠加暴击率"},
|
||||
|
||||
5212:{uuid:5212,name:"穿心弩手",path:"ha1", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Long,
|
||||
hp:160,ap:80,
|
||||
skills:{6003:{uuid:6003,lv:1,cd:1.0,ccd:0}},
|
||||
fstart:[{s_uuid:6403,t_num:1}],
|
||||
atking:[{s_uuid:6404,t_num:2}],
|
||||
info:"开局全队暴击强化,战斗中持续叠加暴击伤害"},
|
||||
|
||||
5405:{uuid:5405,name:"死线执行者",path:"hc1", fac:FacSet.HERO,pool_lv:5,lv:1,type:HType.Melee,
|
||||
hp:220,ap:120,
|
||||
skills:{6001:{uuid:6001,lv:1,cd:1.5,ccd:0}},
|
||||
atking:[{s_uuid:6104,t_num:1,overrides:{ap:150,crt:35}}],
|
||||
dead:[
|
||||
{s_uuid:6403,t_num:1,overrides:{ap:3}},
|
||||
{s_uuid:6404,t_num:1,overrides:{ap:3}}
|
||||
],
|
||||
info:"每次攻击释放穿云箭穿透6个目标35%暴击率,死亡时给全队3层暴击+3层暴伤"},
|
||||
|
||||
// ========== 经济滚雪球流 ==========
|
||||
5109:{uuid:5109,name:"点金学徒",path:"hm2", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Long,
|
||||
hp:120,ap:35,
|
||||
skills:{6007:{uuid:6007,lv:1,cd:1.0,ccd:0}},
|
||||
field:[6401],
|
||||
atking:[{s_uuid:6303,t_num:3,overrides:{gold:8}}],
|
||||
info:"驻场提供攻击力光环,每3次普攻额外获得8金币"},
|
||||
|
||||
5306:{uuid:5306,name:"商贾",path:"hh3", fac:FacSet.HERO,pool_lv:2,lv:1,type:HType.Long,
|
||||
hp:150,ap:30,
|
||||
skills:{6004:{uuid:6004,lv:1,cd:1.1,ccd:0}},
|
||||
atking:[{s_uuid:6303,t_num:2,overrides:{gold:12}}],
|
||||
revive:{s_uuid:6501,r_num:1,upr:0.3},
|
||||
info:"战斗中持续产金币,死了也能复活继续赚钱"},
|
||||
|
||||
5213:{uuid:5213,name:"丰收猎手",path:"ha2", fac:FacSet.HERO,pool_lv:4,lv:1,type:HType.Long,
|
||||
hp:180,ap:65,
|
||||
skills:{6002:{uuid:6002,lv:1,cd:0.8,ccd:0}},
|
||||
fstart:[{s_uuid:6401,t_num:1,overrides:{ap:8}}],
|
||||
atking:[
|
||||
{s_uuid:6303,t_num:2,overrides:{gold:10}},
|
||||
{s_uuid:6401,t_num:1,overrides:{ap:3}}
|
||||
],
|
||||
info:"开战前全队加攻,边打边赚金币,每次攻击给全队加攻击力"},
|
||||
|
||||
// ========== 献祭亡语流 ==========
|
||||
5010:{uuid:5010,name:"烈焰殉道者",path:"hk5", fac:FacSet.HERO,pool_lv:1,lv:1,type:HType.Melee,
|
||||
hp:250,ap:30,
|
||||
skills:{6001:{uuid:6001,lv:1,cd:1.5,ccd:0}},
|
||||
dead:[{s_uuid:6401,t_num:1,overrides:{ap:15}}],
|
||||
info:"死亡时为全队永久增加15点攻击力"},
|
||||
|
||||
5110:{uuid:5110,name:"亡语刺客",path:"hc2", fac:FacSet.HERO,pool_lv:3,lv:1,type:HType.Melee,
|
||||
hp:280,ap:70,
|
||||
skills:{6001:{uuid:6001,lv:1,cd:1.0,ccd:0}},
|
||||
atking:[{s_uuid:6405,t_num:2,overrides:{ap:1}}],
|
||||
dead:[
|
||||
{s_uuid:6401,t_num:1,overrides:{ap:10}},
|
||||
{s_uuid:6405,t_num:1,overrides:{ap:2}},
|
||||
{s_uuid:6301,t_num:1,overrides:{TGroup:TGroup.Team,ap:2,hit_count:2}}
|
||||
],
|
||||
info:"活着时叠冰冻率,死亡时三重亡语:全队+10攻击+2层冰冻率+2层护盾"},
|
||||
|
||||
5111:{uuid:5111,name:"血影绝杀",path:"hc1", fac:FacSet.HERO,pool_lv:5,lv:1,type:HType.Melee,
|
||||
hp:300,ap:100,
|
||||
skills:{6001:{uuid:6001,lv:1,cd:1.2,ccd:0}},
|
||||
atking:[{s_uuid:6404,t_num:1,overrides:{TGroup:TGroup.Self,ap:2}}],
|
||||
dead:[
|
||||
{s_uuid:6401,t_num:1,overrides:{ap:20}},
|
||||
{s_uuid:6404,t_num:1,overrides:{ap:2}},
|
||||
{s_uuid:6402,t_num:1,overrides:{ap:30}}
|
||||
],
|
||||
info:"活着时每次攻击给自己叠暴伤,死后全队+20攻+2层暴伤+30血"},
|
||||
|
||||
|
||||
|
||||
@@ -191,47 +420,61 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
*/
|
||||
|
||||
|
||||
// 基础怪物
|
||||
6001:{uuid:6001,name:"兽人初阶战士",path:"m1", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,dis:360,hp:360,ap:12,speed:100,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.65,ccd:0}},info:""},
|
||||
6002:{uuid:6002,name:"兽人高阶战士",path:"m2", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,dis:360,hp:360,ap:12,speed:100,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.65,ccd:0}},info:""},
|
||||
6003:{uuid:6003,name:"兽人初阶射手",path:"m3", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,dis:360,hp:1050,ap:30,speed:100,
|
||||
skills:{6008:{uuid:6008,lv:1,cd:2,ccd:0}},info:""},
|
||||
6004:{uuid:6004,name:"兽人高阶射手",path:"m4", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Long,hp:720,ap:45,speed:100,
|
||||
skills:{6008:{uuid:6008,lv:1,cd:1.5,ccd:0}},info:""},
|
||||
6005:{uuid:6005,name:"兽人刺客",path:"m5", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Long,hp:720,ap:20,speed:100,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:1.5,ccd:0}},info:""},
|
||||
6006:{uuid:6006,name:"骷髅高阶战士",path:"m6", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,dis:360,hp:4500,ap:20,speed:100,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:2,ccd:0}},info:""},
|
||||
6007:{uuid:6007,name:"兽人蓝色法师",path:"m7", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,dis:360,hp:4500,ap:20,speed:100,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:2,ccd:0}},info:""},
|
||||
6008:{uuid:6008,name:"兽人红色法师",path:"m8", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,dis:360,hp:4500,ap:20,speed:100,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:2,ccd:0}},info:""},
|
||||
// 基础怪物 (全部远程攻击,HType仅决定站位)
|
||||
// 近战位怪物 (站在前排,承受更多伤害) — v4: 数量×2 强度×0.6 爽感设计
|
||||
6001:{uuid:6001,name:"兽人战士",path:"m1", fac:FacSet.MON,lv:1,type:HType.Melee,dis:360,hp:220,ap:10,speed:100,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.65,ccd:0}},info:"基础近战位怪"},
|
||||
6002:{uuid:6002,name:"兽人精锐战士",path:"m2", fac:FacSet.MON,lv:1,type:HType.Melee,dis:360,hp:300,ap:14,speed:110,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:0.55,ccd:0}},info:"进阶近战位怪,更快更痛"},
|
||||
6003:{uuid:6003,name:"兽人重装兵",path:"m3", fac:FacSet.MON,lv:1,type:HType.Melee,dis:360,hp:850,ap:20,speed:80,
|
||||
skills:{6008:{uuid:6008,lv:1,cd:1.8,ccd:0}},info:"重型坦克怪,高HP慢攻"},
|
||||
// 远程位怪物 (站在后排,输出更高)
|
||||
6004:{uuid:6004,name:"兽人射手",path:"m4", fac:FacSet.MON,lv:1,type:HType.Long,hp:190,ap:35,speed:100,
|
||||
skills:{6008:{uuid:6008,lv:1,cd:1.2,ccd:0}},info:"远程高DPS怪"},
|
||||
6005:{uuid:6005,name:"兽人刺客",path:"m5", fac:FacSet.MON,lv:1,type:HType.Long,hp:210,ap:38,speed:130,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:0.8,ccd:0}},info:"高AP快速攻击刺客"},
|
||||
// 特殊位怪物
|
||||
6006:{uuid:6006,name:"骷髅领主",path:"m6", fac:FacSet.MON,lv:1,type:HType.Melee,dis:360,hp:5000,ap:20,speed:90,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:1.5,ccd:0}},info:"MiniBoss级坦克"},
|
||||
6007:{uuid:6007,name:"兽人术士",path:"m7", fac:FacSet.MON,lv:1,type:HType.Melee,dis:360,hp:300,ap:24,speed:100,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:1.2,ccd:0}},info:"法师怪,远程魔法攻击"},
|
||||
6008:{uuid:6008,name:"兽人火法",path:"m8", fac:FacSet.MON,lv:1,type:HType.Melee,dis:360,hp:270,ap:32,speed:100,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:1.0,ccd:0}},info:"高输出法师怪"},
|
||||
|
||||
// BOSS怪物
|
||||
6101:{uuid:6101,name:"兽人首领-双刀战士-蓝边",path:"mb1", fac:FacSet.MON,cards_lv:1,lv:6,type:HType.Long,hp:720,ap:30,speed:100,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:2,ccd:0},6206:{uuid:6206,lv:1,cd:10,ccd:0}},info:""},
|
||||
6102:{uuid:6102,name:"兽人首领-斧头战士-绿边",path:"mb2", fac:FacSet.MON,cards_lv:1,lv:6,type:HType.Melee,dis:360,hp:4500,ap:20,speed:100,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:2,ccd:0},},info:""},
|
||||
6103:{uuid:6103,name:"兽人首领-魔法师-紫边",path:"mb3", fac:FacSet.MON,cards_lv:1,lv:6,type:HType.Long,hp:720,ap:30,speed:100,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:2,ccd:0},6206:{uuid:6206,lv:1,cd:10,ccd:0}},info:""},
|
||||
6104:{uuid:6104,name:"兽人首领-射手-黄边",path:"mb4", fac:FacSet.MON,cards_lv:1,lv:6,type:HType.Melee,dis:360,hp:4500,ap:20,speed:100,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:2,ccd:0},},info:""},
|
||||
6105:{uuid:6105,name:"亡灵首领-法师-红边",path:"mb5", fac:FacSet.MON,cards_lv:1,lv:6,type:HType.Long,hp:720,ap:30,speed:100,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:2,ccd:0},6206:{uuid:6206,lv:1,cd:10,ccd:0}},info:""},
|
||||
6106:{uuid:6106,name:"亡灵首领-骑马战士-红边",path:"mb6", fac:FacSet.MON,cards_lv:1,lv:6,type:HType.Melee,dis:360,hp:4500,ap:20,speed:100,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:2,ccd:0},},info:""},
|
||||
// BOSS怪物 — Boss强度降低~25%,靠护卫小怪制造场面压力
|
||||
6101:{uuid:6101,name:"兽人首领-双刀战士",path:"mb1", fac:FacSet.MON,lv:6,type:HType.Long,hp:1900,ap:30,speed:120,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:0.8,ccd:0},6206:{uuid:6206,lv:1,cd:10,ccd:0}},info:"远程Boss,高攻速"},
|
||||
6102:{uuid:6102,name:"兽人首领-斧头战士",path:"mb2", fac:FacSet.MON,lv:6,type:HType.Melee,dis:360,hp:7500,ap:26,speed:90,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:1.2,ccd:0}},info:"近战Boss,超高HP"},
|
||||
6103:{uuid:6103,name:"兽人首领-魔法师",path:"mb3", fac:FacSet.MON,lv:6,type:HType.Long,hp:2250,ap:38,speed:110,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:0.7,ccd:0},6206:{uuid:6206,lv:1,cd:8,ccd:0}},info:"远程法系Boss,高AP"},
|
||||
6104:{uuid:6104,name:"兽人首领-射手",path:"mb4", fac:FacSet.MON,lv:6,type:HType.Melee,dis:360,hp:6800,ap:30,speed:100,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:1.0,ccd:0}},info:"近战位Boss,均衡型"},
|
||||
6105:{uuid:6105,name:"亡灵首领-法师",path:"mb5", fac:FacSet.MON,lv:6,type:HType.Long,hp:2600,ap:42,speed:110,
|
||||
skills:{6103:{uuid:6103,lv:1,cd:0.7,ccd:0},6206:{uuid:6206,lv:1,cd:8,ccd:0}},info:"远程高AP Boss"},
|
||||
6106:{uuid:6106,name:"亡灵首领-骑马战士",path:"mb6", fac:FacSet.MON,lv:6,type:HType.Melee,dis:360,hp:9000,ap:26,speed:130,
|
||||
skills:{6005:{uuid:6005,lv:1,cd:1.0,ccd:0}},info:"终极Boss,最高HP+高速"},
|
||||
|
||||
|
||||
};
|
||||
|
||||
export const HeroList: number[] = [
|
||||
5001, 5002, 5003, 5004, 5005,
|
||||
5101, 5102, 5103, 5104, 5105,
|
||||
5201, 5202,5203,5204,
|
||||
5301, 5302,
|
||||
5401, 5402,
|
||||
// 铁壁反伤流
|
||||
5001, 5002, 5007, 5008, 5009,
|
||||
// 攻速叠伤流
|
||||
5006, 5205, 5403,
|
||||
// 冰冻控制流
|
||||
5101, 5106, 5107, 5108,
|
||||
// 治疗续航流
|
||||
5301, 5302, 5303, 5304, 5305,
|
||||
// 击退推拉流
|
||||
5209, 5210, 5404,
|
||||
// 暴击爆发流
|
||||
5211, 5212, 5405,
|
||||
// 经济滚雪球流
|
||||
5109, 5306, 5213,
|
||||
// 献祭亡语流
|
||||
5010, 5110, 5111,
|
||||
];
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
BIN
assets/script/game/common/config/heros.xlsx
Normal file
BIN
assets/script/game/common/config/heros.xlsx
Normal file
Binary file not shown.
12
assets/script/game/common/config/heros.xlsx.meta
Normal file
12
assets/script/game/common/config/heros.xlsx.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"ver": "1.0.0",
|
||||
"importer": "*",
|
||||
"imported": true,
|
||||
"uuid": "19f625a6-5615-4db8-8e96-03e227bbf253",
|
||||
"files": [
|
||||
".json",
|
||||
".xlsx"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -3,9 +3,10 @@ import { HeroDisVal, HeroInfo, HSkillInfo, HType } from "../common/config/heroSe
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { Timer } from "db://oops-framework/core/common/timer/Timer";
|
||||
import { FacSet, FightSet } from "../common/config/GameSet";
|
||||
import { FieldSkillSet, FieldSkillType } from "../common/config/SkillSet";
|
||||
import { FieldSkillSet, FieldSkillType, SkillOverrides } from "../common/config/SkillSet";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { TalentConfig, TalentType } from "../common/config/TalentSet";
|
||||
import { Attrs } from "../common/config/HeroAttrs";
|
||||
import { FieldSkillHelper } from "./FieldSkillHelper";
|
||||
@ecs.register('HeroAttrs')
|
||||
export class HeroAttrsComp extends ecs.Comp {
|
||||
@@ -33,12 +34,12 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
skills: Record<number, HSkillInfo> = {};
|
||||
|
||||
// ==================== 触发类技能 ====================
|
||||
call?: number[];
|
||||
dead?: number[];
|
||||
fstart?: number[];
|
||||
fend?: number[];
|
||||
atking?: {s_uuid: number, t_num: number}[];
|
||||
atked?: {s_uuid: number, t_num: number}[];
|
||||
call?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
dead?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
fstart?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
fend?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
atking?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
atked?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
revive?: {s_uuid: number, r_num: number, upr: number};
|
||||
|
||||
// ==================== 特殊属性 ====================
|
||||
@@ -50,7 +51,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
knockback_distance: number = 0; // 击退距离强化
|
||||
knockback_res: number = 0; // 击退抗性
|
||||
crit_damage: number = 0; // 额外暴击伤害
|
||||
puncture: number = 0; // 穿刺次数
|
||||
puncture_chance: number = 0; // 穿透概率
|
||||
wfuny: number = 0; // 风怒
|
||||
|
||||
revived_count: number = 0; // 已复活次数
|
||||
@@ -135,6 +136,25 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一的特殊/固定属性数值增加方法
|
||||
* @param attr_type 属性类型枚举
|
||||
* @param value 增加的数值
|
||||
*/
|
||||
add_special_attr(attr_type: Attrs, value: number) {
|
||||
// 利用枚举值(字符串)与类属性名一致的特性,动态访问并累加属性
|
||||
const key = attr_type as keyof this;
|
||||
|
||||
// 确保目标属性存在且类型为数字,避免运行时错误
|
||||
if (typeof this[key] === 'number') {
|
||||
(this as any)[key] += value;
|
||||
} else {
|
||||
if (this.debugMode) {
|
||||
mLogger.log(this.debugMode, 'HeroAttrs', `未找到对应数字属性或无法累加: attr_type=${attr_type}, value=${value}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
toFrost(time: number=1) {
|
||||
const frostTime = FightSet.FROST_TIME * time;
|
||||
@@ -223,6 +243,11 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
return this.freeze_chance + this.getFieldPercentValue(FieldSkillType.HeroFrost);
|
||||
}
|
||||
|
||||
/** 英雄实时穿透概率 = 基础穿透概率。 */
|
||||
public getRuntimePunctureChance(): number {
|
||||
return this.puncture_chance;
|
||||
}
|
||||
|
||||
/** 英雄实时暴击伤害 = 基础额外暴伤 + 驻场暴伤。 */
|
||||
public getRuntimeCritDamageBonus(): number {
|
||||
if (this.fac !== FacSet.HERO) return this.crit_damage;
|
||||
@@ -310,7 +335,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
this.crit_damage = 0;
|
||||
this.revived_count = 0;
|
||||
this.invincible_time = 0;
|
||||
this.puncture = 0;
|
||||
this.puncture_chance = 0;
|
||||
this.wfuny = 0;
|
||||
this.boom = false;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
||||
import { Vec3, Prefab, instantiate, tween, Node } from "cc";
|
||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { DTType, RType, SkillConfig, SkillKind, SkillSet, SkillUpList, TGroup } from "../common/config/SkillSet";
|
||||
import { DTType, RType, SkillConfig, SkillKind, SkillSet, SkillUpList, TGroup, SkillOverrides, mergeSkillParams } from "../common/config/SkillSet";
|
||||
import { Skill } from "../skill/Skill";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { HeroDisVal, HeroInfo, HType } from "../common/config/heroSet";
|
||||
@@ -11,6 +11,7 @@ import { BoxSet, FacSet, FightSet } from "../common/config/GameSet";
|
||||
import { oops } from "db://oops-framework/core/Oops";
|
||||
import { GameEvent, SkillTriggerType } from "../common/config/GameEvent";
|
||||
import { SkillTriggerHelper } from "./SkillTriggerHelper";
|
||||
import { MissionEconomy } from "../map/MissionEconomy";
|
||||
|
||||
/**
|
||||
* ==================== 自动施法系统 ====================
|
||||
@@ -48,7 +49,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
triggerType?: string,
|
||||
isCardSkill?: boolean,
|
||||
card_lv?: number,
|
||||
targetPos?: Vec3
|
||||
targetPos?: Vec3,
|
||||
overrides?: any
|
||||
}) {
|
||||
if (!args || !args.s_uuid) return;
|
||||
|
||||
@@ -60,7 +62,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
|
||||
// 常规英雄技能触发
|
||||
if (!args.heroAttrs || !args.heroView) return;
|
||||
this.forceCastTriggerSkill(args.s_uuid, args.heroAttrs, args.heroView, args.triggerType);
|
||||
this.forceCastTriggerSkill(args.s_uuid, args.heroAttrs, args.heroView, args.triggerType, args.overrides);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,7 +108,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
mockAttrs.ap = highestAp;
|
||||
mockAttrs.critical = 0;
|
||||
mockAttrs.freeze_chance = 0;
|
||||
mockAttrs.puncture = 0;
|
||||
mockAttrs.puncture_chance = 0;
|
||||
mockAttrs.fac = FacSet.HERO;
|
||||
|
||||
for (let i = 0; i < castTimes; i++) {
|
||||
@@ -140,7 +142,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
skill.load(actualStartPos, parent, s_uuid, targetPos.clone(), mockView, mockAttrs, skillLv, 0);
|
||||
}
|
||||
/** 空施法计划:用于“当前无可施法技能”时的统一返回 */
|
||||
private readonly emptyCastPlan = { skillId: 0, skillLv: 1, isFriendly: false, targetPos: null as Vec3 | null, targetEids: [] as number[] };
|
||||
private readonly emptyCastPlan = { skillId: 0, skillLv: 1, isFriendly: false, targetPos: null as Vec3 | null, targetEids: [] as number[], overrides: undefined as SkillOverrides | undefined };
|
||||
/** 查询缓存:避免每帧重复创建 matcher */
|
||||
private heroMatcher: ecs.IMatcher | null = null;
|
||||
|
||||
@@ -188,7 +190,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
* 强制执行触发技能(召唤/死亡触发)
|
||||
* 忽略CD、状态、动画前摇,直接生效
|
||||
*/
|
||||
public forceCastTriggerSkill(s_uuid: number, heroAttrs: HeroAttrsComp, heroView: HeroViewComp, triggerType?: string) {
|
||||
public forceCastTriggerSkill(s_uuid: number, heroAttrs: HeroAttrsComp, heroView: HeroViewComp, triggerType?: string, overrides?: SkillOverrides) {
|
||||
// 播放相应的触发动画
|
||||
if (triggerType === 'call') {
|
||||
heroView.playReady("yellow");
|
||||
@@ -199,8 +201,9 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
}
|
||||
|
||||
// 如果是敌方攻击技能,必须在战斗中才能释放;友方增益/护盾则允许在非战斗中释放
|
||||
const config = SkillSet[s_uuid];
|
||||
let config = SkillSet[s_uuid];
|
||||
if (!config) return;
|
||||
config = mergeSkillParams(config, overrides);
|
||||
|
||||
const isEnemyTarget = !this.isSelfSkill(config.TGroup) && !this.isFriendlySkill(config.TGroup);
|
||||
if (isEnemyTarget && !smc.mission.in_fight) return;
|
||||
@@ -245,7 +248,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
this.applyFriendlySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, friendlyTargets, null);
|
||||
} else {
|
||||
const enemyTargetPos = this.resolveRepeatCastTargetPos(targetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i, overrides);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,7 +258,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
* 选择顺序:技能候选列表顺序 + 条件过滤(CD、目标可达、目标类型匹配)。
|
||||
* 返回内容同时包含“对敌施法”和“友方施法”两种执行所需数据。
|
||||
*/
|
||||
private pickCastSkill(heroAttrs: HeroAttrsComp, heroView: HeroViewComp): { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[] } {
|
||||
private pickCastSkill(heroAttrs: HeroAttrsComp, heroView: HeroViewComp): { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[]; overrides?: SkillOverrides } {
|
||||
const type = heroAttrs.type as HType;
|
||||
const maxRange = this.resolveMaxCastRange(heroAttrs, type);
|
||||
const target = this.findNearestEnemyInRange(heroAttrs, heroView, maxRange);
|
||||
@@ -263,24 +266,26 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
const selfEid = heroView.ent?.eid;
|
||||
for (const s_uuid of skillCandidates) {
|
||||
if (!s_uuid) continue;
|
||||
const config = SkillSet[s_uuid];
|
||||
let config = SkillSet[s_uuid];
|
||||
if (!config) continue;
|
||||
if (!heroAttrs.isSkillReady(s_uuid)) continue;
|
||||
const skillLv = heroAttrs.getSkillLevel(s_uuid);
|
||||
const overrides = heroAttrs.skills[s_uuid]?.overrides;
|
||||
config = mergeSkillParams(config, overrides);
|
||||
if (this.isSelfSkill(config.TGroup)) {
|
||||
if (typeof selfEid !== "number") continue;
|
||||
return { skillId: s_uuid, skillLv, isFriendly: true, targetPos: null, targetEids: [selfEid] };
|
||||
return { skillId: s_uuid, skillLv, isFriendly: true, targetPos: null, targetEids: [selfEid], overrides };
|
||||
}
|
||||
if (this.isFriendlySkill(config.TGroup)) {
|
||||
const includeSelf = config.TGroup === TGroup.Ally;
|
||||
const friendlyEids = this.collectFriendlyTargetEids(heroAttrs.fac, selfEid, includeSelf);
|
||||
if (friendlyEids.length === 0) continue;
|
||||
return { skillId: s_uuid, skillLv, isFriendly: true, targetPos: null, targetEids: friendlyEids };
|
||||
return { skillId: s_uuid, skillLv, isFriendly: true, targetPos: null, targetEids: friendlyEids, overrides };
|
||||
}
|
||||
if (!target || !heroView.node || !target.node) continue;
|
||||
const targetPos = this.resolveEnemyCastTargetPos(config, heroAttrs, heroView, target, maxRange);
|
||||
if (!targetPos) continue;
|
||||
return { skillId: s_uuid, skillLv, isFriendly: false, targetPos, targetEids: [] };
|
||||
return { skillId: s_uuid, skillLv, isFriendly: false, targetPos, targetEids: [], overrides };
|
||||
}
|
||||
return this.emptyCastPlan;
|
||||
}
|
||||
@@ -291,14 +296,18 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
* - 延迟到出手时机后,按技能目标类型分发到对敌/友方效果处理
|
||||
* - 触发技能CD
|
||||
*/
|
||||
private castSkill(castPlan: { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[] }, heroAttrs: HeroAttrsComp, heroView: HeroViewComp) {
|
||||
private castSkill(castPlan: { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[]; overrides?: SkillOverrides }, heroAttrs: HeroAttrsComp, heroView: HeroViewComp) {
|
||||
if (!smc.mission.in_fight) return;
|
||||
const s_uuid = castPlan.skillId;
|
||||
const skillLv = castPlan.skillLv;
|
||||
const config = SkillSet[s_uuid];
|
||||
const overrides = castPlan.overrides;
|
||||
let config = SkillSet[s_uuid];
|
||||
const sUp = SkillUpList[s_uuid] ? SkillUpList[s_uuid]:SkillUpList[1001];
|
||||
const cNum = Math.min(2, Math.max(0, Math.floor(sUp.num ?? 0)));
|
||||
if (!config) return;
|
||||
|
||||
config = mergeSkillParams(config, overrides);
|
||||
|
||||
//播放前摇技能动画
|
||||
heroView.playReady(config.readyAnm);
|
||||
//播放角色攻击动画
|
||||
@@ -331,7 +340,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
continue;
|
||||
}
|
||||
const enemyTargetPos = this.resolveRepeatCastTargetPos(castPlan.targetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i, overrides);
|
||||
}
|
||||
}, delay);
|
||||
heroAttrs.triggerSkillCD(s_uuid);
|
||||
@@ -360,24 +369,24 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
* 创建技能实体(投射物/范围体等)。
|
||||
* 仅用于对敌伤害技能的实体化表现与碰撞伤害分发。
|
||||
*/
|
||||
private createSkillEntity(s_uuid: number, skillLv: number, caster: HeroViewComp,cAttrsComp: HeroAttrsComp, targetPos: Vec3, castIndex: number = 0) {
|
||||
private createSkillEntity(s_uuid: number, skillLv: number, caster: HeroViewComp,cAttrsComp: HeroAttrsComp, targetPos: Vec3, castIndex: number = 0, overrides?: SkillOverrides) {
|
||||
if (!caster.node || !caster.node.isValid) return;
|
||||
const parent = caster.node.parent;
|
||||
if (!parent) return;
|
||||
const skill = ecs.getEntity<Skill>(Skill);
|
||||
const startPos = this.resolveRepeatCastStartPos(caster.node.position, castIndex);
|
||||
skill.load(startPos, parent, s_uuid, targetPos.clone(), caster, cAttrsComp, skillLv, 0);
|
||||
skill.load(startPos, parent, s_uuid, targetPos.clone(), caster, cAttrsComp, skillLv, 0, overrides);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对敌技能效果处理。
|
||||
* 当前职责:仅处理伤害技能并创建技能实体。
|
||||
*/
|
||||
private applyEnemySkillEffects(s_uuid: number, skillLv: number, config: SkillConfig, heroView: HeroViewComp, cAttrsComp: HeroAttrsComp, targetPos: Vec3 | null, castIndex: number = 0) {
|
||||
private applyEnemySkillEffects(s_uuid: number, skillLv: number, config: SkillConfig, heroView: HeroViewComp, cAttrsComp: HeroAttrsComp, targetPos: Vec3 | null, castIndex: number = 0, overrides?: SkillOverrides) {
|
||||
const kind = config.kind ?? SkillKind.Damage;
|
||||
if (kind !== SkillKind.Damage) return;
|
||||
if (config.ap <= 0 || !targetPos) return;
|
||||
this.createSkillEntity(s_uuid, skillLv, heroView, cAttrsComp, targetPos, castIndex);
|
||||
this.createSkillEntity(s_uuid, skillLv, heroView, cAttrsComp, targetPos, castIndex, overrides);
|
||||
}
|
||||
|
||||
private resolveRepeatCastStartPos(startPos: Readonly<Vec3>, castIndex: number): Vec3 {
|
||||
@@ -403,16 +412,21 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
: this.pickRandomFriendlyTargets(targets, sHit);
|
||||
|
||||
for (const target of applyTargets) {
|
||||
this.applyActualFriendlyEffect(target, kind, sAp, _cAttrsComp, config, sUp);
|
||||
this.applyActualFriendlyEffect(target, kind, sAp, _cAttrsComp, config, sUp, _skillLv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private applyActualFriendlyEffect(target: HeroViewComp, kind: SkillKind, sAp: number, _cAttrsComp: HeroAttrsComp, config: SkillConfig, sUp: any) {
|
||||
private applyActualFriendlyEffect(target: HeroViewComp, kind: SkillKind, sAp: number, _cAttrsComp: HeroAttrsComp, config: SkillConfig, sUp: any, _skillLv: number = 1) {
|
||||
if (!target.ent) return;
|
||||
const model = target.ent.get(HeroAttrsComp);
|
||||
if (!model || model.is_dead) return;
|
||||
|
||||
if (config.endAnm && config.endAnm !== "") {
|
||||
target.playEnd(config.endAnm);
|
||||
}
|
||||
|
||||
if (kind === SkillKind.Heal && sAp !== 0) {
|
||||
const addHp = Math.floor(sAp*_cAttrsComp.ap/100);
|
||||
model.add_hp(addHp);
|
||||
@@ -424,19 +438,37 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
} else if (kind === SkillKind.Shield && sAp !== 0) {
|
||||
const addShield = Math.max(0, Math.floor(sAp));
|
||||
model.add_shield(addShield);
|
||||
} else if (kind === SkillKind.Gold) {
|
||||
const baseGold = config.gold ?? config.ap;
|
||||
const addGold = baseGold + (sUp.ap * _skillLv);
|
||||
if (addGold > 0) {
|
||||
MissionEconomy.addCoin(addGold);
|
||||
}
|
||||
}
|
||||
if (!config.buffs || config.buffs.length === 0) return;
|
||||
for (const buffConf of config.buffs) {
|
||||
if (!buffConf) continue;
|
||||
const sBuffAp=buffConf.value+sUp.buff_ap
|
||||
const sBuffHp=buffConf.value+sUp.buff_hp
|
||||
switch (buffConf.buff){
|
||||
|
||||
if (config.buff_type !== undefined) {
|
||||
const baseValue = config.ap;
|
||||
let upgradeValue = 0;
|
||||
|
||||
// 根据 buff 类型选择对应的升级加成
|
||||
if (config.buff_type === Attrs.ap) upgradeValue = sUp.buff_ap || 0;
|
||||
else if (config.buff_type === Attrs.hp_max) upgradeValue = sUp.buff_hp || 0;
|
||||
else if (config.buff_type === Attrs.critical) upgradeValue = sUp.crt || 0;
|
||||
// 如果后续有冰冻等,在这里加上对应的 sUp 字段即可,如 sUp.frz
|
||||
|
||||
const totalBuffValue = baseValue + upgradeValue;
|
||||
|
||||
switch (config.buff_type){
|
||||
case Attrs.ap:
|
||||
model.add_ap(sBuffAp)
|
||||
break
|
||||
model.add_ap(totalBuffValue);
|
||||
break;
|
||||
case Attrs.hp_max:
|
||||
model.add_hp_max(sBuffHp)
|
||||
break
|
||||
model.add_hp_max(totalBuffValue);
|
||||
break;
|
||||
default:
|
||||
// 除了 hp_max 和 ap,其他固定属性走统一的 add_special_attr 方法
|
||||
model.add_special_attr(config.buff_type, totalBuffValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -512,7 +544,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
}
|
||||
|
||||
/** 判定施法计划是否具备有效目标 */
|
||||
private hasCastTarget(castPlan: { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[] }): boolean {
|
||||
private hasCastTarget(castPlan: { skillId: number; skillLv: number; isFriendly: boolean; targetPos: Vec3 | null; targetEids: number[]; overrides?: SkillOverrides }): boolean {
|
||||
if (castPlan.skillId === 0) return false;
|
||||
if (castPlan.isFriendly) return castPlan.targetEids.length > 0;
|
||||
return !!castPlan.targetPos;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { GameEvent, SkillTriggerType } from "../common/config/GameEvent";
|
||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { FacSet } from "../common/config/GameSet";
|
||||
import { FieldSkillType } from "../common/config/SkillSet";
|
||||
import { FieldSkillType, SkillOverrides } from "../common/config/SkillSet";
|
||||
import { TalentType } from "../common/config/TalentSet";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { FieldSkillHelper } from "./FieldSkillHelper";
|
||||
@@ -105,7 +105,7 @@ export class SkillTriggerHelper {
|
||||
model.atking.forEach(atkConfig => {
|
||||
// atk_count 代表已进行的普攻次数。当其余数刚好整除配置阈值时触发。
|
||||
if (model.atk_count > 0 && model.atk_count % atkConfig.t_num === 0) {
|
||||
this.dispatchSingle(atkConfig.s_uuid, model, view, SkillTriggerType.Atking);
|
||||
this.dispatchSingle(atkConfig.s_uuid, model, view, SkillTriggerType.Atking, atkConfig.overrides);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -119,7 +119,7 @@ export class SkillTriggerHelper {
|
||||
model.atked.forEach(atkConfig => {
|
||||
// atked_count 代表已承受的受击次数。当其余数刚好整除配置阈值时触发。
|
||||
if (model.atked_count > 0 && model.atked_count % atkConfig.t_num === 0) {
|
||||
this.dispatchSingle(atkConfig.s_uuid, model, view, SkillTriggerType.Atked);
|
||||
this.dispatchSingle(atkConfig.s_uuid, model, view, SkillTriggerType.Atked, atkConfig.overrides);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -127,28 +127,29 @@ export class SkillTriggerHelper {
|
||||
/**
|
||||
* 通用的数组型触发器处理(适用于 FStart / FEnd 等无需额外判定的简单列表触发)
|
||||
*/
|
||||
private static handleArrayTrigger(uuids: number[] | undefined, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
||||
if (!uuids || uuids.length === 0) return;
|
||||
this.dispatchArray(uuids, model, view, type);
|
||||
private static handleArrayTrigger(configs: {s_uuid: number, t_num: number, overrides?: SkillOverrides}[] | undefined, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
||||
if (!configs || configs.length === 0) return;
|
||||
this.dispatchArray(configs, model, view, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量派发技能事件
|
||||
*/
|
||||
private static dispatchArray(uuids: number[], model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
||||
uuids.forEach(uuid => this.dispatchSingle(uuid, model, view, type));
|
||||
private static dispatchArray(configs: {s_uuid: number, t_num?: number, overrides?: SkillOverrides}[], model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
||||
configs.forEach(config => this.dispatchSingle(config.s_uuid, model, view, type, config.overrides));
|
||||
}
|
||||
|
||||
/**
|
||||
* 单一技能事件派发底层接口
|
||||
* 事件发出后,将由 SCastSystem 的 forceCastTriggerSkill 监听拦截并执行无视CD的强制施法
|
||||
*/
|
||||
private static dispatchSingle(s_uuid: number, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
||||
private static dispatchSingle(s_uuid: number, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType, overrides?: SkillOverrides) {
|
||||
oops.message.dispatchEvent(GameEvent.TriggerSkill, {
|
||||
s_uuid: s_uuid,
|
||||
heroAttrs: model,
|
||||
heroView: view,
|
||||
triggerType: type
|
||||
triggerType: type,
|
||||
overrides: overrides
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,17 +304,19 @@ export class HInfoComp extends CCComp {
|
||||
*/
|
||||
private onSellHero(event?: Event) {
|
||||
if (!this.eid) return;
|
||||
const heroLv = Math.max(1, Math.floor(this.model?.lv ?? 1));
|
||||
const removed = Hero.removeByEid(this.eid);
|
||||
mLogger.log(this.debugMode, "HInfoComp", "onSellHero", {
|
||||
eid: this.eid,
|
||||
heroLv,
|
||||
isAlive: this.isModelAlive(),
|
||||
removed
|
||||
});
|
||||
if (!removed) return;
|
||||
|
||||
// 使用统一经济管理入口出售英雄
|
||||
MissionEconomy.executeSellHero();
|
||||
|
||||
|
||||
// 使用统一经济管理入口出售英雄(按等级计算卖价)
|
||||
MissionEconomy.executeSellHero(heroLv);
|
||||
|
||||
oops.gui.remove(UIID.IBox);
|
||||
}
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ export class HListComp extends CCComp {
|
||||
if (infoLabel) infoLabel.string = `${hero.info || ""}`;
|
||||
}
|
||||
|
||||
const cardLvStr = `lv${hero.cards_lv ?? 1}`;
|
||||
const cardLvStr = `lv${hero.pool_lv ?? 1}`;
|
||||
if (this.lv_node) {
|
||||
this.lv_node.active = true;
|
||||
this.lv_node.children.forEach(child => {
|
||||
|
||||
@@ -74,7 +74,7 @@ export class MissionCardComp extends CCComp {
|
||||
/** 按钮弹起缩放(峰值) */
|
||||
private readonly buttonClickScale: number = 1.06;
|
||||
/** 抽卡(刷新)费用 */
|
||||
refreshCost: number = 1;
|
||||
refreshCost: number = 2;
|
||||
/** 卡牌面板展开/收起动画时长(秒) */
|
||||
cardsPanelMoveDuration: number = 0.2;
|
||||
|
||||
|
||||
@@ -84,13 +84,13 @@ export class MissionComp extends CCComp {
|
||||
// ======================== 配置参数 ========================
|
||||
|
||||
/** 怪物数量上限(超过后暂停刷怪) */
|
||||
private maxMonsterCount: number = 50;
|
||||
private maxMonsterCount: number = 80;
|
||||
/** 怪物数量恢复阈值(降至此值以下恢复刷怪) */
|
||||
private resumeMonsterCount: number = 30;
|
||||
/** 新一波金币奖励基础值(现已固定,不再随波次增长) */
|
||||
private prepareBaseCoinReward: number = 25;
|
||||
/** 每一波金币增长值(固定收益设为0) */
|
||||
private prepareCoinWaveGrow: number = 0;
|
||||
private resumeMonsterCount: number = 45;
|
||||
/** 新一波金币奖励基础值 */
|
||||
private prepareBaseCoinReward: number = 10;
|
||||
/** 每一波金币增长值(公式: base + (wave-1) * growth) */
|
||||
private prepareCoinWaveGrow: number = 4;
|
||||
/** 金币奖励上限(固定收益,此值不再生效) */
|
||||
private prepareCoinRewardCap: number = 100;
|
||||
/** 卡池升级波次配置:达到对应波次时,推送卡池升级事件 */
|
||||
@@ -788,12 +788,13 @@ export class MissionComp extends CCComp {
|
||||
private grantPrepareCoinByWave(wave: number) {
|
||||
if (wave <= 1) return;
|
||||
if (wave <= this.lastPrepareCoinWave) return;
|
||||
|
||||
// 使用统一经济管理入口发放每波金币
|
||||
const reward = MissionEconomy.executeWaveGold(this.prepareBaseCoinReward);
|
||||
|
||||
|
||||
// 波次金币公式: baseReward + (wave-1) * waveGrow
|
||||
const waveReward = this.prepareBaseCoinReward + (wave - 1) * this.prepareCoinWaveGrow;
|
||||
const reward = MissionEconomy.executeWaveGold(waveReward);
|
||||
|
||||
this.lastPrepareCoinWave = wave;
|
||||
mLogger.log(this.debugMode, "MissionComp", "grantPrepareCoinByWave", { wave, reward, coin: smc.vmdata.mission_data.coin });
|
||||
mLogger.log(this.debugMode, "MissionComp", "grantPrepareCoinByWave", { wave, waveReward, reward, coin: smc.vmdata.mission_data.coin });
|
||||
}
|
||||
|
||||
// ======================== 怪物数量管理 ========================
|
||||
|
||||
@@ -66,11 +66,12 @@ export class MissionEconomy {
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算英雄出售金币
|
||||
/**
|
||||
* 计算英雄出售金币(按英雄等级缩放)
|
||||
*/
|
||||
static getSellGold(): number {
|
||||
const baseSellGold = 1; // 基础卖出金币
|
||||
static getSellGold(heroLevel: number = 1): number {
|
||||
const sellByLevel: Record<number, number> = { 1: 3, 2: 10, 3: 25 };
|
||||
const baseSellGold = sellByLevel[heroLevel] || 3;
|
||||
const goldBoost = FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.SellGold);
|
||||
let totalSellGold = baseSellGold + goldBoost;
|
||||
// 应用天赋 SellBonus (增加数值)
|
||||
@@ -81,11 +82,11 @@ export class MissionEconomy {
|
||||
return Math.floor(totalSellGold);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行出售英雄并增加金币
|
||||
/**
|
||||
* 执行出售英雄并增加金币
|
||||
*/
|
||||
static executeSellHero(): number {
|
||||
const gold = this.getSellGold();
|
||||
static executeSellHero(heroLevel: number = 1): number {
|
||||
const gold = this.getSellGold(heroLevel);
|
||||
this.addCoin(gold);
|
||||
return gold;
|
||||
}
|
||||
|
||||
@@ -183,13 +183,13 @@ export const TemplateModifier: Record<TemplateType, number> = {
|
||||
*/
|
||||
export const MonList: Record<number, number[]> = {
|
||||
[MonType.Melee]: [6001, 6002],
|
||||
[MonType.Heavy]: [6003, 6103],
|
||||
[MonType.Long]: [6004, 6102],
|
||||
[MonType.Support]: [6005],
|
||||
[MonType.Summoner]: [6203],
|
||||
[MonType.Assassin]: [6204],
|
||||
[MonType.MeleeBoss]: [6006, 6105],
|
||||
[MonType.LongBoss]: [6104],
|
||||
[MonType.Heavy]: [6003],
|
||||
[MonType.Long]: [6004],
|
||||
[MonType.Support]: [6007],
|
||||
[MonType.Summoner]: [6008],
|
||||
[MonType.Assassin]: [6005],
|
||||
[MonType.MeleeBoss]: [6006, 6102, 6104, 6106],
|
||||
[MonType.LongBoss]: [6101, 6103, 6105],
|
||||
}
|
||||
|
||||
// ======================== 怪物基础属性 & 成本 ========================
|
||||
@@ -215,14 +215,14 @@ export interface MonsterBaseStats {
|
||||
* @see MonsterBaseStats 字段说明
|
||||
*/
|
||||
export const MonsterStats: Record<MonType, MonsterBaseStats> = {
|
||||
[MonType.Melee]: { hp: 360, ap: 12, cost: 30, isBoss: false },
|
||||
[MonType.Heavy]: { hp: 1050, ap: 30, cost: 50, isBoss: false },
|
||||
[MonType.Long]: { hp: 240, ap: 45, cost: 40, isBoss: false },
|
||||
[MonType.Support]: { hp: 240, ap: 20, cost: 50, isBoss: false },
|
||||
[MonType.Summoner]: { hp: 300, ap: 15, cost: 60, isBoss: false },
|
||||
[MonType.Assassin]: { hp: 270, ap: 55, cost: 45, isBoss: false },
|
||||
[MonType.MeleeBoss]: { hp: 4500, ap: 20, cost: 200, isBoss: true },
|
||||
[MonType.LongBoss]: { hp: 1050, ap: 30, cost: 200, isBoss: true },
|
||||
[MonType.Melee]: { hp: 220, ap: 10, cost: 18, isBoss: false },
|
||||
[MonType.Heavy]: { hp: 850, ap: 20, cost: 35, isBoss: false },
|
||||
[MonType.Long]: { hp: 190, ap: 35, cost: 25, isBoss: false },
|
||||
[MonType.Support]: { hp: 300, ap: 24, cost: 28, isBoss: false },
|
||||
[MonType.Summoner]: { hp: 270, ap: 32, cost: 35, isBoss: false },
|
||||
[MonType.Assassin]: { hp: 210, ap: 38, cost: 25, isBoss: false },
|
||||
[MonType.MeleeBoss]: { hp: 7000, ap: 26, cost: 130, isBoss: true },
|
||||
[MonType.LongBoss]: { hp: 2100, ap: 38, cost: 130, isBoss: true },
|
||||
}
|
||||
|
||||
// ======================== 阶梯(Tier)配置 ========================
|
||||
@@ -252,11 +252,11 @@ const MAJOR_BOSS_TIERS = new Set([3, 5])
|
||||
* 主线 15 波映射:wave 1-3 → T1, wave 4-6 → T2, ..., wave 13-15 → T5
|
||||
*/
|
||||
export const TierConfigs: Record<number, TierConfig> = {
|
||||
1: { multiplier: 1.0, budget: 500, availableTypes: [MonType.Melee, MonType.Heavy, MonType.Long], isBossTier: false },
|
||||
2: { multiplier: 1.6, budget: 1000, availableTypes: [MonType.Melee, MonType.Heavy, MonType.Long, MonType.Support], isBossTier: true },
|
||||
3: { multiplier: 2.5, budget: 1800, availableTypes: [MonType.Melee, MonType.Heavy, MonType.Long, MonType.Support, MonType.Assassin], isBossTier: true },
|
||||
4: { multiplier: 3.8, budget: 3000, availableTypes: [MonType.Melee, MonType.Heavy, MonType.Long, MonType.Support, MonType.Assassin, MonType.Summoner], isBossTier: true },
|
||||
5: { multiplier: 5.5, budget: 5000, availableTypes: [MonType.Melee, MonType.Heavy, MonType.Long, MonType.Support, MonType.Assassin, MonType.Summoner], isBossTier: true },
|
||||
1: { multiplier: 1.0, budget: 350, availableTypes: [MonType.Melee, MonType.Heavy, MonType.Long], isBossTier: false },
|
||||
2: { multiplier: 2.0, budget: 1000, availableTypes: [MonType.Melee, MonType.Heavy, MonType.Long, MonType.Support], isBossTier: true },
|
||||
3: { multiplier: 3.5, budget: 2300, availableTypes: [MonType.Melee, MonType.Heavy, MonType.Long, MonType.Support, MonType.Assassin], isBossTier: true },
|
||||
4: { multiplier: 5.5, budget: 4000, availableTypes: [MonType.Melee, MonType.Heavy, MonType.Long, MonType.Support, MonType.Assassin, MonType.Summoner], isBossTier: true },
|
||||
5: { multiplier: 8.5, budget: 6500, availableTypes: [MonType.Melee, MonType.Heavy, MonType.Long, MonType.Support, MonType.Assassin, MonType.Summoner], isBossTier: true },
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,100 +361,107 @@ export interface BlueprintTemplate {
|
||||
* 生成引擎根据当前 Tier 和波内位置从中筛选并随机抽取
|
||||
*/
|
||||
export const BlueprintTemplates: BlueprintTemplate[] = [
|
||||
// ---- REST 类 ----
|
||||
// ---- REST 类 (恢复波:少量怪,让玩家喘口气) ----
|
||||
{ id: "R1", type: TemplateType.REST, tierMin: 1, allowAffix: false,
|
||||
slots: [{ typePool: [MonType.Melee], countMin: 5, countMax: 10, weight: 1.0 }] },
|
||||
{ id: "R2", type: TemplateType.REST, tierMin: 1, allowAffix: false,
|
||||
slots: [{ typePool: [MonType.Melee, MonType.Heavy], countMin: 5, countMax: 15, weight: 1.0 }] },
|
||||
slots: [{ typePool: [MonType.Melee], countMin: 4, countMax: 7, weight: 1.0 }] },
|
||||
{ id: "R2", type: TemplateType.REST, tierMin: 2, allowAffix: false,
|
||||
slots: [{ typePool: [MonType.Melee, MonType.Heavy], countMin: 6, countMax: 10, weight: 1.0 }] },
|
||||
{ id: "R3", type: TemplateType.REST, tierMin: 3, allowAffix: false,
|
||||
slots: [{ typePool: [MonType.Melee, MonType.Long], countMin: 10, countMax: 15, weight: 1.0 }] },
|
||||
slots: [{ typePool: [MonType.Melee, MonType.Long], countMin: 8, countMax: 14, weight: 1.0 }] },
|
||||
|
||||
// ---- NORMAL 类 ----
|
||||
// N1/N2: T1专用(1-5英雄)
|
||||
{ id: "N1", type: TemplateType.NORMAL, tierMin: 1, allowAffix: false,
|
||||
slots: [{ typePool: [MonType.Melee], countMin: 10, countMax: 20, weight: 1.0 }] },
|
||||
slots: [{ typePool: [MonType.Melee], countMin: 4, countMax: 7, weight: 1.0 }] },
|
||||
{ id: "N2", type: TemplateType.NORMAL, tierMin: 1, allowAffix: false,
|
||||
slots: [
|
||||
{ typePool: [MonType.Melee], countMin: 5, countMax: 15, weight: 0.6 },
|
||||
{ typePool: [MonType.Long, MonType.Heavy], countMin: 5, countMax: 10, weight: 0.4 },
|
||||
{ typePool: [MonType.Melee], countMin: 3, countMax: 6, weight: 0.6 },
|
||||
{ typePool: [MonType.Long], countMin: 2, countMax: 4, weight: 0.4 },
|
||||
] },
|
||||
// N3+: T2起(5-6英雄),正常数量
|
||||
{ id: "N3", type: TemplateType.NORMAL, tierMin: 2, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 10, countMax: 15, weight: 0.5 },
|
||||
{ typePool: [MonType.Long], countMin: 5, countMax: 10, weight: 0.3 },
|
||||
{ typePool: [MonType.Support], countMin: 5, countMax: 5, weight: 0.2 },
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 6, countMax: 12, weight: 0.5 },
|
||||
{ typePool: [MonType.Long], countMin: 4, countMax: 8, weight: 0.3 },
|
||||
{ typePool: [MonType.Support], countMin: 2, countMax: 5, weight: 0.2 },
|
||||
] },
|
||||
{ id: "N4", type: TemplateType.NORMAL, tierMin: 3, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 10, countMax: 20, weight: 0.4 },
|
||||
{ typePool: [MonType.Long, MonType.Assassin], countMin: 5, countMax: 15, weight: 0.3 },
|
||||
{ typePool: [MonType.Support], countMin: 5, countMax: 10, weight: 0.3 },
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 8, countMax: 14, weight: 0.4 },
|
||||
{ typePool: [MonType.Long, MonType.Assassin], countMin: 5, countMax: 10, weight: 0.3 },
|
||||
{ typePool: [MonType.Support], countMin: 3, countMax: 6, weight: 0.3 },
|
||||
] },
|
||||
|
||||
// ---- MIXED 类 ----
|
||||
// M1: T1专用(波3,5英雄)
|
||||
{ id: "M1", type: TemplateType.MIXED, tierMin: 1, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 10, countMax: 15, weight: 0.4 },
|
||||
{ typePool: [MonType.Long], countMin: 5, countMax: 10, weight: 0.3 },
|
||||
{ typePool: [MonType.Support], countMin: 5, countMax: 5, weight: 0.3 },
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 4, countMax: 7, weight: 0.4 },
|
||||
{ typePool: [MonType.Long], countMin: 3, countMax: 5, weight: 0.3 },
|
||||
{ typePool: [MonType.Support], countMin: 1, countMax: 3, weight: 0.3 },
|
||||
] },
|
||||
// M2+: T3起(6英雄)
|
||||
{ id: "M2", type: TemplateType.MIXED, tierMin: 3, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 10, countMax: 20, weight: 0.3 },
|
||||
{ typePool: [MonType.Long, MonType.Assassin], countMin: 10, countMax: 15, weight: 0.3 },
|
||||
{ typePool: [MonType.Support], countMin: 5, countMax: 5, weight: 0.4 },
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 8, countMax: 14, weight: 0.3 },
|
||||
{ typePool: [MonType.Long, MonType.Assassin], countMin: 6, countMax: 10, weight: 0.3 },
|
||||
{ typePool: [MonType.Support], countMin: 4, countMax: 7, weight: 0.4 },
|
||||
] },
|
||||
{ id: "M3", type: TemplateType.MIXED, tierMin: 4, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 15, countMax: 20, weight: 0.3 },
|
||||
{ typePool: [MonType.Long, MonType.Assassin], countMin: 10, countMax: 15, weight: 0.3 },
|
||||
{ typePool: [MonType.Summoner], countMin: 5, countMax: 10, weight: 0.2 },
|
||||
{ typePool: [MonType.Support], countMin: 5, countMax: 10, weight: 0.2 },
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 10, countMax: 16, weight: 0.3 },
|
||||
{ typePool: [MonType.Long, MonType.Assassin], countMin: 6, countMax: 12, weight: 0.3 },
|
||||
{ typePool: [MonType.Summoner], countMin: 3, countMax: 5, weight: 0.2 },
|
||||
{ typePool: [MonType.Support], countMin: 3, countMax: 6, weight: 0.2 },
|
||||
] },
|
||||
|
||||
// ---- ELITE 类 ----
|
||||
// ---- ELITE 类 (精英波:少但强,考验单兵质量) ----
|
||||
{ id: "E1", type: TemplateType.ELITE, tierMin: 3, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 5, countMax: 10, weight: 0.5, forceAffix: true },
|
||||
{ typePool: [MonType.Long, MonType.Assassin], countMin: 5, countMax: 10, weight: 0.5, forceAffix: true },
|
||||
{ typePool: [MonType.Heavy], countMin: 4, countMax: 7, weight: 0.5, forceAffix: true },
|
||||
{ typePool: [MonType.Long, MonType.Assassin], countMin: 4, countMax: 8, weight: 0.5, forceAffix: true },
|
||||
] },
|
||||
{ id: "E2", type: TemplateType.ELITE, tierMin: 4, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.Heavy], countMin: 5, countMax: 10, weight: 0.3, forceAffix: true },
|
||||
{ typePool: [MonType.Assassin], countMin: 5, countMax: 10, weight: 0.4, forceAffix: true },
|
||||
{ typePool: [MonType.Support], countMin: 5, countMax: 10, weight: 0.3, forceAffix: true },
|
||||
{ typePool: [MonType.Heavy], countMin: 4, countMax: 7, weight: 0.3, forceAffix: true },
|
||||
{ typePool: [MonType.Assassin], countMin: 5, countMax: 8, weight: 0.4, forceAffix: true },
|
||||
{ typePool: [MonType.Support], countMin: 3, countMax: 5, weight: 0.3, forceAffix: true },
|
||||
] },
|
||||
|
||||
// ---- BOSS 类 ----
|
||||
{ id: "B1", type: TemplateType.BOSS, tierMin: 1, allowAffix: true,
|
||||
// ---- BOSS 类 (Boss波:1个Boss + 大量护卫小怪,制造清杂兵爽感) ----
|
||||
{ id: "B1", type: TemplateType.BOSS, tierMin: 2, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.MeleeBoss], countMin: 1, countMax: 1, weight: 1.0 },
|
||||
{ typePool: [MonType.Melee], countMin: 10, countMax: 15, weight: 0.6 },
|
||||
{ typePool: [MonType.Long], countMin: 0, countMax: 10, weight: 0.4 },
|
||||
{ typePool: [MonType.Melee], countMin: 6, countMax: 10, weight: 0.5 },
|
||||
{ typePool: [MonType.Long], countMin: 4, countMax: 7, weight: 0.3 },
|
||||
{ typePool: [MonType.Support], countMin: 2, countMax: 3, weight: 0.2 },
|
||||
] },
|
||||
{ id: "B2", type: TemplateType.BOSS, tierMin: 2, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.MeleeBoss], countMin: 1, countMax: 1, weight: 1.0 },
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 10, countMax: 15, weight: 0.5 },
|
||||
{ typePool: [MonType.Long, MonType.Support], countMin: 5, countMax: 10, weight: 0.5 },
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 8, countMax: 12, weight: 0.5 },
|
||||
{ typePool: [MonType.Long, MonType.Support], countMin: 5, countMax: 8, weight: 0.3 },
|
||||
{ typePool: [MonType.Assassin], countMin: 2, countMax: 4, weight: 0.2 },
|
||||
] },
|
||||
{ id: "B3", type: TemplateType.BOSS, tierMin: 3, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.MeleeBoss, MonType.LongBoss], countMin: 1, countMax: 1, weight: 1.0 },
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 10, countMax: 20, weight: 0.4 },
|
||||
{ typePool: [MonType.Long, MonType.Assassin], countMin: 5, countMax: 15, weight: 0.3 },
|
||||
{ typePool: [MonType.Support], countMin: 5, countMax: 10, weight: 0.3 },
|
||||
{ typePool: [MonType.Melee, MonType.Heavy], countMin: 8, countMax: 14, weight: 0.35 },
|
||||
{ typePool: [MonType.Long, MonType.Assassin], countMin: 5, countMax: 10, weight: 0.35 },
|
||||
{ typePool: [MonType.Support], countMin: 3, countMax: 6, weight: 0.3 },
|
||||
] },
|
||||
{ id: "B4", type: TemplateType.BOSS, tierMin: 4, allowAffix: true,
|
||||
slots: [
|
||||
{ typePool: [MonType.MeleeBoss, MonType.LongBoss], countMin: 1, countMax: 1, weight: 1.0 },
|
||||
{ typePool: [MonType.Heavy], countMin: 10, countMax: 15, weight: 0.4 },
|
||||
{ typePool: [MonType.Assassin], countMin: 5, countMax: 10, weight: 0.3 },
|
||||
{ typePool: [MonType.Summoner, MonType.Support], countMin: 5, countMax: 10, weight: 0.3 },
|
||||
{ typePool: [MonType.Heavy], countMin: 6, countMax: 12, weight: 0.35 },
|
||||
{ typePool: [MonType.Assassin], countMin: 5, countMax: 8, weight: 0.3 },
|
||||
{ typePool: [MonType.Summoner, MonType.Support], countMin: 4, countMax: 8, weight: 0.2 },
|
||||
{ typePool: [MonType.Melee], countMin: 5, countMax: 10, weight: 0.15 },
|
||||
] },
|
||||
|
||||
// ---- 教程专用 ----
|
||||
// ---- 教程专用 (波1: 1个英雄,3只弱怪热身) ----
|
||||
{ id: "TUTORIAL", type: TemplateType.NORMAL, tierMin: 1, allowAffix: false,
|
||||
slots: [{ typePool: [MonType.Melee], countMin: 2, countMax: 2, weight: 1.0 }] },
|
||||
slots: [{ typePool: [MonType.Melee], countMin: 3, countMax: 3, weight: 1.0 }] },
|
||||
]
|
||||
|
||||
// ======================== 自适应难度配置 ========================
|
||||
@@ -471,14 +478,14 @@ export const BlueprintTemplates: BlueprintTemplate[] = [
|
||||
* @property antiDriftDelta - 反漂移时的反向微调量
|
||||
*/
|
||||
export const AdaptiveConfig = {
|
||||
factorMin: 0.85,
|
||||
factorMax: 1.15,
|
||||
deltaPerWave: 0.03,
|
||||
targetClearTime: 15.0,
|
||||
factorMin: 0.75,
|
||||
factorMax: 1.30,
|
||||
deltaPerWave: 0.04,
|
||||
targetClearTime: 12.0,
|
||||
strongThreshold: 0.8,
|
||||
weakThreshold: 0.3,
|
||||
maxConsecutiveDirection: 5,
|
||||
antiDriftDelta: 0.01,
|
||||
weakThreshold: 0.4,
|
||||
maxConsecutiveDirection: 4,
|
||||
antiDriftDelta: 0.015,
|
||||
}
|
||||
|
||||
// ======================== 无限模式配置 ========================
|
||||
@@ -866,13 +873,15 @@ export class RogueSpawningEngine {
|
||||
}
|
||||
}
|
||||
|
||||
// 预算利用率检查 (目标 >= 70%)
|
||||
// 预算利用率检查 (目标 >= 70%,但填充上限为模板数量的50%)
|
||||
let totalCost = budget - remainingBudget
|
||||
if (budget > 0 && totalCost / budget < 0.7 && template.id !== "TUTORIAL") {
|
||||
const tierConfig = getTierConfig(tier)
|
||||
const type = MonType.Melee
|
||||
const stats = MonsterStats[type]
|
||||
while (remainingBudget >= stats.cost) {
|
||||
const maxFill = Math.max(5, Math.ceil(monsters.length * 0.8))
|
||||
let fillCount = 0
|
||||
while (remainingBudget >= stats.cost && fillCount < maxFill) {
|
||||
const finalHp = Math.max(1, Math.round(stats.hp * tierConfig.multiplier * this.adaptiveFactor))
|
||||
const finalAp = Math.max(1, Math.round(stats.ap * tierConfig.multiplier * this.adaptiveFactor))
|
||||
const uuids = MonList[type]
|
||||
@@ -884,6 +893,7 @@ export class RogueSpawningEngine {
|
||||
spawnIndex++
|
||||
remainingBudget -= stats.cost
|
||||
totalCost += stats.cost
|
||||
fillCount++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BoxCollider2D, instantiate, Node, Prefab, v3, Vec3, NodePool } from "cc";
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { EType, SkillSet, SkillUpList } from "../common/config/SkillSet";
|
||||
import { EType, SkillSet, SkillUpList, SkillOverrides, mergeSkillParams } from "../common/config/SkillSet";
|
||||
import { oops } from "db://oops-framework/core/Oops";
|
||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
import { Attrs } from "../common/config/HeroAttrs";
|
||||
@@ -101,12 +101,13 @@ export class Skill extends ecs.Entity {
|
||||
this.addComponents<SMoveDataComp>(SMoveDataComp);
|
||||
}
|
||||
load(startPos: Vec3, parent: Node, s_uuid: number, targetPos: Vec3,
|
||||
caster:HeroViewComp,cAttrsComp:HeroAttrsComp, skill_lv:number=0, ext_dmg:number=0) {
|
||||
const config = SkillSet[s_uuid];
|
||||
caster:HeroViewComp,cAttrsComp:HeroAttrsComp, skill_lv:number=0, ext_dmg:number=0, overrides?: SkillOverrides) {
|
||||
let config = SkillSet[s_uuid];
|
||||
if (!config) {
|
||||
mLogger.error(this.debugMode, 'Skill', "[Skill] 技能配置不存在:", s_uuid);
|
||||
return;
|
||||
}
|
||||
config = mergeSkillParams(config, overrides);
|
||||
|
||||
// 加载预制体
|
||||
const path = `game/skill/atk/${config.sp_name}`;
|
||||
@@ -211,13 +212,14 @@ export class Skill extends ecs.Entity {
|
||||
const sCrt = (config.crt ?? 0)+(SUp.crt*skill_lv);
|
||||
const sFrz = (config.frz ?? 0)+(SUp.frz*skill_lv);
|
||||
const sAp =config.ap+(SUp.ap*skill_lv);
|
||||
const sHit=config.hit_count+(SUp.hit_count*skill_lv) + cAttrsComp.puncture
|
||||
const sHit=config.hit_count+(SUp.hit_count*skill_lv);
|
||||
sDataCom.Attrs[Attrs.ap] = Math.floor(cAttrsComp.ap*sAp/100); //技能的ap是百分值 需要/100 而且需要再最终计算总ap时再/100,不然会出现ap为90%变0
|
||||
sDataCom.Attrs[Attrs.critical] = cAttrsComp.getRuntimeCritical() + sCrt;
|
||||
sDataCom.Attrs[Attrs.critical_damage] = cAttrsComp.getRuntimeCritDamageBonus();
|
||||
sDataCom.Attrs[Attrs.freeze_chance] = cAttrsComp.getRuntimeFreezeChance() + sFrz;
|
||||
sDataCom.Attrs[Attrs.knockback_chance] = cAttrsComp.knockback_chance || 0;
|
||||
sDataCom.Attrs[Attrs.knockback_distance] = cAttrsComp.knockback_distance || 0;
|
||||
sDataCom.Attrs[Attrs.puncture_chance] = cAttrsComp.getRuntimePunctureChance(); // 初始化携带施法者的穿透概率
|
||||
sDataCom.s_uuid=s_uuid
|
||||
sDataCom.skill_lv = Math.max(0, skill_lv);
|
||||
sDataCom.fac=cAttrsComp.fac
|
||||
|
||||
@@ -2,11 +2,13 @@ import { _decorator, Animation, CCInteger, Collider2D, Contact2DType, UITransfor
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||
import { HeroViewComp } from "../hero/HeroViewComp";
|
||||
import { EType, SkillConfig, SkillSet } from "../common/config/SkillSet";
|
||||
import { DTType, EType, SkillConfig, SkillSet } from "../common/config/SkillSet";
|
||||
import { SDataCom } from "./SDataCom";
|
||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
import { DamageQueueHelper } from "../hero/DamageQueueComp";
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { FightSet } from "../common/config/GameSet";
|
||||
import { Attrs } from "../common/config/HeroAttrs";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@@ -86,7 +88,30 @@ export class SkillView extends CCComp {
|
||||
}
|
||||
this.sData.hit_count++;
|
||||
if (this.sData.hit_count >= this.sData.max_hit_count) {
|
||||
this.handle_collision_limit();
|
||||
// == 新增:穿透概率判定 ==
|
||||
// 仅对单体伤害技能生效(DTType.single)且存在穿透概率
|
||||
if (this.SConf.DTType === DTType.single) {
|
||||
const punctureChance = this.sData.Attrs[Attrs.puncture_chance] || 0;
|
||||
if (punctureChance > 0) {
|
||||
const rand = Math.random() * 100;
|
||||
if (rand < punctureChance) {
|
||||
// 触发穿透:不销毁,增加 max_hit_count 允许继续穿透
|
||||
this.sData.max_hit_count++;
|
||||
// 概率衰减(减去固定的 PUNCTURE_DOWN 值,比如 50)
|
||||
this.sData.Attrs[Attrs.puncture_chance] = Math.max(0, punctureChance - FightSet.PUNCTURE_DOWN);
|
||||
if (this.debugMode) {
|
||||
mLogger.log(this.debugMode, 'SkillView', `[SkillView] 触发穿透!剩余概率: ${this.sData.Attrs[Attrs.puncture_chance]}%`);
|
||||
}
|
||||
} else {
|
||||
// 未触发穿透,正常销毁
|
||||
this.handle_collision_limit();
|
||||
}
|
||||
} else {
|
||||
this.handle_collision_limit();
|
||||
}
|
||||
} else {
|
||||
this.handle_collision_limit();
|
||||
}
|
||||
}
|
||||
// 命中次数按碰撞事件统计:不依赖是否最终造成伤害
|
||||
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
# 技能配置重构设计(简化版)
|
||||
|
||||
## 背景
|
||||
|
||||
当前技能系统核心问题:**同一个技能 UUID,不同角色无法差异化效果**。例如护盾技能 6301,所有角色都是给自己加盾,无法让某个角色给全队加盾。
|
||||
|
||||
## 设计目标
|
||||
|
||||
- SkillConfig **保持不变**,作为技能基座(动画、弹道、默认数值)
|
||||
- 角色通过 **overrides** 覆盖技能的可定制参数(ap、TGroup、hit_count、buffs 等)
|
||||
- 同一个技能 UUID,不同角色可以有不同效果
|
||||
- 触发技能(atking/atked)也支持 overrides
|
||||
- **不迁移 SkillSet 数据**,不拆分接口,不改消费者文件类型引用
|
||||
|
||||
## 改动内容(共 3 个接口 + 1 个函数)
|
||||
|
||||
### 1. SkillOverrides — 角色可覆盖的技能参数
|
||||
|
||||
```typescript
|
||||
/** 角色可覆盖的技能参数 — 所有字段可选 */
|
||||
export interface SkillOverrides {
|
||||
TGroup?: TGroup;
|
||||
ap?: number;
|
||||
hit_count?: number;
|
||||
hitcd?: number;
|
||||
crt?: number;
|
||||
frz?: number;
|
||||
bck?: number;
|
||||
buffs?: BuffConf[];
|
||||
}
|
||||
```
|
||||
|
||||
### 2. HSkillInfo 增加 overrides
|
||||
|
||||
```typescript
|
||||
export interface HSkillInfo {
|
||||
uuid: number;
|
||||
lv: number;
|
||||
cd: number;
|
||||
ccd: number;
|
||||
overrides?: SkillOverrides; // 新增:角色专属参数覆盖
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 触发技能配置增加 overrides
|
||||
|
||||
```typescript
|
||||
// heroInfo 中触发字段扩展:
|
||||
atking?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
atked?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
call?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
dead?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
fstart?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
fend?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||
```
|
||||
|
||||
### 4. mergeSkillParams — 合并基座 + 覆盖
|
||||
|
||||
```typescript
|
||||
/** 合并技能基座参数和角色覆盖参数 */
|
||||
export function mergeSkillParams(
|
||||
config: SkillConfig,
|
||||
overrides?: SkillOverrides
|
||||
): SkillConfig {
|
||||
if (!overrides) return config;
|
||||
return { ...config, ...overrides };
|
||||
}
|
||||
```
|
||||
|
||||
就这么简单:把 config 展开,把 overrides 展开覆盖上去。没有 overrides 时原样返回。
|
||||
|
||||
## 配置示例
|
||||
|
||||
### SkillSet.ts — 不变
|
||||
|
||||
```typescript
|
||||
// 6301 护盾 — 保持原样
|
||||
6301: {
|
||||
uuid: 6301, name: "护盾", ..., TGroup: TGroup.Self, kind: SkillKind.Shield, ap: 3, ...
|
||||
},
|
||||
```
|
||||
|
||||
### heroSet.ts — 角色差异化
|
||||
|
||||
```typescript
|
||||
// 见习战士:受击2次触发护盾,使用基座默认值(给自己加3次盾)
|
||||
5001: {
|
||||
..., atked: [{ s_uuid: 6301, t_num: 2 }],
|
||||
},
|
||||
|
||||
// 盾骑士:受击2次触发护盾,覆盖为全队加2次盾
|
||||
5002: {
|
||||
..., atked: [{ s_uuid: 6301, t_num: 2,
|
||||
overrides: { TGroup: TGroup.Team, ap: 2, hit_count: 3 }
|
||||
}],
|
||||
},
|
||||
|
||||
// 牧师:普攻2次触发治疗,使用基座默认值
|
||||
5301: {
|
||||
..., atking: [{ s_uuid: 6302, t_num: 2 }],
|
||||
},
|
||||
|
||||
// 医师:普攻2次触发治疗,覆盖为持续3次
|
||||
5302: {
|
||||
..., atking: [{ s_uuid: 6302, t_num: 2,
|
||||
overrides: { hit_count: 3, ap: 200 }
|
||||
}],
|
||||
},
|
||||
```
|
||||
|
||||
## 运行时改动(仅 SCastSystem + SkillTriggerHelper)
|
||||
|
||||
### SCastSystem 改动
|
||||
|
||||
`applyFriendlySkillEffects` 和 `applyActualFriendlyEffect` 中:
|
||||
|
||||
```typescript
|
||||
// 旧:直接读 config
|
||||
const kind = config.kind ?? SkillKind.Support;
|
||||
const sAp = config.ap + sUp.ap * _skillLv;
|
||||
|
||||
// 新:先合并 overrides,再读
|
||||
const effective = mergeSkillParams(config, triggerConf?.overrides);
|
||||
const kind = effective.kind ?? SkillKind.Support;
|
||||
const sAp = effective.ap + sUp.ap * _skillLv;
|
||||
```
|
||||
|
||||
改动范围:只在 `applyFriendlySkillEffects` 入口处加一行 `mergeSkillParams`,其余逻辑不变。
|
||||
|
||||
### SkillTriggerHelper 改动
|
||||
|
||||
触发技能时传递 `triggerConf.overrides` 给 SCastSystem。
|
||||
|
||||
### HeroAttrsComp 类型同步
|
||||
|
||||
atking/atked 的内联类型加上 `overrides?: SkillOverrides`。
|
||||
|
||||
## 涉及文件
|
||||
|
||||
| 文件 | 改动 |
|
||||
|------|------|
|
||||
| `SkillSet.ts` | 新增 `SkillOverrides` 接口 + `mergeSkillParams` 函数 |
|
||||
| `heroSet.ts` | HSkillInfo 增加 `overrides?`,触发配置增加 `overrides?` |
|
||||
| `HeroAttrsComp.ts` | atking/atked 内联类型增加 `overrides?` |
|
||||
| `SCastSystem.ts` | applyFriendlySkillEffects 中调用 mergeSkillParams |
|
||||
| `SkillTriggerHelper.ts` | 传递 overrides |
|
||||
|
||||
**不涉及的文件**:Skill.ts、SkillView.ts、SMoveSystem.ts、STimeComp.ts、HeroAtkSystem.ts、HeroViewComp.ts、Hero.ts、Mon.ts、CardComp.ts、IBoxComp.ts — 这些文件不改动。
|
||||
Reference in New Issue
Block a user