UnionArmband.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. ---@class UnionArmbands.ArmbandsData
  2. ---@field level number -- 等级
  3. ---@field reallevel number -- 真实等级
  4. ---@field strong number -- 强化等级
  5. UnionArmbands = {}
  6. local this = {}
  7. local UnionArmbandsKey = PlayerDefKey.UNION.UnionArmbandsKey
  8. local UnionArmbandsLevelupLimitCacheKey = PlayerDefKey.UNION.UnionArmbandsLevelUpLimitCacheKey
  9. function UnionArmbands.serverStart()
  10. local success, result = xpcall(this.startCacheUnionLevelUpLimit, debug.traceback)
  11. gameDebug.assertPrint(success, "启动时缓存战盟臂章升级限制异常!", result)
  12. end
  13. function UnionArmbands.sendArmbandInfo(actor)
  14. this.sendArmbandInfo(actor)
  15. end
  16. function UnionArmbands.levelupUnionArmband(actor)
  17. this.levelupUnionArmband(actor)
  18. end
  19. function UnionArmbands.strongArmband(actor)
  20. this.strongArmband(actor)
  21. end
  22. function UnionArmbands.onEnterUnion(actor)
  23. this.onEnterUnion(actor)
  24. end
  25. function UnionArmbands.onQuitUnion(actor)
  26. this.onQuitUnion(actor)
  27. end
  28. function this.startCacheUnionLevelUpLimit()
  29. local cache_map = {}
  30. local config_arr = ConfigDataManager.getList("cfg_gard_armbands")
  31. gameDebug.print("------ config_arr ------", config_arr)
  32. if table.isEmpty(config_arr) then
  33. return
  34. end
  35. for _, config in ipairs(config_arr) do
  36. local limit_arr = string.split(config.guildrank, "#")
  37. cache_map[tonumber(limit_arr[1])] = tonumber(limit_arr[2])
  38. end
  39. gameDebug.print("------ cache_map ------", cache_map)
  40. setsysvar(UnionArmbandsLevelupLimitCacheKey, cache_map)
  41. end
  42. function this.cacheStrongAttr(cache_map)
  43. local attr_cache = {}
  44. local config_arr = ConfigDataManager.getList("cfg_gard_bandsStrength")
  45. if table.isEmpty(table.isEmpty) then
  46. return
  47. end
  48. for _, config in pairs(config_arr) do
  49. local level = config.level
  50. local attr_str = config.strengthenattribute
  51. local attr_map = string.toIntIntMap(attr_str, "#", "|")
  52. attr_cache[tonumber(level)] = attr_map
  53. end
  54. cache_map.strong = attr_cache
  55. end
  56. function this.sendArmbandInfo(actor)
  57. ---@type UnionArmbands.ArmbandsData
  58. local armband_data = this.getArmbandData(actor)
  59. if table.isEmpty(armband_data) then
  60. this.jprint("--- 获取战盟臂章数据为空, 开始初始化臂章数据 ---")
  61. armband_data = this.initArmbandData(actor)
  62. end
  63. -- 初始化失败的功能尝试重新初始化
  64. if armband_data.reallevel < 1 then
  65. this.levelupUnionArmband(actor)
  66. end
  67. if armband_data.strong < 0 then
  68. this.strongArmband(actor)
  69. end
  70. sendluamsg(actor, LuaMessageIdToClient.RES_SEND_UNION_ARMBAND_INFO, armband_data)
  71. end
  72. function this.getArmbandData(actor)
  73. return getplaydef(actor, UnionArmbandsKey)
  74. end
  75. function this.setArmbandData(actor, data)
  76. setplaydef(actor, UnionArmbandsKey, data)
  77. end
  78. function this.levelupUnionArmband(actor)
  79. local union_data = getunioninfo(actor)
  80. if table.isEmpty(union_data) then
  81. this.jprint("获取战盟信息异常1")
  82. return
  83. end
  84. ---@type UnionArmbands.ArmbandsData
  85. local armband_data = this.getArmbandData(actor)
  86. local level = armband_data.level
  87. local next_level = level + 1
  88. local config_arr = ConfigDataManager.getTable("cfg_gard_armbands", "level", next_level)
  89. if table.isEmpty(config_arr) then
  90. this.jprint("未获取到配置信息")
  91. return
  92. end
  93. local config = config_arr[1]
  94. local union_level = tostring(union_data.unionlevel)
  95. local max_level = this.getLevelupMaxLevel(union_level)
  96. if tonumber(level) >= tonumber(max_level) then
  97. this.jprint("战盟等级达到上限")
  98. return
  99. end
  100. if armband_data.reallevel < next_level then
  101. -- 消耗道具
  102. local cost_str = config.levelupcost
  103. local cost_ret = this.unionCostItem(actor, cost_str, 1)
  104. if not cost_ret then
  105. this.jprint("消耗道具失败! 资源不足")
  106. return
  107. end
  108. end
  109. this.setArmbandLevel(actor, armband_data, next_level)
  110. sendluamsg(actor, LuaMessageIdToClient.RES_UNION_ARMBAND_LEVEL_UP, next_level)
  111. end
  112. function this.getLevelupMaxLevel(union_level)
  113. local data = getsysvar(UnionArmbandsLevelupLimitCacheKey)
  114. gameDebug.print("----- 臂章等级缓存 ------", data)
  115. -- 获取所有等级的键并排序
  116. local levels = {}
  117. for k in pairs(data) do
  118. table.insert(levels, k)
  119. end
  120. table.sort(levels)
  121. -- 查找最接近的较小等级
  122. local closestLevel = nil
  123. for _, l in ipairs(levels) do
  124. if l <= tonumber(union_level) then
  125. closestLevel = l
  126. else
  127. break
  128. end
  129. end
  130. -- 返回最接近的较小等级的可用最大值
  131. if closestLevel ~= nil then
  132. return data[closestLevel]
  133. else
  134. return 9999999999
  135. end
  136. end
  137. function this.initArmbandData(actor)
  138. local armband_data = {
  139. level = 0,
  140. reallevel = 0,
  141. strong = -1
  142. }
  143. this.setArmbandData(actor, armband_data)
  144. this.levelupUnionArmband(actor)
  145. this.strongArmband(actor)
  146. return armband_data
  147. end
  148. function this.setArmbandLevel(actor, armband_data, level)
  149. armband_data.level = level
  150. if level > armband_data.reallevel then
  151. armband_data.reallevel = level
  152. end
  153. this.setArmbandData(actor, armband_data)
  154. -- 计算属性
  155. this.calculateArmbandAttr(actor, level, RoleAttrKey.UNION_ARMBAND_LEVEL)
  156. end
  157. function this.strongArmband(actor)
  158. local union_data = getunioninfo(actor)
  159. if table.isEmpty(union_data) then
  160. this.jprint("获取战盟信息异常2")
  161. return
  162. end
  163. ---@type UnionArmbands.ArmbandsData
  164. local armband_data = this.getArmbandData(actor)
  165. local strong = armband_data.strong or 0
  166. local next_strong = strong + 1
  167. local config_arr = ConfigDataManager.getTable("cfg_gard_bandsStrength", "level", next_strong)
  168. if table.isEmpty(config_arr) then
  169. this.jprint("未获取到配置信息")
  170. return
  171. end
  172. local config = config_arr[1]
  173. local limit = tonumber(config.playerlevellimit)
  174. if limit then
  175. local level = tonumber(getbaseinfo(actor, "level"))
  176. if level < limit then
  177. this.jprint("玩家等级不足!")
  178. return
  179. end
  180. end
  181. local cost_str = config.strengthcost
  182. local cost_ret = this.unionCostItem(actor, cost_str, 1)
  183. if not cost_ret then
  184. this.jprint("消耗道具失败! 资源不足")
  185. return
  186. end
  187. local rate = tonumber(config.strengthenprobability)
  188. local ret = this.strongResult(rate)
  189. if not ret then
  190. -- 强化失败 获取本级失败退回的等级
  191. local old_config = ConfigDataManager.getTable("cfg_gard_bandsStrength", "level", strong)
  192. local fall_level = ConfigDataManager.getTableValue("cfg_gard_bandsStrength", "levelFailure1", "level", strong)
  193. fall_level = tonumber(fall_level) or -1
  194. if tonumber(fall_level) < 0 then
  195. sendluamsg(actor, LuaMessageIdToClient.RES_UNION_ARMBAND_STRONG, strong)
  196. return
  197. end
  198. next_strong = tonumber(fall_level)
  199. end
  200. armband_data.strong = next_strong
  201. this.setArmbandData(actor, armband_data)
  202. -- 计算属性
  203. this.calculateArmbandAttr(actor, next_strong, RoleAttrKey.UNION_ARMBAND_STRONG)
  204. sendluamsg(actor, LuaMessageIdToClient.RES_UNION_ARMBAND_STRONG, next_strong)
  205. end
  206. function this.calculateArmbandAttr(actor, cfg_id, key)
  207. local attr_str
  208. if key == RoleAttrKey.UNION_ARMBAND_LEVEL then
  209. attr_str = ConfigDataManager.getTableValue("cfg_gard_armbands", "levelupattribute", "level", cfg_id)
  210. else
  211. attr_str = ConfigDataManager.getTableValue("cfg_gard_bandsStrength", "strengthenattribute", "level", cfg_id)
  212. end
  213. local attr_map = string.toIntIntMap(attr_str, "#", "|")
  214. if not table.isEmpty(attr_map) then
  215. this.jprint("添加属性")
  216. addrolekmlattributes(actor, key, attr_map)
  217. end
  218. end
  219. function this.strongResult(probability)
  220. local value = math.random(0, 9999)
  221. return value < probability
  222. end
  223. function this.combineTable(tbl, n)
  224. if type(n) ~= 'number' or n < 1 or n > table.count(tbl) then
  225. return {}
  226. end
  227. local combinedTable = {}
  228. for i = 1, n do
  229. local currentTable = tbl[i]
  230. for key, value in pairs(currentTable) do
  231. if combinedTable[key] then
  232. combinedTable[key] = combinedTable[key] + value
  233. else
  234. combinedTable[key] = value
  235. end
  236. end
  237. end
  238. return combinedTable
  239. end
  240. function this.onEnterUnion(actor)
  241. jprint(actor:toString())
  242. ---@type UnionArmbands.ArmbandsData
  243. local armband_data = this.getArmbandData(actor)
  244. if table.isEmpty(armband_data) then
  245. armband_data = this.initArmbandData(actor)
  246. return
  247. end
  248. local union_data = getunioninfo(actor)
  249. local union_level = union_data.unionlevel
  250. local max_level = this.getLevelupMaxLevel(union_level)
  251. if max_level == armband_data.level then
  252. return
  253. end
  254. local level = math.min(armband_data.reallevel, max_level)
  255. armband_data.level = union_level
  256. this.setArmbandLevel(actor, armband_data, level)
  257. this.calculateArmbandAttr(actor, armband_data.strong, RoleAttrKey.UNION_ARMBAND_STRONG)
  258. end
  259. function this.onQuitUnion(actor)
  260. ---@type UnionArmbands.ArmbandsData
  261. local armband_data = this.getArmbandData(actor)
  262. armband_data.level = 0
  263. this.setArmbandLevel(actor, armband_data, 0)
  264. this.calculateArmbandAttr(actor, 0, RoleAttrKey.UNION_ARMBAND_STRONG)
  265. end
  266. function this.unionCostItem(actor, cost_str, rate)
  267. rate = rate or 1
  268. if not cost_str or cost_str == "" then
  269. return true
  270. end
  271. local cost_item = string.split(cost_str, "#")
  272. local item_id = cost_item[1]
  273. local item_count = cost_item[2]
  274. item_count = math.floor(item_count * rate)
  275. local cost_ret = removeitemfrombag(actor, item_id, item_count, 0, 9999, '战盟臂章')
  276. if not cost_ret then
  277. this.debug("消耗道具失败!无法参与竞选/取代!", "cost_str ", tostring(cost_str), "rate ", tostring(rate))
  278. return false
  279. end
  280. return true
  281. end
  282. ----------------------------------------
  283. this.log_open = false
  284. function this.debug(...)
  285. if not this.log_open then
  286. return
  287. end
  288. gameDebug.print(...)
  289. end
  290. function this.jprint(param)
  291. if not this.log_open then
  292. return
  293. end
  294. if param == nil then
  295. param = "error! 输出内容为空. nil"
  296. end
  297. jprint(param)
  298. end