Compare commits

...

2 Commits

Author SHA1 Message Date
bda98b0cce 补充上一条
...
2025-08-19 03:24:22 +08:00
626808fde9 准备制作食材预处理流程,为lua直接读data table做基建
...
2025-08-19 03:23:36 +08:00
32 changed files with 406 additions and 87 deletions

Binary file not shown.

Binary file not shown.

View File

@ -81,9 +81,13 @@ function CookManager:CheckFinishStatus()
end
function CookManager:AddCookMaterial(cook_material_id, is_auto_push)
local BusyGamePlayLibrary = import("BusyGamePlayLibrary")
local config = Utils.GetDataTableConfig(
"CookMaterialStateConfig", cook_material_id
)
BusyGamePlayLibrary.SetTest(config)
print("?>????", config)
if not config then
print("ERROR: can't find ", cook_material_id, " in CookMaterialStateConfig")
return

View File

@ -1,14 +1,39 @@
local WidgetUtils = require("Utils.UI.WidgetUtils")
local Emitter = require("Utils.Emitter")
local HearthMain = {}
function HearthMain:ctor()
self.switch_to_prep_cook_station_handle = nil
end
function HearthMain:OnInitialized()
self.BtnBack.OnClicked:Add(function()
WidgetUtils.Hide(self, "HearthMain")
end)
self.BtnOpenRecipe.OnClicked:Add(function()
WidgetUtils.Show(self, "RecipeMenu")
self:BP_Close()
end)
end
function HearthMain:Construct()
self.switch_to_prep_cook_station_handle = Emitter.OnEvent(
"switch_to_prep_station", function() self:SwitchToPrepCookStation() end
)
end
function HearthMain:Destruct()
Emitter.OffEvent("switch_to_prep_station", self.switch_to_prep_cook_station_handle)
end
function HearthMain:SwitchToPrepCookStation()
if self:IsAnimationPlaying(self.Anim_StartPrepCook) then
return
end
self:PlayAnimation(self.Anim_StartPrepCook, 0, 1, 0, 1, false)
end
function HearthMain:OnAnimationFinished(anim)
if anim == self.Anim_StartPrepCook then
WidgetUtils.Show(self, "PreCookStation")
print("HearthMain:OnAnimationFinished")
end
end
return Class(nil, nil, HearthMain)

View File

@ -0,0 +1,40 @@
local PreCookStationPanel = {}
local PRE_COOK_TOOL_CNT = 3
function PreCookStationPanel:ctor()
self.cook_tool_slots = {}
end
function PreCookStationPanel:OnInitialized()
self.BackBtn.OnClicked:Add(function() self:BP_Close() end)
self.cook_tool_slots = {}
for i = 1, PRE_COOK_TOOL_CNT do
local slot_name = "PreCookToolSlot_" .. tostring(i)
table.insert(self.cook_tool_slots, self[slot_name])
end
end
function PreCookStationPanel:Construct()
self:Refresh()
end
function PreCookStationPanel:Destruct()
end
function PreCookStationPanel:Refresh()
self:RefreshPreCookTools()
end
function PreCookStationPanel:RefreshPreCookTools()
local display_tools = {"PCT0001"}
for i = 1, PRE_COOK_TOOL_CNT do
self.cook_tool_slots[i]:SetPreCookToolID(display_tools[i])
end
end
return Class(nil, nil, PreCookStationPanel)

View File

@ -0,0 +1,11 @@
local CookPrepStationEntry = {}
local Emitter = require("Utils.Emitter")
function CookPrepStationEntry:OnInitialized()
self.MainBtn.OnClicked:Add(function()
Emitter.EmitEvent("switch_to_prep_station")
end)
end
return Class(nil, nil, CookPrepStationEntry)

View File

@ -88,11 +88,11 @@ end
function CookingBench:UpdateCookState()
if self.temperature > 0 then
self.WBP_CookingProcess:SetVisible(true)
self.WBP_CookingProcess:BP_SetVisible(true)
local percent = self.temperature / self.max_temperature
self.WBP_CookingProcess.TemperatureProcess:SetPercent(percent)
else
self.WBP_CookingProcess:SetVisible(false)
self.WBP_CookingProcess:BP_SetVisible(false)
end
end

View File

