工程参考/配置文件/Public/CityBuilding.txt
CityBuilding.txt 登记城市里每一座建筑。第 1 到 8 列是基础信息(其中第 3、7、8 列是给客户端与编辑器用的名称与摆放数据,服务端不读);第 9 到 13 列是 1 到 5 级的升级条件,第 14 到 18 列是对应等级引用的研究集合,第 19 到 23 列是对应等级的维护消耗。样本 3240 行、23 列。
升级条件指向 Public/Condition.txt 的行号,研究集合指向 Public/ResearchItem.txt 的行号,两者都是 1 起。
文件位置与生效
| 项目 | 说明 |
|---|---|
| 运行文件 | ../Public/Config/CityBuilding.txt,由 FileDef.h 的 FILE_CITY_BUILDING 定义,相对于 World 工作目录;客户端从资源目录按同名文件加载。
|
| 读取程序 | World 进程:TableInit::Init_CityBuilding 用 FILE_CITY_BUILDING 宏("../Public/Config/CityBuilding.txt")打开;客户端 GMDataBase.cpp 以 DBC_CITY_BUILDING 注册同名文件,不限列数 |
| 生效方法 | 正常保存并停 World 后重启 World;客户端一侧需要随资源更新并重启客户端。当前检索未发现单独重载本文件的可用入口。 |
| 样本格式 | GB18030-compatible,CRLF。保留原编码;源码读取器不会自动把中文转为 UTF-8。
|
服务端 Init_CityBuilding 逐行读取,跳过第 3 列(名称)、第 7、8 列(Gfx 位置与旋转)——这三列只有客户端结构里才有对应字段。随后对 nLevel 从 0 到 MAX_BUILDING_LEVEL-1(即 5 个等级)分别读 0 基 8+nLevel、13+nLevel、18+nLevel 三列。
| 列组 | 源码下标 | 含义 |
|---|---|---|
| 第 9 到 13 列 | 0 基 8+nLevel | nLevelRequire:升到该等级所需的 Condition.txt 编号(1 起)。 |
| 第 14 到 18 列 | 0 基 13+nLevel | nResearchItem:该等级引用的 ResearchItem.txt 集合号(1 起)。 |
| 第 19 到 23 列 | 0 基 18+nLevel | nLevelMaintain:该等级的维护消耗。 |
| 易错点 | 说明 |
|---|---|
| 列名起点的两套习惯 | LevelRequire 列名写 1 到 5,ResearchItem 与 Maintain 列名写 0 到 4,但代码一律按 0 基数组使用。列名不能当列号用。 |
| 等级是叠加的 | 取研究集合时 for Level 从 0 到当前等级,高等级建筑会叠加低等级的所有集合。 |
| -1 的含义 | 研究集合列填 -1 表示该等级没有研究项;升级条件列为 -1 会被引擎当成非法编号拒绝。 |
| BuildingType 是下标 | 第 4 列直接作为 m_Builds[BuildingType] 的下标,取值 0 到 17。
|
文件格式
首行是类型行:INT INT STRING INT INT INT STRING STRING INT INT INT INT INT INT INT INT INT INT INT INT INT INT INT;第二行是列名行,程序跳过其内容;从第三行开始读取数据。各列用真实 Tab 分隔,保留首列、空列及行尾,不用空格代替。数据行行首 # 表示注释,分号不是此表的注释规则。首列为空的行被跳过;不足的尾列补为空值,多余列不参与本页字段读取。空整数和非数字经 atoi 可能成为 0,空字符串仍为空,不把解析成功当作业务合法。第一列须唯一,重复会触发读取器错误。
字段详解
列号从 1 开始,源码列下标从 0 开始。
| 字段与类型 | 含义与修改要点 | 缺项或特殊值 |
|---|---|---|
第 1 列INT:ID |
建筑记录编号,同时是 DBC 索引列。加载后写进城市数据的 m_BuildingID。 | 必须唯一且非空;重复触发 DBC 重复索引错误,空首列使整行被跳过。 |
第 2 列INT:CityID |
该建筑所在城市的场景 ID。 | 加载时断言落在 0 到 MAX_SCENE-1(1023)。填错会让建筑挂到别的城市。 |
第 3 列STRING:Name$1$ |
建筑名称。服务端不读这一列,只存在于客户端结构 _DBC_CITY_BUILDING::szCityName 与编辑器数据里。
|
服务端改它无效果;改它只影响客户端显示,需要随资源更新客户端。 |
第 4 列INT:BuildingType |
逻辑建筑类型,直接作为 m_Builds[BuildingType] 的下标:0 县衙、1 厢房、2 酒肆、3 钱庄、4 防具、5 锻台、6 武具、7 米仓、8 城墙、9 集仿、10 医舍、11 武仿、12 箭塔、13 书房、14 奇迹、15 校场、16 火冰塔、17 大旗。
|
加载时断言落在 0 到 BUILDING_MAX(18)。同一城市同一类型只能有一行生效。 |
第 5 列INT:BuildingID |
建筑的资源 ID,客户端按它去建筑定义表里取模型与图标。 | 加载时断言非负。 |
第 6 列INT:InitialLevel |
初始等级。 | 加载时断言非负。 |
第 7 列STRING:GfxPosition |
建筑在场景里的摆放坐标,三个数字用空格分隔(例如 400 1200 -5600)。服务端不读这一列。 | 只有客户端与场景编辑器使用;改它需要同步客户端资源。 |
第 8 列STRING:GfxOrientation |
建筑摆放的旋转四元数,四个数字用空格分隔。服务端不读这一列。 | 同上。 |
第 9 列INT:LevelRequire1 |
升到第 1 级所需的 Condition.txt 条件编号(1 起)。加载后存进 m_nCondition[0],由 BuildingCore::CanLevelUp 在升级时校验并扣除。注意列名从 1 起,代码下标从 0 起。
|
加载时断言 >= -1。实际升级时编号必须落在 1 到 Condition.txt 行数之间,否则日志出现 iCondition 相关错误并失败。 |
第 10 列INT:LevelRequire2 |
升到第 2 级所需的 Condition.txt 条件编号(1 起)。加载后存进 m_nCondition[1],由 BuildingCore::CanLevelUp 在升级时校验并扣除。注意列名从 1 起,代码下标从 0 起。
|
加载时断言 >= -1。实际升级时编号必须落在 1 到 Condition.txt 行数之间,否则日志出现 iCondition 相关错误并失败。 |
第 11 列INT:LevelRequire3 |
升到第 3 级所需的 Condition.txt 条件编号(1 起)。加载后存进 m_nCondition[2],由 BuildingCore::CanLevelUp 在升级时校验并扣除。注意列名从 1 起,代码下标从 0 起。
|
加载时断言 >= -1。实际升级时编号必须落在 1 到 Condition.txt 行数之间,否则日志出现 iCondition 相关错误并失败。 |
第 12 列INT:LevelRequire4 |
升到第 4 级所需的 Condition.txt 条件编号(1 起)。加载后存进 m_nCondition[3],由 BuildingCore::CanLevelUp 在升级时校验并扣除。注意列名从 1 起,代码下标从 0 起。
|
加载时断言 >= -1。实际升级时编号必须落在 1 到 Condition.txt 行数之间,否则日志出现 iCondition 相关错误并失败。 |
第 13 列INT:LevelRequire5 |
升到第 5 级所需的 Condition.txt 条件编号(1 起)。加载后存进 m_nCondition[4],由 BuildingCore::CanLevelUp 在升级时校验并扣除。注意列名从 1 起,代码下标从 0 起。
|
加载时断言 >= -1。实际升级时编号必须落在 1 到 Condition.txt 行数之间,否则日志出现 iCondition 相关错误并失败。 |
第 14 列INT:ResearchItem0 |
第 0 级(代码下标)引用的 ResearchItem.txt 集合号(1 起)。取用代码是 for(Level = 0; Level <= BuildingLevel; ++Level),因此高等级建筑会叠加低等级的所有集合,不是只取最高等级这一个。
|
加载时断言 >= -1。填 -1 表示该等级没有研究项;填 0 或超出 ResearchItem.txt 行数都会被跳过并写日志。 |
第 15 列INT:ResearchItem1 |
第 1 级(代码下标)引用的 ResearchItem.txt 集合号(1 起)。取用代码是 for(Level = 0; Level <= BuildingLevel; ++Level),因此高等级建筑会叠加低等级的所有集合,不是只取最高等级这一个。
|
加载时断言 >= -1。填 -1 表示该等级没有研究项;填 0 或超出 ResearchItem.txt 行数都会被跳过并写日志。 |
第 16 列INT:ResearchItem2 |
第 2 级(代码下标)引用的 ResearchItem.txt 集合号(1 起)。取用代码是 for(Level = 0; Level <= BuildingLevel; ++Level),因此高等级建筑会叠加低等级的所有集合,不是只取最高等级这一个。
|
加载时断言 >= -1。填 -1 表示该等级没有研究项;填 0 或超出 ResearchItem.txt 行数都会被跳过并写日志。 |
第 17 列INT:ResearchItem3 |
第 3 级(代码下标)引用的 ResearchItem.txt 集合号(1 起)。取用代码是 for(Level = 0; Level <= BuildingLevel; ++Level),因此高等级建筑会叠加低等级的所有集合,不是只取最高等级这一个。
|
加载时断言 >= -1。填 -1 表示该等级没有研究项;填 0 或超出 ResearchItem.txt 行数都会被跳过并写日志。 |
第 18 列INT:ResearchItem4 |
第 4 级(代码下标)引用的 ResearchItem.txt 集合号(1 起)。取用代码是 for(Level = 0; Level <= BuildingLevel; ++Level),因此高等级建筑会叠加低等级的所有集合,不是只取最高等级这一个。
|
加载时断言 >= -1。填 -1 表示该等级没有研究项;填 0 或超出 ResearchItem.txt 行数都会被跳过并写日志。 |
第 19 列INT:Maintain0 |
第 0 级(代码下标)的维护消耗。 | 加载时断言非负。 |
第 20 列INT:Maintain1 |
第 1 级(代码下标)的维护消耗。 | 加载时断言非负。 |
第 21 列INT:Maintain2 |
第 2 级(代码下标)的维护消耗。 | 加载时断言非负。 |
第 22 列INT:Maintain3 |
第 3 级(代码下标)的维护消耗。 | 加载时断言非负。 |
第 23 列INT:Maintain4 |
第 4 级(代码下标)的维护消耗。 | 加载时断言非负。 |
常用修改实例
示例为局部教学片段,先备份原运行文件,再修改对应行并保留其余配置。教学值不是程序默认值。 以下代码块保留真实 Tab;本地示例文件保留原样本编码、中文表头与 CRLF。网页文字使用浏览器编码显示,不表示运行文件应改存 UTF-8。
让城墙(ID 15)在 0 级就挂上 1 号研究集合
修改前:
INT INT STRING INT INT INT STRING STRING INT INT INT INT INT INT INT INT INT INT INT INT INT INT INT ID CityID Name$1$ BuildingType BuildingID InitialLevel GfxPosition GfxOrientation LevelRequire1 LevelRequire2 LevelRequire3 LevelRequire4 LevelRequire5 ResearchItem0 ResearchItem1 ResearchItem2 ResearchItem3 ResearchItem4 Maintain0 Maintain1 Maintain2 Maintain3 Maintain4 15 205 城墙 8 17 0 400 0 1000 1 0 0 0 1 1 1 1 -1 -1 -1 -1 -1 -1 0 0 0 0 0
修改后:
INT INT STRING INT INT INT STRING STRING INT INT INT INT INT INT INT INT INT INT INT INT INT INT INT ID CityID Name$1$ BuildingType BuildingID InitialLevel GfxPosition GfxOrientation LevelRequire1 LevelRequire2 LevelRequire3 LevelRequire4 LevelRequire5 ResearchItem0 ResearchItem1 ResearchItem2 ResearchItem3 ResearchItem4 Maintain0 Maintain1 Maintain2 Maintain3 Maintain4 15 205 城墙 8 17 0 400 0 1000 1 0 0 0 1 1 1 1 -1 1 -1 -1 -1 -1 0 0 0 0 0
按第 1 列定位 ID 15。这是一座城墙(BuildingType 8、BuildingID 17、CityID 205),第 14 列 ResearchItem0 原本是 -1,表示 0 级没有研究项;改成 1 之后,等级 0 的建筑就会引用 ResearchItem.txt 的第 1 个集合(18 项研究)。
研究集合是叠加的:代码从 Level 0 一直取到建筑当前等级,所以 0 级挂上的集合在更高等级依然生效。想让某项只在高级出现,应该改对应等级那一列,而不是 0 级这一列。
示例块含类型行、列名行与该行原文,不能覆盖整张表。改完需要重启 World,客户端如果也要显示研究列表还需同步资源。
验证与排查
World 启动日志里 Init_CityBuilding 不会单独打印成功行(它以 Init 的其它日志为准);CityID、BuildingType、BuildingID、InitialLevel 为负或越界、三组分列为负都会断言。改动后重启 World,进入对应城市的建筑界面核对等级、升级条件提示与维护消耗;再发起升级与研究的完整流程,确认条件编号与集合号都指到了正确的行。失败时恢复备份并重启。
列名起点的两套习惯不要混用
同一张表里 LevelRequire 用 1 到 5 命名,ResearchItem 与 Maintain 用 0 到 4 命名,而代码一律按 0 基数组。看列名数格子必然错位,一律按上表的列号对。
研究集合是逐级叠加的
for(Level = 0; Level <= BuildingLevel; ++Level) 说明等级 3 的建筑会依次应用下标 0、1、2、3 四个集合。只改最高等级那一列,低等级的集合依然生效。
三列服务端不读
第 3 列名称、第 7 列 GfxPosition、第 8 列 GfxOrientation 在 World 的加载函数里没有出现,只有客户端结构有对应字段。改这三列不影响服务端,改摆放与名称需要同步客户端资源。
BuildingType 是数组下标不是枚举名
第 4 列直接用作 m_Builds[BuildingType],范围 0 到 17(BUILDING_MAX = 18),与 MAX_CITY_BUILDING_NUM 相同。同一城市里重复的类型只会有一行生效。
客户端整表读取
注册项 DBC_CITY_BUILDING 没有写 nColumnToRead,结构体 _DBC_CITY_BUILDING 覆盖全部 23 列(含服务端不读的三列)。改列数必须同步改结构体。
关联与依据
Public/ResearchItem.txt · Public/Condition.txt
其他配置及整理状态 · 服务端外网设置 · Lua 接口索引
Common/DataBase/TLBB_DBC.cpp:实际加载、解析、字段使用或示例关联依据Common/DataBase/TLBB_DBC.h:实际加载、解析、字段使用或示例关联依据Server/Server/WorldServer/World/Main/WorldTable.cpp:实际加载、解析、字段使用或示例关联依据Server/Server/WorldServer/World/Main/WorldTable.h:实际加载、解析、字段使用或示例关联依据Common/GameDefine_City.h:实际加载、解析、字段使用或示例关联依据Server/Server/WorldServer/World/WorldData/City.cpp:实际加载、解析、字段使用或示例关联依据Server/Server/WorldServer/World/WorldData/IBuilding.cpp:实际加载、解析、字段使用或示例关联依据Server/Server/WorldServer/World/WorldData/BuildingCore.cpp:实际加载、解析、字段使用或示例关联依据Server/Server/WorldServer/World/WorldData/exe/ExeCityResearchLevelUp.cpp:实际加载、解析、字段使用或示例关联依据Server/Server/WorldServer/World/WorldData/exe/ExeCityBuildingLevelUp.cpp:实际加载、解析、字段使用或示例关联依据Common/ServerBase/FileDef.h:实际加载、解析、字段使用或示例关联依据Client/Client/Common/TDDBC_Struct.h:实际加载、解析、字段使用或示例关联依据Client/Client/Game/DBC/GMDataBase.cpp:实际加载、解析、字段使用或示例关联依据Client/Client/Game/Interface/GMInterface_Script_City.cpp:实际加载、解析、字段使用或示例关联依据resources/Public/Config/CityBuilding.txt:实际加载、解析、字段使用或示例关联依据
本页核对 Init_CityBuilding 读取的 0 基列号(含被跳过的第 3、7、8 列)、MAX_BUILDING_LEVEL=5 的三列循环、各字段的断言范围,以及 City.cpp 把三组分列写进 IBuilding、BuildingCore::CanLevelUp 用 m_nCondition 校验、研究集合的逐级叠加取法;同时核对客户端 _DBC_CITY_BUILDING 覆盖 23 列与 nResearchItem 的用法。未启动服务端与游戏,城市建筑的实际表现需要实测。