工程参考/角色外观配置
角色外观分两层:定义表说「有哪些脸型/发型/头像、给哪个门派、要什么物品、多少钱」;模型表说「这个编号对应哪个 mesh、什么材质、男女各是哪一版」。服务端六张表由 TLBBExterior(实现位于 Common/ExteriorTables.h)在 GameServer 启动时加载,客户端另有五张自己读的同主题表。
加载与启动校验
服务端循环加载六张表后调用 Valid(),任一不符 GameServer 拒绝启动:
- 列数硬约束:脸型定义 8、发型定义 9、头像定义 7、脸型模型 11、发型模型 13、头像模型 11;行数必须非空。
- 首列 ID 必须为正且不重复。
- 六类(脸型/发型/头像各含定义与模型)都必须非空。
- 每条定义对两个性别都要能找到对应模型,且模型的性别列与之一致;
visible=1的定义还必须满足 物品>0、数量>0、费用≥0。
定义表:Exterior_Face / Exterior_Hair / Exterior_Head
三张表同构,样本分别 102、151、40 行。
| 列 | 内容 | 说明 |
|---|---|---|
| 1 | 外观 ID | 主键,正数不重复。 |
| 2 | 女性模型编号 | 指向同主题模型表的行(CharFaceGeo / CharHairGeo / CharHead)。 |
| 3 | 男性模型编号 | 同上,男女分开两列,不靠性别列切换。 |
| 4 | 分类 | 界面分组用。 |
| 5 | 是否上架 | 只能 0 或 1。0 表示存在但不许选用。 |
| 6 | 排序权重 | 列表排序按权重大的在前。 |
| 7 | 门派限制 | 负数表示全门派可用;否则必须等于角色门派编号才显示。 |
| 8 | 描述文本 | 脸型与发型有;头像表只有 7 列,没有这一列。 |
| 9 | 物品名 | 只有发型表有(第 9 列),脸型表到第 8 列为止。 |
模型表:CharFaceGeo / CharHairGeo / CharHead
三张表同构,样本分别 216、316、80 行。同一张模型表里男女条目混放,靠第 2 列性别区分。
| 列 | 内容 | 说明 |
|---|---|---|
| 1 | 模型 ID | 主键,可负(加载器允许 id<0,只查重)。 |
| 2 | 性别 | 0 女 1 男。定义表按性别取对应模型,取错性别 Valid 直接失败。 |
| 3 | 名称 | 脸型在第 3 列、发型在第 4 列、其余主题在第 2 列——列位不统一,按 ExteriorTables.h 的 name 取法核对。
|
| 4 | 网格 mesh | 脸型/发型有;头像没有。 |
| 5 | 材质 | 脸型在第 4 列,发型与头像在第 5 列。 |
| 6–8 | 兑换三件套 | 物品编号、数量、选择类型(脸型从第 5 列起、发型从第 7 列起、其余从第 3 列起——同样不统一)。 |
| 9 | 图标 | 紧跟兑换三件套之后。 |
| 10 | 费用 | 图标后一列,≥0。 |
| 末列 | 对立性别模型 | 指向另一性别的对应模型;脸型表是第 11 列、发型表第 13 列、头像表第 11 列。 |
发型表额外两列(第 4 列第二网格、第 7 列第二材质)用于双网格发型;修改时注意它比脸型表宽 2 列。
客户端五张表
这些表 Game.exe 自己读,服务端不读;改玩家看到的外观要同步客户端资源(按 Client/Bin/FairyResources.cfg 的 [General] 定位)。
CharacterFace.txt(头像,6 列 80 行)
客户端 DBC_CHARACTER_FACE 注册(实现位于 Client/Game/DBC/GMDataBase.cpp),解码函数 DecodeCharacterFaceGeometry(实现位于 Client/Common/TDCharacterFaceGeometry.h)。样本列为 编号、性别、set:GirlProtagonist image:GirlProtagonist_1 形式的资源串、两个整数、尾部资源串。列数与类型由 IsCharacterFaceGeometryLayout 校验,不符直接抛异常。
EquipDress.txt(时装外观,7 或 8 列,样本 8 列 173 行)
客户端 DBC_EQUIP_DRESS(编号 121)。七列是官服布局,八列是本项目扩展:
| 列 | 内容 | 说明 |
|---|---|---|
| 1 | 时装 ID | 主键。 |
| 2–5 | 四槽视觉 | 帽子、身体、手臂、鞋各一列,-1 表示该槽不覆盖。 |
| 6 | 披风 | 仅八列布局读取;无披风置 INVALID_ID。 |
| 倒数第 2 | 材质序号 | 每种性别 1..10。 |
| 末列 | 基础时装 ID | 样本末列与首列相同。 |
列数不是 7 或 8 时客户端 TDThrow 拒绝加载(实现位于 GMDataBase.cpp 的 IsEquipDressLayout)。
SpecialDressEffect.txt(时装特效,5 列 12 行)
客户端 Obj_PlayerOther.cpp 用 Util_OpenDBCFromTxt 打开,必须正好 5 列否则抛异常。列为 特效 ID、女性绑点串、男性绑点串、颜色(FFFFFFFF)、名称。样本形如 256 时装_宝石白蛇传_女腰:身体中心点, 时装_宝石白蛇传_男腰:身体中心点, FFFFFFFF 七夕时装;同一行可挂多个绑点,用逗号分隔。
NumberingFashion.txt(编号时装,4 列 300 行)
300 行分三个连续物品区间:10125382–10125481(编号 1–100)、10126034–10126133(101–200)、10126751–10126850(201–300)。列为 编号、物品号、组内序号、提示文本键(如 #{SZBH_231103_01})。
注意:服务端 Lua 接口 LuaFnGetNumberingFashionCode(实现位于 Server/Script/LuaFnTbl_Exterior.h)把这三段区间硬编码在代码里,并不读这个文件;客户端 ExteriorLua.cpp 另有编号时装的视觉与动作查询函数。改区间要同时改代码和表,只改表不生效。
DressColorSpecial.txt(空样本)
只有两行表头(INT、STRING),没有数据行;当前检索未发现读取它的代码。属于预留样本。
修改清单
- 加一种新脸型:模型表加男女各一行(性别列 0/1 各一),定义表加一行指向两个模型编号,
visible、物品、数量、费用填全,否则 Valid 失败。 - 让某脸型只对一个门派可见:定义表第 7 列填门派编号(负数=全门派)。
- 男女模型不要混用:定义表按性别取模型,模型表性别列必须匹配。
- 客户端外观不同步时,玩家看到的还是旧资源;改完服务端表还要按客户端资源更新流程替换
Client/Data/Config或Config.axp内同名文件并重启 Game.exe。