跳到主要内容

SkillBase 技能「效果」字段配置指南

面向新策划的入门手册,帮助你读懂 SkillBase 表中「效果」这一列在配什么, 以及这些效果最终如何作用到角色、如何显示在客户端。

适用对象:技能策划、数值策划 关联文件:tbl/SkillBase.xmltbl/SkillBase.tbl2ScenesServer/SkillStatusManager.cppbase/Command.h


一、效果字段是什么?

SkillBase(技能基础表)的第 21 个字段名为「效果」,是一行技能全部效果的浓缩文本

它不像「技能ID」「技能等级」那样是一个简单数字,而是一串用符号分隔的嵌套文本, 由服务端在启动时解析为「状态组(SkillStatus)× 效果元素(SkillElement)」两个层级。

核心模型:

一个技能 = 若干「状态组」 (每组描述一种攻击/施加方式)
一个状态组 = 若干「效果元素」 (每个元素描述一条具体的数值/状态效果)

直观理解:一个技能可以“先给自身加 buff,再对敌人造成物理伤害”, 这就是两个状态组;其中“给自身加物攻 +458”就是一组里的一个效果元素


二、四级分隔符:. : ; -

效果文本用 4 种符号分隔,按层级从外到内:

分隔符作用层级
.分隔多个状态组(SkillStatus)第 1 层(外层)
:状态组内,分隔「状态定义 | 效果元素列表」第 2 层
;分隔组内多个效果元素(SkillElement)第 3 层
-分隔状态 / 元素内部的各数值字段第 4 层(最内层)

结构示意:

[状态定义]-[状态定义]...:[元素]-[元素]-[元素];[元素]-[元素]-[元素];.下一组...
│ └── 7 个 `-` 分隔的字段(SkillStatus) │ └── 5 个 `-` 分隔的字段(SkillElement)
└──────────────┬──────────────────────────┘
`:` 分隔状态与元素列表
└──────────────────────┬──────────────────────┘
`.` 分隔多个状态组

规则要点:

  • 每组以 : 分隔出「状态定义」和「元素列表」两部分,元素列表可能为空。
  • 每个元素以 ; 分隔;元素内字段以 - 分隔。
  • 末尾的 . 常作为格式结束符(空状态组占位)。
  • 效果为单个 0(或空)表示“无效果”占位。

三、状态定义 SkillStatus(7 个字段)

每个状态组开头的 7 个字段,描述“这一组效果对谁生效、怎么生效”。