@ -0,0 +1,35 @@
local DataTableUtils = require("Utils.DataTableUtils")
local PreCookSlot = {}
function PreCookSlot:OnInitialized()
end
function PreCookSlot:Construct()
end
function PreCookSlot:Destruct()
end
function PreCookSlot:Reset()
end
function PreCookSlot:SetPreCookToolID(pre_cook_tool_id)
self:Reset()
if not pre_cook_tool_id then return end
local row_data = DataTableUtils.GetDataTableRow("PreCookItemConfig", pre_cook_tool_id)
if not row_data then
return
end
self.SlotImg:SetBrushFromSoftTexture(row_data.DisplayResource, true)
print("PreCookSlot:SetPreCookToolID", row_data)
end
return Class(nil, nil, PreCookSlot)

View File

@ -1,7 +1,7 @@
local HomeLandHud = {}
function HomeLandHud:ReceiveBeginPlay()
self:ShowWidget("HomeLandMain")
self:BP_PushWidget("HomeLandMain")
end
return Class(nil, nil, HomeLandHud)

View File

@ -0,0 +1,39 @@
local DataTableUtils = {}
local BusyGamePlayLibrary = import("BusyGamePlayLibrary")
function DataTableUtils.GetDataTable(table_name)
return BusyGamePlayLibrary.GetGameDataTable(table_name)
end
function DataTableUtils.GetDataTableRow(table_name, row_name)
local data_table = DataTableUtils.GetDataTable(table_name)
if not data_table then
return nil
end
return data_table:FindRow(row_name)
end
--[[
LuaExtensionMethod.cpp:22-28
// 封装函数示例
static int FindRowWrapper(lua_State* L) {
UDataTable* dataTable = LuaObject::checkUD<UDataTable>(L, 1);
FName rowName = LuaObject::checkValue<FName>(L, 2);
UScriptStruct* rowStruct = LuaObject::checkUD<UScriptStruct>(L, 3);
// 使用反射调用 FindRow
uint8* rowData = dataTable->FindRowUnchecked(rowName);
if (rowData && rowStruct) {
// 将结果推送到 Lua
return LuaObject::pushStruct(L, rowStruct, rowData);
}
return LuaObject::pushNil(L);
}
这段代码中pushStruct只接受两个参数如何改
]]
return DataTableUtils

View File

@ -10,10 +10,10 @@ end
function WidgetUtils.Show(wco, widget_name)
local hud = GetHud(wco)
if not hud then return end
return hud:ShowWidget(widget_name)
return hud:BP_PushWidget(widget_name)
end
function WidgetUtils.Hide(wco, widget_name)
function WidgetUtils.Close(wco, widget_name)
local hud = GetHud(wco)
if not hud then return end
return hud:PopWidget(widget_name)

View File

