Diner.lua 7.12 KB
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},         	--每日加速次数
	gTime = {"number",skynet.timex()},  --温室最后一次领取时间
}

function Diner:refreshDailyData(notify)
	-- 每日加速次数
	self:updateProperty({field = "expedite", value = 1, notNotify = not notify})
	self:setProperty("expedite", 1)

	-- 特殊订单
	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 = {}
	for id, temp in pairs(taskData) do
		if not hadTask[id] 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)
	local reward = sell.reward or ""
	local popular = 0
	if delta <= 0 then
		return reward, popular
	end
	for key, value in pairs(dishData.item_normal:toNumMap()) do
		reward = reward:incrv(key, value * delta)
	end
	popular = popular + dishData.famous_normal * delta

	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
			local value = reward:getv(ItemId.Gold, 0)
			value = math.floor(value * (100 + buildData.gold_up) / 100)
			if value > 0 then
				reward = reward:setv(ItemId.Gold, value)
			end
		end
		if buildData.item_up > 0 then
			local value = reward:getv(ItemId.DinerCoin, 0)
			value = math.floor(value * (100 + buildData.item_up) / 100)
			if value > 0 then
				reward = reward:setv(ItemId.DinerCoin, value)
			end
		end
		if buildData and buildData.famous_up > 0 then
			popular = math.floor(popular * (100 + buildData.famous_up) / 100)
		end
	end
	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

	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
		self:setProperty("sells", json.encode(sells))
		self:updateProperty({field = "popular", delta = popular})
		self:checkDinerTask(DinerTask.SellDish, deltaCount, sell.dish)
	end
	return {
		deltaCount = deltaCount,
		deltaTime = deltaTime,
		lastCount = lastCount,
		reward = reward,
		popular = popular,
	}
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 = 7200
	local sellTime = 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)
	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:updateProperty({field = "popular", delta = popular})
		self:checkDinerTask(DinerTask.SellDish, expediteCount, sell.dish)
	end
	return {
		expediteCount = expediteCount,
		lastCount = lastCount,
		reward = reward,
		popular = popular,
	}
end

function Diner:getMaxSlots()
	local slotCount = globalCsv.diner_sell_slots_init

	local hangPass = self.owner:getProperty("hangPass")
	for _, carbonId in ipairs(globalCsv.diner_sell_slots_unlock) do
		if hangPass[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:data()
	local properties = {"buildL", "order", "sells", "dishTree", "skillTree","popular","expedite","gTime"}
	local data = self:getProperties(properties)
	return data
end

return Diner