BaiZhanChengShenDefine.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. -- 百战成神 常量定义
  2. --
  3. -- 玩法概要:
  4. -- 跨服 5v5 积分 PvP, 5 种族独立阵容(COMBAT_TYPE39~43), 5 局 3 胜制。
  5. -- 开服>=45 天可参与; 周六 0:10 ~ 周日 23:00 可挑战; 每轮开放后隔 3 个开放周,第 5 周再开新轮。
  6. -- 一次点击挑战仅扣 1 次(每日 5 次免费, 不足扣道具 115 x5)。
  7. -- 攻胜 INT((敌方-己方)/10+100) 限[50,500]; 攻负-50; 守胜+50; 守负-INT(攻方得分/2); 初始积分 3000。
  8. --
  9. -- 架构: 普通服 NS + 跨服 CS + Mongo DB(db_bzcs)
  10. -- 首次挑战完成 REGISTER; 阵容变更 UPDATE_SHOW; 积分/匹配/排行在跨服
  11. --------------------------------------------------------------------------------
  12. -- 活动时间 (Util.getWeekDay: 1=周日, 2=周一, 3=周二 ... 7=周六)
  13. --------------------------------------------------------------------------------
  14. BZCS_OPEN_WDAY_AREA = {7, 1} -- 可挑战星期: 周六~周日 (getWeekDay: 7=周六, 1=周日)
  15. BZCS_START_SEC = 600 -- 每日开始时刻: 0:10 (距 0 点秒数)
  16. BZCS_END_SEC = 82800 -- 每日结束时刻: 23:00
  17. BZCS_SKIP_OPEN_WEEKS = 3 -- 本轮开放后跳过的开放周数(第2~4周不开新轮)
  18. BZCS_CYCLE_DAYS = (1 + BZCS_SKIP_OPEN_WEEKS) * 7 -- 距上次开轮最少天数(28), 第5个开放周可开
  19. BZCS_OPEN_DAYS = 2 -- 单轮活动持续天数(周六+周日, 用于 IsRunning 校验)
  20. -- 开放结束日相对开始日的天数偏移(周六->周日为 1)
  21. function GetOpenEndDayOffset()
  22. local s = BZCS_OPEN_WDAY_AREA[1]
  23. local e = BZCS_OPEN_WDAY_AREA[2]
  24. if s <= e then
  25. return e - s
  26. end
  27. return e + 7 - s
  28. end
  29. --------------------------------------------------------------------------------
  30. -- 积分规则
  31. --------------------------------------------------------------------------------
  32. BZCS_INIT_SCORE = 3000 -- 每轮初始/重置积分
  33. BZCS_ATK_WIN_BASE = 100 -- 进攻胜公式基数: INT((敌方-己方)/10 + BASE)
  34. BZCS_ATK_WIN_MIN = 50 -- 进攻胜最低加分
  35. BZCS_ATK_WIN_MAX = 500 -- 进攻胜最高加分
  36. BZCS_ATK_LOSE_SCORE = -50 -- 进攻方整场失败扣分
  37. BZCS_DEF_WIN_SCORE = 50 -- 防守方整场获胜加分(对手进攻失败)
  38. -- 按战前积分计算攻守本场变化; 返回 atkDelta, defDelta
  39. function CalcFightScoreDelta(atkScore, defScore, atkWin)
  40. if atkWin then
  41. local gain = math.floor((defScore - atkScore) / 10 + BZCS_ATK_WIN_BASE)
  42. if gain < BZCS_ATK_WIN_MIN then
  43. gain = BZCS_ATK_WIN_MIN
  44. elseif gain > BZCS_ATK_WIN_MAX then
  45. gain = BZCS_ATK_WIN_MAX
  46. end
  47. return gain, -math.floor(gain / 2)
  48. end
  49. return BZCS_ATK_LOSE_SCORE, BZCS_DEF_WIN_SCORE
  50. end
  51. -- excel.baiZhanChengShen.fightReward 配置 id
  52. BZCS_FIGHT_REWARD_WIN_ID = 1 -- 挑战整场胜利奖励
  53. BZCS_FIGHT_REWARD_LOSE_ID = 2 -- 挑战整场失败奖励
  54. --------------------------------------------------------------------------------
  55. -- 种族与战斗类型 (teamType 41~45, 见 excel/ssecy/combat.lua)
  56. -- race 1~5 与 camp 一致: 妖/人/兽/仙/魔
  57. --------------------------------------------------------------------------------
  58. BZCS_RACE_ORDER = {1, 2, 3, 4, 5}
  59. BZCS_RACE_COMBAT_TYPE = {39, 40, 41, 42, 43}
  60. BZCS_RACE_NAME = {"妖", "人", "兽", "仙", "魔"}
  61. BZCS_RACE_CNT = 5
  62. BZCS_WIN_TARGET = 3 -- 5 局 3 胜: 先赢 3 族或打满 5 族
  63. --------------------------------------------------------------------------------
  64. -- 挑战次数与门票
  65. --------------------------------------------------------------------------------
  66. BZCS_FREE_TIMES = 5 -- 每日免费挑战次数(0 点重置)
  67. BZCS_TICKET_ITEM_ID = 115 -- 挑战券道具 id
  68. BZCS_TICKET_COST = 5 -- 无免费时每次消耗数量
  69. --------------------------------------------------------------------------------
  70. -- 匹配与排行
  71. --------------------------------------------------------------------------------
  72. BZCS_OPPONENT_CNT = 3 -- 单次匹配对手数量
  73. BZCS_MATCH_CACHE_TTL = 30 -- 匹配列表内存缓存有效期(秒); 过期按 rank 轻量刷新展示
  74. BZCS_MATCH_STEP = 500 -- 积分匹配步进(第1步±500, 第2步±1000, 第3步±1500...)
  75. BZCS_MATCH_MAX_STEP = 50 -- 最大扩大步数(最多 ±25000 分范围)
  76. BZCS_RANK_MAX = 100 -- 客户端展示排行榜条数(全服积分榜含机器人, 规模更大)
  77. -- 全服排行: 积分高者优先; 同分则 scoreTime 小者优先(先达到该积分)
  78. BZCS_REWARD_RANK_MAX = 9999 -- 周期发奖最大排名(超出不发)
  79. --------------------------------------------------------------------------------
  80. -- 准入与其它
  81. --------------------------------------------------------------------------------
  82. BZCS_OPEN_SVR_DAY = 45 -- 开服天数>=此值本服才可参与
  83. BZCS_WARREPORT_MAX = 20 -- 玩家本地战报条数(新记录在前, 超出删最老)
  84. -- 战报类型 warType(客户端展示用)
  85. BZCS_WAR_TYPE_ATK_WIN = 1 -- 主动挑战获胜
  86. BZCS_WAR_TYPE_ATK_LOSE = 2 -- 主动挑战失败
  87. BZCS_WAR_TYPE_DEF_WIN = 3 -- 被挑战, 己方获胜
  88. BZCS_WAR_TYPE_DEF_LOSE = 4 -- 被挑战, 己方失败
  89. BZCS_AWARD_MAIL_ID = 7038 -- 周期结算邮件 id(需在 excel/mail 配置)
  90. -- 机器人池数量 = 策划 robotList 条数(见 GetRobotListCount)
  91. BZCS_SVR_BASE_NUM = 810537 -- 逻辑服 serverId 基准(Config.SVR_INDEX 等)
  92. BZCS_ROBOT_DISPLAY_SERVER_ID = 1 -- 协议下发: 机器人展示为第1服
  93. -- 逻辑服 serverId -> GC 协议展示服号(仅 NS 下发客户端时调用); isRobot=1 固定为第1服
  94. function ToClientServerId(serverId, isRobot)
  95. if isRobot == 1 then
  96. return BZCS_ROBOT_DISPLAY_SERVER_ID
  97. end
  98. if not serverId or serverId <= 0 then
  99. return 0
  100. end
  101. if serverId > BZCS_SVR_BASE_NUM then
  102. return serverId - BZCS_SVR_BASE_NUM
  103. end
  104. return serverId
  105. end
  106. --------------------------------------------------------------------------------
  107. -- 跨服 WL_BZCS_TIPS 错误码 (普通服收到后提示)
  108. --------------------------------------------------------------------------------
  109. BZCS_ERR_NOT_OPEN = 1 -- 活动未开启
  110. BZCS_ERR_NOT_ELIGIBLE = 2 -- 不满足参与条件
  111. BZCS_ERR_NO_TIMES = 3 -- 挑战次数不足
  112. BZCS_ERR_TARGET_INVALID = 4 -- 对手不存在
  113. BZCS_ERR_DATA = 5 -- 数据异常
  114. BZCS_ERR_IN_BATTLE = 6 -- 战斗中(重复挑战)
  115. --------------------------------------------------------------------------------
  116. -- LW_BZCS_UPDATE_SHOW 增量类型(showInfo 仅带变更字段, 跨服 MergeShowInfo 合并)
  117. --------------------------------------------------------------------------------
  118. BZCS_UPDATE_SHOW_NAME = 1 -- name
  119. BZCS_UPDATE_SHOW_HEAD = 3 -- head
  120. BZCS_UPDATE_SHOW_HEAD_FRAME = 4 -- headFrame
  121. BZCS_UPDATE_SHOW_LINEUP = 5 -- heroArr[race], 须配合 race 参数
  122. BZCS_UPDATE_SHOW_BODY = 6 -- body(形象, HEAD_TYPE_3)
  123. -- 将增量 showInfo 合并进跨服已有展示数据
  124. function MergeShowInfo(si, patch)
  125. if not si or not patch then return end
  126. if patch.name ~= nil then
  127. si.name = patch.name
  128. end
  129. if patch.head ~= nil then
  130. si.head = patch.head
  131. end
  132. if patch.headFrame ~= nil then
  133. si.headFrame = patch.headFrame
  134. end
  135. if patch.body ~= nil then
  136. si.body = patch.body
  137. end
  138. if patch.heroArr then
  139. si.heroArr = si.heroArr or {}
  140. for race, raceShow in pairs(patch.heroArr) do
  141. si.heroArr[race] = raceShow
  142. end
  143. end
  144. end
  145. --------------------------------------------------------------------------------
  146. -- robotList 配置(策划表 excel/ssecy/baiZhanChengShen.lua)
  147. -- score: 机器人积分
  148. -- monsterOutIDs[1..5]: 妖/人/兽/仙/魔 五族 monsterOutID, 每 ID 一支队伍(见 CombatLogic.getMonsterObjList)
  149. --------------------------------------------------------------------------------
  150. local BzcsConfig = require("excel.baiZhanChengShen")
  151. local CombatLogic = require("combat.CombatLogic")
  152. local robotListCount
  153. function GetRobotListCount()
  154. if robotListCount then
  155. return robotListCount
  156. end
  157. local max = 0
  158. for k in pairs(BzcsConfig.robotList or {}) do
  159. if type(k) == "number" and k > max then
  160. max = k
  161. end
  162. end
  163. robotListCount = max
  164. return max
  165. end
  166. -- bzcs_robot_N 与 robotList[N] 一一对应
  167. function GetRobotListIndex(uuid)
  168. if not uuid then return end
  169. local n = string.match(uuid, "^bzcs_robot_(%d+)$")
  170. if not n then return end
  171. local idx = tonumber(n)
  172. if not idx or idx < 1 or idx > GetRobotListCount() then return end
  173. return idx
  174. end
  175. function GetRobotListCfg(uuid)
  176. local idx = GetRobotListIndex(uuid)
  177. if not idx then return end
  178. return BzcsConfig.robotList[idx], idx
  179. end
  180. -- 由 monsterOutID 计算单族队伍战力(与战斗 getMonsterObjList 一致)
  181. function CalcMonsterOutPower(monsterOutID)
  182. if not monsterOutID then return 0 end
  183. local _, _, rolebase = CombatLogic.getMonsterObjList(monsterOutID)
  184. return rolebase and rolebase.zhandouli or 0
  185. end
  186. --------------------------------------------------------------------------------
  187. -- 战力与机器人阵容展开(机器人仅存 monsterOutID+racePower, 展示字段用时生成)
  188. --------------------------------------------------------------------------------
  189. local MonsterExcel
  190. local function getMonsterExcel()
  191. MonsterExcel = MonsterExcel or require("excel.monster")
  192. return MonsterExcel
  193. end
  194. -- 机器人单族仅存 monsterOutID+racePower, 有 monsterOutID 则需展开
  195. local function needExpandRaceShow(raceShow)
  196. return raceShow and raceShow.monsterOutID ~= nil
  197. end
  198. -- 由 monsterOut 展开英雄展示; racePower 均分到各英雄 heroPower(不修改入参)
  199. function ExpandBzcsRaceShow(raceShow)
  200. if not raceShow or not needExpandRaceShow(raceShow) then
  201. return raceShow
  202. end
  203. local excel = getMonsterExcel()
  204. local mout = excel.monsterOut[raceShow.monsterOutID]
  205. local racePower = raceShow.racePower or 0
  206. local heroArr = {}
  207. local cnt = 0
  208. if mout and mout.member then
  209. for idx, member in ipairs(mout.member) do
  210. if idx > 6 then break end
  211. cnt = cnt + 1
  212. end
  213. end
  214. local per = cnt > 0 and math.floor(racePower / cnt) or racePower
  215. local len = 0
  216. if mout and mout.member then
  217. for idx, member in ipairs(mout.member) do
  218. if idx > 6 then break end
  219. local mid = member[1]
  220. local mcf = excel.monster[mid]
  221. if mcf then
  222. len = len + 1
  223. heroArr[len] = {
  224. heroBody = mcf.body,
  225. heroStar = mcf.star or 0,
  226. heroLevel = member[2],
  227. heroCamp = mcf.camp or 0,
  228. heroIcon = mcf.head or 0,
  229. heroId = mid,
  230. heroQuality = mcf.heroQuality or 1,
  231. heroPower = per,
  232. }
  233. end
  234. end
  235. end
  236. if len == 0 then
  237. heroArr[1] = {
  238. heroPower = racePower,
  239. heroId = 0,
  240. heroBody = 0,
  241. heroStar = 0,
  242. heroLevel = 0,
  243. heroCamp = 0,
  244. heroIcon = 0,
  245. heroQuality = 1,
  246. }
  247. end
  248. return {
  249. heroArr = heroArr,
  250. formation = raceShow.formation or 1,
  251. helpSkillId = raceShow.helpSkillId or 0,
  252. elfList = raceShow.elfList,
  253. elfSkillIds = raceShow.elfSkillIds,
  254. monsterOutID = raceShow.monsterOutID,
  255. racePower = racePower,
  256. }
  257. end
  258. -- 单族队伍战力: 机器人用 racePower; 真人用 heroArr 内 heroPower 之和
  259. function CalcRaceTeamPower(raceShow)
  260. if not raceShow then return 0 end
  261. if raceShow.racePower then
  262. return raceShow.racePower
  263. end
  264. local sum = 0
  265. for _, h in ipairs(raceShow.heroArr or {}) do
  266. sum = sum + (h.heroPower or 0)
  267. end
  268. return sum
  269. end
  270. -- 玩家总战力 = 五族队伍战力之和
  271. function CalcPlayerPower(showInfo)
  272. if not showInfo then return 0 end
  273. local total = 0
  274. for _, race in ipairs(BZCS_RACE_ORDER) do
  275. total = total + CalcRaceTeamPower(showInfo.heroArr and showInfo.heroArr[race])
  276. end
  277. return total
  278. end