@ -7,6 +7,9 @@
#include "LuaCppBinding.h"
#include "GameplayTagsManager.h"
extern void RegisterDataTableExtension();
static uint8* ReadFile(IPlatformFile& PlatformFile, FString path, uint32& len) {
IFileHandle* FileHandle = PlatformFile.OpenRead(*path);
if (FileHandle) {
@ -94,6 +97,8 @@ void UBusyGameInstance::LuaStateInitCallback(NS_SLUA::lua_State* L) {
LuaGameInstance = state->doFile("GameInstance");
LuaGameInstance.getFromTable("OnEndFrame", OnLuaEndFrame);
// ע<><D7A2>extension
RegisterDataTableExtension();
}
void UBusyGameInstance::OnEndFrame(){

View File

@ -82,3 +82,10 @@ bool UBusyGamePlayLibrary::GetItemDescription(const FName& RowName, FBusyItemDes
bool UBusyGamePlayLibrary::GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData){
return GetTableConfig<FBusyCookMaterialStateConfig>(TEXT("CookMaterialStateConfig"), RowName, RowData);
}
FLuaBPVar UBusyGamePlayLibrary::TestTable(const FName& RowName){
UDataTable* Table = UBusyGamePlayLibrary::GetGameDataTable("CookMaterialStateConfig");
auto Config = Table->FindRow<FTableRowBase>(RowName, "", true);
return FLuaBPVar();
}

View File

@ -2,8 +2,10 @@
#include "Core/PW_UserWidget.h"
#include "Core/UI/PW_UIHud.h"
UPW_SimpleWidget::UPW_SimpleWidget():bVisible(true){
bVisible = true;
SetVisibility(ESlateVisibility::SelfHitTestInvisible);
}
@ -11,9 +13,9 @@ bool UPW_SimpleWidget::Initialize(){
return UUserWidget::Initialize();
}
void UPW_SimpleWidget::SetVisible(bool Visible){
if (bVisible == Visible) { return; }
if ((bVisible = Visible)) {
void UPW_SimpleWidget::SetVisible(bool InVisible){
if (bVisible == InVisible) { return; }
if ((bVisible = InVisible)) {
SetVisibility(ESlateVisibility::SelfHitTestInvisible);
}
else {
@ -21,4 +23,32 @@ void UPW_SimpleWidget::SetVisible(bool Visible){
}
}
void UPW_SimpleWidget::BP_SetVisible(bool InVisible){
SetVisible(InVisible);
}
void UPW_UserWidget::BP_Close(){
APW_UIHud* Hud = Cast<APW_UIHud>(GetPlayerContext().GetHUD());
if (!Hud) return;
Hud->PopWidget(this);
}
void UPW_UserWidget::SetVisible(bool InVisible){
bVisible = InVisible;
_RefreshVisible();
}
void UPW_UserWidget::FrameWorkSetVisible(bool InVisible){
bFrameWorkVisible = InVisible;
_RefreshVisible();
}
void UPW_UserWidget::_RefreshVisible(){
bool FinalVisible = bFrameWorkVisible && bVisible;
if (FinalVisible) {
SetVisibility(ESlateVisibility::SelfHitTestInvisible);
}
else {
SetVisibility(ESlateVisibility::Collapsed);
}
}

View File

@ -27,7 +27,7 @@ UPW_UserWidget* APW_UIHud::PushWidget(const FName& WidgetName) {
return nullptr;
}
if (UILayer->PushWidget(WidgetName, Inst)) {
if (UILayer->PushWidget(Inst)) {
return Inst;
}
else {
@ -35,28 +35,15 @@ UPW_UserWidget* APW_UIHud::PushWidget(const FName& WidgetName) {
}
}
bool APW_UIHud::PopWidget(const FName& WidgetName){
if (UILayer == nullptr) {
return false;
UPW_UserWidget* APW_UIHud::PushWidget(UPW_UserWidget* WidgetInst){
if (UILayer && WidgetInst) {
return UILayer->PushWidget(WidgetInst) ? WidgetInst : nullptr;
}
return UILayer->PopWidget(WidgetName);
return nullptr;
}
UPW_UserWidget* APW_UIHud::ShowWidget(const FName& WidgetName){
UPW_UserWidget* Widget;
if (!UILayer) {
return nullptr;
void APW_UIHud::PopWidget(const UPW_UserWidget* WidgetInst){
if (UILayer) {
UILayer->PopWidget(WidgetInst);
}
if ((Widget = UILayer->ShowWidget(WidgetName))) {
return Widget;
}
return PushWidget(WidgetName);
}
bool APW_UIHud::HideWidget(const FName& WidgetName){
if (UILayer == nullptr) {
return false;
}
return UILayer->PopWidget(WidgetName);
}

View File

@ -7,51 +7,82 @@
#include "Components/OverlaySlot.h"
bool UPW_UILayer::PushWidget(UPW_UserWidget* WidgetInst){
UOverlay* Overlay;
UOverlaySlot* OverlaySlot;
UPW_UserWidget* UPW_UILayer::ShowWidget(const FName& WidgetName){
UPW_UserWidget **result = WidgetPool.Find(WidgetName);
if (result == nullptr) {
return nullptr;
}
UPW_UserWidget* Widget = *result;
if (Widget == nullptr) {
return nullptr;
}
Widget->SetVisible(true);
return Widget;
}
Overlay = _GetOverlayByLayerType(WidgetInst->LayoutType);
if (!Overlay) return false;
bool UPW_UILayer::HideWidget(const FName& WidgetName){
UPW_UserWidget* Widget = *WidgetPool.Find(WidgetName);
if (Widget == nullptr) {
return false;
Overlay->AddChild(WidgetInst);
OverlaySlot = Cast<UOverlaySlot>(WidgetInst->Slot);
if (!OverlaySlot) return false;
OverlaySlot->SetVerticalAlignment(EVerticalAlignment::VAlign_Fill);
OverlaySlot->SetHorizontalAlignment(EHorizontalAlignment::HAlign_Fill);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD>push<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>widget
auto AllOverlayChildren = Overlay->GetAllChildren();
for (int i = 0; i < AllOverlayChildren.Num() - 1; ++i) {
UPW_UserWidget* Child = Cast<UPW_UserWidget>(AllOverlayChildren[i]);
if (!Child) continue;
Child->FrameWorkSetVisible(false);
}
Widget->SetVisible(false);
WidgetInst->FrameWorkSetVisible(true);
return true;
}
bool UPW_UILayer::PushWidget(const FName& WidgetName, UPW_UserWidget* WidgetInst){
void UPW_UILayer::PopWidget(const UPW_UserWidget* WidgetInst){
UOverlay* Overlay;
UOverlaySlot* OverlaySlot;
switch (WidgetInst->LayoutType) {
case EWidgetLayoutType::MainLayer: Overlay = MainLayer; break;
case EWidgetLayoutType::PopupLayer: Overlay = PopupLayer; break;
case EWidgetLayoutType::FloatLayer: Overlay = FloatLayer; break;
case EWidgetLayoutType::TopLayer: Overlay = TopLayer; break;
default: return false;
bool bNeedRemove;
int32 i, OverlayWidgetCount;
UPW_UserWidget* Child, * NeedShowWidget;
TArray<UWidget*> AllOverlayChildren;
TArray<UPW_UserWidget*> NeedRemoveWidgets;
bNeedRemove = true;
NeedShowWidget = nullptr;
Overlay = _GetOverlayByLayerType(WidgetInst->LayoutType);
if (!Overlay) return;
AllOverlayChildren = Overlay->GetAllChildren();
OverlayWidgetCount = AllOverlayChildren.Num();
for (i = OverlayWidgetCount - 1; i >= 0; --i) {
Child = Cast<UPW_UserWidget>(AllOverlayChildren[i]);
if (!Child) continue;
if(bNeedRemove){
NeedRemoveWidgets.Add(Child);
}
else if(Child->bVisible) {
NeedShowWidget = Child;
break;
}
if (Child == WidgetInst) {
bNeedRemove = false;
}
}
Overlay->AddChild(WidgetInst);
if ((OverlaySlot = Cast<UOverlaySlot>(WidgetInst->Slot))) {
OverlaySlot->SetVerticalAlignment(EVerticalAlignment::VAlign_Fill);
OverlaySlot->SetHorizontalAlignment(EHorizontalAlignment::HAlign_Fill);
WidgetInst->SetVisible(true);
WidgetPool.Add(WidgetName, WidgetInst);
return true;
} else {
return false;
for (i = 0; i < NeedRemoveWidgets.Num(); ++i) {
NeedRemoveWidgets[i]->RemoveFromParent();
}
if (NeedShowWidget) {
NeedShowWidget->FrameWorkSetVisible(true);
}
}
bool UPW_UILayer::PopWidget(const FName& WidgetName){
return HideWidget(WidgetName);
UOverlay* UPW_UILayer::_GetOverlayByLayerType(EWidgetLayoutType InLayoutType){
switch (LayoutType) {
case EWidgetLayoutType::MainLayer:
return MainLayer;
case EWidgetLayoutType::PopupLayer:
return PopupLayer;
case EWidgetLayoutType::FloatLayer:
return FloatLayer;
case EWidgetLayoutType::TopLayer:
return TopLayer;
default:
return nullptr;
}
}

View File

@ -0,0 +1,60 @@
#include "LuaCppBinding.h"
using namespace slua;
//static int LuaBinding_FindRow(lua_State* L) {
// UDataTable* DataTable = LuaObject::checkUD<UDataTable>(L, 1);
// FName RowName = LuaObject::checkValue<FName>(L, 2);
//
// UScriptStruct* RowStruct = (UScriptStruct*)DataTable->GetRowStruct();
//
// uint8* RowData = DataTable->FindRowUnchecked(RowName);
//
// if (RowData && RowStruct) {
// // <20><><EFBFBD><EFBFBD> LuaStruct <20><>װ<EFBFBD><D7B0>
// uint32 size = RowStruct->GetStructureSize() ? RowStruct->GetStructureSize() : 1;
// uint8* buf = (uint8*)FMemory::Malloc(size);
// RowStruct->InitializeStruct(buf);
// RowStruct->CopyScriptStruct(buf, RowData);
//
// LuaStruct* ls = new LuaStruct();
// ls->Init(buf, size, RowStruct, false);
// return LuaObject::push(L, ls);
// }
// else {
// return LuaObject::pushNil(L);
// }
//}
static int LuaBinding_FindRow(lua_State* L) {
UDataTable* DataTable = LuaObject::checkUD<UDataTable>(L, 1);
FName RowName = LuaObject::checkValue<FName>(L, 2);
FTableRowBase* TableRow = DataTable->FindRow<FTableRowBase>(RowName, TEXT(""));
const UScriptStruct* rowStruct = DataTable->GetRowStruct();
LuaStruct* luaStruct = new LuaStruct();
luaStruct->Init((uint8*)TableRow, rowStruct->GetStructureSize(), (UScriptStruct*)rowStruct, true);
LuaObject::addLink(L, TableRow); // ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//auto ret = LuaObject::push(L, luaStruct);
return LuaObject::pushReference<LuaStruct*>(L, luaStruct, TableRow);
}
//FTableRowBase* tableRow = DataTable->FindRow<FTableRowBase>(RowName, TEXT(""));
//
//UScriptStruct* rowStruct = DataTable->GetRowStruct();
//
//LuaStruct* luaStruct = new LuaStruct();
//luaStruct->Init((uint8*)tableRow, rowStruct->GetStructureSize(), rowStruct, true);
//
//int ret = LuaObject::push(L, luaStruct);
extern void RegisterDataTableExtension() {
REG_EXTENSION_METHOD_IMP(UDataTable, "FindRow", { return LuaBinding_FindRow(L); });
}

View File

@ -11,6 +11,7 @@
#include "BusyActorManagerSubSystem.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "GameAsset/BusyItem.h"
#include "LuaBlueprintLibrary.h"
#include "BusyGamePlayLibrary.generated.h"
/**
@ -57,4 +58,8 @@ public:
UFUNCTION(BlueprintPure)
static bool GetCookMaterialStateConfig(const FName& RowName, FBusyCookMaterialStateConfig& RowData);
UFUNCTION(BlueprintPure)
static FLuaBPVar TestTable(const FName& RowName);
};

View File

@ -28,12 +28,14 @@ public:
virtual bool Initialize() override;
public:
UPROPERTY(BlueprintReadOnly)
bool bVisible;
virtual void SetVisible(bool InVisible);
UFUNCTION(BlueprintCallable)
void BP_SetVisible(bool InVisible);
public:
UFUNCTION(BlueprintCallable)
void SetVisible(bool Visible);
UPROPERTY(BlueprintReadOnly)
bool bVisible;
};
@ -52,4 +54,21 @@ public:
public:
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
EWidgetLayoutType LayoutType;
public:
UFUNCTION(BlueprintCallable)
void BP_Close();
public:
virtual void SetVisible(bool InVisible)override;
public:
void FrameWorkSetVisible(bool InVisible);
protected:
void _RefreshVisible();
protected:
bool bFrameWorkVisible; // 框架控制的显隐,高优先级
};

View File

@ -17,16 +17,17 @@ class BUSYRABBIT_API APW_UIHud : public AHUD, public ILuaOverriderInterface {
public:
UFUNCTION(BlueprintCallable)
UPW_UserWidget* BP_PushWidget(const FName& WidgetName) { return PushWidget(WidgetName); }
UFUNCTION(BlueprintCallable)
void BP_PopWidget(const UPW_UserWidget* WidgetInst) { PopWidget(WidgetInst); }
public:
UPW_UserWidget* PushWidget(const FName& WidgetName);
UFUNCTION(BlueprintCallable)
bool PopWidget(const FName& WidgetName);
UPW_UserWidget* PushWidget(UPW_UserWidget* WidgetInst);
UFUNCTION(BlueprintCallable)
UPW_UserWidget* ShowWidget(const FName& WidgetName);
UFUNCTION(BlueprintCallable)
bool HideWidget(const FName& WidgetName);
void PopWidget(const UPW_UserWidget* WidgetInst);
public:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)

View File

@ -17,13 +17,12 @@ class BUSYRABBIT_API UPW_UILayer : public UPW_UserWidget
GENERATED_BODY()
public:
UPW_UserWidget* ShowWidget(const FName& WidgetName);
bool PushWidget(UPW_UserWidget* WidgetInst);
bool HideWidget(const FName& WidgetName);
void PopWidget(const UPW_UserWidget* WidgetInst);
bool PushWidget(const FName& WidgetName, UPW_UserWidget* WidgetInst);
bool PopWidget(const FName& WidgetName);
protected:
UOverlay* _GetOverlayByLayerType(EWidgetLayoutType InLayoutType);
protected:
@ -39,6 +38,4 @@ protected:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
TObjectPtr<UOverlay> TopLayer;
protected:
TMap<FName, UPW_UserWidget*> WidgetPool;
};

View File

@ -0,0 +1,23 @@
#pragma once
#include "CoreMinimal.h"
#include "Engine/Texture2D.h"
#include "BusyPreCookTable.generated.h"
USTRUCT()
struct FBusyPreCookItemConfig: public FTableRowBase {
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "名称")
FText Name;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "描述")
FText Desc;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "备注")
FString Description;
UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "用于显示的资源")
TSoftObjectPtr<UTexture2D> DisplayResource;
};