A - B - C - D - E - F - G
id target center range mode clear isInjure
位置字段含义取值说明
1id状态组标识通常为 0,组间靠顺序区分
2target目标类型(位掩码1=自身;2=友方;4=敌方;8=NPC;12=4+8(敌方+NPC);16=地表;32=宠物;64=召唤物。多个目标可用和值叠加
3center施法中心点1=鼠标点;2=自身
4range攻击范围1=单体目标;20/21/22/50 等=范围攻击
5mode飞行模式0=近身(需相邻格);1=飞行(魔法弹道可跨格)
6clear能否被清除该状态可否被驱散 / 覆盖
7isInjure是否触发伤害判定1=进入伤害结算;0=仅施加状态不直接掉血

四、效果元素 SkillElement(5 个字段)

状态组内每个元素,描述一条具体效果

A - B - C - D - E
id percent value time state
位置字段含义说明
1id效果状态 ID对应服务端 SkillStatusManager.cppSkillStatus_XX() 处理函数,即 funlist[XX],决定这条效果做什么
2percent触发百分比按百分比概率触发(100=必定触发;2=2% 概率)
3value效果数值具体加成 / 伤害 / 数值
4time持续时间状态持续时间(秒)
5state状态表现对应客户端 USTATE_* 状态,决定 buff 图标 / 特效显示(见第六节)

五、完整示例解析:「逆手刺」(技能 ID = 12)

原始效果字段:

0-1-2-1-0-0-0:23-100-458-1-0;273-2-200-1-0;.0-12-2-1-0-0-1:133-0-0-0-0;.

拆分为 3 个状态组:

状态组 1:0-1-2-1-0-0-0 → 对自身施加 buff

  • 状态定义:id=0 target=1(自身) center=2(以自身为中心) range=1(单体) mode=0(近身) clear=0 isInjure=0
  • 效果元素① 23-100-458-1-0
    • SkillStatus_23()skillValue.updam = value物理攻击力 +458
    • percent=100 必定触发,time=1
  • 效果元素② 273-2-200-1-0
    • SkillStatus_273()skillValue.nsc_updamp = value隐身/刺客系物理攻击 +200
    • percent=2,即 2% 概率额外触发(对应匕首系特有增益)

状态组 2:0-12-2-1-0-0-1 → 对敌方目标造成物理伤害

  • 状态定义:target=12(敌方+NPC) isInjure=1(触发伤害判定)
  • 效果元素 133-0-0-0-0
    • SkillStatus_133()isPhysics = true标记本次攻击为物理伤害,随后进入伤害结算

状态组 3:末尾 . → 空状态组(格式结束符)

整句含义:逆手刺是一个匕首系物理单体技能,命中时给自身附加 「物攻 +458」与「隐身系物攻 +200(2% 概率)」两个增益, 同时将本次攻击标记为物理伤害并结算。


六、效果如何与客户端关联

6.1 效果在服务端的运行路径

SkillBase.tbl2 → 服务端加载 → 解析为 zSkillB.skillStatus

角色使用技能 → putOperationToMe / putPassivenessOperationToMe

对每条 SkillElement 执行 SkillStatus_[id]()

runStatusElement 返回 SKILL_RECOVERY / SKILL_ACTIVE ...

6.2 SkillElement.id → SkillStatus_XX() 效果函数

SkillElement.id效果逻辑的入口,服务端通过 funlist[id] 调用对应的 SkillStatus_XX(entry, element) 处理函数。函数内部根据 percent(概率)、 value(数值)、time(时长) 落地具体属性 / 状态。

常用效果 ID 速查(部分):

IDSkillStatus_XX效果
23SkillStatus_23物理攻击力 +value(updam
133SkillStatus_133标记本次攻击为物理伤害
134SkillStatus_134取消物理伤害标记
273SkillStatus_273隐身/刺客系物理攻击 +value(nsc_updamp

完整的 SkillStatus_0 ~ SkillStatus_2xx 效果列表见 ScenesServer/SkillStatusManager.cpp(每个函数上方都有中文注释说明用途)。 新增效果需要在 funlist 中登记,并同步客户端协议。

6.3 SkillElement.state → 客户端 USTATE_* 状态

当效果需要以“持续状态”形式显示给玩家时,用 state 字段指定一个客户端状态 ID。

  • 服务端在效果生效时调用 sendSelectStates(state, value, time), 通过 sendtoSelectedState / sendSevenStateToMe 同步给客户端。
  • 客户端用该 ID 对应 base/Command.h 中的 USTATE_* 枚举,渲染 buff 图标 / 头顶特效 / 状态栏。

常用 USTATE 速查:

USTATE 值常量名含义
0USTATE_DEATH死亡
1USTATE_POISON中毒
2USTATE_FREEZE冰冻
4USTATE_HIDE隐身
22USTATE_BLED流血
30USTATE_SLOW缓慢
48USTATE_BOMB诅咒炸弹

客户端 SkillBase 表(skillbase_client.txt)里没有「效果」字段—— 效果数值与状态由服务端按本表的「效果」字段解析后计算,再通过状态同步 协议把 state / value / time 下发给客户端用于表现。因此策划只需在服务端 SkillBase 表配好「效果」列,客户端表现会随状态同步自动显示。


七、关于 tbl2 可变长主业务线(为什么不再截断)

历史上效果字段受定长 1024 字节限制:服务端把效果字符串拷贝进 SkillBase.strField21[1024],超过 1023 字节会被静默截断,导致技能实际效果不完整。

现已在代码层将整张 SkillBase 表迁移到 tbl2 可变长主业务线:

  • 表格已使用 tbl2 池化格式stringPool="1"),字符串变长存储、无长度限制。
  • 服务端加载 tbl2 时,整张表(名称、需要武器、效果及全部数值字段)统一从字符串池 直接解析进 zSkillB 的可变长容器(skillStatus 等),不再经由定长 SkillBasestrField21[1024])中转,彻底消除超长截断风险。
  • 旧版定长 .tbl 格式仍被兼容(通过旧 fill() 路径映射进同一数据结构), 保证老数据不丢失。

对策划的意义:只要在 Excel/XML 里按规范书写「效果」字段,无论配多长、 多少个状态组和元素,都会完整生效,无需担心长度限制。 建议仍保持可读性:一行技能的效果尽量控制在 2~4 个状态组内。


八、配置速查清单

配「效果」字段时,自问几个问题:

  1. 对谁生效? → 填 target(自身/友方/敌方/NPC,可叠加)
  2. 怎么施加? → 填 centerrangemode(近身/飞行、单体/范围)
  3. 会造成伤害吗? → 填 isInjure(1 走伤害结算)
  4. 加什么属性? → 用「效果元素」的 id 选效果函数,value 填数值
  5. 是否必定触发? → 填 percent
  6. 持续多久? → 填 time
  7. 要不要在客户端显示状态图标? → 填 state(对应 USTATE_*