local Diner = class("Diner", require("shared.ModelBase")) function Diner:ctor(properties) Diner.super.ctor(self, properties) end Diner.schema = { buildL = {"string", ""}, -- 家具等级 1=1 2=1 3=1 order = {"string", "[]"}, -- 特殊订单 sells = {"string", "[]"}, -- 贩卖位置 dishTree = {"string", "1=1 101=1 201=1"}, -- 料理天赋 skillTree = {"string", ""}, -- 支援天赋 popular = {"number",0}, -- 累计人气 expedite = {"number",1}, --每日加速次数 gfood = {"table", {}}, -- 愿望食材 {{id = 123, st = 1232144},} task = {"table", {}}, -- 任务刷新 {et = 消失时间 id = 任务id, refuse = 0} entrustB = {"table", {}}, -- 委托完成过的记录 {id = 1} entrust = {"table", {}}, -- 委托 {id, id, id} customer = {"table", {}}, -- 解锁的顾客 {id = 1} -- 1 (已解锁) 0(达成条件 可解锁 服务器用) comboStatus = {"table", {}}, -- 组合领取奖励状态 {id = -1} --有表示已经领取奖励 } function Diner:rankResetData(notify) self:updateProperty({field = "popular", value = 0, notNotify = not notify}) end function Diner:refreshDailyData(notify) -- 委托 local entrust = self:getProperty("entrust") local entrustB = self:getProperty("entrustB") local had = {} local pool = {} local change = false for i = 1, 3 do if not entrust[i] then if not next(pool) then for id, data in pairs(csvdb["diner_missionCsv"]) do local show = true if data.show ~= "" then -- 不填=默认刷出,1=达成前置任务,2=通关关卡 local showC = data.show:toArray(true, "=") if showC[1] == 2 then if not self.owner:checkHangPass(showC[2]) then show = false end elseif showC[1] == 1 then if not entrustB[showC[2]] then show = false end end end if show then table.insert(pool, {id, data.chance}) end end end if #pool > 0 then local idx = math.randWeight(pool, 2) entrust[i] = pool[idx][1] change = true table.remove(pool, idx) end if not next(pool) then break end else had[entrust[i]] = 1 end end if self.owner:getProperty("funcGuide"):getv(51,0) == 0 or (not self.owner:checkOverGuide(27) and self.owner:checkOverGuide(25)) then entrust[1] = 1001 entrust[2] = 1 elseif not self.owner:checkOverGuide(29,4) and self.owner:checkOverGuide(29) then local temp = entrust[1] entrust[1] = 1 entrust[2] = temp end self:updateProperty({field = "entrust", value = entrust, notNotify = not notify}) -- 每日加速次数 self:updateProperty({field = "expedite", value = 1, notNotify = not notify}) -- 特殊订单 local orders = json.decode(self:getProperty("order")) local hadTask = {} local needCount = globalCsv.diner_task_count for idx, temp in pairs(orders) do if temp.lock ~= 0 then hadTask[temp.id] = 1 needCount = needCount - 1 end end if needCount <= 0 then return end -- 等级由订单板等级决定 local taskLevel = self:getProperty("buildL"):getv(5, 1) local taskData = csvdb["diner_questCsv"][taskLevel] if not taskData then return end local pool = {} local dishTree = self:getProperty("dishTree") for id, temp in pairs(taskData) do local unlock = true for _, front in ipairs(temp.front:toArray(true, "=")) do if dishTree:getv(front, 0) == 0 then unlock = false break end end if not hadTask[id] and unlock then table.insert(pool, temp) end end local needCount = math.min(#pool, needCount) -- 需要的任务个数 for idx = 1, globalCsv.diner_task_count do local order = orders[idx] if not order or order.lock == 0 then if needCount > 0 then local index = math.randWeight(pool, "chance") local data = pool[index] orders[idx] = {lv = taskLevel, id = data.id, n = 0, lock = 0, status = 0} needCount = needCount - 1 table.remove(pool, index) end end end self:updateProperty({field = "order", value = json.encode(orders), notNotify = not notify}) end function Diner:updateProperty(params) params = params or {} if not self.schema[params.field] then return end local oldValue = self:getProperty(params.field) if params.value then self:setProperty(params.field, params.value) elseif params.delta then self:incrProperty(params.field, params.delta) else return end local newValue = self:getProperty(params.field) if not params.notNotify then self:notifyUpdateProperty(params.field, newValue, oldValue) end end function Diner:notifyUpdateProperty(field, newValue, oldValue) local datas = { key = field, newValue = newValue, oldValue = oldValue, } SendPacket(actionCodes.Diner_updateProperty, MsgPack.pack(datas)) end function Diner:checkDinerTask(typ, count, param1, param2, notNotify) local orders = json.decode(self:getProperty("order")) local dirty = false for k, order in ipairs(orders) do local taskSet = csvdb["diner_questCsv"][order.lv] if taskSet and taskSet[order.id] then local data = taskSet[order.id] if data.type == typ and data.condition1 == param1 and order.status == 1 then orders[k].n = orders[k].n + count dirty = true end end end if dirty then self:updateProperty({field = "order", value = json.encode(orders), notNotify = notNotify}) end return dirty end function Diner:calSellReward(sell, delta, dishData, isExpedite) local reward = sell.reward or "" if isExpedite then reward = "" end local popular = 0 if delta <= 0 then return reward, popular end local addReward = {} for key, value in pairs(dishData.item_normal:toNumMap()) do addReward[key] = (addReward[key] or 0) + value * delta end popular = dishData.famous_normal * delta local upValue = {} -- 建筑加成 for buildType = 1, 6 do local level = self:getProperty("buildL"):getv(buildType, 1) local buildData = csvdb["diner_buildingCsv"][buildType][level] if buildData.gold_up > 0 then upValue[ItemId.Gold] = (upValue[ItemId.Gold] or 0) + buildData.gold_up end if buildData.item_up > 0 then upValue[ItemId.DinerCoin] = (upValue[ItemId.DinerCoin] or 0) + buildData.item_up end if buildData and buildData.famous_up > 0 then upValue[-1] = (upValue[-1] or 0) + buildData.famous_up end end -- 收集加成 local collectCount = 0 for _id , status in pairs(self:getProperty("customer")) do if status == 1 then collectCount = collectCount + 1 end end local collectAdd = 0 for _, collectData in ipairs(csvdb["diner_customer_collectCsv"]) do if collectData.num <= collectCount then collectAdd = collectData.bonus else break end end upValue[-1] = (upValue[-1] or 0) + collectAdd -- 电波塔加成 local goldCount = self.owner:getBnousDiner(4,addReward[ItemId.Gold]) for id, count in pairs(addReward) do addReward[id] = math.floor(count * (1 + (upValue[id] or 0) / 100)) reward = reward:incrv(id, addReward[id]) end reward = reward:incrv(ItemId.Gold, goldCount) popular = math.floor(popular * (1 + (upValue[-1] or 0) / 100)) return reward, popular end function Diner:updateSell(slot, calOnly) local sells = json.decode(self:getProperty("sells")) local sell = sells[slot] if not sell or sell.count <= 0 then return end local dishData = csvdb["diner_dishCsv"][sell.dish][sell.level] local deltaTime = 0 local deltaCount = 0 local timePass = skynet.timex() - sell.time local sellTime = dishData.sell_time + self.owner:getBnousDiner(3, dishData.sell_time) deltaCount = math.floor(timePass / sellTime) if deltaCount < sell.count then deltaTime = math.floor(timePass - sellTime * deltaCount) end deltaCount = math.min(deltaCount, sell.count) local lastCount = sell.count - deltaCount local reward, popular = self:calSellReward(sell, deltaCount, dishData) if not calOnly and deltaCount > 0 then sells[slot].time = skynet.timex() - deltaTime sells[slot].count = lastCount sells[slot].level = self:getProperty("dishTree"):getv(sell.dish, 1) sells[slot].reward = reward sells[slot].popular = (sells[slot].popular or 0) + popular self:setProperty("sells", json.encode(sells)) self:checkDinerTask(DinerTask.SellDish, deltaCount, sell.dish) self:checkDinerTask(DinerTask.SellDishType, deltaCount, math.ceil(sell.dish / 100)) self:checkDinerTask(DinerTask.SellDishRare, deltaCount, dishData.rarity) self.owner:checkTaskEnter("FoodSell", {count = deltaCount}) end return { deltaCount = deltaCount, deltaTime = deltaTime, lastCount = lastCount, reward = reward, } end function Diner:expediteSell(slot) local sells = json.decode(self:getProperty("sells")) local sell = sells[slot] if not sell or sell.count <= 0 then return end local dishData = csvdb["diner_dishCsv"][sell.dish][sell.level] local expediteCount = 0 local expediteTime = globalCsv.diner_sell_expediteTime local sellTime = dishData.sell_time + self.owner:getBnousDiner(3,dishData.sell_time) expediteCount = math.floor(expediteTime / sellTime) expediteCount = math.min(expediteCount, sell.count) local lastCount = sell.count - expediteCount local reward, popular = self:calSellReward(sell, expediteCount, dishData, true) local deltaTime = math.floor(expediteTime - sellTime * expediteCount) if expediteCount > 0 then sells[slot].time = sell.time - deltaTime sells[slot].count = lastCount self:setProperty("sells", json.encode(sells)) self:checkDinerTask(DinerTask.SellDish, expediteCount, sell.dish) self:checkDinerTask(DinerTask.SellDishType, expediteCount, math.ceil(sell.dish / 100)) self:checkDinerTask(DinerTask.SellDishRare, expediteCount, dishData.rarity) self.owner:checkTaskEnter("FoodSell", {count = expediteCount}) local needTime = sells[slot].count * dishData.sell_time + sells[slot].time - skynet.timex() self.owner:pushMsg({type = "food", slot = slot, time = needTime}) end return { expediteCount = expediteCount, lastCount = lastCount, reward = reward, popular = popular, deltaTime = deltaTime, } end function Diner:getMaxSlots() local slotCount = globalCsv.diner_sell_slots_init for _, carbonId in ipairs(globalCsv.diner_sell_slots_unlock) do if self.owner:checkHangPass(carbonId) then slotCount = slotCount + 1 end end return slotCount end function Diner:getMaxDishs() local dishCount = globalCsv.diner_sell_dish_init -- local buildingCsv = csvdb["diner_buildingCsv"] -- for id, level in pairs(self:getProperty("buildL"):toNumMap()) do -- if buildingCsv[id][level].storage > 0 then -- dishCount = dishCount + buildingCsv[id][level].storage -- end -- end return dishCount end function Diner:popularAdd(popular) if popular ~= 0 then self:updateProperty({field = "popular", delta = popular}) local dbKey = self.owner:getCurDinerRankKey() local roleId = self.owner:getProperty("id") -- 更新排行榜 local curPopular = self:getProperty("popular") self.owner:checkTaskEnter("DinerPopular", {count = curPopular}) redisproxy:pipelining(function (red) red:zadd(dbKey, curPopular, roleId) --更新分数 red:hset(RANK_DINER_INFO, roleId, MsgPack.pack({ lv = self:getProperty("buildL"):getv(1, 1), name = self.owner:getProperty("name"), headId = self.owner:getProperty("headId") })) end) end end function Diner:getPopularRank() local dbKey = self.owner:getCurDinerRankKey() local list = {} local ids = redisproxy:zrevrange(dbKey, 0 , 99, "WITHSCORES") local redret = {} if ids and next(ids) then redret = redisproxy:pipelining(function (red) for i = 1, #ids, 2 do local roleId = ids[i] local score = ids[i + 1] list[#list + 1] = {score = tonumber(score), roleId = tonumber(roleId)} red:hget(RANK_DINER_INFO, roleId) end end) end for i = 1, #redret do local player = MsgPack.unpack(redret[i]) list[i].player = player end local rank = redisproxy:ZREVRANK(dbKey, self.owner:getProperty("id")) if not rank then rank = -1 else rank = rank + 1 end return {list = list, rank = rank} end function Diner:data() local properties = { "buildL", "order", "sells", "dishTree", "skillTree", "popular", "expedite", "gfood", "task", "entrust", "customer", "comboStatus", } local data = self:getProperties(properties) return data end return Diner