自动化烹饪流程

This commit is contained in:
2025-08-07 00:15:18 +08:00
parent 44fc2371be
commit b09eeeef18
30 changed files with 269 additions and 42 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,99 @@
local CookManager = {}
local Utils = require("GamePlay.Utils")
local Emitter = require("Utils.Emitter")
local ECookingHeat = import("ECookingHeat")
--- @enum ECookCheckStatus
local ECookCheckStatus = {
Normal = 0, -- 不用做任何操作
NextState = 1, -- 可以进入下一个阶段
OverCook = 2, -- 炸锅了,结束游戏
Error = 3, -- 出现了错误
}
local function TemperatureToDoneness(temperature)
return math.floor(temperature / 70)
end
function CookManager:Reset()
self.temperature_thresholds = {} -- 温度临界值,缓存表格内容
self.heating_record_table = {} -- 食材受热记录表
end
function CookManager:Tick(temperature, delta_time)
local need_remove_record = {} -- 记录已经到火候,或其他原因,需要移除的食材
-- 遍历,为所有的食材加热
for cook_material_id, record_table in pairs(self.heating_record_table) do
local doneness = TemperatureToDoneness(temperature) -- 获取此时的火候
local record_value = record_table[doneness] or 0
record_table[doneness] = record_value + (delta_time * 1000)
local check_status = self:CheckHeatingStatus(cook_material_id)
if check_status == ECookCheckStatus.NextState then
local next_cook_material = self:GetCookMaterialNextState(cook_material_id, doneness)
if next_cook_material == "None" then -- 炸锅了
-- TODO 抛出事件
self:Reset()
return
end
self:AddCookMaterial(next_cook_material, true)
need_remove_record[cook_material_id] = true
end
print(cook_material_id, doneness, record_table[doneness])
end
-- 移除已经加热到下一阶段的食材
for cook_material_id, need_remove in pairs(need_remove_record) do
if need_remove then
self.heating_record_table[cook_material_id] = nil
end
end
end
function CookManager:GetCookMaterialNextState(cook_material_id, doneness)
local threshold = self.temperature_thresholds[cook_material_id]
print(threshold, "here ---------------")
if not threshold then return "None" end
local state_config = threshold.CookConfig:Get(doneness)
if not state_config then return "None" end
return state_config.NextStateID
end
function CookManager:CheckHeatingStatus(cook_material_id)
local threshold = self.temperature_thresholds[cook_material_id]
local record_state = self.heating_record_table[cook_material_id]
if not threshold or not record_state then return ECookCheckStatus.Error end
local state_configs = threshold.CookConfig
for doneness, cook_time in pairs(record_state) do
local config = state_configs:Get(doneness)
if config and cook_time >= config.CookingDuration then
return ECookCheckStatus.NextState
end
end
return ECookCheckStatus.Normal
end
function CookManager:CheckFinishStatus()
-- 检测当前菜品是否完成
end
function CookManager:AddCookMaterial(cook_material_id, is_auto_push)
local config = Utils.GetDataTableConfig(
"CookMaterialStateConfig", cook_material_id
)
if not config then
print("ERROR: can't find ", cook_material_id, " in CookMaterialStateConfig")
return
end
self.heating_record_table[cook_material_id] = {}
self.temperature_thresholds[cook_material_id] = config
print("call", cook_material_id, is_auto_push)
Emitter.EmitEvent("cook_material_change", cook_material_id, is_auto_push)
end
return CookManager

View File

@ -21,13 +21,20 @@ end
function _M.GetItemDescConfig(item_id)
return GetConfig("GetLevelItemDescription", item_id)
end
function _M.GetHomelandItemDesc(item_id)
return GetConfig("GetHomelandItemDescription", item_id)
end
function _M.GetRoleConfigByID(role_id)
return GetConfig("GetRoleConfig", role_id)
end
function _M.GetDataTableConfig(table_name, row_id)
return GetConfig("Get" .. table_name, row_id)
end
function _M.GetGameplayTag(name)
local tag = GameplayTag(name)
tag.TagName = name

View File

