local RolePlugin = {} function RolePlugin.bind(Role) function Role:log() end function Role:loadAll() self:loadDaily() self:loadEquips() self:loadRunes() self:loadHeros() self:loadDiner() end function Role:reloadWhenLogin() end function Role:onCrossDay(now, notify) local ltime = self:getProperty("ltime") if isCrossDay(ltime, now) then local response = {} self.dailyData:refreshDailyData(notify) self.dinerData:refreshDailyData(notify) if notify then self:notifyUpdateProperties(response) end return true end end function Role:onOfflineEvent() end local function checkItemCount(self, itemId, count) local itemData = csvdb["itemCsv"][itemId] -- 种类 类型数量限制 local page = globalCsv.store_type[itemData.type] local limit = self:getProperty("bagLimit")[page] if limit and self:getItemCount(itemId) == 0 then local curCount = 0 local items = self:getProperty("items"):toNumMap() for _,_ in pairs(items) do if globalCsv.store_type[itemData.type] == page then curCount = curCount + 1 if curCount >= limit then count = 0 break end end end end return count end local function _award(self, itemId, count, params) local pms = clone(params) local itemData = csvdb["itemCsv"][itemId] local curType = itemData.type local change = {} -- 奖励被转化为了其他奖励 id = count local itemIdAward = { [ItemId.PlayerExp] = function() self:addPlayExp(count) end, } local itemTypeAward = { [ItemType.Hero] = function() pms.type = itemId - ItemStartId.Hero for _= 1, count do self:addHero(pms) end end, [ItemType.AdvItem] = function() --冒险道具不会进入 玩家仓库 count = 0 end, } -- 对数量筛查 count = checkItemCount(self, itemId, count) if count ~= 0 then if itemIdAward[itemId] then itemIdAward[itemId]() elseif itemTypeAward[curType] then itemTypeAward[curType]() else pms.itemId = itemId pms.count = count self:addItem(pms) end end return count, change -- count 刷新实际发放的奖励个数 change 物品实际奖励与当前id 不符 就发生转换 而不实际发奖 end -- 发奖功能入口 award string id=count or {[id] = count} function Role:award(gift, params) params = params or {} local tgift = {} if type(gift) == "string" then for _, one in pairs(gift:toTableArray(true)) do tgift[one[1]] = (tgift[one[1]] or 0) + one[2] end else tgift = gift end local reward, allChange = {}, {} for itemId, count in pairs(tgift) do local count, change = _award(self, itemId, count, params) if next(change) then local cr, cc = self:award(change, params) -- 内部转换忽略 for _id, _ct in pairs(cr) do reward[_id] = (reward[_id] or 0) + _ct end table.insert(allChange, {form = {[itemId] = count}, to = cr}) else if count > 0 then reward[itemId] = (reward[itemId] or 0) + count end end end return reward, allChange --实际获得的奖励 和 最高级奖励转化过程 end function Role:addPlayExp(addExp) local level = self:getProperty("level") if not csvdb["player_expCsv"][level + 1] then return end local exp = self:getProperty("exp") local newExp = exp + addExp while newExp >= csvdb["player_expCsv"][level].exp do if csvdb["player_expCsv"][level + 1] then -- 有下一级 newExp = newExp - csvdb["player_expCsv"][level].exp level = level + 1 else newExp = csvdb["player_expCsv"][level].exp - 1 -- 没有下一级了 经验溢出太多 扣除 end end self:updateProperties({level = level, exp = newExp}) end function Role:addItem(params) params = params or {} if params.itemId == ItemId.Diamond then self:gainDiamond(params) return end local items = self:getProperty("items") local origin = items:getv(params.itemId, 0) local nums = origin+params.count if nums <= 0 then items = items:delk(params.itemId) nums = 0 else items = items:incrv(params.itemId, params.count) end self:setProperty("items", items) if not params.notNotify then SendPacket(actionCodes.Role_updateItems, MsgPack.pack({[params.itemId] = nums})) end end function Role:checkItemEnough(itemCountT) local less = {} if not next(itemCountT) then return false, less end for itemId, count in pairs(itemCountT) do if count <= 0 then -- 判断物品数量值不应该小于等于0 less[itemId] = 0 else local last = self:getItemCount(itemId) - count if last < 0 then less[itemId] = -last end end end return (not next(less)), less -- 是否足够,,缺什么缺多少 end function Role:costItems(itemCountT, params) local pms = clone(params or {}) if itemCountT[ItemId.Diamond] then --优先扣除钻石 pms.count = itemCountT[ItemId.Diamond] if not self:costDiamond(pms) then return end itemCountT[ItemId.Diamond] = nil end for itemId, count in pairs(itemCountT) do pms.itemId = itemId pms.count = - count self:addItem(pms) end return true end function Role:getItemCount(itemId) if itemId == ItemId.Diamond then return self:getAllDiamond() end return self:getProperty("items"):getv(itemId, 0) end function Role:getAllDiamond() return self:getProperty("diamond") + self:getProperty("reDiamond") end function Role:gainDiamond(params) if not params or type(params) ~= "table" then return false end local count = tonum(params.count) if isnan(count) then return false end local origind = self:getProperty("diamond") local originr = self:getProperty("reDiamond") local origin = origind + originr if params.isRecharge then self:incrProperty("reDiamond", count) else self:incrProperty("diamond", count) end self:notifyUpdateProperty("diamond", self:getAllDiamond()) return true end function Role:costDiamond(params) if not params or type(params) ~= "table" then return false end local count = tonum(params.count) if isnan(count) then return false end if count <= 0 then return false end local origind = self:getProperty("diamond") local originr = self:getProperty("reDiamond") local origin = origind + originr if origin < 0 then return false end if origin < count then return false end local last = count local costFirst = {"diamond", "reDiamond"} if params.isRecharge then costFirst = {"reDiamond", "diamond"} end last = math.max(last - self:getProperty(costFirst[1]), 0) if last < count then self:incrProperty(costFirst[1], last - count) end if last > 0 then self:incrProperty(costFirst[2], -last) end self:notifyUpdateProperty("diamond", self:getAllDiamond()) return true end function Role:addHero(params) local roleId = self:getProperty("id") local heroId = tonum(redisproxy:hincrby(string.format(R_INCR, roleId), "hero", 1)) local heroType = params.type redisproxy:sadd(string.format(R_HEROS, roleId), heroId) local heroInfo = { key = string.format(R_HERO, roleId, heroId), id = heroId, type= heroType, } local newHero = require("models.Hero").new(heroInfo) newHero:create() newHero.owner = self newHero:saveBattleValue() self.heros[heroId] = newHero if not params.notNotify then local heroResponse = {} table.insert(heroResponse, newHero:data()) local bin = MsgPack.pack(heroResponse) SendPacket(actionCodes.Hero_loadInfos, bin) end end function Role:delHero(heroId) local roleId = self:getProperty('id') local hero = self.heros[heroId] if not hero then return end self.heros[heroId] = nil redisproxy:pipelining(function (red) red:del(string.format(R_HERO, roleId, heroId)) red:srem(string.format(R_HEROS, roleId), heroId) end) SendPacket(actionCodes.Hero_loadInfos, MsgPack.pack({{id = heroId, bDel = true}})) end function Role:loadHeros() local roleId = self:getProperty("id") local heroIds = redisproxy:smembers(string.format(R_HEROS, roleId)) local redret = redisproxy:pipelining(function (red) for _, heroId in ipairs(heroIds) do red:hgetall(string.format(R_HERO, roleId, heroId)) end end) for index, heroId in ipairs(heroIds) do local hero = require("models.Hero").new({key = string.format(R_HERO, roleId, heroId)}) if hero:load(table.array2Table(redret[index])) then hero.owner = self self.heros[tonumber(heroId)] = hero end end end function Role:loadDaily() local roleId = self:getProperty("id") local dataKey = string.format(R_DAILY, roleId) self.dailyData = require("models.Daily").new({key = dataKey}) self.dailyData.owner = self if not redisproxy:exists(dataKey) then self.dailyData:create() else self.dailyData:load() end end function Role:loadDiner() local roleId = self:getProperty("id") local dataKey = string.format(R_DINER, roleId) self.dinerData = require("models.Diner").new({key = dataKey}) self.dinerData.owner = self if not redisproxy:exists(dataKey) then self.dinerData:create() else self.dinerData:load() end end function Role:loadEquips() local roleId = self:getProperty("id") self.equipBag = {} local keys = redisproxy:keys(string.format(R_EQUIP_ROOT, roleId)) if keys and next(keys) then for _,v in pairs(keys) do local equip = require("models.Equip").new({key = v}) equip:load() local typ,lv = equip:getProperty("type"),equip:getProperty("level") equip.owner = self if not self.equipBag[typ] then self.equipBag[typ] = {} end self.equipBag[typ][lv] = equip end end end function Role:addEquip(params) if params.type and params.level and params.count then local equipType = params.type local equipLv = params.level local count = params.count -- isRefer为true时count>0为卸载操作,<0为装备操作 local isRefer = params.isRefer or false local equip = nil local equipSet = self.equipBag[equipType] if equipSet then equip = self.equipBag[equipType][equipLv] else self.equipBag[equipType] = {} end if equip then local originCount = equip:getProperty("count") if isRefer and count < 0 then if count < 0 then if count+originCount<0 then return end else if equip:getProperty("refer")-count<0 then return end end end count = originCount+count else if isRefer then return end local roleId = self:getProperty("id") local data = { key = string.format(R_EQUIP,roleId,equipType,equipLv), type = equipType, level = equipLv, } equip = require("models.Equip").new(data) equip.owner = self equip:create() end equip:updateProperty({field = "count", value = math.min(count,0)}) if isRefer then equip:updateProperty({field = "refer", value = math.min(equip:getProperty("refer")+count,0)}) end self.equipBag[equipType][equipLv] = equip end end function Role:getEquipCount(typ,lv) local equipSet = self.equipBag[typ] if equipSet then local equip = equipSet[lv] if equip then return equip:getProperty("count") else return 0 end else return 0 end end function Role:loadRunes() -- local roleId = self:getProperty("id") -- self.runeBag = {} -- local keys = redisproxy:keys(string.format(R_EQUIP_ROOT, roleId)) -- if keys and next(keys) then -- for _,v in pairs(keys) do -- local rune = require("models.Rune").new({key = v}) -- rune.owner = self -- self.runeBag[rune.id][rune.level] = rune -- end -- end end function Role:addHero(params) local roleId = self:getProperty("id") local heroId = tonum(redisproxy:hincrby(string.format(R_INCR, roleId), "hero", 1)) local heroType = params.type redisproxy:sadd(string.format(R_HEROS, roleId), heroId) local heroInfo = { key = string.format(R_HERO, roleId, heroId), id = heroId, type= heroType, } local newHero = require("models.Hero").new(heroInfo) newHero:create() newHero.owner = self newHero:saveBattleValue() self.heros[heroId] = newHero if not params.notNotify then local heroResponse = {} table.insert(heroResponse, newHero:data()) local bin = MsgPack.pack(heroResponse) SendPacket(actionCodes.Hero_loadInfos, bin) end end function Role:addRune(params) local roleId = self:getProperty("id") local runeId = params.id local runeLv = params.level local count = params.count local rune = nil local runeSet = self.runeBag[runeId] if runeSet then rune = self.runeBag[runeId][runeLv] else self.runeBag[runeId] = {} end if rune then count = rune:getProperty("count")+count else local data = { key = string.format(R_RUNE,roleId,runeId,runeLv), id = runeId, level = runeLv, } rune = require("models.Rune").new(data) rune.owner = self rune:create() end rune:updateProperty({field = "count", value = math.min(count,0)}) self.runeBag[runeId][runeLv] = rune end function Role:getRuneCount(id,lv) local runeSet = self.runeBag[id] if runeSet then local rune = runeSet[lv] if rune then return rune:getProperty("count") else return 0 end else return 0 end end function Role:getAdvData() if not self.advData then self.advData = require("adv.Adv").new(self) self.advData:initByInfo() end return self.advData end end return RolePlugin