TransfermationCard.lua 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787
  1. -- 变身卡牌
  2. -- 卡牌孔位的数据结构 <前缀+部位,孔位信息{hole={孔位集合}}>
  3. -- 卡牌背包的数据结构 <数值的卡牌id, 卡牌对象>
  4. TransferCard = {}
  5. local this = {}
  6. local CardType = {
  7. TRANSFER = 1, --变身
  8. ENTRY = 2, --词条
  9. SHEN_FU = 3, -- 神赋
  10. }
  11. local UnlockLimitType = {
  12. SCORES = 1, --品阶
  13. JEWELRY_LEVEL = 2, --首饰等级
  14. }
  15. -- -----------------------------------------------词条类-----------------------------------------------------
  16. -- 定义词条类
  17. local CardEntry = {}
  18. CardEntry.__index = CardEntry
  19. function CardEntry.new(group)
  20. local instance = setmetatable({}, CardEntry)
  21. local entryId, attrId, attrValue = instance:randomOne(group)
  22. instance.entryid = entryId
  23. instance.attrid = attrId
  24. instance.attrvalue = attrValue
  25. return instance
  26. end
  27. function CardEntry.newById(cfgId)
  28. local instance = setmetatable({}, CardEntry)
  29. local entryId, attrId, attrValue = instance:randomOneById(cfgId)
  30. instance.entryid = entryId
  31. instance.attrid = attrId
  32. instance.attrvalue = attrValue
  33. return instance
  34. end
  35. function CardEntry:randomOneById(cfgId)
  36. local oneTable = ConfigDataManager.getTableFirst("cfg_card_att", "id", cfgId)
  37. return self:GetOne0(oneTable)
  38. end
  39. function CardEntry:randomOne(group)
  40. local cfgTableList = ConfigDataManager.getTable("cfg_card_att", "group", group)
  41. local index = math.random(1, #cfgTableList)
  42. local oneTable = cfgTableList[index]
  43. return self:GetOne0(oneTable)
  44. end
  45. function CardEntry:GetOne0(oneTable)
  46. local attrStr = oneTable.att
  47. -- 定义一个表来存储属性信息
  48. local attributes = {}
  49. for attr in attrStr:gmatch("([^|]+)") do
  50. local id, minVal, maxVal, weight = attr:match("(%d+)#(%d+)#(%d+)#(%d+)")
  51. if id and minVal and maxVal and weight then
  52. table.insert(attributes, {
  53. id = tonumber(id),
  54. minVal = tonumber(minVal),
  55. maxVal = tonumber(maxVal),
  56. weight = tonumber(weight)
  57. })
  58. end
  59. end
  60. -- 计算总权重
  61. local totalWeight = 0
  62. for _, attr in ipairs(attributes) do
  63. totalWeight = totalWeight + attr.weight
  64. end
  65. -- 根据权重随机选择一个属性
  66. local randomWeight = math.random(1, totalWeight)
  67. local cumulativeWeight = 0
  68. local selectedAttribute = nil
  69. for _, attr in ipairs(attributes) do
  70. cumulativeWeight = cumulativeWeight + attr.weight
  71. if randomWeight <= cumulativeWeight then
  72. selectedAttribute = attr
  73. break
  74. end
  75. end
  76. -- 生成随机数值
  77. local randomValue = math.random(selectedAttribute.minVal, selectedAttribute.maxVal)
  78. -- 返回属性ID和随机数值
  79. return oneTable.id, selectedAttribute.id, randomValue
  80. end
  81. -- -------------------------------------------------------------------------------------------------------
  82. -- -----------------------------------------------卡牌类-----------------------------------------------------
  83. -- 定义卡牌类
  84. local RoleTransferCard = {}
  85. RoleTransferCard.__index = RoleTransferCard
  86. -- 创建卡牌对象
  87. function RoleTransferCard.new(id, cfgId)
  88. local instance = setmetatable({}, RoleTransferCard)
  89. instance.id = tonumber(id)
  90. instance.cfgid = tonumber(cfgId)
  91. instance.entry = instance:genCardEntry(cfgId)
  92. return instance
  93. end
  94. -- 生成词条
  95. function RoleTransferCard:genCardEntry(itemCfgId)
  96. local entryList = {}
  97. local specialAttStr = ConfigDataManager.getTableValue("cfg_card_shapeshift", "specialAtt", "id", itemCfgId)
  98. if specialAttStr == "" then
  99. return entryList
  100. end
  101. local entrySplit = string.split(specialAttStr, "#")
  102. if #entrySplit <= 0 then
  103. return entryList
  104. end
  105. for _, group in pairs(entrySplit) do
  106. local entry = CardEntry.new(group)
  107. table.insert(entryList, entry)
  108. end
  109. return entryList
  110. end
  111. --获取所有词条的属性
  112. function RoleTransferCard.getAllEntryAttr(entryList)
  113. local resAttr = {}
  114. if table.count(entryList) <= 0 then
  115. return
  116. end
  117. for _, entry in pairs(entryList) do
  118. local attrId = entry.attrid
  119. local attrValue = entry.attrvalue
  120. resAttr[attrId] = (resAttr[attrId] or 0) + attrValue
  121. end
  122. return resAttr
  123. end
  124. -- -------------------------------------------------------------------------------------------------------
  125. -- @description 玩家登录
  126. function TransferCard.Login(actor)
  127. TransferCard.InitRole(actor)
  128. this.ResHoleInfo(actor, 0)
  129. this.ResRoleCardBag(actor)
  130. --变身cd
  131. this.ResTransfermationCD(actor)
  132. -- 如果是变身状态,变身并响应给客户端
  133. local notExpired = TransferCard.CheckTransfermationExpired(actor, true)
  134. if notExpired then
  135. --如果是赤色要塞,取消变身
  136. local mapId = getbaseinfo(actor, "unimapid")
  137. local dupInfo = getduplicate(mapId)
  138. if type(dupInfo) == "table" then
  139. local dupType = dupInfo["type"]
  140. if dupType == DuplicateType.RED_FORTRESS then
  141. this.CancelTransfermation(actor, true)
  142. return
  143. end
  144. end
  145. -- 还未过期,通知客户端变身
  146. local roleState = this.GetRoleState(actor)
  147. local current = roleState.current
  148. local group = current.group
  149. -- 解锁技能
  150. local skillList = this.GetSkillListByActiveGroup(actor, group)
  151. this.AddSkills(actor, skillList, true)
  152. this.ResTransfermationRound(actor, group)
  153. this.ResTransferDuration(actor)
  154. end
  155. -- 变身自动挂机的设置
  156. TransferCard.ResTransferSetting(actor)
  157. end
  158. -- @description 穿装
  159. function TransferCard.EquipChange(actor)
  160. this.UpdateCardAttr(actor)
  161. this.CardOrEquipChanged(actor)
  162. end
  163. -- @description 初始化信息
  164. -- @param 玩家对象
  165. -- @return
  166. function TransferCard.InitRole(actor)
  167. TransferCard.InitRoleCardBag(actor)
  168. TransferCard.InitRoleCardHole(actor)
  169. TransferCard.InitRoleState(actor)
  170. TransferCard.PutOffFuNengCard(actor, 1)
  171. TransferCard.PutOffFuNengCard(actor, 2)
  172. TransferCard.PutOffFuNengCard(actor, 3)
  173. end
  174. -- @description 请求部位信息
  175. -- @param 玩家对象;装备部位;
  176. -- @return
  177. function TransferCard.ReqGetHoleInfo(actor, part)
  178. this.ResHoleInfo(actor, part)
  179. end
  180. -- @description 请求卡牌背包信息
  181. -- @param 玩家对象
  182. -- @return
  183. function TransferCard.ReqGetAllBagCard(actor)
  184. this.ResRoleCardBag(actor)
  185. end
  186. -- @description 保存挂机变身设置
  187. -- @param 玩家对象;设置的数据
  188. -- @return
  189. function TransferCard.ReqUpdateTransferSetting(actor, data)
  190. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_SETTING, data)
  191. TransferCard.ResTransferSetting(actor)
  192. end
  193. -- 挂机变身信息给客户端
  194. function TransferCard.ResTransferSetting(actor)
  195. local setting = getplaydef(actor, PlayerDefKey.TRANSFER_CARD_SETTING)
  196. if type(setting) ~= "table" then
  197. setting = {}
  198. end
  199. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_SETTING, setting)
  200. end
  201. -- @description 请求镶嵌卡牌
  202. -- @param 玩家对象;装备部位;孔位索引;卡牌id
  203. -- @return
  204. function TransferCard.ReqInlayCard(actor, part, idx, cardId)
  205. -- 孔位是否解锁
  206. local roleHole = this.GetRoleHole(actor)
  207. local partKey = tonumber(part)
  208. local holeData = table.getValue(roleHole, partKey)
  209. if holeData == nil then
  210. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqInlayCard==> " .. part .. "索引" .. idx .. "部位不存在")
  211. return
  212. end
  213. local holeList = holeData.hole
  214. local idxKey = tostring(idx)
  215. if holeList[idxKey] == nil then
  216. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqInlayCard==> " .. part .. "索引" .. idx .. "孔位不存在")
  217. return
  218. end
  219. local holeInfo = holeList[idxKey]
  220. if not holeInfo.unlock then
  221. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqInlayCard==> " .. part .. "索引" .. idx .. "孔位未解锁")
  222. return
  223. end
  224. -- 背包是否存在这个卡牌
  225. local cardBag = this.GetCardBag(actor)
  226. if cardBag == nil then
  227. return
  228. end
  229. local card = cardBag[tonumber(cardId)]
  230. if card == nil then
  231. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqInlayCard==> " .. "背包中" .. cardId .. "卡牌不存在")
  232. return
  233. end
  234. -- 原索引是否存在卡牌,如果存在先拆卸再装
  235. local oldCard = holeInfo.card
  236. if oldCard ~= nil then
  237. --放入背包
  238. this.AddCard0(actor, cardBag, oldCard, false)
  239. holeInfo.card = nil
  240. end
  241. -- 从背包移除,装卡牌
  242. this.RemoveCard0(actor, cardBag, cardId, false)
  243. holeInfo.card = card
  244. -- 持久化孔位和背包
  245. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_HOLE, roleHole)
  246. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  247. -- 发送孔位信息
  248. this.ResHoleInfo(actor, part)
  249. -- 发送背包信息
  250. this.ResRoleCardBag(actor)
  251. -- 计算全身卡牌的加成属性
  252. this.UpdateCardAttr(actor)
  253. -- 触发任务刷新
  254. local quality = ConfigDataManager.getTableValue("cfg_card_shapeshift", "quality", "id", card.cfgid)
  255. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.INLAID_TRANSFORMATION_CARD, { card.cfgid, string.tonumber(quality) })
  256. -- 更新开服竞技排行数据
  257. local score = TransferCard.GetRoleScore(actor)
  258. OpenServerCompetition.updateRankData(actor, CompetitionType.CARDSCORE, score)
  259. end
  260. -- @description 请求卸下卡牌
  261. -- @param 玩家对象;装备部位;孔位索引
  262. -- @return
  263. function TransferCard.ReqPutOffCard(actor, part, idx)
  264. -- 孔位是否解锁
  265. local roleHole = this.GetRoleHole(actor)
  266. local partKey = tonumber(part)
  267. local holeData = table.getValue(roleHole, partKey)
  268. if holeData == nil then
  269. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqPutOffCard==> " .. part .. "部位不存在")
  270. end
  271. local holeList = holeData.hole
  272. local idxKey = tostring(idx)
  273. if holeList[idxKey] == nil then
  274. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqPutOffCard==> " .. part .. "索引" .. idx .. "孔位不存在")
  275. return
  276. end
  277. local holeInfo = holeList[idxKey]
  278. if not holeInfo.unlock then
  279. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqPutOffCard==> " .. part .. "索引" .. idx .. "孔位未解锁")
  280. return
  281. end
  282. -- 卸下卡牌,加入背包
  283. local card = holeInfo.card
  284. if card == nil then
  285. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqPutOffCard==> " .. part .. "索引" .. idx .. "卡牌不存在")
  286. return
  287. end
  288. holeInfo.card = nil
  289. local cardBag = this.GetCardBag(actor)
  290. this.AddCard0(actor, cardBag, card, false)
  291. -- 持久化孔位和背包
  292. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_HOLE, roleHole)
  293. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  294. -- 发送孔位信息
  295. this.ResHoleInfo(actor, part)
  296. -- 发送背包信息
  297. this.ResRoleCardBag(actor)
  298. -- 计算全身卡牌的加成属性
  299. this.UpdateCardAttr(actor)
  300. -- 变身状态可能会取消
  301. this.CardOrEquipChanged(actor)
  302. -- 更新开服竞技排行数据
  303. local score = TransferCard.GetRoleScore(actor)
  304. OpenServerCompetition.updateRankData(actor, CompetitionType.CARDSCORE, score)
  305. end
  306. -- @description 兑换卡牌
  307. -- @param 玩家对象;cfg_card_shop的id;购买数量
  308. -- @return
  309. function TransferCard.ReqExchangeCards(actor, cfgId, count)
  310. -- 判断孔位
  311. local needLevel = ConfigDataManager.getTableValue("cfg_card_shop", "condition", "id", cfgId)
  312. needLevel = tonumber(needLevel) == nil and 0 or tonumber(needLevel)
  313. local roleLevel = getbaseinfo(actor, "level")
  314. if roleLevel < needLevel then
  315. return
  316. end
  317. -- 判断消耗
  318. local consumerCfg = ConfigDataManager.getTableValue("cfg_card_shop", "exchangeConsume", "id", cfgId)
  319. local consumerMap = string.toIntIntMap(consumerCfg, "#", "|")
  320. for counsumerId, onceCount in pairs(consumerMap) do
  321. local needItemCount = tonumber(onceCount) * count
  322. local ownCount = getbagitemcountbyid(actor, counsumerId)
  323. if ownCount < needItemCount then
  324. return
  325. end
  326. end
  327. -- 消耗道具
  328. for counsumerId, onceCount in pairs(consumerMap) do
  329. local needItemCount = tonumber(onceCount) * count
  330. removeitemfrombag(actor, counsumerId, needItemCount, 0, 9999, '变身卡牌')
  331. end
  332. -- 获得道具
  333. local itemAdd = ConfigDataManager.getTableValue("cfg_card_shop", "exchangeAdd", "id", cfgId)
  334. local itemAddMap = string.toIntIntMap(itemAdd, "#", "|")
  335. local totalAdd = {}
  336. for itemId, itemCount in pairs(itemAddMap) do
  337. local totalAddCount = tonumber(itemCount) * count
  338. totalAdd[itemId] = totalAddCount
  339. end
  340. additemmaptobag(actor, totalAdd, 0, 9999, '变身卡牌')
  341. end
  342. -- @description 解锁孔位
  343. -- @param 玩家对象;装备部位;孔位索引;解锁类型(1-普通解锁,2-特殊解锁)
  344. -- @return
  345. function TransferCard.ReqUnlockHole(actor, part, idx, type)
  346. local roleHole = this.GetRoleHole(actor)
  347. if roleHole == nil then
  348. return
  349. end
  350. local partKey = tonumber(part)
  351. local holeData = table.getValue(roleHole, partKey)
  352. if holeData == nil then
  353. return
  354. end
  355. local holeList = holeData.hole
  356. -- 判断孔位有无达到最大
  357. local maxCount = ConfigDataManager.getTableValue("cfg_card_inlay", "holeAmount", "part", part)
  358. local nowCount = 0
  359. for _, hole in pairs(holeList) do
  360. if hole.unlock then
  361. nowCount = nowCount + 1
  362. end
  363. end
  364. if nowCount >= tonumber(maxCount) then
  365. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==>" .. part .. "孔位数量已达到最大")
  366. return
  367. end
  368. -- 判断该孔位是否已经解锁
  369. local idxKey = tostring(idx)
  370. if holeList[idxKey] == nil then
  371. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==>" .. part .. "索引" .. idx .. "孔位不存在", holeList)
  372. return
  373. end
  374. local holeInfo = holeList[idxKey]
  375. if holeInfo.unlock then
  376. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==>" .. part .. "索引" .. idx .. "孔位已解锁")
  377. return
  378. end
  379. local equip = this.GetPosEquip(actor, part)
  380. if equip == nil then
  381. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==>" .. part .. "未穿戴装备")
  382. return
  383. end
  384. -- 获取解锁限制
  385. local unlockType = tonumber(ConfigDataManager.getTableValue("cfg_card_inlay", "unlockType", "part", part))
  386. if unlockType == UnlockLimitType.SCORES then
  387. -- 判断品阶
  388. local unlockGradeStr = ConfigDataManager.getTableValue("cfg_card_inlay", "unlockParameter", "part", part)
  389. local unlockGradeMap = string.toIntIntMap(unlockGradeStr, "#", "|")
  390. local needGrade = unlockGradeMap[tonumber(idx)]
  391. local equipCfg = equip.cfgid
  392. local equipGrade = ConfigDataManager.getTableValue("cfg_item", "rank", "id", equipCfg)
  393. needGrade = tonumber(needGrade) == nil and 999 or tonumber(needGrade)
  394. equipGrade = tonumber(equipGrade) == nil and 0 or tonumber(equipGrade)
  395. if equipGrade < needGrade then
  396. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==> 装备品阶未达到要求,当前" .. equipGrade .. ",需要" .. needGrade)
  397. return
  398. end
  399. elseif unlockType == UnlockLimitType.JEWELRY_LEVEL then
  400. -- 判断首饰等级
  401. local unlockGradeStr = ConfigDataManager.getTableValue("cfg_card_inlay", "unlockParameter", "part", part)
  402. local unlockGradeMap = string.toIntIntMap(unlockGradeStr, "#", "|")
  403. local needLevel = unlockGradeMap[tonumber(idx)]
  404. needLevel = tonumber(needLevel) == nil and 999 or tonumber(needLevel)
  405. local equipId = equip.id
  406. local allequip = getplaydef(actor, "T$luaitemextdata")
  407. local equipext = allequip[tonumber(equipId)]
  408. local equipLevel = tonumber(equipext.ssuplv or 999)
  409. if equipLevel < needLevel then
  410. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==> 首饰等级未达到要求,当前" .. equipLevel .. ",需要" .. equipLevel)
  411. return
  412. end
  413. end
  414. -- 是不是免费解锁
  415. local unlockFreeStr = ConfigDataManager.getTableValue("cfg_card_inlay", "unlockFree", "part", part)
  416. local free = false
  417. for _, value in pairs(string.split(unlockFreeStr, "#")) do
  418. if tonumber(idx) == tonumber(value) then
  419. free = true
  420. break
  421. end
  422. end
  423. local unlockRate
  424. if not free then
  425. -- 判断道具数量、消耗道具、解锁的逻辑都一样
  426. local costItemCfg
  427. if tonumber(type) == 1 then
  428. costItemCfg = ConfigDataManager.getTableValue("cfg_card_inlay", "unlockNormal", "part", part)
  429. elseif tonumber(type) == 2 then
  430. costItemCfg = ConfigDataManager.getTableValue("cfg_card_inlay", "unlockSpecial", "part", part)
  431. else
  432. gameDebug.assertPrintTrace(false, actor:toString() .. "不存在的解锁类型")
  433. return
  434. end
  435. local configList = string.split(costItemCfg, "|")
  436. for _, v in pairs(configList) do
  437. local vList = string.split(v, "#")
  438. local index = vList[1]
  439. if tonumber(index) == tonumber(idx) then
  440. local costItemId = vList[2]
  441. local costItemCount = vList[3]
  442. -- 解锁概率,免得后面再循环一次
  443. if tonumber(type) == 1 then
  444. unlockRate = tonumber(vList[4])
  445. elseif tonumber(type) == 2 then
  446. unlockRate = 10000
  447. else
  448. unlockRate = 0
  449. end
  450. local ownCount = getbagitemcountbyid(actor, costItemId)
  451. if tonumber(ownCount) < tonumber(costItemCount) then
  452. --道具不足
  453. return
  454. end
  455. end
  456. end
  457. -- 扣除道具
  458. for _, v in pairs(configList) do
  459. local vList = string.split(v, "#")
  460. local index = vList[1]
  461. if tonumber(index) == tonumber(idx) then
  462. local costItemId = vList[2]
  463. local costItemCount = vList[3]
  464. removeitemfrombag(actor, costItemId, costItemCount, 0, 9999, '变身卡牌')
  465. end
  466. end
  467. end
  468. -- 普通解锁判断条件
  469. local canUnlock = false
  470. if not free then
  471. -- 幸运值如果大于小于一百,概率解锁,解锁失败,加幸运值
  472. if holeInfo.luck < 100 then
  473. local success = this.SelectRate(unlockRate / 10000)
  474. if success then
  475. -- 需要提示吗
  476. canUnlock = true
  477. else
  478. --未解锁
  479. end
  480. else
  481. canUnlock = true
  482. end
  483. end
  484. if canUnlock or free then
  485. -- 解锁
  486. holeInfo["unlock"] = true
  487. else
  488. -- 增加幸运值
  489. local luckPointCfg = ConfigDataManager.getTableValue("cfg_card_inlay", "luckPoint", "part", part)
  490. local luckPointMap = string.getAttrByStr(luckPointCfg)
  491. local luckPoint = luckPointMap[tostring(idx)]
  492. holeInfo["luck"] = holeInfo.luck + tonumber(luckPoint)
  493. noticeTip.noticeinfo(actor, StringIdConst.TEXT436)
  494. end
  495. -- 持久化
  496. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_HOLE, roleHole)
  497. this.ResHoleInfo(actor, part)
  498. end
  499. -- @description 初始化玩家的变身卡牌孔位
  500. -- @param 玩家对象
  501. -- @return
  502. function TransferCard.InitRoleCardHole(actor)
  503. local inlayCfgList = ConfigDataManager.getList("cfg_card_inlay")
  504. if type(inlayCfgList) ~= "table" then
  505. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.InitRoleCardHole==> 读取配置表错误")
  506. return
  507. end
  508. -- 加校验,防止有数据被清空
  509. local oldHole = this.GetRoleHole(actor)
  510. -- 数据结构《部位key,孔位信息列表》
  511. if type(oldHole) ~= "table" then
  512. oldHole = {}
  513. end
  514. for _, dataMap in pairs(inlayCfgList) do
  515. local part = dataMap.part
  516. local varKey = tonumber(part)
  517. -- 如果不存在该部位,初始化该部位
  518. if oldHole[varKey] == nil then
  519. if varKey == nil then
  520. gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.InitRoleCardHole==> 字符串转数值异常" .. part)
  521. return
  522. end
  523. local varValue = {}
  524. -- 所有孔位
  525. local allHole = tonumber(dataMap.holeamount)
  526. local holeList = {}
  527. for i = 1, allHole, 1 do
  528. local holeInfo = {}
  529. local holeKey = tostring(i)
  530. -- 孔位信息具体未定
  531. holeInfo["luck"] = 0
  532. holeInfo["unlock"] = false
  533. holeList[holeKey] = holeInfo
  534. end
  535. varValue["hole"] = holeList
  536. oldHole[varKey] = varValue
  537. end
  538. end
  539. -- 持久化玩家变量
  540. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_HOLE, oldHole)
  541. end
  542. -- @description 初始化玩家的变身卡牌背包
  543. -- @param 玩家对象
  544. -- @return
  545. function TransferCard.InitRoleCardBag(actor)
  546. -- 加校验,如果背包存在,则返回
  547. local oldBag = this.GetCardBag(actor)
  548. if type(oldBag) == "table" then
  549. return
  550. end
  551. -- 创建背包的结构<卡牌唯一id,卡牌信息(Map)>
  552. local cardBag = {}
  553. -- 持久化玩家变量
  554. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  555. end
  556. -- @description 初始化玩家的变身状态信息
  557. -- @param 玩家对象
  558. -- @return
  559. function TransferCard.InitRoleState(actor)
  560. local oldState = this.GetRoleState(actor)
  561. if type(oldState) == "table" then
  562. return
  563. end
  564. -- 创建数据结构
  565. local roleState = { current = nil, cd = {}, skill = {} }
  566. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_STATE, roleState)
  567. return roleState
  568. end
  569. -- 卸下指定位置的赋能卡牌
  570. function TransferCard.PutOffFuNengCard(actor, part)
  571. local roleHole = this.GetRoleHole(actor)
  572. local partKey = tonumber(part)
  573. local holeData = table.getValue(roleHole, partKey)
  574. local holeList = holeData.hole
  575. for idx, holeInfo in pairs(holeList) do
  576. local card = holeInfo.card
  577. if card ~= nil then
  578. local cfgId = card.cfgid
  579. local type = tonumber(ConfigDataManager.getTableValue("cfg_item", "subType", "id", cfgId))
  580. if type ~= CardType.SHEN_FU then
  581. TransferCard.ReqPutOffCard(actor, part, idx)
  582. end
  583. end
  584. end
  585. end
  586. -- @description 卡牌入包事件
  587. -- @param 玩家对象;道具配置id
  588. -- @return
  589. function TransferCard.NotEnterBagItemAdd(actor, itemList)
  590. -- 获取卡牌背包
  591. local cardBag = this.GetCardBag(actor)
  592. local rewardList = {}
  593. for _, itemInfo in pairs(itemList) do
  594. local itemId = itemInfo.id
  595. local itemCfgId = itemInfo.cfgid
  596. local itemType = tonumber(ConfigDataManager.getTableValue("cfg_item", "type", "id", itemCfgId))
  597. if itemType == 8 then
  598. local card = RoleTransferCard.new(itemId, itemCfgId)
  599. this.AddCard0(actor, cardBag, card, false)
  600. table.insert(rewardList, card)
  601. end
  602. end
  603. -- 最后统一持久化优化性能
  604. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  605. if table.count(rewardList) > 0 then
  606. this.ResRoleCardBag(actor)
  607. -- 客户端提示奖励
  608. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_REWARD_PANEL, rewardList)
  609. end
  610. end
  611. -- @description 合成卡牌
  612. -- @param 玩家对象;{主,{副,副,...}}
  613. -- @return
  614. function TransferCard.ReqSynthesisCard(actor, cards)
  615. -- 自定义卡牌数量
  616. local mainCardId = cards[1]
  617. local fuCardIdList = cards[2]
  618. -- 校验参数
  619. local cardBag = this.GetCardBag(actor)
  620. local mainCard = cardBag[tonumber(mainCardId)]
  621. if mainCard == nil then
  622. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "合成卡牌时,卡牌不存在,主卡id:" .. mainCardId)
  623. return
  624. end
  625. local cardCfg = mainCard.cfgid
  626. local upAmount = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "upAmount", "id", cardCfg))
  627. if table.count(fuCardIdList) + 1 < upAmount then
  628. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "合成卡牌时,卡牌数量不足")
  629. return
  630. end
  631. local type = tonumber(ConfigDataManager.getTableValue("cfg_item", "subType", "id", cardCfg))
  632. -- 判断背包里卡牌是否存在;都是相同类型
  633. for _, cardId in pairs(fuCardIdList) do
  634. local card = cardBag[tonumber(cardId)]
  635. if card == nil then
  636. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "合成卡牌时,卡牌不存在,主卡id:" .. cardId)
  637. return
  638. end
  639. if cardCfg ~= card.cfgid then
  640. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "合成卡牌时,卡牌非同同种卡牌,主卡cfgId:" .. cardCfg .. " , 副卡cfgId:" .. card.cfgid)
  641. return
  642. end
  643. end
  644. -- 是否有下一级
  645. local group = ConfigDataManager.getTableValue("cfg_card_shapeshift", "group", "id", cardCfg)
  646. local level = ConfigDataManager.getTableValue("cfg_card_shapeshift", "level", "id", cardCfg)
  647. local nextLevl = tonumber(level) + 1
  648. local nextCardCfg = ConfigDataManager.getTableValue("cfg_card_shapeshift", "id", "level", nextLevl, "group", group)
  649. if nextCardCfg == nil or nextCardCfg == "" then
  650. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "合成卡牌时,卡牌不能再合成到下一级,主卡cfgId:" .. cardCfg)
  651. return
  652. end
  653. -- 消耗副卡
  654. for _, fuCardId in pairs(fuCardIdList) do
  655. this.RemoveCard0(actor, cardBag, fuCardId, false)
  656. end
  657. -- 生成新卡,本质是主卡修改道具id
  658. mainCard.cfgid = tonumber(nextCardCfg)
  659. -- 如果是词条卡牌,生成新词条,并添加进去
  660. local oldEntryList = mainCard.entry
  661. if type == CardType.ENTRY or type == CardType.SHEN_FU then
  662. local newEntryList = RoleTransferCard:genCardEntry(nextCardCfg)
  663. table.insertArray(oldEntryList, newEntryList)
  664. end
  665. -- 持久化背包并回包
  666. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  667. this.ResRoleCardBag(actor)
  668. -- 客户端提示奖励
  669. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_REWARD_PANEL, { mainCard })
  670. -- 合成卡牌刷新任务进度
  671. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.SYNTHESIS_CARD, type)
  672. end
  673. -- @description 一键合成
  674. -- @param 玩家对象;卡牌类型;卡牌等级
  675. -- @return
  676. function TransferCard.ReqSynthesisAll(actor, cardType, level)
  677. cardType = tonumber(cardType)
  678. level = tonumber(level)
  679. if cardType == nil or level == nil then
  680. gameDebug.assertPrintTrace(false, actor:toString() .. "一键合成卡牌时参数有误!" .. cardType .. " , " .. level)
  681. return
  682. end
  683. local cardBag = this.GetCardBag(actor)
  684. if cardBag == nil then
  685. gameDebug.assertPrintTrace(false, actor:toString() .. "玩家卡牌牌库不存在!")
  686. return
  687. end
  688. -- 卡牌根据id分类
  689. local cfg2CardList = {} -- 分类卡牌 <cfgId, {card,card..} >
  690. for _, card in pairs(cardBag) do
  691. local cfgId = card.cfgid
  692. local itemType = ConfigDataManager.getTableValue("cfg_item", "subType", "id", cfgId)
  693. if tonumber(itemType) == cardType then
  694. local cardLevel = ConfigDataManager.getTableValue("cfg_card_shapeshift", "level", "id", cfgId)
  695. if tonumber(cardLevel) == level then
  696. local existTypeCards = cfg2CardList[cfgId] or {}
  697. table.insert(existTypeCards, card)
  698. cfg2CardList[cfgId] = existTypeCards
  699. end
  700. end
  701. end
  702. local newCardList = {} --合成后的新卡牌
  703. local hasCardToSyn = false -- 能否合成
  704. for cfgId, cards in pairs(cfg2CardList) do
  705. -- 是否有下一级
  706. local group = ConfigDataManager.getTableValue("cfg_card_shapeshift", "group", "id", cfgId)
  707. local currentLevel = ConfigDataManager.getTableValue("cfg_card_shapeshift", "level", "id", cfgId)
  708. local nextLevl = tonumber(currentLevel) + 1
  709. local nextCardCfg = ConfigDataManager.getTableValue("cfg_card_shapeshift", "id", "level", nextLevl, "group", group)
  710. if tonumber(nextCardCfg) ~= nil and tonumber(nextCardCfg) > 0 then
  711. -- 判断能否合成直接在这个循环做了
  712. local upAmount = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "upAmount", "id", cfgId))
  713. if #cards >= upAmount then
  714. if hasCardToSyn == false then
  715. hasCardToSyn = true
  716. end
  717. -- 合成卡牌
  718. local size = #cards
  719. local step = upAmount
  720. local loopCount = math.floor(size / upAmount)
  721. for k = 1, loopCount do
  722. local i = (k - 1) * step + 1
  723. if i <= size then
  724. local maxInnerLoop = math.min(step - 1, size - i)
  725. for j = 1, maxInnerLoop do
  726. local fuCard = cards[i + j]
  727. -- 消耗副卡
  728. this.RemoveCard0(actor, cardBag, fuCard.id, false)
  729. end
  730. local mainCard = cards[i]
  731. -- 生成新卡,本质是主卡修改道具id
  732. mainCard.cfgid = tonumber(nextCardCfg)
  733. table.insert(newCardList, mainCard)
  734. -- 如果是词条卡牌,生成新词条,并添加进去
  735. local oldEntryList = mainCard.entry
  736. if cardType == CardType.ENTRY or cardType == CardType.SHEN_FU then
  737. local newEntryList = RoleTransferCard:genCardEntry(nextCardCfg)
  738. table.insertArray(oldEntryList, newEntryList)
  739. end
  740. -- 合成卡牌刷新任务进度
  741. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.SYNTHESIS_CARD, cardType)
  742. end
  743. end
  744. end
  745. end
  746. end
  747. -- 是否有可以合成的卡牌
  748. if hasCardToSyn == false then
  749. gameDebug.assertPrintTrace(false, actor:toString() .. "一键合成卡牌时,没有可以合成的卡牌")
  750. return
  751. end
  752. -- 持久化背包并回包
  753. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  754. this.ResRoleCardBag(actor)
  755. -- 客户端提示奖励
  756. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_REWARD_PANEL, newCardList)
  757. end
  758. -- @description 请求回收卡牌
  759. -- @param 玩家对象;卡牌集合
  760. -- @return
  761. function TransferCard.ReqRecoveryCard(actor, cardList)
  762. local cardBag = this.GetCardBag(actor)
  763. -- 首先判断卡牌数量是否正确
  764. for _, value in pairs(cardList) do
  765. local cardId = tonumber(value)
  766. if cardBag[cardId] == nil then
  767. return
  768. end
  769. end
  770. -- 记录回收获得的道具
  771. local recoverItems = {}
  772. -- 移除卡牌
  773. for _, value in pairs(cardList) do
  774. local cardId = tonumber(value)
  775. local card = cardBag[cardId]
  776. local cfgId = card.cfgid
  777. this.RemoveCard0(actor, cardBag, cardId, false)
  778. -- 记录回收获得的道具
  779. local oneMap = this.GetRecoverItems(cfgId, 1)
  780. this.MergeMap(recoverItems, oneMap)
  781. end
  782. -- 持久化
  783. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  784. -- 发送道具
  785. additemmaptobag(actor, recoverItems, 0, 9999, '变身卡牌')
  786. -- 通用奖励面板
  787. GameTips.sendGetRewardMsg(actor, recoverItems)
  788. -- 发送背包卡牌信息
  789. this.ResRoleCardBag(actor)
  790. end
  791. -- @description 变身
  792. -- @param 玩家对象;卡牌组
  793. -- @return
  794. function TransferCard.ReqTransformation(actor, group)
  795. -- 校验
  796. -- 是否存在对应group的卡牌
  797. local existGroup = this.IsExistGroupCard(actor, group)
  798. if existGroup == false then
  799. return
  800. end
  801. -- 如果是赤色要塞不让变身
  802. local mapId = getbaseinfo(actor, "unimapid")
  803. local dupInfo = getduplicate(mapId)
  804. if type(dupInfo) == "table" then
  805. local dupType = dupInfo["type"]
  806. if dupType == DuplicateType.RED_FORTRESS then
  807. return
  808. end
  809. end
  810. -- 获取玩家变身状态,是否处于变身,需要存储(变身状态,冷却CD)
  811. local roleState = this.GetRoleState(actor)
  812. if roleState == nil then
  813. return
  814. end
  815. -- 是否冷却CD中
  816. local cdMap = roleState.cd
  817. local cdTime = cdMap[group]
  818. local nowMillis = getbaseinfo("now")
  819. if cdTime ~= nil and cdTime > nowMillis then
  820. return
  821. end
  822. local currentState = roleState.current
  823. if currentState ~= nil then
  824. local currentGroup = currentState.group
  825. if currentGroup == group then
  826. return
  827. end
  828. --当前在变身状态
  829. -- 取消技能
  830. local skillList = this.GetSkillListByActiveGroup(actor, currentGroup)
  831. if table.count(skillList) > 0 then
  832. this.RemoveSkills(actor, table.keys(skillList), true)
  833. end
  834. end
  835. -- 加CD
  836. this.AddCd(group, cdMap, nowMillis)
  837. -- 解锁变身技能,并储存下来
  838. local skillList = this.GetSkillListByActiveGroup(actor, group)
  839. this.AddSkills(actor, skillList, true)
  840. roleState.skill = skillList
  841. roleState.current = { group = group, start = nowMillis }
  842. roleState.cd = cdMap
  843. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_STATE, roleState)
  844. -- 通知客户端变身
  845. this.ResTransfermationRound(actor, group)
  846. -- 客户端变身CD
  847. this.ResTransfermationCD(actor, cdMap)
  848. this.ResTransferDuration(actor)
  849. -- 被动技能
  850. PassiveSkill.DoTransfermation(actor, group)
  851. end
  852. function TransferCard.ReqCancelTransfermation(actor)
  853. this.CancelTransfermation(actor, true)
  854. end
  855. -- @description 卡牌突破
  856. -- @param 玩家对象;{主,{副,副,...}}
  857. -- @return
  858. function TransferCard.ReqBreakthrough(actor, cards)
  859. -- 自定义卡牌数量
  860. local mainCardId = cards[1]
  861. local fuCardIdList = cards[2]
  862. -- 校验参数
  863. local cardBag = this.GetCardBag(actor)
  864. local mainCard = cardBag[tonumber(mainCardId)]
  865. if mainCard == nil then
  866. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "卡牌突破时,卡牌不存在,主卡id:" .. mainCardId)
  867. return
  868. end
  869. local cardCfg = mainCard.cfgid
  870. local upAmount = tonumber(ConfigDataManager.getTableValue("cfg_card_breakthrough", "expend", "id", cardCfg))
  871. if table.count(fuCardIdList) + 1 < upAmount then
  872. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "突破卡牌时,卡牌数量不足")
  873. return
  874. end
  875. -- 判断背包里卡牌是否存在;都是相同类型
  876. for _, cardId in pairs(fuCardIdList) do
  877. local card = cardBag[tonumber(cardId)]
  878. if card == nil then
  879. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "突破卡牌时,卡牌不存在,主卡id:" .. cardId)
  880. return
  881. end
  882. if cardCfg ~= card.cfgid then
  883. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "突破卡牌时,卡牌非同同种卡牌,主卡cfgId:" .. cardCfg .. " , 副卡cfgId:" .. card.cfgid)
  884. return
  885. end
  886. end
  887. -- 是否存在突破
  888. local nextCardCfgString = ConfigDataManager.getTableValue("cfg_card_breakthrough", "result", "id", cardCfg)
  889. if string.isNullOrEmpty(nextCardCfgString) then
  890. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "突破卡牌时,不存在突破后的卡牌,主卡id:" .. cardCfg)
  891. return
  892. end
  893. local success, breakCard = this.BreakThrough0(actor, cardBag, mainCard, fuCardIdList)
  894. if success then
  895. -- 客户端提示奖励
  896. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_REWARD_PANEL, { breakCard })
  897. else
  898. -- 突破失败
  899. sendluamsg(actor, LuaMessageIdToClient.RES_CARD_BREAKTHROUGH_FAIL, nil)
  900. end
  901. -- 持久化背包并回包
  902. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  903. this.ResRoleCardBag(actor)
  904. end
  905. -- @description 请求一键突破
  906. -- @param 玩家对象;卡牌类型;卡牌品质
  907. -- @return
  908. function TransferCard.ReqBreakthroughAll(actor, cardType, quality)
  909. if quality == nil or quality <= 0 or cardType == nil or cardType <= 0 then
  910. gameDebug.assertPrintTrace(false, actor:toString() .. "一键卡牌突破时参数有误!quality:" .. quality .. " ;cardType:" .. cardType)
  911. return
  912. end
  913. local cardBag = this.GetCardBag(actor)
  914. if cardBag == nil then
  915. gameDebug.assertPrintTrace(false, actor:toString() .. "玩家卡牌牌库不存在!")
  916. return
  917. end
  918. -- 卡牌根据id分类
  919. local cfg2CardList = {} -- 分类卡牌 <cfgId, {card,card..} >
  920. for _, card in pairs(cardBag) do
  921. local cfgId = card.cfgid
  922. local itemType = ConfigDataManager.getTableValue("cfg_item", "subType", "id", cfgId)
  923. if tonumber(itemType) == cardType then
  924. local needQuality = ConfigDataManager.getTableValue("cfg_card_shapeshift", "quality", "id", cfgId)
  925. if tonumber(needQuality) == quality then
  926. local existTypeCards = cfg2CardList[cfgId] or {}
  927. table.insert(existTypeCards, card)
  928. cfg2CardList[cfgId] = existTypeCards
  929. end
  930. end
  931. end
  932. local newCardList = {} --突破后的新卡牌
  933. local hasCardToBreakthrough = false -- 能否突破
  934. for cfgId, cards in pairs(cfg2CardList) do
  935. -- todo 是否存在突破
  936. local nextCardCfgString = ConfigDataManager.getTableValue("cfg_card_breakthrough", "result", "id", cfgId)
  937. if not string.isNullOrEmpty(nextCardCfgString) then
  938. local upAmount = tonumber(ConfigDataManager.getTableValue("cfg_card_breakthrough", "expend", "id", cfgId))
  939. if #cards >= upAmount then
  940. if hasCardToBreakthrough == false then
  941. hasCardToBreakthrough = true
  942. end
  943. --突破卡牌
  944. local size = #cards
  945. local step = upAmount
  946. local loopCount = math.floor(size / upAmount)
  947. for k = 1, loopCount do
  948. local i = (k - 1) * step + 1
  949. if i <= size then
  950. local fuCardIdList = {}
  951. local maxInnerLoop = math.min(step - 1, size - i)
  952. for j = 1, maxInnerLoop do
  953. local fuCard = cards[i + j]
  954. table.insert(fuCardIdList, fuCard.id)
  955. end
  956. local mainCard = cards[i]
  957. local success, breakCard = this.BreakThrough0(actor, cardBag, mainCard, fuCardIdList)
  958. if success then
  959. table.insert(newCardList, breakCard)
  960. end
  961. end
  962. end
  963. end
  964. end
  965. end
  966. if not hasCardToBreakthrough then
  967. gameDebug.assertPrintTrace(false, actor:toString() .. "一键卡牌突破时,没有可以突破的卡牌!")
  968. return
  969. end
  970. if table.count(newCardList) > 0 then
  971. -- 客户端提示奖励
  972. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_REWARD_PANEL, newCardList)
  973. else
  974. -- 突破失败
  975. sendluamsg(actor, LuaMessageIdToClient.RES_CARD_BREAKTHROUGH_FAIL, nil)
  976. end
  977. -- 持久化背包并回包
  978. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  979. this.ResRoleCardBag(actor)
  980. end
  981. -- @description 卡牌突破根方法,内部不做校验,请确保参数都是正确的
  982. -- @param 玩家对象;卡牌背包;主卡对象;副卡id列表
  983. -- @return 突破结果;突破后的卡牌,突破失败仍是原卡牌
  984. function this.BreakThrough0(actor, cardBag, mainCard, fuCardIdList)
  985. local cardCfg = mainCard.cfgid
  986. local nextCardCfgString = ConfigDataManager.getTableValue("cfg_card_breakthrough", "result", "id", cardCfg)
  987. local nextCardCfgList = string.toIntIntMap(nextCardCfgString, "#", "|")
  988. local totalWeight = 0
  989. for key, weight in pairs(nextCardCfgList) do
  990. totalWeight = totalWeight + weight
  991. end
  992. local randomWeight = math.random(1, totalWeight)
  993. local cumulativeWeight = 0
  994. local nextCardCfg = nil
  995. for key, weight in pairs(nextCardCfgList) do
  996. cumulativeWeight = cumulativeWeight + weight
  997. if randomWeight <= cumulativeWeight then
  998. nextCardCfg = key
  999. break
  1000. end
  1001. end
  1002. if nextCardCfg == nil then
  1003. gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "突破卡牌时,配置有误,突破后的配置不存在!cfg_card_breakthrough的id:" .. cardCfg)
  1004. return false, mainCard
  1005. end
  1006. -- 消耗副卡
  1007. for _, fuCardId in pairs(fuCardIdList) do
  1008. this.RemoveCard0(actor, cardBag, fuCardId, false)
  1009. end
  1010. -- 概率和幸运值
  1011. local probability = tonumber(ConfigDataManager.getTableValue("cfg_card_breakthrough", "probability", "id", cardCfg))
  1012. local success = false
  1013. local oldLuck = mainCard.breakluck or 0
  1014. if oldLuck < 100 then
  1015. success = this.SelectRate(probability / 10000)
  1016. else
  1017. success = true
  1018. end
  1019. if success then
  1020. mainCard.breakluck = 0
  1021. -- 生成新卡,本质是主卡修改道具id
  1022. mainCard.cfgid = tonumber(nextCardCfg)
  1023. -- 如果是词条卡牌,替换词条
  1024. local oldEntryList = mainCard.entry
  1025. local type = tonumber(ConfigDataManager.getTableValue("cfg_item", "subType", "id", cardCfg))
  1026. if type == CardType.ENTRY or type == CardType.SHEN_FU then
  1027. -- 替换词条
  1028. local newEntryList = {}
  1029. for _, entry in pairs(oldEntryList) do
  1030. local entryId = entry.entryid
  1031. local newEntryId = tonumber(ConfigDataManager.getTableValue("cfg_card_att", "breakthroughAtt", "id", entryId))
  1032. local canReplace = false
  1033. if newEntryId ~= nil then
  1034. local newEntryTable = ConfigDataManager.getById("cfg_card_att", newEntryId)
  1035. if newEntryTable ~= nil then
  1036. canReplace = true
  1037. end
  1038. end
  1039. if canReplace then
  1040. local newEntry = CardEntry.newById(newEntryId)
  1041. table.insert(newEntryList, newEntry)
  1042. else
  1043. table.insert(newEntryList, entry)
  1044. end
  1045. end
  1046. mainCard.entry = newEntryList
  1047. end
  1048. else
  1049. local luckPoint = tonumber(ConfigDataManager.getTableValue("cfg_card_breakthrough", "luckPoint", "id", cardCfg))
  1050. mainCard.breakluck = math.min(100, oldLuck + luckPoint)
  1051. end
  1052. return success, mainCard
  1053. end
  1054. -- @description 5秒心跳监测变身时间是否过期
  1055. -- @param 玩家对象;是否响应客户端
  1056. -- @return true(未过期) |false(过期)
  1057. function TransferCard.CheckTransfermationExpired(actor, sendMsg)
  1058. -- 是否过期
  1059. local roleState = this.GetRoleState(actor)
  1060. if roleState == nil then
  1061. return false
  1062. end
  1063. local currentState = roleState.current
  1064. if currentState == nil then
  1065. return false
  1066. end
  1067. local nowMillis = getbaseinfo("now")
  1068. local startTime = currentState.start
  1069. local group = currentState.group
  1070. local duration = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "time", "group", group))
  1071. duration = duration == nil and 0 or duration
  1072. local endTime = startTime + duration
  1073. if nowMillis >= endTime then
  1074. -- 取消变身
  1075. this.CancelTransfermation(actor, sendMsg)
  1076. return false
  1077. end
  1078. return true
  1079. end
  1080. -- @description 获取角色卡牌评分
  1081. -- @param 玩家对象
  1082. -- @return 评分
  1083. function TransferCard.GetRoleScore(actor)
  1084. local totalScore = 0
  1085. local roleHole = this.GetRoleHole(actor)
  1086. if type(roleHole) ~= "table" then
  1087. return 0
  1088. end
  1089. for partKey, partData in pairs(roleHole) do
  1090. -- 卡牌要和装备栏关联
  1091. local pos = tonumber(partKey)
  1092. if this.IsExistEquip(actor, pos) then
  1093. local holeList = partData.hole
  1094. for holeKey, holeInfo in pairs(holeList) do
  1095. local card = holeInfo.card
  1096. if card ~= nil then
  1097. -- 评分
  1098. local cardCfg = card.cfgid
  1099. local oneScore = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "score", "id", cardCfg))
  1100. oneScore = (oneScore or 0)
  1101. totalScore = totalScore + oneScore
  1102. end
  1103. end
  1104. end
  1105. end
  1106. return totalScore
  1107. end
  1108. -- @description 变身状态下卡牌或者装备发生变化
  1109. -- @param
  1110. -- @return
  1111. function this.CardOrEquipChanged(actor)
  1112. local roleState = this.GetRoleState(actor)
  1113. if roleState == nil then
  1114. return
  1115. end
  1116. local currentState = roleState.current
  1117. if currentState == nil then
  1118. return
  1119. end
  1120. local group = currentState.group
  1121. -- 如果不存在这个group了,取消变身
  1122. local exist = this.IsExistGroupCard(actor, group)
  1123. if exist == false then
  1124. -- 取消变身
  1125. this.CancelTransfermation(actor, true)
  1126. return
  1127. end
  1128. -- 如果技能发生变化,解锁或者升级
  1129. local oldSkillList = roleState.skill
  1130. local nowSkillList = this.GetSkillListByActiveGroup(actor, group)
  1131. -- 取消掉旧的
  1132. local removeskillList = {}
  1133. for id, level in pairs(oldSkillList) do
  1134. if nowSkillList[id] == nil then
  1135. table.insert(removeskillList, id)
  1136. end
  1137. end
  1138. this.RemoveSkills(actor, removeskillList, false)
  1139. -- 更改成新的
  1140. local levelUpSkills = {}
  1141. for id, level in pairs(nowSkillList) do
  1142. if oldSkillList[id] ~= level then
  1143. levelUpSkills[tonumber(id)] = tonumber(level)
  1144. end
  1145. end
  1146. this.AddSkills(actor, levelUpSkills, false)
  1147. -- 持久化
  1148. roleState.skill = nowSkillList
  1149. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_STATE, roleState)
  1150. end
  1151. -- @description 取消技能
  1152. -- @param 玩家对象;技能列表;是否取消全部
  1153. -- @return
  1154. function this.RemoveSkills(actor, skillList, cover)
  1155. cover = cover == nil and false or true
  1156. if table.count(skillList) <= 0 then
  1157. return
  1158. end
  1159. removeskill(actor, skillList)
  1160. setlimitskills(actor, LimitSkillType.TRANSFER_CARD, 2, cover, skillList)
  1161. end
  1162. -- @description 升级技能
  1163. -- @param 玩家对象;技能列表;是否直接覆盖
  1164. -- @return
  1165. function this.AddSkills(actor, skillMap, cover)
  1166. cover = cover == nil and false or true
  1167. if table.count(skillMap) <= 0 then
  1168. return
  1169. end
  1170. for skillId, skillLevel in pairs(skillMap) do
  1171. levelupskill(actor, skillId, skillLevel)
  1172. end
  1173. local skillIdList = table.keys(skillMap)
  1174. -- 不屏蔽连击技能
  1175. local comboSkill = getrolefield(actor, "role.roleskill.comboskill")
  1176. local skillCfgId = comboSkill.skillCfgId
  1177. if skillCfgId > 0 then
  1178. table.insert(skillIdList, skillCfgId)
  1179. end
  1180. setlimitskills(actor, LimitSkillType.TRANSFER_CARD, 1, cover, skillIdList)
  1181. end
  1182. -- @description 取消变身
  1183. -- @param
  1184. -- @return
  1185. function this.CancelTransfermation(actor, sendMsg)
  1186. local roleState = this.GetRoleState(actor)
  1187. if roleState == nil then
  1188. return
  1189. end
  1190. local skillList = roleState.skill
  1191. local allIds = table.keys(skillList)
  1192. -- 取消变身
  1193. roleState.skill = nil
  1194. roleState.current = nil
  1195. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_STATE, roleState)
  1196. --取消技能
  1197. this.RemoveSkills(actor, allIds, true)
  1198. -- 取消buff
  1199. local allBuff = getbuffinfo(actor)
  1200. for _, buffInfo in pairs(allBuff) do
  1201. local buffCfgId = buffInfo.buffcfgid
  1202. local source = tonumber(ConfigDataManager.getTableValue("cfg_buff", "source", "id", buffCfgId))
  1203. if source == BuffSource.TRANSFER_CARD then
  1204. delbuff(actor, buffCfgId)
  1205. end
  1206. end
  1207. if sendMsg then
  1208. -- 给客户端回包
  1209. this.ResTransfermationRound(actor, "0")
  1210. end
  1211. end
  1212. -- @description 玩家进入视野
  1213. -- @param 自己;对方
  1214. -- @return
  1215. function TransferCard.PlayerEnterView(actor, targetPlayer)
  1216. -- 对方是否变身
  1217. local roleState = getplaydef(targetPlayer, PlayerDefKey.TRANSFER_CARD_STATE)
  1218. if roleState == nil then
  1219. return
  1220. end
  1221. local currentState = roleState.current
  1222. if currentState == nil then
  1223. return
  1224. end
  1225. local group = currentState.group
  1226. -- 如果是赤色要塞不发视野包
  1227. local mapId = getbaseinfo(actor, "unimapid")
  1228. local dupInfo = getduplicate(mapId)
  1229. if type(dupInfo) == "table" then
  1230. local dupType = dupInfo["type"]
  1231. if dupType == DuplicateType.RED_FORTRESS then
  1232. return
  1233. end
  1234. end
  1235. -- 变身的话发送视野包给自己
  1236. local rid = getbaseinfo(targetPlayer, "rid")
  1237. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_MODEL_VIEW, { tostring(rid), tostring(group) })
  1238. end
  1239. -- @description 变身视野包
  1240. -- @param 玩家对象;变身-group,取消变身- 0
  1241. -- @return
  1242. function this.ResTransfermationRound(actor, group)
  1243. -- 赤色要塞不能变身
  1244. local mapId = getbaseinfo(actor, "unimapid")
  1245. local dupInfo = getduplicate(mapId)
  1246. if type(dupInfo) == "table" and tonumber(group) ~= 0 then
  1247. local dupType = dupInfo["type"]
  1248. if dupType == DuplicateType.RED_FORTRESS then
  1249. return
  1250. end
  1251. end
  1252. local rid = getbaseinfo(actor, "rid")
  1253. -- 协议待定
  1254. sendrefluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_MODEL_VIEW, { tostring(rid), tostring(group) })
  1255. end
  1256. function this.AddCd(group, cdMap, nowMillis)
  1257. local allGroups = this.GetAllGroup()
  1258. -- 给当前group加技能CD
  1259. local cd = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "cd", "group", group))
  1260. cd = cd == nil and 0 or cd
  1261. local commonCd = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "commonCd", "group", group))
  1262. commonCd = commonCd == nil and 0 or commonCd
  1263. local trueCd = math.max(cd, commonCd)
  1264. cdMap[group] = nowMillis + trueCd
  1265. -- 给其他group加公共CD
  1266. if commonCd > 0 then
  1267. for _, value in pairs(allGroups) do
  1268. if value ~= group then
  1269. local endTime = nowMillis + commonCd
  1270. local currentCd = cdMap[value]
  1271. if currentCd == nil or currentCd < endTime then
  1272. cdMap[value] = endTime
  1273. end
  1274. end
  1275. end
  1276. end
  1277. return cdMap
  1278. end
  1279. function this.GetAllGroup()
  1280. local ret = {}
  1281. local cfgList = ConfigDataManager.getList("cfg_card_shapeshift")
  1282. if cfgList == nil then
  1283. return ret
  1284. end
  1285. for _, value in pairs(cfgList) do
  1286. local group = tonumber(value.group)
  1287. if not table.contains(ret, group) then
  1288. table.insert(ret, group)
  1289. end
  1290. end
  1291. return ret
  1292. end
  1293. -- @description 更新全身卡牌的属性
  1294. -- @param 玩家对象
  1295. -- @return
  1296. function this.UpdateCardAttr(actor)
  1297. --属性容器,id-value
  1298. local addAttr = {}
  1299. -- 遍历所有装配的卡牌
  1300. local roleHole = this.GetRoleHole(actor)
  1301. if type(roleHole) ~= "table" then
  1302. return
  1303. end
  1304. for partKey, partData in pairs(roleHole) do
  1305. -- 卡牌要和装备栏关联
  1306. local pos = tonumber(partKey)
  1307. if this.IsExistEquip(actor, pos) then
  1308. local holeList = partData.hole
  1309. for holeKey, holeInfo in pairs(holeList) do
  1310. local card = holeInfo.card
  1311. if card ~= nil then
  1312. --属性
  1313. local cardCfg = card.cfgid
  1314. local cardAttr = this.GetCardAttr(cardCfg)
  1315. local entryAttr = RoleTransferCard.getAllEntryAttr(card.entry)
  1316. this.MergeMap(addAttr, cardAttr)
  1317. this.MergeMap(addAttr, entryAttr)
  1318. end
  1319. end
  1320. end
  1321. end
  1322. -- 属性加到人身上去
  1323. addrolekmlattributes(actor, ScriptAttrType.TRANSFER_CARD, addAttr)
  1324. end
  1325. -- @description 是否存在对应group的已激活卡牌
  1326. -- @param
  1327. -- @return
  1328. function this.IsExistGroupCard(actor, group)
  1329. if tonumber(group) == nil then
  1330. return false
  1331. end
  1332. local roleHole = this.GetRoleHole(actor)
  1333. for partKey, partData in pairs(roleHole) do
  1334. local holeList = partData.hole
  1335. for holeKey, holeInfo in pairs(holeList) do
  1336. local pos = tonumber(partKey)
  1337. if this.IsExistEquip(actor, pos) then
  1338. local card = holeInfo.card
  1339. if card ~= nil then
  1340. local cardCfg = card.cfgid
  1341. local cardGroup = ConfigDataManager.getTableValue("cfg_card_shapeshift", "group", "id", cardCfg)
  1342. if tonumber(cardGroup) == group then
  1343. return true
  1344. end
  1345. end
  1346. end
  1347. end
  1348. end
  1349. return false
  1350. end
  1351. -- @description 部位是否存在装备
  1352. -- @param 玩家对象;部位
  1353. -- @return
  1354. function this.IsExistEquip(actor, pos)
  1355. local putOnEquipList = getputonequipinfo(actor)
  1356. for _, equipinfo in pairs(putOnEquipList) do
  1357. if this.GetPosByEquipIdx(equipinfo.equipindex) == tonumber(pos) then
  1358. return true
  1359. end
  1360. end
  1361. return false
  1362. end
  1363. -- @description 获取穿戴栏穿戴的部位
  1364. -- @param 穿戴栏
  1365. -- @return
  1366. function this.GetPosByEquipIdx(idx)
  1367. return idx & 255
  1368. end
  1369. -- 获取部位上穿戴装备的信息
  1370. function this.GetPosEquip(actor, pos)
  1371. local putOnEquipList = getputonequipinfo(actor)
  1372. for _, equipinfo in pairs(putOnEquipList) do
  1373. if this.GetPosByEquipIdx(equipinfo.equipindex) == tonumber(pos) then
  1374. return equipinfo
  1375. end
  1376. end
  1377. return nil
  1378. end
  1379. -- @description 通过配置表获取卡牌组的所有技能
  1380. -- @param
  1381. -- @return
  1382. function this.GetAllSkillFromCfg(group)
  1383. local skillList = {} -- 技能id,技能等级
  1384. local cfgList = ConfigDataManager.getTable("cfg_card_shapeshift", "group", group)
  1385. if table.count(cfgList) > 0 then
  1386. for key, tableData in pairs(cfgList) do
  1387. local cardId = tableData.id
  1388. local cardSkill = this.GetCardSkill(cardId)
  1389. this.CoveringSkillMap(skillList, cardSkill)
  1390. end
  1391. end
  1392. return skillList
  1393. end
  1394. -- @description 获取可以激活的变身技能
  1395. -- @param 玩家对象;卡牌组
  1396. -- @return 技能列表<技能id,技能等级>
  1397. function this.GetSkillListByActiveGroup(actor, group)
  1398. local skillList = {} -- 技能id,技能等级
  1399. local roleHole = this.GetRoleHole(actor)
  1400. for partKey, partData in pairs(roleHole) do
  1401. local holeList = partData.hole
  1402. for holeKey, holeInfo in pairs(holeList) do
  1403. -- 卡牌要和装备栏关联
  1404. local pos = tonumber(partKey)
  1405. if this.IsExistEquip(actor, pos) then
  1406. local card = holeInfo.card
  1407. if card ~= nil then
  1408. local cardCfg = card.cfgid
  1409. local cardGroup = ConfigDataManager.getTableValue("cfg_card_shapeshift", "group", "id", cardCfg)
  1410. if tonumber(group) == tonumber(cardGroup) then
  1411. local cardSkill = this.GetCardSkill(cardCfg)
  1412. this.CoveringSkillMap(skillList, cardSkill)
  1413. end
  1414. end
  1415. end
  1416. end
  1417. end
  1418. return skillList
  1419. end
  1420. -- 合并属性表
  1421. function this.MergeMap(allMap, oneMap)
  1422. if table.count(oneMap) <= 0 then
  1423. return
  1424. end
  1425. for key, value in pairs(oneMap) do
  1426. key = tonumber(key)
  1427. value = tonumber(value)
  1428. if key ~= nil and value ~= nil then
  1429. local num = allMap[key]
  1430. if num == 0 or num == nil then
  1431. allMap[key] = value
  1432. else
  1433. allMap[key] = num + value
  1434. end
  1435. end
  1436. end
  1437. end
  1438. -- 覆盖技能表,等级更高的会覆盖
  1439. function this.CoveringSkillMap(allMap, oneMap)
  1440. for key, value in pairs(oneMap) do
  1441. key = tonumber(key)
  1442. value = tonumber(value)
  1443. if key ~= nil and value ~= nil then
  1444. local num = allMap[key]
  1445. if num == 0 or num == nil then
  1446. allMap[key] = value
  1447. else
  1448. if value > num then
  1449. allMap[key] = value
  1450. end
  1451. end
  1452. end
  1453. end
  1454. end
  1455. function this.GetCardSkill(cardId)
  1456. local ret = {}
  1457. local attrCfg = ConfigDataManager.getTableValue("cfg_card_shapeshift", "skill", "id", cardId)
  1458. local data = string.split(attrCfg, "|")
  1459. if data then
  1460. for _, v in ipairs(data) do
  1461. local data2 = string.split(v, "#")
  1462. ret[tonumber(data2[1])] = tonumber(data2[2])
  1463. end
  1464. end
  1465. return ret
  1466. end
  1467. function this.GetCardAttr(cardId)
  1468. local ret = {}
  1469. local attrCfg = ConfigDataManager.getTableValue("cfg_card_shapeshift", "attribute", "id", cardId)
  1470. local data = string.split(attrCfg, "|")
  1471. if data then
  1472. for _, v in ipairs(data) do
  1473. local data2 = string.split(v, "#")
  1474. ret[tonumber(data2[1])] = tonumber(data2[2])
  1475. end
  1476. end
  1477. return ret
  1478. end
  1479. function this.AddCard0(actor, cardBag, card, persistent)
  1480. local cardId = tonumber(card.id)
  1481. if cardId == nil then
  1482. gameDebug.assertPrintTrace(false, actor:toString() .. "localThis.AddCard00 -> card id is nil")
  1483. return
  1484. end
  1485. cardBag[cardId] = card
  1486. if persistent then
  1487. -- 持久化玩家变量
  1488. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  1489. end
  1490. end
  1491. function this.RemoveCard0(actor, cardBag, cardId, persistent)
  1492. cardBag[tonumber(cardId)] = nil
  1493. if persistent then
  1494. setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag)
  1495. end
  1496. return cardBag
  1497. end
  1498. -- @description 获取回收获得的道具
  1499. -- @param 卡牌id;数量
  1500. -- @return
  1501. function this.GetRecoverItems(cardCfg, num)
  1502. local itemMap = {}
  1503. local recoverId = ConfigDataManager.getTableValue("cfg_item", "recoveryGroup", "id", cardCfg)
  1504. local recoverCfg = ConfigDataManager.getById("cfg_recovery", recoverId)
  1505. if recoverCfg == nil then
  1506. return
  1507. end
  1508. local shuXianSplit = string.split(recoverCfg.material, "|")
  1509. for _, value in pairs(shuXianSplit) do
  1510. local jinHaoSplit = string.split(value, "#")
  1511. local itemId = jinHaoSplit[1]
  1512. local minCount = jinHaoSplit[2]
  1513. local maxCount = jinHaoSplit[3]
  1514. for i = 1, tonumber(num), 1 do
  1515. local randomCount
  1516. if minCount >= maxCount then
  1517. randomCount = minCount
  1518. else
  1519. randomCount = math.random(tonumber(minCount), tonumber(maxCount))
  1520. end
  1521. local oneItem = {}
  1522. oneItem[tonumber(itemId)] = randomCount
  1523. this.MergeMap(itemMap, oneItem)
  1524. end
  1525. end
  1526. return itemMap
  1527. end
  1528. function this.ResHoleInfo(actor, part)
  1529. part = tonumber(part) == nil and 0 or tonumber(part)
  1530. local roleHole = this.GetRoleHole(actor)
  1531. local res = {}
  1532. if part == 0 then
  1533. for key, value in pairs(roleHole) do
  1534. local onePart = tonumber(key)
  1535. onePart = tonumber(onePart)
  1536. res[onePart] = value.hole
  1537. end
  1538. else
  1539. local partKey = tonumber(part)
  1540. local holeData = table.getValue(roleHole, partKey)
  1541. local holeList = holeData.hole
  1542. -- 发送协议给客户端
  1543. res[part] = holeList
  1544. end
  1545. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_PART_INFO, res)
  1546. end
  1547. -- @description 发送卡牌背包给客户端
  1548. -- @param
  1549. -- @return
  1550. function this.ResRoleCardBag(actor)
  1551. local cardBag = this.GetCardBag(actor)
  1552. local res = table.values(cardBag)
  1553. -- 发送协议给客户端
  1554. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_BAG, res)
  1555. end
  1556. function this.ResTransfermationCD(actor, cdMap)
  1557. local res = {}
  1558. if cdMap == nil then
  1559. local roleState = this.GetRoleState(actor)
  1560. cdMap = roleState.cd
  1561. end
  1562. local nowMillis = getbaseinfo("now")
  1563. for group, endTime in pairs(cdMap) do
  1564. if endTime > nowMillis then
  1565. res[group] = endTime
  1566. end
  1567. end
  1568. if table.count(res) > 0 then
  1569. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_CD, res)
  1570. end
  1571. end
  1572. -- @description 响应变身持续时间
  1573. -- @param
  1574. -- @return
  1575. function this.ResTransferDuration(actor)
  1576. local roleState = this.GetRoleState(actor)
  1577. local currentState = roleState.current
  1578. if currentState == nil then
  1579. return
  1580. end
  1581. local startTime = currentState.start
  1582. local group = currentState.group
  1583. local duration = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "time", "group", group))
  1584. duration = duration == nil and 0 or duration
  1585. local endTime = startTime + duration
  1586. sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_DURATION, { group, tostring(endTime) })
  1587. end
  1588. -- @description 获取全身孔位数量
  1589. -- @param
  1590. -- @return
  1591. function this.GetAllHoleCount(actor)
  1592. local count = 0
  1593. local roleHole = this.GetRoleHole(actor)
  1594. for partKey, varValue in pairs(roleHole) do
  1595. local holeList = varValue.hole
  1596. for _, hole in pairs(holeList) do
  1597. if hole.unlock then
  1598. count = count + 1
  1599. end
  1600. end
  1601. end
  1602. return count
  1603. end
  1604. -- @description 获取某个部位的孔位数量
  1605. -- @param 玩家对象;装备部位
  1606. -- @return
  1607. function this.GetPartHoleCount(actor, part)
  1608. local count = 0
  1609. local roleHole = this.GetRoleHole(actor)
  1610. local partKey = tonumber(part)
  1611. local holeData = table.getValue(roleHole, partKey)
  1612. local holeList = holeData.hole
  1613. for _, hole in pairs(holeList) do
  1614. if hole.unlock then
  1615. count = count + 1
  1616. end
  1617. end
  1618. return count
  1619. end
  1620. -- @description 根据概率随机true或者false
  1621. -- @param 概率值 1=100%
  1622. -- @return
  1623. function this.SelectRate(probability)
  1624. local randomNum = math.random()
  1625. if randomNum <= probability then
  1626. return true
  1627. else
  1628. return false
  1629. end
  1630. end
  1631. function this.GetCardBag(actor)
  1632. local cardBag = getplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG)
  1633. return cardBag
  1634. end
  1635. function this.GetRoleHole(actor)
  1636. local roleHole = getplaydef(actor, PlayerDefKey.TRANSFER_CARD_HOLE)
  1637. return roleHole
  1638. end
  1639. function this.GetRoleState(actor)
  1640. local roleState = getplaydef(actor, PlayerDefKey.TRANSFER_CARD_STATE)
  1641. return roleState
  1642. end
  1643. -- @description 获取当前变身
  1644. -- @param 玩家对象
  1645. -- @return 变身的group;0-表示无变身
  1646. function TransferCard.GetCurrentTransfermation(actor)
  1647. local roleState = this.GetRoleState(actor)
  1648. if roleState == nil then
  1649. return 0
  1650. end
  1651. local currentState = roleState.current
  1652. if currentState == nil then
  1653. return 0
  1654. end
  1655. return currentState.group
  1656. end
  1657. -- 注册登录事件
  1658. LoginEventListerTable:eventLister("0", "变身卡牌", TransferCard.Login, 9999)