PGRData/Script/matrix/xmodule/xrestaurant/XRestaurantWorkBench.lua
2024-09-01 22:49:41 +02:00

576 lines
No EOL
16 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--服务端工作状态
local ServerWorkState = {
Normal = 0,
WaitForStorage = 1,
WaitForConsume = 2,
}
---@class XRestaurantWorkBench : XDataEntityBase 工作台基类
---@field protected _Id number 下标或者Id
---@field protected _ProductId number 产品Id
---@field protected _CharacterId number 员工Id
---@field protected _AreaType number 区域类型
---@field protected _State XRestaurantConfigs.WorkState 工作状态
---@field protected _UpdateTime number 扣除材料时间
---@field protected _SimulationSecond number 模拟时长
---@field protected _Progress number 当前进度
---@field protected _CountDown number 倒计时
---@field protected _Tolerances number 工作误差,由于员工升级等造成
---@field protected _IsConsume boolean 是否已经消耗原材料
local XRestaurantWorkBench = XClass(XDataEntityBase, "XRestaurantWorkBench")
local default = {
_Id = 0,
_ProductId = 0,
_CharacterId = 0,
_AreaType = XRestaurantConfigs.AreaType.IngredientArea,
_State = XRestaurantConfigs.WorkState.Free,
_UpdateTime = 0,
_SimulationSecond = 0,
_Progress = 0,
_CountDown = 0,
_Tolerances = 0,
_IsConsume = false,
}
function XRestaurantWorkBench:Ctor(id)
self:Init(default, id)
end
function XRestaurantWorkBench:InitData(id)
self:SetProperty("_Id", id)
end
function XRestaurantWorkBench:OnNotify(notifyData)
local productId, characterId, state = notifyData.ProductId, notifyData.CharacterId, notifyData.State
if XTool.IsNumberValid(productId) then
self:AddProduct(productId)
else
self:DelProduct()
end
if XTool.IsNumberValid(characterId) then
self:AddStaff(characterId)
else
self:DelStaff()
end
local updateTime = notifyData.UpdateTime
self:UpdateTimeAndConsume(updateTime, state)
end
function XRestaurantWorkBench:OnWorking()
if self:IsFree() then
return
end
if self:IsWorking() then
return
end
local character = self:GetCharacter()
character:ReWork()
self:ChangeStateAndMarkSort(XRestaurantConfigs.WorkState.Working)
end
function XRestaurantWorkBench:OnPause()
if self:IsFree() then
return
end
if self:IsPause() then
return
end
local character = self:GetCharacter()
character:Pause()
self:ChangeStateAndMarkSort(XRestaurantConfigs.WorkState.Pause)
end
function XRestaurantWorkBench:OnFree()
if self._State == XRestaurantConfigs.WorkState.Free then
return
end
self:ChangeStateAndMarkSort(XRestaurantConfigs.WorkState.Free)
end
function XRestaurantWorkBench:UpdateCountDown(produceNeedTime)
local totalTime = self._SimulationSecond + self._Tolerances
local countDown = math.max(0, produceNeedTime - totalTime)
local progress = math.min(1, totalTime / produceNeedTime)
self:SetProperty("_CountDown", countDown)
self:SetProperty("_Progress", progress)
end
--- 更新扣除材料时间
---@param updateTime number
---@param state number 服务器状态
---@return void
--------------------------
function XRestaurantWorkBench:UpdateTimeAndConsume(updateTime, state)
if updateTime <= 0 or not (XTool.IsNumberValid(self._CharacterId)
and XTool.IsNumberValid(self._ProductId)) then
self:SetProperty("_UpdateTime", 0)
self:SetProperty("_SimulationSecond", 0)
self:SetProperty("_IsConsume", false)
return
end
local produceNeedTime = self:GetProduceSingleTime()
self:SetProperty("_UpdateTime", updateTime)
local now = XTime.GetServerNowTimestamp()
local subTime = math.max(0, now - updateTime)
if state == ServerWorkState.WaitForConsume then --等待材料满足
self:SetProperty("_SimulationSecond", 0)
self:SetProperty("_IsConsume", false)
elseif state == ServerWorkState.Normal then --正常工作状态
self:SetProperty("_IsConsume", true)
self:SetProperty("_SimulationSecond", math.min(subTime, produceNeedTime))
elseif state == ServerWorkState.WaitForStorage then --等待库存消耗
self:SetProperty("_IsConsume", true)
self:SetProperty("_SimulationSecond", math.min(subTime, produceNeedTime - 1))
end
end
--- 产品排序
---@return XRestaurantProduct[] 排序后的产品
--------------------------
function XRestaurantWorkBench:SortProduct()
return {}
end
--- 开始工作, 此接口由服务端更新数据后调用
--------------------------
function XRestaurantWorkBench:TryWorking()
if self:IsFree() then
return false
end
if self._IsConsume then
self:OnWorking()
else
self:OnPause()
self:SetProperty("_IsConsume", false)
end
local character = self:GetCharacter()
if character:IsWorking()
and character:GetProperty("_WorkBenchId") ~= self._Id then
return false
end
character:Produce(self._Id, self._AreaType)
self:Simulation(0)
return true
end
--- 工作台添加员工
---@param characterId number 员工id
---@return void
--------------------------
function XRestaurantWorkBench:AddStaff(characterId)
characterId = characterId or 0
self:SetProperty("_CharacterId", characterId)
end
--- 工作台添加产品
---@param productId number 产品Id
---@return void
--------------------------
function XRestaurantWorkBench:AddProduct(productId)
productId = productId or 0
self:SetProperty("_ProductId", productId)
end
--- 移除员工
---@return void
--------------------------
function XRestaurantWorkBench:DelStaff()
local characterId = self._CharacterId
self:SetProperty("_CharacterId", 0)
self:SetProperty("_Progress", 0)
self:SetProperty("_IsConsume", false)
if XTool.IsNumberValid(characterId) then
local viewModel = XDataCenter.RestaurantManager.GetViewModel()
local staff = viewModel:GetStaffViewModel(characterId)
staff:Stop()
end
self:OnFree()
end
--- 移除产品
---@return void
--------------------------
function XRestaurantWorkBench:DelProduct()
local characterId = self._CharacterId
self:SetProperty("_ProductId", 0)
self:SetProperty("_Progress", 0)
self:SetProperty("_IsConsume", false)
if XTool.IsNumberValid(characterId) then
local viewModel = XDataCenter.RestaurantManager.GetViewModel()
local staff = viewModel:GetStaffViewModel(characterId)
staff:Pause()
end
self:OnFree()
end
--- 手动停止工作
--------------------------
function XRestaurantWorkBench:Stop()
self:DelProduct()
self:DelStaff()
end
--- 产品图标
---@return string
--------------------------
function XRestaurantWorkBench:GetProductIcon()
end
--- 工作台上的产品是否已满
---@return boolean
--------------------------
function XRestaurantWorkBench:IsFull()
if not XTool.IsNumberValid(self._ProductId) then
return false
end
local product = self:GetProduct()
return product and product:IsFull() or false
end
--- 材料不足
---@return boolean
--------------------------
function XRestaurantWorkBench:IsInsufficient()
return false
end
--- 工作台是否运行
---@return boolean
--------------------------
function XRestaurantWorkBench:IsRunning()
return self:IsWorking() or self:IsPause()
end
--- 是否暂停
---@return boolean
--------------------------
function XRestaurantWorkBench:IsPause()
return self._State == XRestaurantConfigs.WorkState.Pause
end
--- 是否工作中
---@return boolean
--------------------------
function XRestaurantWorkBench:IsWorking()
return self._State == XRestaurantConfigs.WorkState.Working
end
--- 是否空闲
---@return boolean
--------------------------
function XRestaurantWorkBench:IsFree()
return not XTool.IsNumberValid(self._CharacterId) or not XTool.IsNumberValid(self._ProductId)
end
--- 员工名
---@return string
--------------------------
function XRestaurantWorkBench:GetStaffName()
if not XTool.IsNumberValid(self._CharacterId) then
return ""
end
local character = self:GetCharacter()
return character:GetName()
end
--- 产品数
---@return number
--------------------------
function XRestaurantWorkBench:GetProductCount()
if not XTool.IsNumberValid(self._ProductId) then
return ""
end
local product = self:GetProduct()
return product and product:GetProperty("_Count") or 0
end
--- 产品名
---@return
--------------------------
function XRestaurantWorkBench:GetProductName()
if not XTool.IsNumberValid(self._ProductId) then
return ""
end
local product = self:GetProduct()
return product and product:GetProperty("_Name") or "nil"
end
--- 预先扣除材料
--------------------------
function XRestaurantWorkBench:PreviewConsume(count)
if self._IsConsume then
return
end
self:SetProperty("_IsConsume", true)
end
--- 生产单个需要的时间s
---@return number
--------------------------
function XRestaurantWorkBench:GetBaseProduceSpeed()
return 0
end
--- 获取生产力
---@param timeUnit number 生产单位时间,默认为小时
---@return number
--------------------------
function XRestaurantWorkBench:GetProductiveness(timeUnit)
timeUnit = timeUnit or XRestaurantConfigs.TimeUnit.Hour
if self:IsFree() then
return 0
end
local produceNeedTime = self:GetProduceSingleTime()
if produceNeedTime == 0 then
return timeUnit
end
return XRestaurantConfigs.GetAroundValue(timeUnit / produceNeedTime, XRestaurantConfigs.Digital.One)
end
--- 消耗力
---@param productId number 产品Id
---@param timeUnit number 生产单位时间,默认为小时
---@return number
--------------------------
function XRestaurantWorkBench:GetConsumption(productId, timeUnit)
return 0
end
--- 生产单个所需时间(S)
---@return number
--------------------------
function XRestaurantWorkBench:GetProduceSingleTime()
return 0
end
--- 模拟生产
---@param workSecond number 模拟间隔
--------------------------
function XRestaurantWorkBench:Simulation(workSecond)
if not self:IsRunning() then
return
end
-- 未消耗材料
if not self._IsConsume then
--材料不足
if self:IsInsufficient() then
self:OnPause()
--设置工作时间为0
return
end
self:OnWorking()
self:PreviewConsume(1)
--消耗材料,开始模拟计时
self:SetProperty("_SimulationSecond", 0)
end
local simulationTime = self._SimulationSecond
if self._Tolerances > 0 then
simulationTime = simulationTime + self._Tolerances
self:SetProperty("_Tolerances", 0)
end
local produceNeedTime = self:GetProduceSingleTime()
local subTime = produceNeedTime - simulationTime
--正常跑到倒计时最后一秒 或者 角色升级增加模拟时间
if ((subTime >= 0 and subTime <= 1) or subTime > produceNeedTime)
and self:IsFull() then
--结算时,如果库存满了,会暂停在最后一秒
self:SetProperty("_SimulationSecond", produceNeedTime - 1)
self:UpdateCountDown(produceNeedTime)
self:OnPause()
return
else
--由暂停转为工作,这时的暂停为满的最后一秒
if self:IsPause() then
self:SetProperty("_SimulationSecond", produceNeedTime - 1)
end
self:OnWorking()
end
-- workSecond 可能的值为 01
simulationTime = simulationTime + workSecond
local count = math.floor(simulationTime / produceNeedTime)
if count > 0 then
self:EndOfRound(simulationTime - (count * produceNeedTime))
else
self:SetProperty("_SimulationSecond", simulationTime)
end
self:UpdateCountDown(produceNeedTime)
end
--- 工作进度
---@return number
--------------------------
function XRestaurantWorkBench:GetWorkProgress()
return self._Progress
end
--- 倒计时
---@return number
--------------------------
function XRestaurantWorkBench:GetCountDown()
return self._CountDown
end
--- 工作台角色
---@return XRestaurantStaff
--------------------------
function XRestaurantWorkBench:GetCharacter()
local characterId = self._CharacterId
if not XTool.IsNumberValid(characterId) then
return
end
local viewModel = XDataCenter.RestaurantManager.GetViewModel()
return viewModel:GetStaffViewModel(characterId)
end
function XRestaurantWorkBench:GetBuff()
local viewModel = XDataCenter.RestaurantManager.GetViewModel()
return viewModel:GetAreaBuff(self._AreaType)
end
--- 工作台产品
---@return XRestaurantProduct
--------------------------
function XRestaurantWorkBench:GetProduct()
local productId = self._ProductId
if not XTool.IsNumberValid(productId) then
return
end
local viewModel = XDataCenter.RestaurantManager.GetViewModel()
return viewModel:GetProduct(self._AreaType, productId)
end
--- 工作一个轮回结束
---@return boolean
--------------------------
function XRestaurantWorkBench:EndOfRound(tolerances)
self:SetProperty("_Tolerances", tolerances)
self:SetProperty("_IsConsume", false)
self:SetProperty("_UpdateTime", XTime.GetServerNowTimestamp())
self:SetProperty("_SimulationSecond", 0)
end
--- 获取加速提示与加速道具提示
---@return string, table
--------------------------
function XRestaurantWorkBench:GetAccelerateContentAndItemData(accelerateTime)
end
--- 材料不足提示
---@return string, string
--------------------------
function XRestaurantWorkBench:GetInsufficientTitleAndContent()
end
--- 库存满提示
---@return string, string
--------------------------
function XRestaurantWorkBench:GetFullTitleAndContent()
local title = XRestaurantConfigs.GetClientConfig("StorageFullTip", 3)
local content = XRestaurantConfigs.GetClientConfig("StorageFullTip", 4)
local productName = self:GetProductName()
content = XUiHelper.ReplaceTextNewLine(string.format(content, productName, productName))
return title, content
end
--- 终止工作 提示标题,提示文案
---@return string, string
--------------------------
function XRestaurantWorkBench:GetStopTipTitleAndContent()
return "", ""
end
--- 工作台优先级
---@return number
--------------------------
function XRestaurantWorkBench:GetWorkPriority()
return 0
end
--- 检查能否加速
---@return boolean
--------------------------
function XRestaurantWorkBench:CheckCanAccelerate()
local viewModel = XDataCenter.RestaurantManager.GetViewModel()
--使用达到上限
if viewModel:IsAccelerateUpperLimit() then
return false
end
--道具不够
if viewModel:GetAccelerateCount() <= 0 then
return false
end
--未工作
if not self:IsWorking() then
return false
end
--仓库满或材料不足
if self:IsFull() or self:IsInsufficient() then
return false
end
return true
end
function XRestaurantWorkBench:ToString()
return XRestaurantConfigs.GetCameraAuxiliaryAreaName(self._AreaType) .. ", Index:" ..self._Id
end
function XRestaurantWorkBench:ChangeStateAndMarkSort(state)
self:SetProperty("_State", state)
local viewModel = XDataCenter.RestaurantManager.GetViewModel()
viewModel:MarkNewSort(self._AreaType)
end
--- 当前工作台是否拥有Buff
---@return boolean
--------------------------
function XRestaurantWorkBench:CheckHasBuff()
local viewModel = XDataCenter.RestaurantManager.GetViewModel()
local buff = viewModel:GetAreaBuff(self._AreaType)
if not buff then
return false
end
return buff:CheckBenchEffect(self._AreaType, self._CharacterId, self._ProductId)
end
function XRestaurantWorkBench:GetAddition()
if self:IsFree() then
return 0
end
local character = self:GetCharacter()
--技能加成
local addition = character:GetSkillAddition(self._AreaType, self._ProductId)
return addition + self:GetBuffAddition()
end
--- 获取buff加成仅用于区域Buff
---@return number
--------------------------
function XRestaurantWorkBench:GetBuffAddition()
if self:IsFree() then
return 0
end
local buff = self:GetBuff()
if not buff then
return 0
end
return buff:GetEffectAddition(self._AreaType, self._CharacterId, self._ProductId)
end
return XRestaurantWorkBench