-- 变身卡牌 -- 卡牌孔位的数据结构 <前缀+部位,孔位信息{hole={孔位集合}}> -- 卡牌背包的数据结构 <数值的卡牌id, 卡牌对象> TransferCard = {} local this = {} local CardType = { TRANSFER = 1, --变身 ENTRY = 2, --词条 SHEN_FU = 3, -- 神赋 } local UnlockLimitType = { SCORES = 1, --品阶 JEWELRY_LEVEL = 2, --首饰等级 } -- -----------------------------------------------词条类----------------------------------------------------- -- 定义词条类 local CardEntry = {} CardEntry.__index = CardEntry function CardEntry.new(group) local instance = setmetatable({}, CardEntry) local entryId, attrId, attrValue = instance:randomOne(group) instance.entryid = entryId instance.attrid = attrId instance.attrvalue = attrValue return instance end function CardEntry.newById(cfgId) local instance = setmetatable({}, CardEntry) local entryId, attrId, attrValue = instance:randomOneById(cfgId) instance.entryid = entryId instance.attrid = attrId instance.attrvalue = attrValue return instance end function CardEntry:randomOneById(cfgId) local oneTable = ConfigDataManager.getTableFirst("cfg_card_att", "id", cfgId) return self:GetOne0(oneTable) end function CardEntry:randomOne(group) local cfgTableList = ConfigDataManager.getTable("cfg_card_att", "group", group) local index = math.random(1, #cfgTableList) local oneTable = cfgTableList[index] return self:GetOne0(oneTable) end function CardEntry:GetOne0(oneTable) local attrStr = oneTable.att -- 定义一个表来存储属性信息 local attributes = {} for attr in attrStr:gmatch("([^|]+)") do local id, minVal, maxVal, weight = attr:match("(%d+)#(%d+)#(%d+)#(%d+)") if id and minVal and maxVal and weight then table.insert(attributes, { id = tonumber(id), minVal = tonumber(minVal), maxVal = tonumber(maxVal), weight = tonumber(weight) }) end end -- 计算总权重 local totalWeight = 0 for _, attr in ipairs(attributes) do totalWeight = totalWeight + attr.weight end -- 根据权重随机选择一个属性 local randomWeight = math.random(1, totalWeight) local cumulativeWeight = 0 local selectedAttribute = nil for _, attr in ipairs(attributes) do cumulativeWeight = cumulativeWeight + attr.weight if randomWeight <= cumulativeWeight then selectedAttribute = attr break end end -- 生成随机数值 local randomValue = math.random(selectedAttribute.minVal, selectedAttribute.maxVal) -- 返回属性ID和随机数值 return oneTable.id, selectedAttribute.id, randomValue end -- ------------------------------------------------------------------------------------------------------- -- -----------------------------------------------卡牌类----------------------------------------------------- -- 定义卡牌类 local RoleTransferCard = {} RoleTransferCard.__index = RoleTransferCard -- 创建卡牌对象 function RoleTransferCard.new(id, cfgId) local instance = setmetatable({}, RoleTransferCard) instance.id = tonumber(id) instance.cfgid = tonumber(cfgId) instance.entry = instance:genCardEntry(cfgId) return instance end -- 生成词条 function RoleTransferCard:genCardEntry(itemCfgId) local entryList = {} local specialAttStr = ConfigDataManager.getTableValue("cfg_card_shapeshift", "specialAtt", "id", itemCfgId) if specialAttStr == "" then return entryList end local entrySplit = string.split(specialAttStr, "#") if #entrySplit <= 0 then return entryList end for _, group in pairs(entrySplit) do local entry = CardEntry.new(group) table.insert(entryList, entry) end return entryList end --获取所有词条的属性 function RoleTransferCard.getAllEntryAttr(entryList) local resAttr = {} if table.count(entryList) <= 0 then return end for _, entry in pairs(entryList) do local attrId = entry.attrid local attrValue = entry.attrvalue resAttr[attrId] = (resAttr[attrId] or 0) + attrValue end return resAttr end -- ------------------------------------------------------------------------------------------------------- -- @description 玩家登录 function TransferCard.Login(actor) TransferCard.InitRole(actor) this.ResHoleInfo(actor, 0) this.ResRoleCardBag(actor) --变身cd this.ResTransfermationCD(actor) -- 如果是变身状态,变身并响应给客户端 local notExpired = TransferCard.CheckTransfermationExpired(actor, true) if notExpired then --如果是赤色要塞,取消变身 local mapId = getbaseinfo(actor, "unimapid") local dupInfo = getduplicate(mapId) if type(dupInfo) == "table" then local dupType = dupInfo["type"] if dupType == DuplicateType.RED_FORTRESS then this.CancelTransfermation(actor, true) return end end -- 还未过期,通知客户端变身 local roleState = this.GetRoleState(actor) local current = roleState.current local group = current.group -- 解锁技能 local skillList = this.GetSkillListByActiveGroup(actor, group) this.AddSkills(actor, skillList, true) this.ResTransfermationRound(actor, group) this.ResTransferDuration(actor) end -- 变身自动挂机的设置 TransferCard.ResTransferSetting(actor) end -- @description 穿装 function TransferCard.EquipChange(actor) this.UpdateCardAttr(actor) this.CardOrEquipChanged(actor) end -- @description 初始化信息 -- @param 玩家对象 -- @return function TransferCard.InitRole(actor) TransferCard.InitRoleCardBag(actor) TransferCard.InitRoleCardHole(actor) TransferCard.InitRoleState(actor) TransferCard.PutOffFuNengCard(actor, 1) TransferCard.PutOffFuNengCard(actor, 2) TransferCard.PutOffFuNengCard(actor, 3) end -- @description 请求部位信息 -- @param 玩家对象;装备部位; -- @return function TransferCard.ReqGetHoleInfo(actor, part) this.ResHoleInfo(actor, part) end -- @description 请求卡牌背包信息 -- @param 玩家对象 -- @return function TransferCard.ReqGetAllBagCard(actor) this.ResRoleCardBag(actor) end -- @description 保存挂机变身设置 -- @param 玩家对象;设置的数据 -- @return function TransferCard.ReqUpdateTransferSetting(actor, data) setplaydef(actor, PlayerDefKey.TRANSFER_CARD_SETTING, data) TransferCard.ResTransferSetting(actor) end -- 挂机变身信息给客户端 function TransferCard.ResTransferSetting(actor) local setting = getplaydef(actor, PlayerDefKey.TRANSFER_CARD_SETTING) if type(setting) ~= "table" then setting = {} end sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_SETTING, setting) end -- @description 请求镶嵌卡牌 -- @param 玩家对象;装备部位;孔位索引;卡牌id -- @return function TransferCard.ReqInlayCard(actor, part, idx, cardId) -- 孔位是否解锁 local roleHole = this.GetRoleHole(actor) local partKey = tonumber(part) local holeData = table.getValue(roleHole, partKey) if holeData == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqInlayCard==> " .. part .. "索引" .. idx .. "部位不存在") return end local holeList = holeData.hole local idxKey = tostring(idx) if holeList[idxKey] == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqInlayCard==> " .. part .. "索引" .. idx .. "孔位不存在") return end local holeInfo = holeList[idxKey] if not holeInfo.unlock then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqInlayCard==> " .. part .. "索引" .. idx .. "孔位未解锁") return end -- 背包是否存在这个卡牌 local cardBag = this.GetCardBag(actor) if cardBag == nil then return end local card = cardBag[tonumber(cardId)] if card == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqInlayCard==> " .. "背包中" .. cardId .. "卡牌不存在") return end -- 原索引是否存在卡牌,如果存在先拆卸再装 local oldCard = holeInfo.card if oldCard ~= nil then --放入背包 this.AddCard0(actor, cardBag, oldCard, false) holeInfo.card = nil end -- 从背包移除,装卡牌 this.RemoveCard0(actor, cardBag, cardId, false) holeInfo.card = card -- 持久化孔位和背包 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_HOLE, roleHole) setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) -- 发送孔位信息 this.ResHoleInfo(actor, part) -- 发送背包信息 this.ResRoleCardBag(actor) -- 计算全身卡牌的加成属性 this.UpdateCardAttr(actor) -- 触发任务刷新 local quality = ConfigDataManager.getTableValue("cfg_card_shapeshift", "quality", "id", card.cfgid) TaskHandler.TriggerTaskGoal(actor, TaskTargetType.INLAID_TRANSFORMATION_CARD, { card.cfgid, string.tonumber(quality) }) -- 更新开服竞技排行数据 local score = TransferCard.GetRoleScore(actor) OpenServerCompetition.updateRankData(actor, CompetitionType.CARDSCORE, score) end -- @description 请求卸下卡牌 -- @param 玩家对象;装备部位;孔位索引 -- @return function TransferCard.ReqPutOffCard(actor, part, idx) -- 孔位是否解锁 local roleHole = this.GetRoleHole(actor) local partKey = tonumber(part) local holeData = table.getValue(roleHole, partKey) if holeData == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqPutOffCard==> " .. part .. "部位不存在") end local holeList = holeData.hole local idxKey = tostring(idx) if holeList[idxKey] == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqPutOffCard==> " .. part .. "索引" .. idx .. "孔位不存在") return end local holeInfo = holeList[idxKey] if not holeInfo.unlock then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqPutOffCard==> " .. part .. "索引" .. idx .. "孔位未解锁") return end -- 卸下卡牌,加入背包 local card = holeInfo.card if card == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqPutOffCard==> " .. part .. "索引" .. idx .. "卡牌不存在") return end holeInfo.card = nil local cardBag = this.GetCardBag(actor) this.AddCard0(actor, cardBag, card, false) -- 持久化孔位和背包 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_HOLE, roleHole) setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) -- 发送孔位信息 this.ResHoleInfo(actor, part) -- 发送背包信息 this.ResRoleCardBag(actor) -- 计算全身卡牌的加成属性 this.UpdateCardAttr(actor) -- 变身状态可能会取消 this.CardOrEquipChanged(actor) -- 更新开服竞技排行数据 local score = TransferCard.GetRoleScore(actor) OpenServerCompetition.updateRankData(actor, CompetitionType.CARDSCORE, score) end -- @description 兑换卡牌 -- @param 玩家对象;cfg_card_shop的id;购买数量 -- @return function TransferCard.ReqExchangeCards(actor, cfgId, count) -- 判断孔位 local needLevel = ConfigDataManager.getTableValue("cfg_card_shop", "condition", "id", cfgId) needLevel = tonumber(needLevel) == nil and 0 or tonumber(needLevel) local roleLevel = getbaseinfo(actor, "level") if roleLevel < needLevel then return end -- 判断消耗 local consumerCfg = ConfigDataManager.getTableValue("cfg_card_shop", "exchangeConsume", "id", cfgId) local consumerMap = string.toIntIntMap(consumerCfg, "#", "|") for counsumerId, onceCount in pairs(consumerMap) do local needItemCount = tonumber(onceCount) * count local ownCount = getbagitemcountbyid(actor, counsumerId) if ownCount < needItemCount then return end end -- 消耗道具 for counsumerId, onceCount in pairs(consumerMap) do local needItemCount = tonumber(onceCount) * count removeitemfrombag(actor, counsumerId, needItemCount, 0, 9999, '变身卡牌') end -- 获得道具 local itemAdd = ConfigDataManager.getTableValue("cfg_card_shop", "exchangeAdd", "id", cfgId) local itemAddMap = string.toIntIntMap(itemAdd, "#", "|") local totalAdd = {} for itemId, itemCount in pairs(itemAddMap) do local totalAddCount = tonumber(itemCount) * count totalAdd[itemId] = totalAddCount end additemmaptobag(actor, totalAdd, 0, 9999, '变身卡牌') end -- @description 解锁孔位 -- @param 玩家对象;装备部位;孔位索引;解锁类型(1-普通解锁,2-特殊解锁) -- @return function TransferCard.ReqUnlockHole(actor, part, idx, type) local roleHole = this.GetRoleHole(actor) if roleHole == nil then return end local partKey = tonumber(part) local holeData = table.getValue(roleHole, partKey) if holeData == nil then return end local holeList = holeData.hole -- 判断孔位有无达到最大 local maxCount = ConfigDataManager.getTableValue("cfg_card_inlay", "holeAmount", "part", part) local nowCount = 0 for _, hole in pairs(holeList) do if hole.unlock then nowCount = nowCount + 1 end end if nowCount >= tonumber(maxCount) then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==>" .. part .. "孔位数量已达到最大") return end -- 判断该孔位是否已经解锁 local idxKey = tostring(idx) if holeList[idxKey] == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==>" .. part .. "索引" .. idx .. "孔位不存在", holeList) return end local holeInfo = holeList[idxKey] if holeInfo.unlock then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==>" .. part .. "索引" .. idx .. "孔位已解锁") return end local equip = this.GetPosEquip(actor, part) if equip == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==>" .. part .. "未穿戴装备") return end -- 获取解锁限制 local unlockType = tonumber(ConfigDataManager.getTableValue("cfg_card_inlay", "unlockType", "part", part)) if unlockType == UnlockLimitType.SCORES then -- 判断品阶 local unlockGradeStr = ConfigDataManager.getTableValue("cfg_card_inlay", "unlockParameter", "part", part) local unlockGradeMap = string.toIntIntMap(unlockGradeStr, "#", "|") local needGrade = unlockGradeMap[tonumber(idx)] local equipCfg = equip.cfgid local equipGrade = ConfigDataManager.getTableValue("cfg_item", "rank", "id", equipCfg) needGrade = tonumber(needGrade) == nil and 999 or tonumber(needGrade) equipGrade = tonumber(equipGrade) == nil and 0 or tonumber(equipGrade) if equipGrade < needGrade then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==> 装备品阶未达到要求,当前" .. equipGrade .. ",需要" .. needGrade) return end elseif unlockType == UnlockLimitType.JEWELRY_LEVEL then -- 判断首饰等级 local unlockGradeStr = ConfigDataManager.getTableValue("cfg_card_inlay", "unlockParameter", "part", part) local unlockGradeMap = string.toIntIntMap(unlockGradeStr, "#", "|") local needLevel = unlockGradeMap[tonumber(idx)] needLevel = tonumber(needLevel) == nil and 999 or tonumber(needLevel) local equipId = equip.id local allequip = getplaydef(actor, "T$luaitemextdata") local equipext = allequip[tonumber(equipId)] local equipLevel = tonumber(equipext.ssuplv or 999) if equipLevel < needLevel then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.ReqUnlockHole==> 首饰等级未达到要求,当前" .. equipLevel .. ",需要" .. equipLevel) return end end -- 是不是免费解锁 local unlockFreeStr = ConfigDataManager.getTableValue("cfg_card_inlay", "unlockFree", "part", part) local free = false for _, value in pairs(string.split(unlockFreeStr, "#")) do if tonumber(idx) == tonumber(value) then free = true break end end local unlockRate if not free then -- 判断道具数量、消耗道具、解锁的逻辑都一样 local costItemCfg if tonumber(type) == 1 then costItemCfg = ConfigDataManager.getTableValue("cfg_card_inlay", "unlockNormal", "part", part) elseif tonumber(type) == 2 then costItemCfg = ConfigDataManager.getTableValue("cfg_card_inlay", "unlockSpecial", "part", part) else gameDebug.assertPrintTrace(false, actor:toString() .. "不存在的解锁类型") return end local configList = string.split(costItemCfg, "|") for _, v in pairs(configList) do local vList = string.split(v, "#") local index = vList[1] if tonumber(index) == tonumber(idx) then local costItemId = vList[2] local costItemCount = vList[3] -- 解锁概率,免得后面再循环一次 if tonumber(type) == 1 then unlockRate = tonumber(vList[4]) elseif tonumber(type) == 2 then unlockRate = 10000 else unlockRate = 0 end local ownCount = getbagitemcountbyid(actor, costItemId) if tonumber(ownCount) < tonumber(costItemCount) then --道具不足 return end end end -- 扣除道具 for _, v in pairs(configList) do local vList = string.split(v, "#") local index = vList[1] if tonumber(index) == tonumber(idx) then local costItemId = vList[2] local costItemCount = vList[3] removeitemfrombag(actor, costItemId, costItemCount, 0, 9999, '变身卡牌') end end end -- 普通解锁判断条件 local canUnlock = false if not free then -- 幸运值如果大于小于一百,概率解锁,解锁失败,加幸运值 if holeInfo.luck < 100 then local success = this.SelectRate(unlockRate / 10000) if success then -- 需要提示吗 canUnlock = true else --未解锁 end else canUnlock = true end end if canUnlock or free then -- 解锁 holeInfo["unlock"] = true else -- 增加幸运值 local luckPointCfg = ConfigDataManager.getTableValue("cfg_card_inlay", "luckPoint", "part", part) local luckPointMap = string.getAttrByStr(luckPointCfg) local luckPoint = luckPointMap[tostring(idx)] holeInfo["luck"] = holeInfo.luck + tonumber(luckPoint) noticeTip.noticeinfo(actor, StringIdConst.TEXT436) end -- 持久化 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_HOLE, roleHole) this.ResHoleInfo(actor, part) end -- @description 初始化玩家的变身卡牌孔位 -- @param 玩家对象 -- @return function TransferCard.InitRoleCardHole(actor) local inlayCfgList = ConfigDataManager.getList("cfg_card_inlay") if type(inlayCfgList) ~= "table" then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.InitRoleCardHole==> 读取配置表错误") return end -- 加校验,防止有数据被清空 local oldHole = this.GetRoleHole(actor) -- 数据结构《部位key,孔位信息列表》 if type(oldHole) ~= "table" then oldHole = {} end for _, dataMap in pairs(inlayCfgList) do local part = dataMap.part local varKey = tonumber(part) -- 如果不存在该部位,初始化该部位 if oldHole[varKey] == nil then if varKey == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "TransferCard.InitRoleCardHole==> 字符串转数值异常" .. part) return end local varValue = {} -- 所有孔位 local allHole = tonumber(dataMap.holeamount) local holeList = {} for i = 1, allHole, 1 do local holeInfo = {} local holeKey = tostring(i) -- 孔位信息具体未定 holeInfo["luck"] = 0 holeInfo["unlock"] = false holeList[holeKey] = holeInfo end varValue["hole"] = holeList oldHole[varKey] = varValue end end -- 持久化玩家变量 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_HOLE, oldHole) end -- @description 初始化玩家的变身卡牌背包 -- @param 玩家对象 -- @return function TransferCard.InitRoleCardBag(actor) -- 加校验,如果背包存在,则返回 local oldBag = this.GetCardBag(actor) if type(oldBag) == "table" then return end -- 创建背包的结构<卡牌唯一id,卡牌信息(Map)> local cardBag = {} -- 持久化玩家变量 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) end -- @description 初始化玩家的变身状态信息 -- @param 玩家对象 -- @return function TransferCard.InitRoleState(actor) local oldState = this.GetRoleState(actor) if type(oldState) == "table" then return end -- 创建数据结构 local roleState = { current = nil, cd = {}, skill = {} } setplaydef(actor, PlayerDefKey.TRANSFER_CARD_STATE, roleState) return roleState end -- 卸下指定位置的赋能卡牌 function TransferCard.PutOffFuNengCard(actor, part) local roleHole = this.GetRoleHole(actor) local partKey = tonumber(part) local holeData = table.getValue(roleHole, partKey) local holeList = holeData.hole for idx, holeInfo in pairs(holeList) do local card = holeInfo.card if card ~= nil then local cfgId = card.cfgid local type = tonumber(ConfigDataManager.getTableValue("cfg_item", "subType", "id", cfgId)) if type ~= CardType.SHEN_FU then TransferCard.ReqPutOffCard(actor, part, idx) end end end end -- @description 卡牌入包事件 -- @param 玩家对象;道具配置id -- @return function TransferCard.NotEnterBagItemAdd(actor, itemList) -- 获取卡牌背包 local cardBag = this.GetCardBag(actor) local rewardList = {} for _, itemInfo in pairs(itemList) do local itemId = itemInfo.id local itemCfgId = itemInfo.cfgid local itemType = tonumber(ConfigDataManager.getTableValue("cfg_item", "type", "id", itemCfgId)) if itemType == 8 then local card = RoleTransferCard.new(itemId, itemCfgId) this.AddCard0(actor, cardBag, card, false) table.insert(rewardList, card) end end -- 最后统一持久化优化性能 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) if table.count(rewardList) > 0 then this.ResRoleCardBag(actor) -- 客户端提示奖励 sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_REWARD_PANEL, rewardList) end end -- @description 合成卡牌 -- @param 玩家对象;{主,{副,副,...}} -- @return function TransferCard.ReqSynthesisCard(actor, cards) -- 自定义卡牌数量 local mainCardId = cards[1] local fuCardIdList = cards[2] -- 校验参数 local cardBag = this.GetCardBag(actor) local mainCard = cardBag[tonumber(mainCardId)] if mainCard == nil then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "合成卡牌时,卡牌不存在,主卡id:" .. mainCardId) return end local cardCfg = mainCard.cfgid local upAmount = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "upAmount", "id", cardCfg)) if table.count(fuCardIdList) + 1 < upAmount then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "合成卡牌时,卡牌数量不足") return end local type = tonumber(ConfigDataManager.getTableValue("cfg_item", "subType", "id", cardCfg)) -- 判断背包里卡牌是否存在;都是相同类型 for _, cardId in pairs(fuCardIdList) do local card = cardBag[tonumber(cardId)] if card == nil then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "合成卡牌时,卡牌不存在,主卡id:" .. cardId) return end if cardCfg ~= card.cfgid then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "合成卡牌时,卡牌非同同种卡牌,主卡cfgId:" .. cardCfg .. " , 副卡cfgId:" .. card.cfgid) return end end -- 是否有下一级 local group = ConfigDataManager.getTableValue("cfg_card_shapeshift", "group", "id", cardCfg) local level = ConfigDataManager.getTableValue("cfg_card_shapeshift", "level", "id", cardCfg) local nextLevl = tonumber(level) + 1 local nextCardCfg = ConfigDataManager.getTableValue("cfg_card_shapeshift", "id", "level", nextLevl, "group", group) if nextCardCfg == nil or nextCardCfg == "" then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "合成卡牌时,卡牌不能再合成到下一级,主卡cfgId:" .. cardCfg) return end -- 消耗副卡 for _, fuCardId in pairs(fuCardIdList) do this.RemoveCard0(actor, cardBag, fuCardId, false) end -- 生成新卡,本质是主卡修改道具id mainCard.cfgid = tonumber(nextCardCfg) -- 如果是词条卡牌,生成新词条,并添加进去 local oldEntryList = mainCard.entry if type == CardType.ENTRY or type == CardType.SHEN_FU then local newEntryList = RoleTransferCard:genCardEntry(nextCardCfg) table.insertArray(oldEntryList, newEntryList) end -- 持久化背包并回包 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) this.ResRoleCardBag(actor) -- 客户端提示奖励 sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_REWARD_PANEL, { mainCard }) -- 合成卡牌刷新任务进度 TaskHandler.TriggerTaskGoal(actor, TaskTargetType.SYNTHESIS_CARD, type) end -- @description 一键合成 -- @param 玩家对象;卡牌类型;卡牌等级 -- @return function TransferCard.ReqSynthesisAll(actor, cardType, level) cardType = tonumber(cardType) level = tonumber(level) if cardType == nil or level == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "一键合成卡牌时参数有误!" .. cardType .. " , " .. level) return end local cardBag = this.GetCardBag(actor) if cardBag == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "玩家卡牌牌库不存在!") return end -- 卡牌根据id分类 local cfg2CardList = {} -- 分类卡牌 for _, card in pairs(cardBag) do local cfgId = card.cfgid local itemType = ConfigDataManager.getTableValue("cfg_item", "subType", "id", cfgId) if tonumber(itemType) == cardType then local cardLevel = ConfigDataManager.getTableValue("cfg_card_shapeshift", "level", "id", cfgId) if tonumber(cardLevel) == level then local existTypeCards = cfg2CardList[cfgId] or {} table.insert(existTypeCards, card) cfg2CardList[cfgId] = existTypeCards end end end local newCardList = {} --合成后的新卡牌 local hasCardToSyn = false -- 能否合成 for cfgId, cards in pairs(cfg2CardList) do -- 是否有下一级 local group = ConfigDataManager.getTableValue("cfg_card_shapeshift", "group", "id", cfgId) local currentLevel = ConfigDataManager.getTableValue("cfg_card_shapeshift", "level", "id", cfgId) local nextLevl = tonumber(currentLevel) + 1 local nextCardCfg = ConfigDataManager.getTableValue("cfg_card_shapeshift", "id", "level", nextLevl, "group", group) if tonumber(nextCardCfg) ~= nil and tonumber(nextCardCfg) > 0 then -- 判断能否合成直接在这个循环做了 local upAmount = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "upAmount", "id", cfgId)) if #cards >= upAmount then if hasCardToSyn == false then hasCardToSyn = true end -- 合成卡牌 local size = #cards local step = upAmount local loopCount = math.floor(size / upAmount) for k = 1, loopCount do local i = (k - 1) * step + 1 if i <= size then local maxInnerLoop = math.min(step - 1, size - i) for j = 1, maxInnerLoop do local fuCard = cards[i + j] -- 消耗副卡 this.RemoveCard0(actor, cardBag, fuCard.id, false) end local mainCard = cards[i] -- 生成新卡,本质是主卡修改道具id mainCard.cfgid = tonumber(nextCardCfg) table.insert(newCardList, mainCard) -- 如果是词条卡牌,生成新词条,并添加进去 local oldEntryList = mainCard.entry if cardType == CardType.ENTRY or cardType == CardType.SHEN_FU then local newEntryList = RoleTransferCard:genCardEntry(nextCardCfg) table.insertArray(oldEntryList, newEntryList) end -- 合成卡牌刷新任务进度 TaskHandler.TriggerTaskGoal(actor, TaskTargetType.SYNTHESIS_CARD, cardType) end end end end end -- 是否有可以合成的卡牌 if hasCardToSyn == false then gameDebug.assertPrintTrace(false, actor:toString() .. "一键合成卡牌时,没有可以合成的卡牌") return end -- 持久化背包并回包 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) this.ResRoleCardBag(actor) -- 客户端提示奖励 sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_REWARD_PANEL, newCardList) end -- @description 请求回收卡牌 -- @param 玩家对象;卡牌集合 -- @return function TransferCard.ReqRecoveryCard(actor, cardList) local cardBag = this.GetCardBag(actor) -- 首先判断卡牌数量是否正确 for _, value in pairs(cardList) do local cardId = tonumber(value) if cardBag[cardId] == nil then return end end -- 记录回收获得的道具 local recoverItems = {} -- 移除卡牌 for _, value in pairs(cardList) do local cardId = tonumber(value) local card = cardBag[cardId] local cfgId = card.cfgid this.RemoveCard0(actor, cardBag, cardId, false) -- 记录回收获得的道具 local oneMap = this.GetRecoverItems(cfgId, 1) this.MergeMap(recoverItems, oneMap) end -- 持久化 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) -- 发送道具 additemmaptobag(actor, recoverItems, 0, 9999, '变身卡牌') -- 通用奖励面板 GameTips.sendGetRewardMsg(actor, recoverItems) -- 发送背包卡牌信息 this.ResRoleCardBag(actor) end -- @description 变身 -- @param 玩家对象;卡牌组 -- @return function TransferCard.ReqTransformation(actor, group) -- 校验 -- 是否存在对应group的卡牌 local existGroup = this.IsExistGroupCard(actor, group) if existGroup == false then return end -- 如果是赤色要塞不让变身 local mapId = getbaseinfo(actor, "unimapid") local dupInfo = getduplicate(mapId) if type(dupInfo) == "table" then local dupType = dupInfo["type"] if dupType == DuplicateType.RED_FORTRESS then return end end -- 获取玩家变身状态,是否处于变身,需要存储(变身状态,冷却CD) local roleState = this.GetRoleState(actor) if roleState == nil then return end -- 是否冷却CD中 local cdMap = roleState.cd local cdTime = cdMap[group] local nowMillis = getbaseinfo("now") if cdTime ~= nil and cdTime > nowMillis then return end local currentState = roleState.current if currentState ~= nil then local currentGroup = currentState.group if currentGroup == group then return end --当前在变身状态 -- 取消技能 local skillList = this.GetSkillListByActiveGroup(actor, currentGroup) if table.count(skillList) > 0 then this.RemoveSkills(actor, table.keys(skillList), true) end end -- 加CD this.AddCd(group, cdMap, nowMillis) -- 解锁变身技能,并储存下来 local skillList = this.GetSkillListByActiveGroup(actor, group) this.AddSkills(actor, skillList, true) roleState.skill = skillList roleState.current = { group = group, start = nowMillis } roleState.cd = cdMap setplaydef(actor, PlayerDefKey.TRANSFER_CARD_STATE, roleState) -- 通知客户端变身 this.ResTransfermationRound(actor, group) -- 客户端变身CD this.ResTransfermationCD(actor, cdMap) this.ResTransferDuration(actor) -- 被动技能 PassiveSkill.DoTransfermation(actor, group) end function TransferCard.ReqCancelTransfermation(actor) this.CancelTransfermation(actor, true) end -- @description 卡牌突破 -- @param 玩家对象;{主,{副,副,...}} -- @return function TransferCard.ReqBreakthrough(actor, cards) -- 自定义卡牌数量 local mainCardId = cards[1] local fuCardIdList = cards[2] -- 校验参数 local cardBag = this.GetCardBag(actor) local mainCard = cardBag[tonumber(mainCardId)] if mainCard == nil then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "卡牌突破时,卡牌不存在,主卡id:" .. mainCardId) return end local cardCfg = mainCard.cfgid local upAmount = tonumber(ConfigDataManager.getTableValue("cfg_card_breakthrough", "expend", "id", cardCfg)) if table.count(fuCardIdList) + 1 < upAmount then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "突破卡牌时,卡牌数量不足") return end -- 判断背包里卡牌是否存在;都是相同类型 for _, cardId in pairs(fuCardIdList) do local card = cardBag[tonumber(cardId)] if card == nil then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "突破卡牌时,卡牌不存在,主卡id:" .. cardId) return end if cardCfg ~= card.cfgid then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "突破卡牌时,卡牌非同同种卡牌,主卡cfgId:" .. cardCfg .. " , 副卡cfgId:" .. card.cfgid) return end end -- 是否存在突破 local nextCardCfgString = ConfigDataManager.getTableValue("cfg_card_breakthrough", "result", "id", cardCfg) if string.isNullOrEmpty(nextCardCfgString) then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "突破卡牌时,不存在突破后的卡牌,主卡id:" .. cardCfg) return end local success, breakCard = this.BreakThrough0(actor, cardBag, mainCard, fuCardIdList) if success then -- 客户端提示奖励 sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_REWARD_PANEL, { breakCard }) else -- 突破失败 sendluamsg(actor, LuaMessageIdToClient.RES_CARD_BREAKTHROUGH_FAIL, nil) end -- 持久化背包并回包 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) this.ResRoleCardBag(actor) end -- @description 请求一键突破 -- @param 玩家对象;卡牌类型;卡牌品质 -- @return function TransferCard.ReqBreakthroughAll(actor, cardType, quality) if quality == nil or quality <= 0 or cardType == nil or cardType <= 0 then gameDebug.assertPrintTrace(false, actor:toString() .. "一键卡牌突破时参数有误!quality:" .. quality .. " ;cardType:" .. cardType) return end local cardBag = this.GetCardBag(actor) if cardBag == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "玩家卡牌牌库不存在!") return end -- 卡牌根据id分类 local cfg2CardList = {} -- 分类卡牌 for _, card in pairs(cardBag) do local cfgId = card.cfgid local itemType = ConfigDataManager.getTableValue("cfg_item", "subType", "id", cfgId) if tonumber(itemType) == cardType then local needQuality = ConfigDataManager.getTableValue("cfg_card_shapeshift", "quality", "id", cfgId) if tonumber(needQuality) == quality then local existTypeCards = cfg2CardList[cfgId] or {} table.insert(existTypeCards, card) cfg2CardList[cfgId] = existTypeCards end end end local newCardList = {} --突破后的新卡牌 local hasCardToBreakthrough = false -- 能否突破 for cfgId, cards in pairs(cfg2CardList) do -- todo 是否存在突破 local nextCardCfgString = ConfigDataManager.getTableValue("cfg_card_breakthrough", "result", "id", cfgId) if not string.isNullOrEmpty(nextCardCfgString) then local upAmount = tonumber(ConfigDataManager.getTableValue("cfg_card_breakthrough", "expend", "id", cfgId)) if #cards >= upAmount then if hasCardToBreakthrough == false then hasCardToBreakthrough = true end --突破卡牌 local size = #cards local step = upAmount local loopCount = math.floor(size / upAmount) for k = 1, loopCount do local i = (k - 1) * step + 1 if i <= size then local fuCardIdList = {} local maxInnerLoop = math.min(step - 1, size - i) for j = 1, maxInnerLoop do local fuCard = cards[i + j] table.insert(fuCardIdList, fuCard.id) end local mainCard = cards[i] local success, breakCard = this.BreakThrough0(actor, cardBag, mainCard, fuCardIdList) if success then table.insert(newCardList, breakCard) end end end end end end if not hasCardToBreakthrough then gameDebug.assertPrintTrace(false, actor:toString() .. "一键卡牌突破时,没有可以突破的卡牌!") return end if table.count(newCardList) > 0 then -- 客户端提示奖励 sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_REWARD_PANEL, newCardList) else -- 突破失败 sendluamsg(actor, LuaMessageIdToClient.RES_CARD_BREAKTHROUGH_FAIL, nil) end -- 持久化背包并回包 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) this.ResRoleCardBag(actor) end -- @description 卡牌突破根方法,内部不做校验,请确保参数都是正确的 -- @param 玩家对象;卡牌背包;主卡对象;副卡id列表 -- @return 突破结果;突破后的卡牌,突破失败仍是原卡牌 function this.BreakThrough0(actor, cardBag, mainCard, fuCardIdList) local cardCfg = mainCard.cfgid local nextCardCfgString = ConfigDataManager.getTableValue("cfg_card_breakthrough", "result", "id", cardCfg) local nextCardCfgList = string.toIntIntMap(nextCardCfgString, "#", "|") local totalWeight = 0 for key, weight in pairs(nextCardCfgList) do totalWeight = totalWeight + weight end local randomWeight = math.random(1, totalWeight) local cumulativeWeight = 0 local nextCardCfg = nil for key, weight in pairs(nextCardCfgList) do cumulativeWeight = cumulativeWeight + weight if randomWeight <= cumulativeWeight then nextCardCfg = key break end end if nextCardCfg == nil then gameDebug.assertPrintTrace(false, "玩家" .. actor:toString() .. "突破卡牌时,配置有误,突破后的配置不存在!cfg_card_breakthrough的id:" .. cardCfg) return false, mainCard end -- 消耗副卡 for _, fuCardId in pairs(fuCardIdList) do this.RemoveCard0(actor, cardBag, fuCardId, false) end -- 概率和幸运值 local probability = tonumber(ConfigDataManager.getTableValue("cfg_card_breakthrough", "probability", "id", cardCfg)) local success = false local oldLuck = mainCard.breakluck or 0 if oldLuck < 100 then success = this.SelectRate(probability / 10000) else success = true end if success then mainCard.breakluck = 0 -- 生成新卡,本质是主卡修改道具id mainCard.cfgid = tonumber(nextCardCfg) -- 如果是词条卡牌,替换词条 local oldEntryList = mainCard.entry local type = tonumber(ConfigDataManager.getTableValue("cfg_item", "subType", "id", cardCfg)) if type == CardType.ENTRY or type == CardType.SHEN_FU then -- 替换词条 local newEntryList = {} for _, entry in pairs(oldEntryList) do local entryId = entry.entryid local newEntryId = tonumber(ConfigDataManager.getTableValue("cfg_card_att", "breakthroughAtt", "id", entryId)) local canReplace = false if newEntryId ~= nil then local newEntryTable = ConfigDataManager.getById("cfg_card_att", newEntryId) if newEntryTable ~= nil then canReplace = true end end if canReplace then local newEntry = CardEntry.newById(newEntryId) table.insert(newEntryList, newEntry) else table.insert(newEntryList, entry) end end mainCard.entry = newEntryList end else local luckPoint = tonumber(ConfigDataManager.getTableValue("cfg_card_breakthrough", "luckPoint", "id", cardCfg)) mainCard.breakluck = math.min(100, oldLuck + luckPoint) end return success, mainCard end -- @description 5秒心跳监测变身时间是否过期 -- @param 玩家对象;是否响应客户端 -- @return true(未过期) |false(过期) function TransferCard.CheckTransfermationExpired(actor, sendMsg) -- 是否过期 local roleState = this.GetRoleState(actor) if roleState == nil then return false end local currentState = roleState.current if currentState == nil then return false end local nowMillis = getbaseinfo("now") local startTime = currentState.start local group = currentState.group local duration = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "time", "group", group)) duration = duration == nil and 0 or duration local endTime = startTime + duration if nowMillis >= endTime then -- 取消变身 this.CancelTransfermation(actor, sendMsg) return false end return true end -- @description 获取角色卡牌评分 -- @param 玩家对象 -- @return 评分 function TransferCard.GetRoleScore(actor) local totalScore = 0 local roleHole = this.GetRoleHole(actor) if type(roleHole) ~= "table" then return 0 end for partKey, partData in pairs(roleHole) do -- 卡牌要和装备栏关联 local pos = tonumber(partKey) if this.IsExistEquip(actor, pos) then local holeList = partData.hole for holeKey, holeInfo in pairs(holeList) do local card = holeInfo.card if card ~= nil then -- 评分 local cardCfg = card.cfgid local oneScore = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "score", "id", cardCfg)) oneScore = (oneScore or 0) totalScore = totalScore + oneScore end end end end return totalScore end -- @description 变身状态下卡牌或者装备发生变化 -- @param -- @return function this.CardOrEquipChanged(actor) local roleState = this.GetRoleState(actor) if roleState == nil then return end local currentState = roleState.current if currentState == nil then return end local group = currentState.group -- 如果不存在这个group了,取消变身 local exist = this.IsExistGroupCard(actor, group) if exist == false then -- 取消变身 this.CancelTransfermation(actor, true) return end -- 如果技能发生变化,解锁或者升级 local oldSkillList = roleState.skill local nowSkillList = this.GetSkillListByActiveGroup(actor, group) -- 取消掉旧的 local removeskillList = {} for id, level in pairs(oldSkillList) do if nowSkillList[id] == nil then table.insert(removeskillList, id) end end this.RemoveSkills(actor, removeskillList, false) -- 更改成新的 local levelUpSkills = {} for id, level in pairs(nowSkillList) do if oldSkillList[id] ~= level then levelUpSkills[tonumber(id)] = tonumber(level) end end this.AddSkills(actor, levelUpSkills, false) -- 持久化 roleState.skill = nowSkillList setplaydef(actor, PlayerDefKey.TRANSFER_CARD_STATE, roleState) end -- @description 取消技能 -- @param 玩家对象;技能列表;是否取消全部 -- @return function this.RemoveSkills(actor, skillList, cover) cover = cover == nil and false or true if table.count(skillList) <= 0 then return end removeskill(actor, skillList) setlimitskills(actor, LimitSkillType.TRANSFER_CARD, 2, cover, skillList) end -- @description 升级技能 -- @param 玩家对象;技能列表;是否直接覆盖 -- @return function this.AddSkills(actor, skillMap, cover) cover = cover == nil and false or true if table.count(skillMap) <= 0 then return end for skillId, skillLevel in pairs(skillMap) do levelupskill(actor, skillId, skillLevel) end local skillIdList = table.keys(skillMap) -- 不屏蔽连击技能 local comboSkill = getrolefield(actor, "role.roleskill.comboskill") local skillCfgId = comboSkill.skillCfgId if skillCfgId > 0 then table.insert(skillIdList, skillCfgId) end setlimitskills(actor, LimitSkillType.TRANSFER_CARD, 1, cover, skillIdList) end -- @description 取消变身 -- @param -- @return function this.CancelTransfermation(actor, sendMsg) local roleState = this.GetRoleState(actor) if roleState == nil then return end local skillList = roleState.skill local allIds = table.keys(skillList) -- 取消变身 roleState.skill = nil roleState.current = nil setplaydef(actor, PlayerDefKey.TRANSFER_CARD_STATE, roleState) --取消技能 this.RemoveSkills(actor, allIds, true) -- 取消buff local allBuff = getbuffinfo(actor) for _, buffInfo in pairs(allBuff) do local buffCfgId = buffInfo.buffcfgid local source = tonumber(ConfigDataManager.getTableValue("cfg_buff", "source", "id", buffCfgId)) if source == BuffSource.TRANSFER_CARD then delbuff(actor, buffCfgId) end end if sendMsg then -- 给客户端回包 this.ResTransfermationRound(actor, "0") end end -- @description 玩家进入视野 -- @param 自己;对方 -- @return function TransferCard.PlayerEnterView(actor, targetPlayer) -- 对方是否变身 local roleState = getplaydef(targetPlayer, PlayerDefKey.TRANSFER_CARD_STATE) if roleState == nil then return end local currentState = roleState.current if currentState == nil then return end local group = currentState.group -- 如果是赤色要塞不发视野包 local mapId = getbaseinfo(actor, "unimapid") local dupInfo = getduplicate(mapId) if type(dupInfo) == "table" then local dupType = dupInfo["type"] if dupType == DuplicateType.RED_FORTRESS then return end end -- 变身的话发送视野包给自己 local rid = getbaseinfo(targetPlayer, "rid") sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_MODEL_VIEW, { tostring(rid), tostring(group) }) end -- @description 变身视野包 -- @param 玩家对象;变身-group,取消变身- 0 -- @return function this.ResTransfermationRound(actor, group) -- 赤色要塞不能变身 local mapId = getbaseinfo(actor, "unimapid") local dupInfo = getduplicate(mapId) if type(dupInfo) == "table" and tonumber(group) ~= 0 then local dupType = dupInfo["type"] if dupType == DuplicateType.RED_FORTRESS then return end end local rid = getbaseinfo(actor, "rid") -- 协议待定 sendrefluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_MODEL_VIEW, { tostring(rid), tostring(group) }) end function this.AddCd(group, cdMap, nowMillis) local allGroups = this.GetAllGroup() -- 给当前group加技能CD local cd = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "cd", "group", group)) cd = cd == nil and 0 or cd local commonCd = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "commonCd", "group", group)) commonCd = commonCd == nil and 0 or commonCd local trueCd = math.max(cd, commonCd) cdMap[group] = nowMillis + trueCd -- 给其他group加公共CD if commonCd > 0 then for _, value in pairs(allGroups) do if value ~= group then local endTime = nowMillis + commonCd local currentCd = cdMap[value] if currentCd == nil or currentCd < endTime then cdMap[value] = endTime end end end end return cdMap end function this.GetAllGroup() local ret = {} local cfgList = ConfigDataManager.getList("cfg_card_shapeshift") if cfgList == nil then return ret end for _, value in pairs(cfgList) do local group = tonumber(value.group) if not table.contains(ret, group) then table.insert(ret, group) end end return ret end -- @description 更新全身卡牌的属性 -- @param 玩家对象 -- @return function this.UpdateCardAttr(actor) --属性容器,id-value local addAttr = {} -- 遍历所有装配的卡牌 local roleHole = this.GetRoleHole(actor) if type(roleHole) ~= "table" then return end for partKey, partData in pairs(roleHole) do -- 卡牌要和装备栏关联 local pos = tonumber(partKey) if this.IsExistEquip(actor, pos) then local holeList = partData.hole for holeKey, holeInfo in pairs(holeList) do local card = holeInfo.card if card ~= nil then --属性 local cardCfg = card.cfgid local cardAttr = this.GetCardAttr(cardCfg) local entryAttr = RoleTransferCard.getAllEntryAttr(card.entry) this.MergeMap(addAttr, cardAttr) this.MergeMap(addAttr, entryAttr) end end end end -- 属性加到人身上去 addrolekmlattributes(actor, ScriptAttrType.TRANSFER_CARD, addAttr) end -- @description 是否存在对应group的已激活卡牌 -- @param -- @return function this.IsExistGroupCard(actor, group) if tonumber(group) == nil then return false end local roleHole = this.GetRoleHole(actor) for partKey, partData in pairs(roleHole) do local holeList = partData.hole for holeKey, holeInfo in pairs(holeList) do local pos = tonumber(partKey) if this.IsExistEquip(actor, pos) then local card = holeInfo.card if card ~= nil then local cardCfg = card.cfgid local cardGroup = ConfigDataManager.getTableValue("cfg_card_shapeshift", "group", "id", cardCfg) if tonumber(cardGroup) == group then return true end end end end end return false end -- @description 部位是否存在装备 -- @param 玩家对象;部位 -- @return function this.IsExistEquip(actor, pos) local putOnEquipList = getputonequipinfo(actor) for _, equipinfo in pairs(putOnEquipList) do if this.GetPosByEquipIdx(equipinfo.equipindex) == tonumber(pos) then return true end end return false end -- @description 获取穿戴栏穿戴的部位 -- @param 穿戴栏 -- @return function this.GetPosByEquipIdx(idx) return idx & 255 end -- 获取部位上穿戴装备的信息 function this.GetPosEquip(actor, pos) local putOnEquipList = getputonequipinfo(actor) for _, equipinfo in pairs(putOnEquipList) do if this.GetPosByEquipIdx(equipinfo.equipindex) == tonumber(pos) then return equipinfo end end return nil end -- @description 通过配置表获取卡牌组的所有技能 -- @param -- @return function this.GetAllSkillFromCfg(group) local skillList = {} -- 技能id,技能等级 local cfgList = ConfigDataManager.getTable("cfg_card_shapeshift", "group", group) if table.count(cfgList) > 0 then for key, tableData in pairs(cfgList) do local cardId = tableData.id local cardSkill = this.GetCardSkill(cardId) this.CoveringSkillMap(skillList, cardSkill) end end return skillList end -- @description 获取可以激活的变身技能 -- @param 玩家对象;卡牌组 -- @return 技能列表<技能id,技能等级> function this.GetSkillListByActiveGroup(actor, group) local skillList = {} -- 技能id,技能等级 local roleHole = this.GetRoleHole(actor) for partKey, partData in pairs(roleHole) do local holeList = partData.hole for holeKey, holeInfo in pairs(holeList) do -- 卡牌要和装备栏关联 local pos = tonumber(partKey) if this.IsExistEquip(actor, pos) then local card = holeInfo.card if card ~= nil then local cardCfg = card.cfgid local cardGroup = ConfigDataManager.getTableValue("cfg_card_shapeshift", "group", "id", cardCfg) if tonumber(group) == tonumber(cardGroup) then local cardSkill = this.GetCardSkill(cardCfg) this.CoveringSkillMap(skillList, cardSkill) end end end end end return skillList end -- 合并属性表 function this.MergeMap(allMap, oneMap) if table.count(oneMap) <= 0 then return end for key, value in pairs(oneMap) do key = tonumber(key) value = tonumber(value) if key ~= nil and value ~= nil then local num = allMap[key] if num == 0 or num == nil then allMap[key] = value else allMap[key] = num + value end end end end -- 覆盖技能表,等级更高的会覆盖 function this.CoveringSkillMap(allMap, oneMap) for key, value in pairs(oneMap) do key = tonumber(key) value = tonumber(value) if key ~= nil and value ~= nil then local num = allMap[key] if num == 0 or num == nil then allMap[key] = value else if value > num then allMap[key] = value end end end end end function this.GetCardSkill(cardId) local ret = {} local attrCfg = ConfigDataManager.getTableValue("cfg_card_shapeshift", "skill", "id", cardId) local data = string.split(attrCfg, "|") if data then for _, v in ipairs(data) do local data2 = string.split(v, "#") ret[tonumber(data2[1])] = tonumber(data2[2]) end end return ret end function this.GetCardAttr(cardId) local ret = {} local attrCfg = ConfigDataManager.getTableValue("cfg_card_shapeshift", "attribute", "id", cardId) local data = string.split(attrCfg, "|") if data then for _, v in ipairs(data) do local data2 = string.split(v, "#") ret[tonumber(data2[1])] = tonumber(data2[2]) end end return ret end function this.AddCard0(actor, cardBag, card, persistent) local cardId = tonumber(card.id) if cardId == nil then gameDebug.assertPrintTrace(false, actor:toString() .. "localThis.AddCard00 -> card id is nil") return end cardBag[cardId] = card if persistent then -- 持久化玩家变量 setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) end end function this.RemoveCard0(actor, cardBag, cardId, persistent) cardBag[tonumber(cardId)] = nil if persistent then setplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG, cardBag) end return cardBag end -- @description 获取回收获得的道具 -- @param 卡牌id;数量 -- @return function this.GetRecoverItems(cardCfg, num) local itemMap = {} local recoverId = ConfigDataManager.getTableValue("cfg_item", "recoveryGroup", "id", cardCfg) local recoverCfg = ConfigDataManager.getById("cfg_recovery", recoverId) if recoverCfg == nil then return end local shuXianSplit = string.split(recoverCfg.material, "|") for _, value in pairs(shuXianSplit) do local jinHaoSplit = string.split(value, "#") local itemId = jinHaoSplit[1] local minCount = jinHaoSplit[2] local maxCount = jinHaoSplit[3] for i = 1, tonumber(num), 1 do local randomCount if minCount >= maxCount then randomCount = minCount else randomCount = math.random(tonumber(minCount), tonumber(maxCount)) end local oneItem = {} oneItem[tonumber(itemId)] = randomCount this.MergeMap(itemMap, oneItem) end end return itemMap end function this.ResHoleInfo(actor, part) part = tonumber(part) == nil and 0 or tonumber(part) local roleHole = this.GetRoleHole(actor) local res = {} if part == 0 then for key, value in pairs(roleHole) do local onePart = tonumber(key) onePart = tonumber(onePart) res[onePart] = value.hole end else local partKey = tonumber(part) local holeData = table.getValue(roleHole, partKey) local holeList = holeData.hole -- 发送协议给客户端 res[part] = holeList end sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_PART_INFO, res) end -- @description 发送卡牌背包给客户端 -- @param -- @return function this.ResRoleCardBag(actor) local cardBag = this.GetCardBag(actor) local res = table.values(cardBag) -- 发送协议给客户端 sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_BAG, res) end function this.ResTransfermationCD(actor, cdMap) local res = {} if cdMap == nil then local roleState = this.GetRoleState(actor) cdMap = roleState.cd end local nowMillis = getbaseinfo("now") for group, endTime in pairs(cdMap) do if endTime > nowMillis then res[group] = endTime end end if table.count(res) > 0 then sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_CD, res) end end -- @description 响应变身持续时间 -- @param -- @return function this.ResTransferDuration(actor) local roleState = this.GetRoleState(actor) local currentState = roleState.current if currentState == nil then return end local startTime = currentState.start local group = currentState.group local duration = tonumber(ConfigDataManager.getTableValue("cfg_card_shapeshift", "time", "group", group)) duration = duration == nil and 0 or duration local endTime = startTime + duration sendluamsg(actor, LuaMessageIdToClient.RES_TRANSFER_CARD_DURATION, { group, tostring(endTime) }) end -- @description 获取全身孔位数量 -- @param -- @return function this.GetAllHoleCount(actor) local count = 0 local roleHole = this.GetRoleHole(actor) for partKey, varValue in pairs(roleHole) do local holeList = varValue.hole for _, hole in pairs(holeList) do if hole.unlock then count = count + 1 end end end return count end -- @description 获取某个部位的孔位数量 -- @param 玩家对象;装备部位 -- @return function this.GetPartHoleCount(actor, part) local count = 0 local roleHole = this.GetRoleHole(actor) local partKey = tonumber(part) local holeData = table.getValue(roleHole, partKey) local holeList = holeData.hole for _, hole in pairs(holeList) do if hole.unlock then count = count + 1 end end return count end -- @description 根据概率随机true或者false -- @param 概率值 1=100% -- @return function this.SelectRate(probability) local randomNum = math.random() if randomNum <= probability then return true else return false end end function this.GetCardBag(actor) local cardBag = getplaydef(actor, PlayerDefKey.TRANSFER_CARD_BAG) return cardBag end function this.GetRoleHole(actor) local roleHole = getplaydef(actor, PlayerDefKey.TRANSFER_CARD_HOLE) return roleHole end function this.GetRoleState(actor) local roleState = getplaydef(actor, PlayerDefKey.TRANSFER_CARD_STATE) return roleState end -- @description 获取当前变身 -- @param 玩家对象 -- @return 变身的group;0-表示无变身 function TransferCard.GetCurrentTransfermation(actor) local roleState = this.GetRoleState(actor) if roleState == nil then return 0 end local currentState = roleState.current if currentState == nil then return 0 end return currentState.group end -- 注册登录事件 LoginEventListerTable:eventLister("0", "变身卡牌", TransferCard.Login, 9999)