BingshuLogic.lua 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. ------------------------------------------------------
  2. -- 兵书逻辑
  3. ------------------------------------------------------
  4. local FuwenExcel = require("excel.fuwen")
  5. local HeroExcel = require("excel.hero")
  6. local Lang = require("common.Lang")
  7. local Util = require("common.Util")
  8. local Msg = require("core.Msg")
  9. local ObjHuman = require("core.ObjHuman")
  10. local Broadcast = require("broadcast.Broadcast")
  11. local Grid = require("bag.Grid")
  12. local BagLogic = require("bag.BagLogic")
  13. local BingshuGrid = require("fuwen.BingshuGrid")
  14. local HeroLogic = require("hero.HeroLogic")
  15. local LiLianLogic = require("dailyTask.LiLianLogic")
  16. local Log = require("common.Log")
  17. BINGSHU_MAXCNT = 3 -- 最多x个兵书
  18. BINGSHU_OPEN_LIST = {6, 11, 13}
  19. ------------------------------------- config ------------------------------------------
  20. -- 获取可以激活的技能列表
  21. local CAN_LEARN_LIST = nil
  22. function getCanLearnList()
  23. if not CAN_LEARN_LIST then
  24. CAN_LEARN_LIST = {}
  25. for id, config in Util.pairsByKeys(FuwenExcel.skill) do
  26. if config.isBingshuSkill == 1 and config.lv == 1 then
  27. CAN_LEARN_LIST[#CAN_LEARN_LIST + 1] = id
  28. end
  29. end
  30. end
  31. return CAN_LEARN_LIST
  32. end
  33. -- 获取下一级技能
  34. function getNextSkillID(skillID)
  35. local tconfig = FuwenExcel.skill[skillID]
  36. if not tconfig then return end
  37. for id, config in pairs(FuwenExcel.skill) do
  38. if (config.isBingshuSkill == 1) and
  39. (config.groupID == tconfig.groupID) and
  40. (config.lv == tconfig.lv + 1) and
  41. (#config.bingshuUpNeed > 0) then
  42. return id
  43. end
  44. end
  45. end
  46. ----------------------------------------- db -------------------------------------------------
  47. -- 获取兵书grid
  48. function getBingshuGrid(heroGrid, index)
  49. if not heroGrid then return end
  50. if not heroGrid.bingshu then return end
  51. return index and heroGrid.bingshu[index]
  52. end
  53. -- 是否已经学过某个技能
  54. function isLearnSkill(heroGrid, skillID)
  55. if not heroGrid then return end
  56. if not heroGrid.bingshu then return end
  57. local skillConfig = FuwenExcel.skill[skillID]
  58. for _, grid in pairs(heroGrid.bingshu) do
  59. local tconfig = FuwenExcel.skill[grid.skillID]
  60. if tconfig.groupID == skillConfig.groupID then
  61. return true
  62. end
  63. end
  64. end
  65. ----------------------------------------- msg -------------------------------------------------
  66. -- 查询
  67. function sendQuery(human, heroID, heroIndex)
  68. local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
  69. if not heroGrid then return end
  70. local msgRet = Msg.gc.GC_BINGSHU_QUERY
  71. msgRet.heroID = heroID
  72. msgRet.heroIndex = heroIndex
  73. msgRet.skills[0] = 0
  74. for i = 1, BINGSHU_MAXCNT do
  75. local grid = getBingshuGrid(heroGrid, i)
  76. if grid then
  77. msgRet.skills[0] = msgRet.skills[0] + 1
  78. BingshuGrid.makeBingshuNet(msgRet.skills[msgRet.skills[0]], grid, i)
  79. end
  80. end
  81. msgRet.openList[0] = BINGSHU_MAXCNT
  82. for i = 1, msgRet.openList[0] do
  83. msgRet.openList[i] = BINGSHU_OPEN_LIST[i] or 0
  84. end
  85. for i = 1, BINGSHU_MAXCNT do
  86. msgRet.red[i] = isBingShuDotByIndex(human, heroGrid, i) and 1 or 0
  87. end
  88. msgRet.red[0] = BINGSHU_MAXCNT
  89. -- Msg.trace(msgRet)
  90. Msg.send(msgRet, human.fd)
  91. end
  92. -- 可激活列表
  93. function sendLearnList(human, heroID, heroIndex, index)
  94. local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
  95. if not heroGrid then return end
  96. local learnList = getCanLearnList()
  97. local msgRet = Msg.gc.GC_BINGSHU_LEARN_LIST
  98. msgRet.list[0] = 0
  99. for _, skillID in ipairs(learnList) do
  100. if msgRet.list[0] >= #msgRet.list then
  101. break
  102. end
  103. if not isLearnSkill(heroGrid, skillID) then
  104. msgRet.list[0] = msgRet.list[0] + 1
  105. BingshuGrid.makeBingshuLearnNet(msgRet.list[msgRet.list[0]], skillID)
  106. end
  107. end
  108. msgRet.index = index
  109. -- Msg.trace(msgRet)
  110. Msg.send(msgRet, human.fd)
  111. end
  112. -- 学习技能
  113. function learnSkill(human, heroID, heroIndex, index, skillID)
  114. local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
  115. if not heroGrid then
  116. return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_FRIEND_ERR_INFO)
  117. end
  118. if index < 1 or index > BINGSHU_MAXCNT then
  119. return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_FRIEND_ERR_INFO)
  120. end
  121. local heroConfig = HeroExcel.hero[heroGrid.id]
  122. if heroGrid.star < BINGSHU_OPEN_LIST[index] then
  123. return
  124. end
  125. if getBingshuGrid(heroGrid, index) then
  126. return Broadcast.sendErr(human, Lang.SKIN_PARAM_ERR)
  127. end
  128. local config = FuwenExcel.skill[skillID]
  129. if not config then return end
  130. if config.isBingshuSkill ~= 1 then return end
  131. if config.lv ~= 1 then return end
  132. for _, item in ipairs(config.bingshuUpNeed) do
  133. local itemID = item[1]
  134. local itemCnt = item[2]
  135. if not BagLogic.checkItemCnt(human, itemID, itemCnt) then
  136. return Broadcast.sendErr(human, Lang.ABS_ITEM_ERR)
  137. end
  138. end
  139. for _, item in ipairs(config.bingshuUpNeed) do
  140. local itemID = item[1]
  141. local itemCnt = item[2]
  142. BagLogic.delItem(human, itemID, itemCnt, "bingshu")
  143. end
  144. local grid = BingshuGrid.create(skillID)
  145. heroGrid.bingshu = heroGrid.bingshu or {}
  146. heroGrid.bingshu[index] = grid
  147. local msgRet = Msg.gc.GC_BINGSHU_LEARN
  148. msgRet.heroID = heroID
  149. msgRet.heroIndex = heroIndex
  150. BingshuGrid.makeBingshuNet(msgRet.data, grid, index)
  151. -- Msg.trace(msgRet)
  152. Msg.send(msgRet, human.fd)
  153. ObjHuman.doCalcHero(human, heroIndex)
  154. local newcf = FuwenExcel.skill[grid.skillID]
  155. LiLianLogic.onCallback(human,LiLianLogic.LILIAN_OUTID28,1,newcf.lv)
  156. HeroLogic.sendHeroBagDynamic(human, heroID, heroIndex)
  157. sendQuery(human, heroID, heroIndex)
  158. end
  159. function getForgetCost(lv)
  160. local costs = FuwenExcel.define[1].bingshuForgetCosts
  161. return costs[lv] or costs[#costs]
  162. end
  163. -- 升级查询
  164. function sendLevelUpQuery(human, heroID, heroIndex, index)
  165. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] 收到查询请求: heroID="..(heroID or "nil")..", heroIndex="..(heroIndex or "nil")..", index="..(index or "nil"))
  166. local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
  167. if not heroGrid then
  168. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] 英雄不存在: heroID="..(heroID or "nil")..", heroIndex="..(heroIndex or "nil"))
  169. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  170. end
  171. local grid = getBingshuGrid(heroGrid, index)
  172. if not grid then
  173. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] 兵书格子不存在: heroID="..(heroID or "nil")..", heroIndex="..(heroIndex or "nil")..", index="..(index or "nil"))
  174. return Broadcast.sendErr(human, "兵书格子不存在")
  175. end
  176. local config = FuwenExcel.skill[grid.skillID]
  177. local nextSkillID = getNextSkillID(grid.skillID)
  178. local nextConfig = nextSkillID and FuwenExcel.skill[nextSkillID]
  179. local msgRet = Msg.gc.GC_BINGSHU_LEVELUP_QUERY
  180. msgRet.heroID = heroID
  181. msgRet.heroIndex = heroIndex
  182. -- 检查grid和skillID
  183. if not grid or not grid.skillID then
  184. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] ERROR: grid或grid.skillID不存在, grid="..tostring(grid)..", skillID="..(grid and grid.skillID or "nil"))
  185. return Broadcast.sendErr(human, "兵书数据错误")
  186. end
  187. -- 检查技能配置
  188. if not config then
  189. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] ERROR: 技能配置不存在, skillID="..grid.skillID)
  190. return Broadcast.sendErr(human, "技能配置不存在")
  191. end
  192. BingshuGrid.makeBingshuNet(msgRet.bingshu, grid, index)
  193. msgRet.upData[0] = 0
  194. if nextConfig then
  195. msgRet.upData[0] = 1
  196. BingshuGrid.makeBingshuLearnNet(msgRet.upData[1], nextSkillID)
  197. end
  198. msgRet.forgetCost = getForgetCost(config.lv)
  199. msgRet.returnItems[0] = config and #config.bingshuForgetReturn or 0
  200. for i = 1, msgRet.returnItems[0] do
  201. local itemID = config.bingshuForgetReturn[i][1]
  202. local itemCnt = config.bingshuForgetReturn[i][2]
  203. Grid.makeItem(msgRet.returnItems[i], itemID, itemCnt)
  204. end
  205. -- 检查消息格式
  206. local protoID = msgRet[1]
  207. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] 准备发送消息: protoID="..(protoID or "nil")..", heroID="..heroID..", heroIndex="..heroIndex..", index="..index..", skillID="..(grid.skillID or "nil")..", forgetCost="..msgRet.forgetCost)
  208. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] human.fd="..(human.fd or "nil")..", upData[0]="..(msgRet.upData[0] or "nil")..", returnItems[0]="..(msgRet.returnItems[0] or "nil"))
  209. -- 检查bingshu数据
  210. if msgRet.bingshu then
  211. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] msgRet.bingshu存在, index="..(msgRet.bingshu.index or "nil")..", skillID="..(msgRet.bingshu.skill and msgRet.bingshu.skill.skillID or "nil"))
  212. if msgRet.bingshu.skill then
  213. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] msgRet.bingshu.skill.skillID="..(msgRet.bingshu.skill.skillID or "nil")..", skillName="..(msgRet.bingshu.skill.skillName or "nil"))
  214. else
  215. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] WARNING: msgRet.bingshu.skill为nil")
  216. end
  217. else
  218. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] WARNING: msgRet.bingshu为nil")
  219. end
  220. -- 检查upData数据
  221. if msgRet.upData[0] > 0 and msgRet.upData[1] then
  222. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] msgRet.upData[1]存在, skillID="..(msgRet.upData[1].skill and msgRet.upData[1].skill.skillID or "nil"))
  223. end
  224. -- 检查returnItems数据
  225. if msgRet.returnItems[0] > 0 then
  226. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] msgRet.returnItems[0]="..msgRet.returnItems[0])
  227. for i = 1, msgRet.returnItems[0] do
  228. if msgRet.returnItems[i] then
  229. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] msgRet.returnItems["..i.."]: id="..(msgRet.returnItems[i].id or "nil")..", cnt="..(msgRet.returnItems[i].cnt or "nil"))
  230. end
  231. end
  232. end
  233. if not human.fd then
  234. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] ERROR: human.fd为nil,无法发送消息")
  235. return Broadcast.sendErr(human, "连接已断开")
  236. end
  237. -- 使用Msg.trace检查消息格式(如果可用)
  238. -- Msg.trace(msgRet)
  239. Msg.send(msgRet, human.fd)
  240. --Log.write(Log.LOGID_DEBUG, "[sendLevelUpQuery] 消息已发送: protoID="..(protoID or "nil")..", heroID="..heroID..", heroIndex="..heroIndex..", index="..index)
  241. end
  242. -- 升级
  243. function levelUp(human, heroID, heroIndex, index)
  244. local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
  245. if not heroGrid then return end
  246. local grid = getBingshuGrid(heroGrid, index)
  247. if not grid then return end
  248. local nextSkillID = getNextSkillID(grid.skillID)
  249. local nextConfig = nextSkillID and FuwenExcel.skill[nextSkillID]
  250. if not nextConfig then
  251. return Broadcast.sendErr(human, Lang.BINGSHU_LEVELUP_ERR_FULL)
  252. end
  253. for _, item in ipairs(nextConfig.bingshuUpNeed) do
  254. local itemID = item[1]
  255. local itemCnt = item[2]
  256. if not BagLogic.checkItemCnt(human, itemID, itemCnt) then
  257. return
  258. end
  259. end
  260. for _, item in ipairs(nextConfig.bingshuUpNeed) do
  261. local itemID = item[1]
  262. local itemCnt = item[2]
  263. BagLogic.delItem(human, itemID, itemCnt, "bingshu")
  264. end
  265. grid.skillID = nextSkillID
  266. local msgRet = Msg.gc.GC_BINGSHU_LEVELUP
  267. msgRet.heroID = heroID
  268. msgRet.heroIndex = heroIndex
  269. BingshuGrid.makeBingshuNet(msgRet.bingshu, grid, index)
  270. -- Msg.trace(msgRet)
  271. Msg.send(msgRet, human.fd)
  272. ObjHuman.doCalcHero(human, heroIndex)
  273. sendLevelUpQuery(human, heroID, heroIndex, index)
  274. sendQuery(human, heroID, heroIndex)
  275. HeroLogic.sendHeroBagDynamic(human, heroID, heroIndex)
  276. end
  277. -- 遗忘
  278. function forget(human, heroID, heroIndex, index)
  279. local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
  280. if not heroGrid then return end
  281. local grid = getBingshuGrid(heroGrid, index)
  282. if not grid then return end
  283. local config = FuwenExcel.skill[grid.skillID]
  284. local needZuanshi = getForgetCost(config.lv)
  285. if not ObjHuman.checkRMB(human, needZuanshi) then
  286. return
  287. end
  288. ObjHuman.decZuanshi(human, -needZuanshi, "bingshu")
  289. heroGrid.bingshu[index] = nil
  290. BagLogic.addItemList(human, config.bingshuForgetReturn, "bingshu")
  291. local msgRet = Msg.gc.GC_BINGSHU_FORGET
  292. msgRet.heroID = heroID
  293. msgRet.heroIndex = heroIndex
  294. msgRet.index = index
  295. Msg.send(msgRet, human.fd)
  296. ObjHuman.doCalcHero(human, heroIndex)
  297. HeroLogic.sendHeroBagDynamic(human, heroID, heroIndex)
  298. end
  299. BINGSHU_OPEN_TIME = nil
  300. function isBingShuDot(human, heroGrid)
  301. if not BINGSHU_OPEN_TIME then
  302. -- local d = os.date("*t",time)
  303. local tmpDate = {}
  304. tmpDate.year = 2022
  305. tmpDate.month = 1
  306. tmpDate.day = 31
  307. tmpDate.hour = 0
  308. tmpDate.min = 0
  309. tmpDate.sec = 0
  310. BINGSHU_OPEN_TIME = os.time(tmpDate)
  311. end
  312. if os.time() <= BINGSHU_OPEN_TIME then return -1 end
  313. if not heroGrid then return end
  314. if heroGrid.star < BINGSHU_OPEN_LIST[1] then return end
  315. for i = 1, BINGSHU_MAXCNT do
  316. if heroGrid.star < BINGSHU_OPEN_LIST[i] then return end
  317. local grid = getBingshuGrid(heroGrid, i)
  318. if grid then
  319. -- 检测是否能升级
  320. local nextSkillID = getNextSkillID(grid.skillID)
  321. local nextConfig = nextSkillID and FuwenExcel.skill[nextSkillID]
  322. if nextConfig then
  323. local canUp = true
  324. for _, item in ipairs(nextConfig.bingshuUpNeed) do
  325. local itemID = item[1]
  326. local itemCnt = item[2]
  327. if BagLogic.getItemCnt(human, itemID) < itemCnt then
  328. canUp = false
  329. end
  330. end
  331. if canUp then
  332. return true
  333. end
  334. end
  335. else
  336. local learnList = getCanLearnList()
  337. local canUp = true
  338. for i, skillID in ipairs(learnList) do
  339. canUp = true
  340. local config = FuwenExcel.skill[skillID]
  341. for k, v in ipairs(config.bingshuUpNeed) do
  342. local itemID = v[1]
  343. local itemCnt = v[2]
  344. if BagLogic.getItemCnt(human, itemID) < itemCnt then
  345. canUp = false
  346. end
  347. end
  348. if canUp then
  349. return true
  350. end
  351. end
  352. end
  353. end
  354. end
  355. function isBingShuDotByIndex(human, heroGrid, index)
  356. if not BINGSHU_OPEN_TIME then
  357. -- local d = os.date("*t",time)
  358. local tmpDate = {}
  359. tmpDate.year = 2022
  360. tmpDate.month = 1
  361. tmpDate.day = 31
  362. tmpDate.hour = 0
  363. tmpDate.min = 0
  364. tmpDate.sec = 0
  365. BINGSHU_OPEN_TIME = os.time(tmpDate)
  366. end
  367. if os.time() <= BINGSHU_OPEN_TIME then return end
  368. if not heroGrid then return end
  369. if heroGrid.star < BINGSHU_OPEN_LIST[index] then return end
  370. local grid = getBingshuGrid(heroGrid, index)
  371. if grid then
  372. -- 检测是否能升级
  373. local nextSkillID = getNextSkillID(grid.skillID)
  374. local nextConfig = nextSkillID and FuwenExcel.skill[nextSkillID]
  375. if nextConfig then
  376. local canUp = true
  377. for _, item in ipairs(nextConfig.bingshuUpNeed) do
  378. local itemID = item[1]
  379. local itemCnt = item[2]
  380. if BagLogic.getItemCnt(human, itemID) < itemCnt then
  381. canUp = false
  382. end
  383. end
  384. if canUp then
  385. return true
  386. end
  387. end
  388. else
  389. local learnList = getCanLearnList()
  390. local canUp = true
  391. for i, skillID in ipairs(learnList) do
  392. canUp = true
  393. local config = FuwenExcel.skill[skillID]
  394. for k, v in ipairs(config.bingshuUpNeed) do
  395. local itemID = v[1]
  396. local itemCnt = v[2]
  397. if BagLogic.getItemCnt(human, itemID) < itemCnt then
  398. canUp = false
  399. end
  400. end
  401. if canUp then
  402. return true
  403. end
  404. end
  405. end
  406. end