local Msg = require("core.Msg") local Util = require("common.Util") local Grid = require("bag.Grid") local ItemDefine = require("bag.ItemDefine") local TuJianExcel = require("excel.equip").tujian local EquipExcel = require("excel.equip").equip local ItemExcel = require("excel.item").item local EquipLogicGrid = require("equip.EquipLogicGrid") local Log = require("common.Log") local LogDefine = require("common.LogDefine") local Lang = require("common.Lang") local Broadcast = require("broadcast.Broadcast") local MailManager = require("mail.MailManager") local MailExcel = require("excel.mail") local HeroLogic = require("hero.HeroLogic") local TriggerDefine = require("trigger.TriggerDefine") local TriggerLogic = require("trigger.TriggerLogic") local effectCfg = require("excel.equip").texiao local HeroDefine = require("hero.HeroDefine") EQUIP_BAG_MAX_CNT = 500 EQUIP_BAG_OP_ADD = 1 -- 增 EQUIP_BAG_OP_DEL = 2 -- 删 EQUIP_BAG_OP_CHANGE = 3 -- 改 EQUIP_QUALITY_MAX = 5 EQUIP_QUALITY = { 5000, 3000, 1500, 500 } EQUIP_QUALITY_WEIGHT = 10000 EQUIP_QUALITY_BASE_RATE = { 7000, 8000, 9000, 10000, 12000 } local EQUIP_HEROEXCLUSIVE_WEIGHT = 4000 --戒指、护符随机出英雄专属属性权重 local EQUIP_NO_HEROEXCLUSIVE_WEIGHT = 6000 --戒指、护符随不出英雄专属属性权重 -- 转换装备洗练数据格式 function AttrHashToArray(attrData) local _, attrInfo = next(attrData) if type(attrInfo) == "table" then return attrData end local len = 0 local attrArray = {} for attrType, attrVal in pairs(attrData) do len = len + 1 attrArray[len] = {attrType, attrVal, EquipLogicGrid.EQUIP_COLOR_3} end return attrArray end -- 随出单条洗练属性的品质 和 倍数 local function randAttrValMul() local totalWeight = 0 for _, weight in ipairs(EquipLogicGrid.EQUIPWASH_COLOR_WEIGHT) do totalWeight = totalWeight + weight end local color = 0 local mul = 0 local randNum = math.random(1, totalWeight) local weight = 0 for k, v in ipairs(EquipLogicGrid.EQUIPWASH_COLOR_WEIGHT) do weight = weight + v if randNum <= weight then color = k break end end assert(color > 0, "============装备洗练配置错误===============") local mulTbl = EquipLogicGrid.EQUIPWASH_COLOR_MUL[color] mul = math.random(mulTbl[1], mulTbl[2]) / 100 return color, mul end -- 随机装备品质 local function randColor(randomAttrCfg) local color = 0 local random = math.random(1, EQUIP_QUALITY_WEIGHT) for i = 1, #EQUIP_QUALITY do local weight = EQUIP_QUALITY[i] if random <= weight then color = i > #randomAttrCfg and #randomAttrCfg or i break else random = random - weight end end return color end -- 随机出装备洗练属性 local function randAttrArray(randomAttrCfg, equipColor, excludeAttrList) --品质 equipColor = equipColor or randColor(randomAttrCfg) -- 排除特定属性 if excludeAttrList then for idx, attrInfo in pairs(randomAttrCfg) do local attrType = attrInfo[1] if excludeAttrList[attrType] then randomAttrCfg[idx] = nil end end end -- 计算总权重 local totalWeight = 0 for k, v in pairs(randomAttrCfg) do totalWeight = totalWeight + v[3] end local len = 0 local attr = {} local MathRandom = math.random -- for i = 1, equipColor do -- local weight = 0 -- local randmWeight = MathRandom(1, totalWeight) -- for _, v in ipairs(randomAttrCfg) do -- weight = weight + v[3] -- if randmWeight <= weight then -- len = len + 1 -- local attrColor, mul = randAttrValMul() -- local finalVal = math.floor(v[2] * mul) -- attr[len] = {v[1], finalVal, attrColor} -- break -- end -- end -- end for z = 1, equipColor do local randmWeight = MathRandom(1, totalWeight) for k, v in pairs(randomAttrCfg) do local key = v[1] local value = v[2] local weight = v[3] if randmWeight <= weight then len = len + 1 local attrColor, mul = randAttrValMul() local finalVal = math.floor(value * mul) attr[len] = {key, finalVal, attrColor} randomAttrCfg[k] = nil -- 排除这个权重 totalWeight = totalWeight - weight break else randmWeight = randmWeight - weight end end end return attr end ---------------------------------------------------------戒指、护符随机特效--------------------------------------------------- local function generateRandData(excludeTypeList) local totalWeight = 0 local type2List = {} for k,v in ipairs(effectCfg) do local tp = v.type if not excludeTypeList or not excludeTypeList[tp] then local weight = v.weight type2List[tp] = type2List[tp] or {weight = 0, typeList = {}} type2List[tp].weight = type2List[tp].weight + weight table.insert(type2List[tp].typeList, {id = k, weight = weight}) totalWeight = totalWeight + weight end end local len = 0 local randList = {} for _, tpData in pairs(type2List) do len = len + 1 randList[len] = tpData end return totalWeight, randList end local function getIndexByRand(totalWeight, randList) local tpList local weight = 0 local randWeight = math.random(0, totalWeight) for _,v in ipairs(randList) do weight = weight + v.weight if randWeight <= weight then tpList = v break end end weight = 0 randWeight = math.random(0, tpList.weight) for _,v in ipairs(tpList.typeList) do weight = weight + v.weight if randWeight <= weight then return v.id end end end -- 随机出戒指、护符的特效 local function randEffectAttrList(equipId) local equipCfg = EquipExcel[equipId] if equipCfg.subType ~= ItemDefine.EQUIP_SUBTYPE_RING and equipCfg.subType ~= ItemDefine.EQUIP_SUBTYPE_AMULET then return end local excludeTypeList local noEffectTimes = 0 local effectList = {} for i=1, 3 do local totalWeight, randList = generateRandData(excludeTypeList) local effctId = getIndexByRand(totalWeight, randList) if effctId == 1 then noEffectTimes = noEffectTimes + 1 else effectList[effctId] = 1 excludeTypeList = excludeTypeList or {} local excludeType = effectCfg[effctId].type excludeTypeList[excludeType] = 1 end -- 保底要有一条特效 if noEffectTimes >= 2 then excludeTypeList = excludeTypeList or {} local excludeType = effectCfg[1].type excludeTypeList[excludeType] = 1 end end return effectList end -------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------戒指、护符随机英雄专属--------------------------------------------------- local function randHeroExclusive(equipId) local equipCfg = EquipExcel[equipId] if equipCfg.subType ~= ItemDefine.EQUIP_SUBTYPE_RING and equipCfg.subType ~= ItemDefine.EQUIP_SUBTYPE_AMULET then return end local randWeight = math.random(0, (EQUIP_HEROEXCLUSIVE_WEIGHT + EQUIP_NO_HEROEXCLUSIVE_WEIGHT)) if randWeight > EQUIP_HEROEXCLUSIVE_WEIGHT then return end local heroList = HeroDefine.GetAllHighQualityHero() local len = #heroList if len <= 0 then return end local idx = math.random(1, len) return heroList[idx] end -------------------------------------------------------------------------------------------------------------------------------- -- 随机属性 local attrCheck = {} function checkAttr(equipGrid) local quality = equipGrid.quality local len = 0 -- for key, value in pairs(equipGrid.attr) do -- len = len + 1 -- attrCheck[len] = {key, value} -- end for k, v in ipairs(equipGrid.attr) do len = len + 1 attrCheck[len] = {v[1], v[2], v[3]} end -- 砍掉后面的 if quality < len then equipGrid.attr = {} for z = 1, quality do -- equipGrid.attr[attrCheck[z][1]] = attrCheck[z][2] equipGrid.attr[z] = { attrCheck[z][1], attrCheck[z][2], attrCheck[z][3], } end end end -- 随机属性 function randomAttr(itemID, isRandom, otherData, excludeAttrList) local equipConfig = EquipExcel[itemID] if not equipConfig then return end -- 固定属性 local quality = 1 -- local attr = {} -- 所有装备的随机属性使用同一套规则 -- if equipConfig.random == 1 and not isRandom then -- quality = #equipConfig.randomAttr -- if quality > EQUIP_QUALITY_MAX then -- quality = EQUIP_QUALITY_MAX -- end -- for i = 1, quality do -- local key = equipConfig.randomAttr[i][1] -- local value = equipConfig.randomAttr[i][2] -- attr[key] = attr[key] or 0 -- attr[key] = attr[key] + value -- end -- return attr, quality -- end if not otherData then -- 随机品质 quality = randColor(equipConfig.randomAttr) else if type(otherData) == "number" then otherData = otherData < 0 and 1 or otherData quality = otherData > #equipConfig.randomAttr and #equipConfig.randomAttr or otherData end end if quality > EQUIP_QUALITY_MAX then quality = EQUIP_QUALITY_MAX end -- 计算总权重 -- local totalWeight = 0 -- for k, v in pairs(equipConfig.randomAttr) do -- totalWeight = totalWeight + v[3] -- end -- 随机条目属性 -- local MathRandom = math.random local randomAttr = Util.copyTable(equipConfig.randomAttr) -- for z = 1, quality do -- local randmWeight = MathRandom(1, totalWeight) -- for k, v in pairs(randomAttr) do -- local key = v[1] -- local value = v[2] -- local weight = v[3] -- if randmWeight <= weight then -- attr[key] = attr[key] or 0 -- attr[key] = attr[key] + value -- randomAttr[k] = nil -- -- 排除这个权重 -- totalWeight = totalWeight - weight -- break -- else -- randmWeight = randmWeight - weight -- end -- end -- end local attr = randAttrArray(randomAttr, quality, excludeAttrList) return attr, quality end -- 检查背包空间 function checkEmptyCnt(human, itemCnt) if itemCnt > getEmptyCnt(human) then Broadcast.sendErr(human, Lang.COMMON_BAG_FULL) return end return true end -- 获取装备对基础属性的影响 function getEquipBaseRate(quality) local baseRate = EQUIP_QUALITY_BASE_RATE[quality] if not baseRate then return 1 end return baseRate / 10000 end -- 获取装备品质 function getEquipMaxQuality(equipConfig) if not equipConfig.randomAttr then return 0 end local maxQuality = 0 if equipConfig.random == 1 then maxQuality = #equipConfig.randomAttr else maxQuality = equipConfig.quality or 0 end return maxQuality end -- 获取装备洗练属性 function getEquipTzAttr(equipConfig) if not equipConfig.randomAttr then return end if equipConfig.random == 1 then return equipConfig.randomAttr end -- local quality -- if equipConfig.subType == ItemDefine.EQUIP_SUBTYPE_RING or equipConfig.subType == ItemDefine.EQUIP_SUBTYPE_AMULET then -- quality = equipConfig.quality -- end -- local attr = randAttrArray(Util.copyTable(equipConfig.randomAttr), quality) -- return attr end -- 返回装备背包空余格子数 function getEmptyCnt(human) local emptyCnt = 0 for i = 1, EQUIP_BAG_MAX_CNT do if human.db.equipBag[i] == nil then emptyCnt = emptyCnt + 1 end end return emptyCnt end -- 获得装备背包第一个空格子下标 function getEmptyIndex(human) for index = 1, EQUIP_BAG_MAX_CNT do local grid = human.db.equipBag[index] if grid == nil then return index end end end -- 返回装备根据uuid function getEquipByUuid(human, uuid) local emptyCnt = 0 for i = 1, EQUIP_BAG_MAX_CNT do local equipGrid = human.db.equipBag[i] if equipGrid and equipGrid.uuid == uuid then return equipGrid end end end -- 返回装备根据pos function getEquipByPos(human, star, pos) local emptyCnt = 0 for i = 1, EQUIP_BAG_MAX_CNT do local equipGrid = human.db.equipBag[i] if equipGrid then local conf = EquipExcel[equipGrid.id] if conf and conf.subType == pos and star >= conf.star then return equipGrid end end end end -- 修复老数据 function modifyEquip(human, equipGrid) if equipGrid.putUuid == nil then return end local heroGrid = HeroLogic.getHeroGridByUuid(human, equipGrid.putUuid) if heroGrid == nil then equipGrid.putUuid = nil end end -- 兼容老数据处理 : 修改装备的 wash 和 attr 的数据格式 function TransformEuipAttrData(human) for index = 1, EQUIP_BAG_MAX_CNT do local equipGrid = human.db.equipBag[index] if equipGrid then if equipGrid.attr then equipGrid.attr = AttrHashToArray(equipGrid.attr) end if equipGrid.washAttr then equipGrid.washAttr = AttrHashToArray(equipGrid.washAttr) end end end end -- 推送装备背包信息 function sendEquipBagList(human) local msgRet = Msg.gc.GC_EQUIP_BAG_LIST local len = 0 for index = 1, EQUIP_BAG_MAX_CNT do local equipGrid = human.db.equipBag[index] if equipGrid then equipGrid.putUuid = nil --处理数据异常的装备 len = len + 1 Grid.makeItem(msgRet.list[len], equipGrid.id, 1, nil, equipGrid, index, Grid.getOpflagAtBag(equipGrid.id)) if len >= 30 then msgRet.list[0] = len len = 0 Msg.send(msgRet, human.fd) end end end if len > 0 then msgRet.list[0] = len Msg.send(msgRet, human.fd) end end -- 制造一个获得列表 function makeEquipItem(human, nets, len) if not human.getEquip then return len end for i = 1, #human.getEquip do len = len + 1 if not nets[len] then len = len - 1 break end local equipGrid = human.getEquip[i] Grid.makeItem(nets[len], equipGrid.id, 1, nil, equipGrid) end human.getEquip = nil return len end -- 制造一个装备获得 function makeEquipItemOne(human, net) if not human.getEquip then return end local equipGrid = human.getEquip[1] Grid.makeItem(net, equipGrid.id, 1, nil, equipGrid) human.getEquip = nil end -- 制造一个装备 function makeEquip(itemID, otherData) local equipGrid = EquipLogicGrid.createGrid(itemID) if not equipGrid then return end local bl = false local equipCfg = EquipExcel[equipGrid.id] if equipCfg.subType == ItemDefine.EQUIP_SUBTYPE_RING or equipCfg.subType == ItemDefine.EQUIP_SUBTYPE_AMULET then otherData = equipCfg.quality bl = true end -- 随机洗练属性 local attr, quality = randomAttr(itemID, nil, otherData) equipGrid.attr = attr if not bl then equipGrid.quality = quality else -- 装备特效 equipGrid.effectList = randEffectAttrList(itemID) -- 英雄专属 equipGrid.exclusiveHeroId = randHeroExclusive(itemID) end checkAttr(equipGrid) return equipGrid end -- 添加装备 function addEquip(human, itemID, itemCnt, logType, otherData) if not EquipExcel[itemID] then return end for i = 1, itemCnt do local equipGrid = makeEquip(itemID, otherData) if equipGrid then addByEquipGrid(human, equipGrid, logType) TriggerLogic.PublishEvent(TriggerDefine.EQUIP_GETQUALITY, human.db._id, equipGrid.quality, 1) end end end -- 通过gird添加装备 function addByEquipGrid(human, equipGrid, logType, noSend) local index = getEmptyIndex(human) if not index then --邮件处理 local items = {} items[1] = { equipGrid.id, equipGrid } local title = MailExcel.mail[1000].title local content = MailExcel.mail[1000].content local senderName = MailExcel.mail[1000].senderName MailManager.add(MailManager.SYSTEM, human.db._id, title, content, items, senderName) return end human.db.equipBag[index] = equipGrid sendEquipChange(human, index, equipGrid, EQUIP_BAG_OP_ADD) Log.write(Log.LOGID_OSS_EQUIP, human.db._id, human.db.account, human.db.name, human.db.lv, LogDefine.DEFINE[logType] + LogDefine.TYPE["equip"], equipGrid.id, 1, equipGrid.uuid) if not noSend then human.getEquip = human.getEquip or {} human.getEquip[#human.getEquip + 1] = equipGrid end return index end -- 从背包删除装备 function delEquip(human, index, logType, sendNotify) local equipGrid = human.db.equipBag[index] if not equipGrid then return end Log.write(Log.LOGID_OSS_EQUIP, human.db._id, human.db.account, human.db.name, human.db.lv, LogDefine.DEFINE[logType] + LogDefine.TYPE["equip"], equipGrid.id, -1, equipGrid.uuid) human.db.equipBag[index] = nil if not sendNotify then sendEquipChange(human, index, nil, EQUIP_BAG_OP_DEL) end end -- 发送装备改变 function sendEquipChange(human, bagIndex, equipGrid, op) local msgRet = Msg.gc.GC_EQUIP_BAG_CHANGE if op == EQUIP_BAG_OP_ADD or op == EQUIP_BAG_OP_CHANGE then msgRet.itemID = equipGrid.id msgRet.itemIndex = bagIndex msgRet.itemData[0] = 1 Grid.makeItem(msgRet.itemData[1], equipGrid.id, 1, nil, equipGrid, bagIndex, Grid.getOpflagAtBag(equipGrid.id)) elseif op == EQUIP_BAG_OP_DEL then msgRet.itemID = 0 msgRet.itemIndex = bagIndex msgRet.itemData[0] = 0 else assert(nil) end Msg.send(msgRet, human.fd) end function getNewAttrByItemID(itemID, equipGrid) local config = EquipExcel[itemID] -- if not config then return end -- for _, v in ipairs(config.randomAttr) do -- if attr[v[1]] then -- attr[v[1]] = v[2] -- end -- end equipGrid.attr = randAttrArray(Util.copyTable(config.randomAttr), equipGrid.quality) end