自动化烹饪流程

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) function _M.GetItemDescConfig(item_id)
return GetConfig("GetLevelItemDescription", item_id) return GetConfig("GetLevelItemDescription", item_id)
end
function _M.GetHomelandItemDesc(item_id)
return GetConfig("GetHomelandItemDescription", item_id)
end end
function _M.GetRoleConfigByID(role_id) function _M.GetRoleConfigByID(role_id)
return GetConfig("GetRoleConfig", role_id) return GetConfig("GetRoleConfig", role_id)
end end
function _M.GetDataTableConfig(table_name, row_id)
return GetConfig("Get" .. table_name, row_id)
end
function _M.GetGameplayTag(name) function _M.GetGameplayTag(name)
local tag = GameplayTag(name) local tag = GameplayTag(name)
tag.TagName = name tag.TagName = name

View File

@ -1,11 +1,31 @@
local CookingBench = {} local CookingBench = {}
local Utils = require("GamePlay.Utils")
local Emitter = require("Utils.Emitter")
local CookManager = require("GamePlay.CookSystem.CookManager")
local KismetSystemLibrary = import("KismetSystemLibrary") local KismetSystemLibrary = import("KismetSystemLibrary")
local ESlateVisibility = import("ESlateVisibility") 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() function CookingBench:ctor()
self.is_cooking = false self.is_cooking = false
self.temperature = 0 self.temperature = 0
self.max_temperature = 200 self.max_temperature = 200
self.burn_timer = nil self.burn_timer = nil
end end
@ -14,6 +34,7 @@ function CookingBench:OnInitialized()
end end
function CookingBench:Construct() function CookingBench:Construct()
CookManager:Reset()
self:UpdateCookState() self:UpdateCookState()
self:UpdateFireState() self:UpdateFireState()
end end
@ -27,20 +48,34 @@ end
function CookingBench:OnRabbitClicked() function CookingBench:OnRabbitClicked()
if self.is_cooking then if self.is_cooking then
local new_value = self.temperature + 8 local max = GetMaxTemperature(self)
if new_value > self.max_temperature then local once = GetHeatingEfficiency(self)
self.temperature = self.max_temperature local new_value = self.temperature + once
if new_value > max then
self.temperature = max
else else
self.temperature = new_value self.temperature = new_value
end end
else else
self.is_cooking = true self.is_cooking = true
self.temperature = 100 self.temperature = 50
self.burn_timer = KismetSystemLibrary.K2_SetTimerDelegate( self.burn_timer = KismetSystemLibrary.K2_SetTimerDelegate(
slua.createDelegate(function() slua.createDelegate(function() self:CookTick() end),
local new_value = self.temperature - 1 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 if new_value > 0 then
self.temperature = new_value self.temperature = new_value
CookManager:Tick(self.temperature, 1 / 30)
else else
self.temperature = 0 self.temperature = 0
self.is_cooking = false self.is_cooking = false
@ -49,12 +84,6 @@ function CookingBench:OnRabbitClicked()
end end
self:UpdateCookState() self:UpdateCookState()
self:UpdateFireState() self:UpdateFireState()
end),
0.1, true, true, 0, 0
)
end
self:UpdateCookState()
self:UpdateFireState()
end end
function CookingBench:UpdateCookState() function CookingBench:UpdateCookState()

View File

@ -1,26 +1,43 @@
-- 锅的控件 -- 锅的控件
local CookingPot = {} local CookingPot = {}
local Utils = require("GamePlay.Utils")
local Emitter = require("Utils.Emitter") local Emitter = require("Utils.Emitter")
local ESlateVisibility = import("ESlateVisibility")
function CookingPot:ctor() function CookingPot:ctor()
self.cook_slot_clicked_handle = nil self.cook_material_change_handle = nil
end end
function CookingPot:Construct() function CookingPot:Construct()
self.cook_slot_clicked_handle = Emitter.OnEvent( self.MaterialImg:SetVisibility(ESlateVisibility.Collapsed)
"cook_slot_clicked", self.cook_material_change_handle = Emitter.OnEvent(
function(slot) self:OnCookSlotClicked(slot) end "cook_material_change",
function(cook_material_id, is_auto_push) self:OnCookMaterialChange(cook_material_id, is_auto_push) end
) )
end end
function CookingPot:Destruct() function CookingPot:Destruct()
Emitter.OffEvent("cook_slot_clicked", self.cook_slot_clicked_handle) Emitter.OffEvent("cook_material_change", self.cook_material_change_handle)
end end
function CookingPot:OnCookSlotClicked(slot)
local item = slot:ConsumeMaterial() function CookingPot:OnCookMaterialChange(cook_material_id, is_auto_push)
if item == nil then end 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) self:PlayAnimation(self.Anim_Cook, 0, 1, 0, 1, false)
end end

