12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313 |
- -- 资源
- local code = require "code"
- local gameConst = require("const.gameConst")
- local util_user = require("utils.util_user")
- local timeUtil = require "utils.timeUtil"
- local baseAdapt = require "base.baseAdapt"
- local resAdapt = require("adapt.resAdapt")
- local moduleData = require("data.module")
- local heroData = require("data.hero")
- local hookData = require("data.hook")
- local MODULE_NAME = "tb_res"
- -- 升序排.
- local function sortAsc(list, key)
- table.sort(
- list or {},
- function(a, b)
- return a[key] < b[key]
- end
- )
- end
- local root = {}
- -- 玩家资源初始化(新手物品初始化)
- function root:init(uid)
- local lastInitTime = self:_get_last_init_time(uid)
- -- 仅初始化1次
- if lastInitTime > 0 then
- return
- end
- local initConfig = resAdapt:get_init_conf()
- local initItems = {}
- for _, v in ipairs(initConfig) do
- table.arry_merge(initItems, v.items)
- end
- if #initItems > 0 then
- local reason = gameConst.RES_REASON_PRE.INIT
- self:update_items(uid, initItems, reason)
- end
- local curTime = timeUtil.now(uid)
- self:_set_last_init_time(uid, curTime)
- end
- -- 请求获取背包信息
- function root:get_info(uid)
- log.info("get_info uid:%s", uid)
- local itemInfo = moduleData:hget_json(uid, MODULE_NAME, "itemInfo") or {}
- local isUpdate = false
- local curTime = timeUtil.now(uid)
- for i = #(itemInfo or {}), 1, -1 do
- local item = itemInfo[i]
- if item.expTime and curTime > item.expTime then
- -- 已经过期
- isUpdate = true
- item.count = 0
- end
- if item.count == 0 then
- isUpdate = true
- table.remove(itemInfo, i)
- end
- end
- if isUpdate then
- -- 存储
- moduleData:hset(uid, MODULE_NAME, "itemInfo", itemInfo)
- end
- return itemInfo
- end
- --[[ 请求增减资源列表
- 返回的是 DataResUpdateItem 列表
- ]]
- function root:update_items(uid, items, reason)
- -- log.info("update_items uid:%s items:%s reason:%s", uid, tostring(items), tostring(reason))
- local itemInfo = moduleData:hget_json(uid, MODULE_NAME, "itemInfo") or {}
- local list = {}
- for _, v in ipairs(items) do
- local updateItems = self:_update_item(uid, itemInfo, v.id, v.count, v.bid)
- if updateItems then
- table.arry_merge(list, updateItems)
- end
- end
- -- 存储
- moduleData:hset(uid, MODULE_NAME, "itemInfo", itemInfo)
- -- 推送
- self:_on_res_update(uid, list, reason)
- -- 事件
- self:_dispatch_event(uid, list)
- -- 日志-资源变化
- self:_log_resource(uid, list, reason)
- -- 英雄卡的自动激活、自动溢出转化
- self:_check_hero_item(uid, list, reason)
- return list
- end
- -- 判断 兑换随机英雄 资源是否足够
- function root:check_hero_random_exchange(uid, sourceId, times)
- local conf = resAdapt:get_hero_exchange_conf(sourceId)
- if not conf then
- return false, code.RES.ID_ERROR
- end
- local sourceCount = conf.sourceCount
- local needCount = sourceCount * times
- local count = self:get_item_count(uid, sourceId)
- if count < needCount then
- return false, code.RES.NOT_ENOUGH
- end
- return true
- end
- -- 请求兑换英雄。物品类型200的使用这个接口
- function root:hero_random_exchange(uid, sourceId, times)
- -- log.info("hero_random_exchange uid:%s sourceId:%s times:%s", uid, sourceId, times)
- local conf = resAdapt:get_hero_exchange_conf(sourceId)
- if not conf then
- log.error("兑换英雄的配置异常")
- return
- end
- local sourceCount = conf.sourceCount
- local targetQa = conf.targetQa
- local targetColor = conf.targetColor
- local targetCamp = conf.targetCamp
- local targetCount = conf.targetCount
- local heroItemIds = nil
- -- 限定英雄
- if not is_empty(conf.baseRandomHeros) then
- -- 玩家已获得同品质英雄
- heroItemIds = table.copy(conf.baseRandomHeros)
- local ownQaHeroList = heroData:get_qa_hero_id_list(uid, targetQa)
- if not is_empty(ownQaHeroList) then
- for _, v in ipairs(ownQaHeroList) do
- local heroId = v + 10000
- table.unique_insert(heroItemIds, heroId)
- end
- end
- else
- heroItemIds = resAdapt:get_hero_item_ids(targetQa, targetColor, targetCamp)
- end
- log.info(
- "hero_random_exchange uid[%s] sourceId[%s] heroItemIds[%s]",
- tostring(uid),
- tostring(sourceId),
- tostring(heroItemIds)
- )
- if not heroItemIds then
- log.error("兑换英雄的配置异常 找不到可以随机的英雄卡id")
- return
- end
- local targetItems = {}
- local totalCount = targetCount * times
- for i = 1, totalCount do
- local heroItemId = heroItemIds[math.random(#heroItemIds)]
- table.insert(targetItems, {id = heroItemId, count = 1})
- end
- local reason = gameConst.RES_REASON_PRE.HERO_RANDOM_EXCHANGE
- local needCount = sourceCount * times
- local sourceItems = {
- {id = sourceId, count = needCount}
- }
- self:consume_items(uid, sourceItems, reason)
- self:add_items(uid, targetItems, reason)
- return targetItems
- end
- -- 请求兑换英雄。物品类型220的使用这个接口
- function root:hero_compound(uid, resId, times)
- -- log.info("hero_random_exchange uid:%s sourceId:%s times:%s", uid, resId, times)
- local conf = resAdapt:get_hero_exchange_conf(resId)
- if not conf then
- log.error("兑换英雄的配置异常")
- return
- end
- local sourceCount = conf.sourceCount or 1
- local targetCount = conf.targetCount or 1
- local targetItems = {}
- local reason = gameConst.RES_REASON_PRE.HERO_COMPOUND
- do
- local needCount = sourceCount * times
- local sourceItems = {
- {id = resId, count = needCount}
- }
- self:consume_items(uid, sourceItems, reason)
- end
- do
- local totalCount = targetCount * times
- table.insert(targetItems, {id = conf.appointHero, count = totalCount})
- self:add_items(uid, targetItems, reason)
- end
- return targetItems
- end
- -- 判断 兑换自选英雄 资源是否足够
- function root:check_hero_optional_exchange(uid, sourceId, items)
- local conf = resAdapt:get_hero_exchange_conf(sourceId)
- if not conf then
- return false, code.RES.ID_ERROR
- end
- local sourceCount = conf.sourceCount
- local targetQa = conf.targetQa
- local targetColor = conf.targetColor
- local targetCamp = conf.targetCamp
- local targetCount = conf.targetCount
- local heroItemIds = resAdapt:get_hero_item_ids(targetQa, targetColor, targetCamp)
- if not heroItemIds then
- log.error("兑换英雄的配置异常 找不到可以自选的英雄卡id")
- return false, code.RES.CONFIG_ERROR
- end
- -- 兑换卡的数量
- local totalCount = 0
- for _, v in ipairs(items) do
- totalCount = totalCount + v.count
- end
- local times = math.floor(totalCount / targetCount)
- -- 兑换数量检查
- local needCount = sourceCount * times
- local count = self:get_item_count(uid, sourceId)
- if count < needCount then
- return false, code.RES.NOT_ENOUGH
- end
- -- 兑换卡属性检查
- local ok = true
- for _, v in ipairs(items) do
- if not table.indexof(heroItemIds, v.id) then
- ok = false
- break
- end
- end
- if not ok then
- return false, code.RES.LOGIC_ERROR
- end
- return true
- end
- -- 请求兑换自选英雄。物品类型210的使用这个接口
- function root:hero_optional_exchange(uid, sourceId, items)
- log.info("hero_optional_exchange uid:%s sourceId:%s items:%s", uid, sourceId, tostring(items))
- local conf = resAdapt:get_hero_exchange_conf(sourceId)
- if not conf then
- log.error("兑换英雄的配置异常")
- return
- end
- local sourceCount = conf.sourceCount
- local targetCount = conf.targetCount
- local targetItems = {}
- local totalCount = 0 -- 兑换卡的次数
- for _, v in ipairs(items) do
- table.insert(targetItems, {id = v.id, count = v.count})
- totalCount = totalCount + v.count
- end
- local times = math.floor(totalCount / targetCount)
- local reason = gameConst.RES_REASON_PRE.HERO_OPTIONAL_EXCHANGE
- local needCount = sourceCount * times
- local sourceItems = {
- {id = sourceId, count = needCount}
- }
- self:consume_items(uid, sourceItems, reason)
- self:add_items(uid, targetItems, reason)
- return targetItems
- end
- -- 判断 兑换资源包 资源是否足够
- function root:check_item_count(uid, sourceId, times)
- local needCount = times
- local count = self:get_item_count(uid, sourceId)
- if count < needCount then
- return false, code.RES.NOT_ENOUGH
- end
- return true
- end
- -- 请求兑换资源包。物品类型30的使用这个接口
- function root:onhook_exchange(uid, sourceId, times)
- log.info("onhook_exchange uid:%s sourceId:%s times:%s", uid, sourceId, times)
- local conf = resAdapt:get_onhook_exchange_conf(sourceId)
- if not conf then
- log.error("兑换资源包的配置异常")
- return
- end
- local targetType = conf.targetType
- local duration = conf.duration
- -- 获取挂机效率
- local rateItems = hookData:get_hook_minute_rate_items(uid)
- -- 灵晶
- local speedItem1 = table.key_find(rateItems, "id", gameConst.ITEM_ID.SPAR) or {}
- local speed1 = speedItem1.count or 0
- -- 突破石
- local speedItem2 = table.key_find(rateItems, "id", gameConst.ITEM_ID.BREAK) or {}
- local speed2 = speedItem2.count or 0
- -- 帝国币
- local speedItem3 = table.key_find(rateItems, "id", gameConst.ITEM_ID.GOLD) or {}
- local speed3 = speedItem3.count or 0
- -- 装备强化石
- local speedItem4 = table.key_find(rateItems, "id", gameConst.ITEM_ID.EQ_LEVEL) or {}
- local speed4 = speedItem4.count or 0
- -- 装备精练石
- local speedItem5 = table.key_find(rateItems, "id", gameConst.ITEM_ID.EQ_BREAK) or {}
- local speed5 = speedItem5.count or 0
- local targetItems
- if targetType == gameConst.ONHOOK_TYPE.ALL then
- targetItems = {
- {id = gameConst.ITEM_ID.SPAR, count = duration * speed1 * times},
- {id = gameConst.ITEM_ID.BREAK, count = duration * speed2 * times},
- {id = gameConst.ITEM_ID.GOLD, count = duration * speed3 * times}
- }
- elseif targetType == gameConst.ONHOOK_TYPE.SPAR then
- targetItems = {
- {id = gameConst.ITEM_ID.SPAR, count = duration * speed1 * times}
- }
- elseif targetType == gameConst.ONHOOK_TYPE.BREAK then
- targetItems = {
- {id = gameConst.ITEM_ID.BREAK, count = duration * speed2 * times}
- }
- elseif targetType == gameConst.ONHOOK_TYPE.GOLD then
- targetItems = {
- {id = gameConst.ITEM_ID.GOLD, count = duration * speed3 * times}
- }
- elseif targetType == gameConst.ONHOOK_TYPE.QIANGHUA then
- targetItems = {
- {id = gameConst.ITEM_ID.EQ_LEVEL, count = duration * speed4 * times}
- }
- elseif targetType == gameConst.ONHOOK_TYPE.JINGJIAN then
- targetItems = {
- {id = gameConst.ITEM_ID.EQ_BREAK, count = duration * speed5 * times}
- }
- else
- log.error("不支持的挂机资源类型")
- end
- if targetItems then
- local reason = gameConst.RES_REASON_PRE.ONHOOK_EXCHANGE
- local needCount = times
- local sourceItems = {
- {id = sourceId, count = needCount}
- }
- self:consume_items(uid, sourceItems, reason)
- self:add_items(uid, targetItems, reason)
- end
- return targetItems
- end
- -- 请求兑换英雄。物品类型200的使用这个接口
- function root:use_equip_box(uid, resId, times)
- -- log.debug("use_equip_box uid:%s resId:%s times:%s \n", uid, resId, tostring(times))
- local configs = resAdapt:getResEquipBoxConfig(resId)
- if not configs then
- log.error(string.format("获取到相应的装备宝箱的配置异常,resId:[%s]", tostring(resId)))
- return
- end
- local function keyRandWeight(array, totalWeight)
- local weight = {}
- local t = 0
- if not totalWeight then
- for _, v in ipairs(array) do
- if v.totalWeight then
- totalWeight = v.totalWeight
- break
- end
- end
- end
- if not totalWeight then
- return
- end
- for _, v in ipairs(array) do
- local ranNum = math.random(0, totalWeight)
- if v.weight and ranNum <= v.weight then
- return v.equipBag
- end
- end
- end
- local targetItems = {}
- do
- -- 可能一次性开N个宝箱
- -- 先排序
- sortAsc(configs, "seq")
- for i = 1, (times or 0), 1 do
- local equipBag = keyRandWeight(configs)
- local reqbConfigs = resAdapt:getResEquipBagConfig(equipBag or 0)
- if reqbConfigs then
- -- 随机配置
- local index = random_list_by_weight(reqbConfigs)
- local conf = reqbConfigs[index]
- log.debug(
- "use_equip_box uid[%s] resId[%s] equipBag[%s] index[%s], conf[%s]",
- tostring(self.uid),
- tostring(resId),
- tostring(equipBag),
- tostring(index),
- tostring(conf)
- )
- if conf and conf.resId then
- table.insert(targetItems, {id = conf.resId, count = conf.count or 1})
- end
- else
- log.error(string.format("获取到相应的装备包的配置异常,resId:[%s]", tostring(resId)))
- end
- end
- end
- local reason = "equip_box_random"
- local sourceItems = {
- {id = resId, count = times}
- }
- if #targetItems > 0 then
- self:consume_items(uid, sourceItems, reason)
- self:add_items(uid, targetItems, reason)
- end
- return targetItems
- end
- function root:useEquipBoxDebris(uid, resId, times)
- local resConfig = baseAdapt:getOneConfig("ResEquipExchangeConfig", resId, "id")
- if not resConfig or not resConfig.sourceCount or not resConfig.targetId then
- return code.CONFIG_ERROR
- end
- local getCount = math.floor(times / resConfig.sourceCount)
- local totalCount = (resConfig.sourceCount * getCount)
- if totalCount > times or getCount <= 0 then
- return code.RES.NOT_ENOUGH
- end
- local haveCount = self:get_item_count(uid, resId)
- if haveCount < times then
- return code.RES.NOT_ENOUGH
- end
- local reason = "equip_box_random_debris"
- local sourceItems = {
- {id = resId, count = totalCount}
- }
- local targetItems = {
- {id = resConfig.targetId, count = getCount}
- }
- self:consume_items(uid, sourceItems, reason)
- self:add_items(uid, targetItems, reason)
- targetItems = self:use_equip_box(uid, resConfig.targetId, getCount)
- return code.OK, targetItems
- end
- function root:use_equip_optional_box(uid, resId, items, times)
- -- log.debug("use_equip_optional_box uid:%s resId:%s items:%s", uid, resId, tostring(items))
- local configs = resAdapt:getResEquipChoiceConfig(resId)
- if not configs then
- log.error("装备包配置的配置异常")
- return
- end
- -- log.debug("use_equip_optional_box uid:%s items:%sm v.id:%s", uid, tostring(resId), tostring(configs))
- local targetItems = {}
- for _, v in ipairs(items or {}) do
- local config = table.key_find(configs, "equipId", v.id)
- -- log.debug("use_equip_optional_box uid:%s items:%sm v.id:%s", uid, tostring(v), tostring(config))
- if config then
- for i = 1, (times or 1), 1 do
- table.insert(targetItems, {id = v.id, count = (config.count or 1)})
- end
- end
- end
- local reason = "use_equip_optional_box"
- local sourceItems = {
- {id = resId, count = times or 1}
- }
- if #targetItems > 0 then
- self:consume_items(uid, sourceItems, reason)
- self:add_items(uid, targetItems, reason)
- end
- return targetItems
- end
- ----------------------------------------------------------------
- -- 判断资源是否足够
- function root:is_enough(uid, items)
- -- 求和
- local tempMap = {}
- for _, v in ipairs(items) do
- if not tempMap[v.id] then
- tempMap[v.id] = v.count
- else
- tempMap[v.id] = tempMap[v.id] + v.count
- end
- end
- local itemInfo = moduleData:hget_json(uid, MODULE_NAME, "itemInfo") or {}
- local ret = true
- for k, v in pairs(tempMap) do
- local item = table.key_find(itemInfo, "id", k)
- if not item or not item.count or item.count < v then
- ret = false
- break
- end
- end
- return ret
- end
- function root:is_enough_by_bid(uid, items)
- -- 求和
- local tempMap = {}
- for _, v in ipairs(items) do
- if not tempMap[v.bid] then
- tempMap[v.bid] = v.count
- else
- tempMap[v.bid] = tempMap[v.bid] + v.count
- end
- end
- local itemInfo = moduleData:hget_json(uid, MODULE_NAME, "itemInfo") or {}
- local ret = true
- for k, v in pairs(tempMap) do
- local item = table.key_find(itemInfo, "bid", k)
- if not item or not item.count or item.count < v then
- ret = false
- break
- end
- end
- return ret
- end
- --[[ 增加资源
- 返回的是 DataResUpdateItem 列表
- ]]
- function root:add_items(uid, items, reason)
- return self:update_items(uid, items, reason)
- end
- --[[ 消耗资源。资源不足也会消耗,消耗到0为止
- 返回的是 DataResUpdateItem 列表
- ]]
- function root:consume_items(uid, items, reason)
- local tempList = {}
- for _, v in ipairs(items) do
- table.insert(tempList, {id = v.id, count = -v.count, bid = v.bid})
- end
- return self:update_items(uid, tempList, reason)
- end
- -- 获取资源数量
- function root:get_item_count(uid, itemId)
- -- log.info("get_item_count uid:%s itemId:%s", uid, itemId)
- local itemInfo = moduleData:hget_json(uid, MODULE_NAME, "itemInfo") or {}
- local item = table.key_find(itemInfo, "id", itemId) or {}
- return item.count or 0
- end
- -- 获取资源数量
- function root:get_item_by_bid(uid, bid)
- -- log.info("get_item_by_bid uid:%s bid:%s", uid, bid)
- local itemInfo = moduleData:hget_json(uid, MODULE_NAME, "itemInfo") or {}
- local item = table.key_find(itemInfo, "bid", bid) or {}
- return item
- end
- -- 获取帝国币
- function root:get_gold(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.GOLD)
- end
- -- 获取宝石
- function root:get_diamond(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.DIAMOND)
- end
- -- 获取友情点
- function root:get_friend_coin(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.FRIEND_COIN)
- end
- -- 获取祈愿币
- function root:get_hero_coin(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.HERO_COIN)
- end
- -- 获取公会声望
- function root:get_club_coin(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.CLUB_COIN)
- end
- -- 获取灵晶
- function root:get_spar(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.SPAR)
- end
- -- 获取突破石
- function root:get_break(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.BREAK)
- end
- -- 获取觉醒石
- function root:get_awake(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.AWAKE)
- end
- -- 获取装备强化石
- function root:get_eqlevel(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.EQ_LEVEL)
- end
- -- 获取装备精练石
- function root:get_eqbreak(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.EQ_BREAK)
- end
- -- 获取试炼券
- function root:get_trial_ticket(uid)
- return self:get_item_count(uid, gameConst.ITEM_ID.TRIAL_TICKET)
- end
- -- 判断是否开启了指定的头像
- function root:is_open_album(uid, albumId)
- local conf = resAdapt:get_album_conf(albumId)
- if not conf then
- return false
- end
- local type = conf.type
- if type == 1 then
- -- 默认解锁的
- return true
- elseif type == 2 then
- -- 拥有英雄解锁的
- local heroId = conf.heroId
- return heroData:user_is_own_hero(uid, heroId)
- else
- -- 拥有物品解锁的
- local count = self:get_item_count(uid, albumId)
- return count > 0
- end
- end
- -- 判断是否开启了指定的头像框
- function root:is_open_frame(uid, frameId)
- local conf = resAdapt:get_frame_conf(frameId)
- if not conf then
- return false
- end
- local type = conf.type
- if type == 1 then
- -- 默认解锁的
- return true
- elseif type == 2 then
- -- 拥有英雄解锁的
- local heroId = conf.heroId
- return heroData:user_is_own_hero(uid, heroId)
- else
- -- 拥有物品解锁的
- local count = self:get_item_count(uid, frameId)
- return count > 0
- end
- end
- -- 判断是否开启了指定的称号
- function root:is_open_title(uid, titleId)
- local conf = resAdapt:get_title_conf(titleId)
- if not conf then
- return false
- end
- local type = conf.type
- if type == 1 then
- -- 默认解锁的
- return true
- elseif type == 2 then
- -- 拥有英雄解锁的
- local heroId = conf.heroId
- return heroData:user_is_own_hero(uid, heroId)
- else
- -- 拥有物品解锁的
- local count = self:get_item_count(uid, titleId)
- return count > 0
- end
- end
- -- 判断是否开启了指定的表情
- function root:is_open_face(uid, faceId)
- local conf = resAdapt:get_face_conf(faceId)
- if not conf then
- return false
- end
- local type = conf.type
- if type == 1 then
- -- 默认解锁的
- return true
- elseif type == 2 then
- -- 拥有英雄解锁的
- local heroId = conf.heroId
- return heroData:user_is_own_hero(uid, heroId)
- else
- -- 拥有物品解锁的
- local count = self:get_item_count(uid, faceId)
- return count > 0
- end
- end
- -- 判断是否开启了指定的看板娘
- function root:is_open_signboard(uid, signboardId)
- -- 拥有英雄解锁的
- local heroId = signboardId
- return heroData:user_is_own_hero(uid, heroId)
- end
- -- 已获得类型物品ID列表
- function root:get_own_type_item_id_list(uid, resType)
- if uid == nil or resType == nil then
- return
- end
- local resIdList = {}
- local itemInfo = moduleData:hget_json(uid, MODULE_NAME, "itemInfo") or {}
- for k, v in ipairs(itemInfo) do
- if resAdapt:is_type(v.id, resType) then
- table.insert(resIdList, v.id)
- end
- end
- return resIdList
- end
- -- 获取英雄拥有数量(包括觉醒)
- function root:get_hero_count(uid, heroId)
- if uid == nil or heroId == nil then
- return
- end
- -- 背包剩余数量
- local count = self:get_item_count(uid, heroId)
- -- 觉醒消耗数量
- local awakeCount = heroData:get_hero_awake_cost_count(uid, heroId)
- count = count + (awakeCount or 0)
- return count
- end
- ----------------------------------------
- -- 以下是私有方法
- ----------------------------------------
- -- 获取新的bid
- function root:_new_bid(uid)
- local lastBid = moduleData:hget_int(uid, MODULE_NAME, "lastBid") or 0
- lastBid = lastBid + 1
- moduleData:hset(uid, MODULE_NAME, "lastBid", lastBid)
- return lastBid
- end
- -- 最后初始化资源的时间戳
- function root:_get_last_init_time(uid)
- return moduleData:hget_int(uid, MODULE_NAME, "lastInitTime") or 0
- end
- function root:_set_last_init_time(uid, timestamp)
- moduleData:hset(uid, MODULE_NAME, "lastInitTime", timestamp)
- end
- function root:_AddExpirationTime(resConfing, uid)
- -- 计算失效时间/过期时间,expiration time ==> expTime;
- local expTime
- if resConfing then
- local curTime = timeUtil.now(uid)
- if resConfing.activeDays then
- expTime = curTime + (expTime or 0) + 86400 * tonumber(resConfing.activeDays)
- end
- if resConfing.termOfValidity then
- expTime = curTime + (expTime or 0) + tonumber(resConfing.termOfValidity)
- end
- end
- return expTime
- end
- function root:_AddItemByBid(uid, itemInfo, itemId, count, bid, resConfing, composite)
- local item
- if count > 0 and composite then
- local newBid = self:_new_bid(uid)
- item = {
- id = itemId,
- count = 0,
- bid = newBid
- }
- table.insert(itemInfo, item)
- else
- -- 不可叠加的物品只能通过bid来获取,但只有装备是通过bid来获取.
- item = table.key_find(itemInfo, "bid", bid)
- if not item and not bid then
- item = table.key_find(itemInfo, "id", itemId)
- end
- end
- -- 都没有获取到,就新建一个.
- if not item then
- local newBid = self:_new_bid(uid)
- item = {
- id = itemId,
- count = 0,
- bid = newBid
- }
- table.insert(itemInfo, item)
- end
- local oldCount = item.count or 0
- local newCount = oldCount + count
- newCount = math.max(newCount, 0)
- item.count = newCount
- item.expTime = self:_AddExpirationTime(resConfing, uid)
- return {{id = itemId, deltaCount = count, count = newCount, bid = item.bid}}
- end
- -- 更新单个资源
- function root:_update_item(uid, itemInfo, itemId, count, bid)
- local conf = resAdapt:get_item_conf(itemId)
- if not conf then
- log.error("更新资源异常,未找到[%s]资源配置", tostring(itemId))
- return
- end
- -- 处理特殊id的资源
- local otherModule = conf.otherModule
- local isSpecial = self:_update_special_item(uid, itemId, count, otherModule)
- if isSpecial then
- -- 特殊资源,不返回新数量
- return
- end
- local updateItems
- -- 必须执行
- if 1 == 1 then
- -- 资源可叠加
- if conf.enableComposite then
- updateItems = self:_AddItemByBid(uid, itemInfo, itemId, count, bid, conf)
- else
- updateItems = self:_AddItemByBid(uid, itemInfo, itemId, count, bid, conf, true)
- end
- else
- local itemType = conf.type
- if itemType == gameConst.RES_TYPE.COIN then
- updateItems = self:_update_coin_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.EXP then
- updateItems = self:_update_exp_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.CONSUME then
- updateItems = self:_update_consume_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.LOTTERY then
- updateItems = self:_update_lottery_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.TICKET then
- updateItems = self:_update_ticket_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.PAY then
- updateItems = self:_update_pay_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.ONHOOK then
- updateItems = self:_update_onhook_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.HERO_CARD then
- updateItems = self:_update_hero_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.RANDOM_HERO_CARD then
- updateItems = self:_update_random_hero_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.OPTIONAL_HERO_CARD then
- updateItems = self:_update_optional_hero_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.ALBUM then
- updateItems = self:_update_album_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.FACE then
- updateItems = self:_update_face_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.FRAME then
- updateItems = self:_update_frame_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.TITLE then
- updateItems = self:_update_title_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.EQUIP then
- updateItems = self:_update_unable_composit_type_item(uid, itemInfo, itemId, count, bid)
- elseif itemType == gameConst.RES_TYPE.EQUIP_BOX then
- updateItems = self:_update_enable_composit_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.EQUIP_CHOICE_BOX then
- updateItems = self:_update_enable_composit_type_item(uid, itemInfo, itemId, count)
- elseif itemType == gameConst.RES_TYPE.EQUIP_BOX_DEBRIS then
- updateItems = self:_update_enable_composit_type_item(uid, itemInfo, itemId, count)
- else
- log.error("更新资源异常,未知资源类型 itemId:%s", itemId)
- end
- end
- return updateItems
- end
- -- 特殊资源更新
- function root:_update_special_item(uid, itemId, count, otherModule)
- log.debug("-- DEBUG INFO : uid, itemId, count, otherModule :[%s]", tostring({uid, itemId, count, otherModule}))
- if otherModule == "pass" then
- self:_update_special_item_pay_pass(uid, itemId, count)
- return true
- elseif otherModule == "adventure" then
- self:_update_special_item_adventure_active(uid, itemId, count)
- return true
- elseif itemId == gameConst.ITEM_ID.USER_EXP then
- self:_update_special_item_user_exp(uid, itemId, count)
- return true
- elseif itemId == gameConst.ITEM_ID.VIP_EXP then
- self:_update_special_item_vip_exp(uid, itemId, count)
- return true
- elseif itemId == gameConst.ITEM_ID.ARENA_CUP then
- self:_update_special_item_arena_cup(uid, itemId, count)
- return true
- elseif itemId == gameConst.ITEM_ID.PASS_EXP then
- self:_update_special_item_pass_exp(uid, itemId, count)
- return true
- elseif itemId == gameConst.ITEM_ID.ADVENTURE_POINTS then
- self:_update_special_item_adventure_points(uid, itemId, count)
- return true
- elseif itemId == gameConst.ITEM_ID.ARENA then
- local arenaData = require("data.arena")
- arenaData:active_vip_status(uid, itemId)
- return true
- elseif itemId == gameConst.ITEM_ID.PETBORN_AWARD then
- self:_update_special_item_pve_vip_status(uid, itemId, count)
- return true
- else
- return false
- end
- end
- function root:_update_special_item_user_exp(uid, itemId, count)
- local playerData = require("data.player")
- playerData:add_level_exp(uid, count)
- end
- function root:_update_special_item_vip_exp(uid, itemId, count)
- local playerData = require("data.player")
- playerData:add_vip_level_exp(uid, count)
- end
- function root:_update_special_item_arena_cup(uid, itemId, count)
- local arenaData = require("data.arena")
- arenaData:user_add_cups(uid, count, "gm")
- end
- -- 悬赏经验
- function root:_update_special_item_pass_exp(uid, itemId, count)
- local exploitData = require("data.exploit")
- exploitData:add_progress(uid, count)
- end
- function root:_update_special_item_pay_pass(uid, itemId, count)
- local exploitData = require("data.exploit")
- exploitData:active_vip_award(uid)
- end
- -- 冒险积分
- function root:_update_special_item_adventure_points(uid, itemId, count)
- local pveStarsData = require("data.pveStars")
- pveStarsData:add_adventure_points(uid, count)
- end
- -- 冒险经费付费奖励激活
- function root:_update_special_item_adventure_active(uid, itemId, count)
- local adventureData = require("data.adventure")
- adventureData:active_vip_award(uid, itemId)
- end
- function root:_update_special_item_pve_vip_status(uid, itemId, count)
- local THIS_MODULE_NAME = "tb_pve"
- local contractData = moduleData:hget_json(uid, THIS_MODULE_NAME, "contractData")
- contractData = contractData or {}
- contractData.statusVip = 1
- moduleData:hset(uid, THIS_MODULE_NAME, "contractData", contractData)
- local currSeasonId = moduleData:hget_int(uid, THIS_MODULE_NAME, "pveId") or 1
- -- 通知玩家
- local msg = {
- statusVip = 1,
- seasonId = currSeasonId
- }
- util_user:user_proto_notify(uid, "on_pve_vip_status", msg)
- local keyEvent = string.format("pve-active-vip-item")
- local cnt = string.format("%s", tostring(itemId))
- util_user:log_event(uid, keyEvent, cnt)
- end
- -- 通用资源更新。仅数量累计
- function root:_update_common_type_item(uid, itemInfo, itemId, deltaCount)
- local item = table.key_find(itemInfo, "id", itemId)
- if not item then
- local newBid = self:_new_bid(uid)
- item = {id = itemId, count = 0, bid = newBid}
- table.insert(itemInfo, item)
- end
- local bid = item.bid
- local oldCount = item.count or 0
- local newCount = oldCount + deltaCount
- newCount = math.max(newCount, 0)
- item.count = newCount
- return {id = itemId, deltaCount = deltaCount, count = newCount, bid = bid}
- end
- -- 通用资源更新。不可叠加的物品,仅数量累计
- function root:_update_ones_type_item(uid, itemInfo, itemId, deltaCount, bId)
- local item = table.key_find(itemInfo or {}, "bid", bId or 0)
- if not item then
- local newBid = self:_new_bid(uid)
- item = {id = itemId, count = 0, bid = newBid}
- table.insert(itemInfo, item)
- end
- local bid = item.bid
- local oldCount = item.count or 0
- local newCount = oldCount + deltaCount
- newCount = math.max(newCount, 0)
- item.count = newCount
- return {id = itemId, deltaCount = deltaCount, count = newCount, bid = bid}
- end
- -- 更新代币类资源
- function root:_update_coin_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新经验类资源
- function root:_update_exp_type_item(uid, itemInfo, itemId, count)
- log.error("更新资源异常:经验类资源都是特殊资源,不应该进入本逻辑")
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新消耗类类资源
- function root:_update_consume_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新祈愿券类资源
- function root:_update_lottery_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新门票类资源
- function root:_update_ticket_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新付费订阅道具类资源
- function root:_update_pay_type_item(uid, itemInfo, itemId, count)
- log.error("更新资源异常:付费订阅道具类资源都是特殊资源,不应该进入本逻辑")
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新挂机资源包类资源
- function root:_update_onhook_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新英雄卡类资源。
- function root:_update_hero_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新随机英雄卡类资源
- function root:_update_random_hero_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新自选英雄卡类资源
- function root:_update_optional_hero_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新头像类资源
- function root:_update_album_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新表情类资源
- function root:_update_face_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新头像框类资源
- function root:_update_frame_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 更新称号类资源
- function root:_update_title_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 可叠加的物品
- function root:_update_enable_composit_type_item(uid, itemInfo, itemId, count)
- local updateItem = self:_update_common_type_item(uid, itemInfo, itemId, count)
- return {updateItem}
- end
- -- 不可叠加的物品
- function root:_update_unable_composit_type_item(uid, itemInfo, itemId, count, bid)
- local updateItem = self:_update_ones_type_item(uid, itemInfo, itemId, count, bid)
- return {updateItem}
- end
- -- 检查英雄列表。检查自动激活、自动溢出兑换
- function root:_check_hero_item(uid, updateItems, reason)
- local itemIdMap = {}
- for _, v in ipairs(updateItems) do
- if v.deltaCount and v.deltaCount > 0 then
- if resAdapt:is_type(v.id, gameConst.RES_TYPE.HERO_CARD) then
- itemIdMap[v.id] = true
- end
- end
- end
- for k, _ in pairs(itemIdMap) do
- self:_check_hero_active(uid, k, reason)
- self:_check_hero_overflow(uid, k, reason)
- end
- end
- -- 检查英雄自动激活
- function root:_check_hero_active(uid, itemId, srcReason)
- local conf = resAdapt:get_hero_conf(itemId)
- if not conf then
- log.error("检查英雄激活异常:没找到对应英雄配置")
- return
- end
- local count = self:get_item_count(uid, itemId)
- if count <= 0 then
- return
- end
- local heroId = conf.heroId
- -- 是否拥有该英雄
- local hasHero = heroData:user_is_own_hero(uid, heroId)
- if not hasHero then
- local ok = heroData:user_active_hero(uid, heroId)
- if ok then
- local reason = gameConst.RES_REASON_PRE.AUTO_HERO_ACTIVE
- local cardItem = {id = itemId, count = 1}
- self:consume_items(uid, {cardItem}, reason)
- self:_on_res_auto_hero_active(uid, cardItem, heroId, srcReason)
- end
- end
- end
- -- 检查英雄自动激活
- function root:_check_hero_overflow(uid, itemId, srcReason)
- local conf = resAdapt:get_hero_conf(itemId)
- if not conf then
- log.error("检查英雄溢出异常:没找到对应英雄配置")
- return
- end
- local count = self:get_item_count(uid, itemId)
- if count <= 0 then
- return
- end
- local heroId = conf.heroId
- local overflowItems = conf.overflowItems
- -- 英雄觉醒满还需要的卡牌数量
- local needCardCount = heroData:get_hero_full_awake_card_count(uid, heroId)
- local overflowCount = count - needCardCount
- if overflowCount <= 0 then
- return
- end
- local reason = gameConst.RES_REASON_PRE.AUTO_EXCHANGE
- local fromItems = {{id = itemId, count = overflowCount}}
- local toItems = {}
- for _, v in ipairs(overflowItems) do
- local count = v.count * overflowCount
- table.insert(toItems, {id = v.id, count = count})
- end
- self:consume_items(uid, fromItems, reason)
- self:add_items(uid, toItems, reason)
- self:_on_res_auto_exchange(uid, fromItems, toItems, srcReason)
- end
- -- 推送资源变化
- function root:_on_res_update(uid, updateItems, reason)
- local msg = {
- reason = reason,
- items = updateItems
- }
- util_user:user_proto_notify(uid, "on_res_update", msg)
- end
- -- 推送资源自动激活英雄
- function root:_on_res_auto_hero_active(uid, cardItem, heroId, reason)
- local msg = {
- reason = reason,
- cardItem = cardItem,
- heroId = heroId
- }
- util_user:user_proto_notify(uid, "on_res_auto_hero_active", msg)
- end
- -- 推送资源自动兑换
- function root:_on_res_auto_exchange(uid, fromItems, toItems, reason)
- local msg = {
- reason = reason,
- fromItems = fromItems,
- toItems = toItems
- }
- util_user:user_proto_notify(uid, "on_res_auto_exchange", msg)
- end
- -- 资源变化事件
- function root:_dispatch_event(uid, updateItems)
- for _, v in ipairs(updateItems) do
- local conf = resAdapt:get_item_conf(v.id) or {}
- local evtParams = {
- times = 1,
- id = v.id,
- count = math.abs(v.deltaCount),
- add = v.deltaCount,
- type = conf.type,
- bId = v.bid,
- totalCount = v.count
- }
- util_user:user_dispatch_event(uid, gameConst.EVENT_ID.RES, evtParams)
- end
- end
- -- 资源变化事件
- function root:_log_resource(uid, updateItems, reason)
- for _, v in ipairs(updateItems) do
- util_user:log_resource(uid, reason, v.id, v.deltaCount, v.count)
- end
- end
- return root
|