@ -1,11 +1,31 @@
local CookingBench = {}
local Utils = require("GamePlay.Utils")
local Emitter = require("Utils.Emitter")
local CookManager = require("GamePlay.CookSystem.CookManager")
local KismetSystemLibrary = import("KismetSystemLibrary")
local ESlateVisibility = import("ESlateVisibility")
--- 获取每次tick温度下降速度
local function GetCoolingRate(wco)
return 0.5
end
--- 获取每次点火的效率
local function GetHeatingEfficiency(wco)
return 8
end
local function GetMaxTemperature(wco)
return 210
end
function CookingBench:ctor()
self.is_cooking = false
self.temperature = 0
self.max_temperature = 200
self.burn_timer = nil
end
@ -14,6 +34,7 @@ function CookingBench:OnInitialized()
end
function CookingBench:Construct()
CookManager:Reset()
self:UpdateCookState()
self:UpdateFireState()
end
@ -27,36 +48,44 @@ end
function CookingBench:OnRabbitClicked()
if self.is_cooking then
local new_value = self.temperature + 8
if new_value > self.max_temperature then
self.temperature = self.max_temperature
local max = GetMaxTemperature(self)
local once = GetHeatingEfficiency(self)
local new_value = self.temperature + once
if new_value > max then
self.temperature = max
else
self.temperature = new_value
end
else
self.is_cooking = true
self.temperature = 100
self.temperature = 50
self.burn_timer = KismetSystemLibrary.K2_SetTimerDelegate(
slua.createDelegate(function()
local new_value = self.temperature - 1
if new_value > 0 then
self.temperature = new_value
else
self.temperature = 0
self.is_cooking = false
KismetSystemLibrary.K2_ClearTimerHandle(self, self.burn_timer)
self.burn_timer = nil
end
self:UpdateCookState()
self:UpdateFireState()
end),
0.1, true, true, 0, 0
slua.createDelegate(function() self:CookTick() end),
1 / 30, true, true, 0, 0
)
end
self:UpdateCookState()
self:UpdateFireState()
end
--- 每秒30次tick
function CookingBench:CookTick()
local drop_value = GetCoolingRate(self)
local new_value = self.temperature - drop_value
if new_value > 0 then
self.temperature = new_value
CookManager:Tick(self.temperature, 1 / 30)
else
self.temperature = 0
self.is_cooking = false
KismetSystemLibrary.K2_ClearTimerHandle(self, self.burn_timer)
self.burn_timer = nil
end
self:UpdateCookState()
self:UpdateFireState()
end
function CookingBench:UpdateCookState()
if self.temperature > 0 then
self.WBP_CookingProcess:SetVisible(true)

View File

