#pragma once #include #include #include "UnrealWrapper.hpp" #include "UmgTypes.hpp" #include "Widget.hpp" #include "UserWidget.hpp" #include "WidgetTree.hpp" #include "CanvasPanel.hpp" #include "TextBlock.hpp" namespace PalUIExtension::Api { // ================================================================== // THE PALBOX GRID CHAIN // // PalBoxWidget (the screen) // -> WBP_BoxPalList_C THIS FILE // -> WBP_BoxPalListBase_C THIS FILE // -> WBP_BoxPalScrollList // == WBP_PalCharacterScrollList_C // -> the slot tiles // ================================================================== class BoxPalListWidget : public UserWidget { public: static auto ClassPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalList.WBP_BoxPalList_C"); } static auto DebugTag() -> const TCHAR* { return STR("BoxPalList"); } BoxPalListWidget() = default; explicit BoxPalListWidget(UObject* Obj) : UserWidget(Obj, ClassOf(), DebugTag()) {} auto BaseObject() const -> UObject* { return BoundObject(STR("WBP_BoxPalListBase")); } auto CanDragDrop() const -> std::optional { return PropertyBoolValue(STR("CanDragDrop")); } auto DisplaysBanMarkInExpedition() const -> std::optional { return PropertyBoolValue(STR("bDisplayBanMarkInExpedition")); } // ---- hooks --------------------------------------------------- static auto UpdateSlotFilteringPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalList.WBP_BoxPalList_C:UpdateSlotFiltering"); } static auto UpdateAllSlotFilteringPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalList.WBP_BoxPalList_C:UpdateAllSlotFiltering"); } static auto SetupPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalList.WBP_BoxPalList_C:Setup"); } static auto DestructPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalList.WBP_BoxPalList_C:Destruct"); } struct SlotButtonFrame { UObject* SlotButton; }; }; class BoxPalListBaseWidget : public UserWidget { public: static auto ClassPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalListBase.WBP_BoxPalListBase_C"); } static auto DebugTag() -> const TCHAR* { return STR("BoxPalListBase"); } BoxPalListBaseWidget() = default; explicit BoxPalListBaseWidget(UObject* Obj) : UserWidget(Obj, ClassOf(), DebugTag()) {} auto ScrollList() const -> UObject* { return BoundObject(STR("WBP_BoxPalScrollList")); } auto LastSelectedPage() const -> std::optional { return PropertyValue(STR("LastSelectedPageNum")); } auto MaxPageNum() const -> std::optional { return PropertyValue(STR("MaxPageNum")); } auto SkipPageNum() const -> std::optional { return PropertyValue(STR("SkipPageNum")); } auto IsValidPageAction() const -> std::optional { return PropertyBoolValue(STR("bIsValidPageAction")); } auto IsSkippingPage() const -> std::optional { return PropertyBoolValue(STR("bSkipPage")); } // ---- chrome, promoted ----------------------------------------- auto CanvasSliderValue() const -> CanvasPanel { UObject* O = BoundObject(STR("Canvas_SliderValue")); return O ? CanvasPanel{ O } : CanvasPanel{}; } auto TextBoxName() const -> TextBlock { return WrapText(STR("Text_BoxName")); } auto TextSliderValue() const -> TextBlock { return WrapText(STR("Text_SliderValue")); } auto Slider() const -> UObject* { return BoundObject(STR("Slider")); } auto SearchButton() const -> UObject* { return BoundObject(STR("WBP_CommonButton_Activation_Search")); } auto SortButton() const -> UObject* { return BoundObject(STR("WBP_CommonButton_Sort")); } auto NumArrowLeft() const -> UObject* { return BoundObject(STR("WBP_Common_NumArrow_L")); } auto NumArrowRight() const -> UObject* { return BoundObject(STR("WBP_Common_NumArrow_R")); } static auto OnCreatedNewSlotPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalListBase.WBP_BoxPalListBase_C:OnCreatedNewSlot__DelegateSignature"); } static auto OnUpdateSlotPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalListBase.WBP_BoxPalListBase_C:OnUpdateSlot__DelegateSignature"); } static auto OnSlotSyncedPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalListBase.WBP_BoxPalListBase_C:OnSlotSynced__DelegateSignature"); } static auto OnUpdatedPagePath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalListBase.WBP_BoxPalListBase_C:OnUpdatedPage__DelegateSignature"); } static auto SetCharacterSlotsPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalListBase.WBP_BoxPalListBase_C:SetCharacterSlots"); } static auto SetCurrentPagePath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalListBase.WBP_BoxPalListBase_C:SetCurrentPage"); } static auto DestructPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/Common/" "WBP_BoxPalListBase.WBP_BoxPalListBase_C:Destruct"); } struct SlotWidgetFrame { UObject* Widget; }; struct SlotClickFrame { UObject* Widget; // 0x00 uint8 PressType; // 0x08 }; struct PageFrame { int32 NowPage; }; // OnUpdatedPage, OnSelectPalBoxPage struct SetCharacterSlotsFrame { UObject** Data; int32 Num; int32 Max; }; static_assert(sizeof(SetCharacterSlotsFrame) == 16, "SetCharacterSlots frame is 16 bytes on the dumped build"); auto GetCurrentPage() -> std::optional { struct Frame { int32 CurrentPageNum; } p{}; if (!Call(STR("GetCurrentPage"), p)) return std::nullopt; return p.CurrentPageNum; } private: auto WrapText(const TCHAR* Name) const -> TextBlock { UObject* O = BoundObject(Name); return O ? TextBlock{ O } : TextBlock{}; } protected: BoxPalListBaseWidget(UObject* Obj, UClass* Expected, const TCHAR* Tag) : UserWidget(Obj, Expected, Tag) {} }; }