TransfermationCard.lua 64 KB

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