@ -1,26 +1,43 @@
-- 锅的控件
local CookingPot = {}
local Utils = require("GamePlay.Utils")
local Emitter = require("Utils.Emitter")
local ESlateVisibility = import("ESlateVisibility")
function CookingPot:ctor()
self.cook_slot_clicked_handle = nil
self.cook_material_change_handle = nil
end
function CookingPot:Construct()
self.cook_slot_clicked_handle = Emitter.OnEvent(
"cook_slot_clicked",
function(slot) self:OnCookSlotClicked(slot) end
self.MaterialImg:SetVisibility(ESlateVisibility.Collapsed)
self.cook_material_change_handle = Emitter.OnEvent(
"cook_material_change",
function(cook_material_id, is_auto_push) self:OnCookMaterialChange(cook_material_id, is_auto_push) end
)
end
function CookingPot:Destruct()
Emitter.OffEvent("cook_slot_clicked", self.cook_slot_clicked_handle)
Emitter.OffEvent("cook_material_change", self.cook_material_change_handle)
end
function CookingPot:OnCookSlotClicked(slot)
local item = slot:ConsumeMaterial()
if item == nil then end
function CookingPot:OnCookMaterialChange(cook_material_id, is_auto_push)
print(cook_material_id, is_auto_push)
local config = Utils.GetHomelandItemDesc(cook_material_id)
if config == nil then return end
self.MaterialImg:SetVisibility(ESlateVisibility.SelfHitTestInvisible)
self.MaterialImg:SetBrushFromSoftTexture(config.DisplayResource, true)
if not is_auto_push then
self:PlayAnimation(self.Anim_Cook, 0, 1, 0, 1, false)
end
end
function CookingPot:OnCookSlotClicked(config)
if config == nil then return end
self.MaterialImg:SetVisibility(ESlateVisibility.SelfHitTestInvisible)
self.MaterialImg:SetBrushFromSoftTexture(config.DisplayResource, true)
self:PlayAnimation(self.Anim_Cook, 0, 1, 0, 1, false)
end

View File

@ -1,22 +1,21 @@
local CookingSlot = {}
local Emitter = require("Utils.Emitter")
local CookManager = require("GamePlay.CookSystem.CookManager")
local Utils = require("GamePlay.Utils")
local ESlateVisibility = import("ESlateVisibility")
function CookingSlot:ctor()
self.cook_item = nil
self.material = "500001"
end
function CookingSlot:OnInitialized()
self.MainBtn.OnClicked:Add(function()
Emitter.EmitEvent("cook_slot_clicked", self)
CookManager:AddCookMaterial(self.material)
self:ConsumeMaterial()
end)
self:SetCookMaterial("400009")
end
function CookingSlot:SetCookMaterial(cook_item)
self.cook_item = cook_item
function CookingSlot:SetCookMaterial(material)
self.material = material
self:RefreshDisplay()
end
@ -26,14 +25,16 @@ end
function CookingSlot:RefreshDisplay()
self:SetEmpty()
if self.cook_item then
self.CookingMaterialImg:SetVisibility(ESlateVisibility.SelfHitTestInvisible)
end
if not self.material then return end
local config = Utils.GetHomelandItemDesc(self.material)
if config == nil then return end
self.CookingMaterialImg:SetBrushFromSoftTexture(config.DisplayResource, true)
self.CookingMaterialImg:SetVisibility(ESlateVisibility.SelfHitTestInvisible)
end
function CookingSlot:ConsumeMaterial()
-- if self.cook_item == nil then return end
local item = self.cook_item
if self.material == nil then return end
local item = self.material
self:SetCookMaterial(nil)
return item
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -70,3 +70,15 @@ bool UBusyGamePlayLibrary::GetItemResourceConfig(const FName& RowName, FBusyLeve
bool UBusyGamePlayLibrary::GetLevelItemDescription(const FName& RowName, FBusyLevelItemDescription& RowData){
return GetTableConfig<FBusyLevelItemDescription>(TEXT("LevelItemDesc"), RowName, RowData);
}
bool UBusyGamePlayLibrary::GetHomelandItemDescription(const FName& RowName, FBusyHomelandItemDescription& RowData){
return GetTableConfig<FBusyHomelandItemDescription>(TEXT("HomelandItemDesc"), RowName, RowData);
}
bool UBusyGamePlayLibrary::GetItemDescription(const FName& RowName, FBusyItemDescription& RowData){
return GetTableConfig<FBusyItemDescription>(TEXT("ItemDesc"), RowName, RowData);
}
bool UBusyGamePlayLibrary::GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData){
return GetTableConfig<FBusyCookMaterialStateConfig>(TEXT("CookMaterialStateConfig"), RowName, RowData);
}

View File

@ -48,4 +48,13 @@ public:
UFUNCTION(BlueprintPure)
static bool GetLevelItemDescription(const FName& RowName, FBusyLevelItemDescription& RowData);
UFUNCTION(BlueprintPure)
static bool GetHomelandItemDescription(const FName& RowName, FBusyHomelandItemDescription& RowData);
UFUNCTION(BlueprintPure)
static bool GetItemDescription(const FName& RowName, FBusyItemDescription& RowData);
UFUNCTION(BlueprintPure)
static bool GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData);
};

View File

@ -2,6 +2,13 @@
#include "CoreMinimal.h"
#include "BusyItem.generated.h"
UENUM(BlueprintType) // 烹饪火候
enum class ECookingHeat : uint8 {
LOW_HEAT, // 小火
MEDIUM_HEAT, // 中火
HIGH_HEAT // 大火
};
USTRUCT(BlueprintType)
struct FBusyLevelCollectionDropRate {
@ -39,10 +46,17 @@ struct FBusyLevelItemConfig : public FTableRowBase {
TArray<FBusyLevelCollectionDropConfig> DropConfigs;
};
USTRUCT()
struct FBusyItemDescription : public FTableRowBase { // 物品描述信息
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "道具名称")
FText Name;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "道具描述")
FText Description;
};
USTRUCT()
struct FBusyLevelItemDescription : public FTableRowBase { // 物品描述表头
struct FBusyLevelItemDescription : public FTableRowBase { // 关卡内物品描述信息
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "道具名称")
@ -61,4 +75,43 @@ struct FBusyLevelItemDescription : public FTableRowBase { // 物品描述表头
FGameplayTagContainer ItemTags;
};
USTRUCT()
struct FBusyHomelandItemDescription : public FTableRowBase { // 家园物品描述信息
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "备注")
FString Description;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "物品UI图标资源")
TSoftObjectPtr<UObject> DisplayResource;
};
USTRUCT()
struct FBusyCookMaterialStateChangeConfig : public FTableRowBase {
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "备注")
FString Description;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "下一个状态ID")
FName NextStateID;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "用于渐变的资源")
TSoftObjectPtr<UObject> TransformMask;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "烹饪时长: Ms")
float CookingDuration;
};
USTRUCT()
struct FBusyCookMaterialStateConfig : public FTableRowBase {
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "状态备注")
FString Description;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "用于显示的资源")
TSoftObjectPtr<UObject> DisplayResource;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "烹饪配置")
TMap<ECookingHeat, FBusyCookMaterialStateChangeConfig> CookConfig;
};