View File

@ -1,22 +1,21 @@
local CookingSlot = {} local CookingSlot = {}
local Emitter = require("Utils.Emitter") local CookManager = require("GamePlay.CookSystem.CookManager")
local Utils = require("GamePlay.Utils")
local ESlateVisibility = import("ESlateVisibility") local ESlateVisibility = import("ESlateVisibility")
function CookingSlot:ctor() function CookingSlot:ctor()
self.cook_item = nil self.material = "500001"
end end
function CookingSlot:OnInitialized() function CookingSlot:OnInitialized()
self.MainBtn.OnClicked:Add(function() self.MainBtn.OnClicked:Add(function()
Emitter.EmitEvent("cook_slot_clicked", self) CookManager:AddCookMaterial(self.material)
self:ConsumeMaterial()
end) end)
self:SetCookMaterial("400009")
end end
function CookingSlot:SetCookMaterial(cook_item) function CookingSlot:SetCookMaterial(material)
self.cook_item = cook_item self.material = material
self:RefreshDisplay() self:RefreshDisplay()
end end
@ -26,14 +25,16 @@ end
function CookingSlot:RefreshDisplay() function CookingSlot:RefreshDisplay()
self:SetEmpty() self:SetEmpty()
if self.cook_item then 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) self.CookingMaterialImg:SetVisibility(ESlateVisibility.SelfHitTestInvisible)
end end
end
function CookingSlot:ConsumeMaterial() function CookingSlot:ConsumeMaterial()
-- if self.cook_item == nil then return end if self.material == nil then return end
local item = self.cook_item local item = self.material
self:SetCookMaterial(nil) self:SetCookMaterial(nil)
return item return item
end 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){ bool UBusyGamePlayLibrary::GetLevelItemDescription(const FName& RowName, FBusyLevelItemDescription& RowData){
return GetTableConfig<FBusyLevelItemDescription>(TEXT("LevelItemDesc"), RowName, 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) UFUNCTION(BlueprintPure)
static bool GetLevelItemDescription(const FName& RowName, FBusyLevelItemDescription& RowData); 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 "CoreMinimal.h"
#include "BusyItem.generated.h" #include "BusyItem.generated.h"
UENUM(BlueprintType) // 烹饪火候
enum class ECookingHeat : uint8 {
LOW_HEAT, // 小火
MEDIUM_HEAT, // 中火
HIGH_HEAT // 大火
};
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct FBusyLevelCollectionDropRate { struct FBusyLevelCollectionDropRate {
@ -39,10 +46,17 @@ struct FBusyLevelItemConfig : public FTableRowBase {
TArray<FBusyLevelCollectionDropConfig> DropConfigs; TArray<FBusyLevelCollectionDropConfig> DropConfigs;
}; };
USTRUCT()
struct FBusyItemDescription : public FTableRowBase { // 物品描述信息
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "道具名称")
FText Name;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "道具描述")
FText Description;
};
USTRUCT() USTRUCT()
struct FBusyLevelItemDescription : public FTableRowBase { // 物品描述表头 struct FBusyLevelItemDescription : public FTableRowBase { // 关卡内物品描述信息
GENERATED_BODY() GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "道具名称") UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "道具名称")
@ -61,4 +75,43 @@ struct FBusyLevelItemDescription : public FTableRowBase { // 物品描述表头
FGameplayTagContainer ItemTags; 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;
};