TransfermationCard.lua 63 KB

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