#pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace PalUIExtension::Api { class PalBoxPalListWidget : public UserWidget { public: static auto ClassPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalList.WBP_IngameMenu_PalBox_PalList_C"); } static auto WidgetTreePath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalList.WBP_IngameMenu_PalBox_PalList_C:WidgetTree"); } static auto DebugTag() -> const TCHAR* { return STR("PalListEntry"); } PalBoxPalListWidget() = default; explicit PalBoxPalListWidget(UObject* Obj) : UserWidget(Obj, ClassOf(), DebugTag()) {} static auto BindFromSlotPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalList.WBP_IngameMenu_PalBox_PalList_C:BindFromSlot"); } static auto SetupPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalList.WBP_IngameMenu_PalBox_PalList_C:Setup"); } static auto UnbindPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalList.WBP_IngameMenu_PalBox_PalList_C:Unbind"); } static auto SetEmptyPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalList.WBP_IngameMenu_PalBox_PalList_C:SetEmpty"); } static auto OnUpdateHandleSlotPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalList.WBP_IngameMenu_PalBox_PalList_C:OnUpdateHandleSlot"); } static auto OnUpdateSkinPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalList.WBP_IngameMenu_PalBox_PalList_C:OnUpdateSkin"); } static auto UpdateHPPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalList.WBP_IngameMenu_PalBox_PalList_C:UpdateHP"); } static auto UpdateLevelPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalList.WBP_IngameMenu_PalBox_PalList_C:Update Level"); } // ============================================================== // FRAME LAYOUTS // ============================================================== // ParmsSize 0x08. Full frame ends 0x3C by my arithmetic. struct BindFromSlotFrame { UObject* TargetSlot; // 0x00 UPalIndividualSlot-ish uint8 CompilerLocals[0x34]; // 0x08 }; // ParmsSize 0x08. Full frame ends 0x1C. struct SetupFrame { UObject* TargetSlot; // 0x00 uint8 CompilerLocals[0x14]; // 0x08 }; struct UnbindFrame { uint8 CompilerLocals[0x30]; }; struct OnUpdateHandleSlotFrame { UObject* Slot; // 0x00 UObject* LastHandle; // 0x08 }; // ParmsSize 0x08 (FName). Full frame ends 0x62. struct OnUpdateSkinFrame { FName NewSkinName; // 0x00 uint8 CompilerLocals[0x5A]; // 0x08 }; // ParmsSize 0x10. Full frame ends 0x158 struct UpdateHPFrame { Pal::FFixedPoint64_ nowHP; // 0x00 Pal::FFixedPoint64_ nowMaxHP; // 0x08 uint8 CompilerLocals[0x148]; // 0x10 }; // ParmsSize 0x10. Note DOUBLE, not FFixedPoint64 struct UpdateHungerFrame { double nowHunger; // 0x00 double nowMaxHunger; // 0x08 uint8 CompilerLocals[0x64]; // 0x10 }; // ParmsSize 0x04. Full frame ends 0x38. struct UpdateLevelFrame { int32 NewLevel; // 0x00 uint8 CompilerLocals[0x38]; // 0x04 }; // ParmsSize 0x04. Full frame ends 0x39. struct UpdateFavoriteFrame { int32 NewIndex; // 0x00 uint8 CompilerLocals[0x35]; // 0x04 }; // ParmsSize 0x10 (FString). Full frame ends 0x28. struct UpdateNicknameFrame { FString NewNickName; // 0x00 uint8 CompilerLocals[0x18]; // 0x10 }; struct SetEnableDragDropFrame { bool bIsEnable; }; // EnumProperty at 0x08 with one byte before the frame ends. struct DraggedButtonEventFrame { UObject* Widget; // 0x00 uint8 PressType; // 0x08 }; // ============================================================== // CALLS // ============================================================== auto BindFromSlot(UObject* Slot) -> bool { BindFromSlotFrame p{ Slot, {} }; return Call(STR("BindFromSlot"), p); } auto Setup(UObject* Slot) -> bool { SetupFrame p{ Slot, {} }; return Call(STR("Setup"), p); } auto Unbind() -> bool { UnbindFrame p{}; return Call(STR("Unbind"), p); } auto SetEmpty() -> bool { return CallVoid(STR("SetEmpty")); } auto SetEnableDragDrop(bool bIsEnable) -> bool { SetEnableDragDropFrame p{ bIsEnable }; return Call(STR("SetEnableDragDrop"), p); } auto SetLevel(int32 NewLevel) -> bool { UpdateLevelFrame p{ NewLevel, {} }; return Call(STR("Update Level"), p); // the space is real } auto SetFavorite(int32 NewIndex) -> bool { UpdateFavoriteFrame p{ NewIndex, {} }; return Call(STR("UpdateFavorite"), p); } auto UpdateHP(Pal::FFixedPoint64_ NowHP, Pal::FFixedPoint64_ NowMaxHP) -> bool { UpdateHPFrame p{ NowHP, NowMaxHP, {} }; return Call(STR("UpdateHP"), p); } auto UpdateHunger(double NowHunger, double NowMaxHunger) -> bool { UpdateHungerFrame p{ NowHunger, NowMaxHunger, {} }; return Call(STR("UpdateHunger"), p); } auto UpdateSkin(FName NewSkinName) -> bool { OnUpdateSkinFrame p{ NewSkinName, {} }; return Call(STR("OnUpdateSkin"), p); } static auto SlotHandle(UObject* Slot) -> UObject* { if (!Slot) return nullptr; Pal::LooseObject S{ Slot, STR("PalIndividualSlot") }; return S.CallForReturn(STR("GetHandle")).value_or(nullptr); } static auto SlotIsEmpty(UObject* Slot) -> std::optional { if (!Slot) return std::nullopt; Pal::LooseObject S{ Slot, STR("PalIndividualSlot") }; return S.CallForReturn(STR("IsEmpty")); } static auto SpeciesFromSlot(UObject* Slot) -> std::optional { return Pal::PalIndividual::CharacterIdFromHandle(SlotHandle(Slot)); } auto BoundSlot() const -> UObject* { return BoundObject(STR("TargetSlot")); } auto BoundHandle() const -> UObject* { return SlotHandle(BoundSlot()); } // ============================================================== // BOUND WIDGETS (promoted variables -- property read, no walk) // ============================================================== auto TextHP() const -> TextBlock { return WrapText(STR("Text_HP")); } auto TextMaxHP() const -> TextBlock { return WrapText(STR("Text_MaxHP")); } auto TextLevel() const -> TextBlock { return WrapText(STR("Text_LevelValue")); } auto TextNickName() const -> TextBlock { return WrapText(STR("Text_NickName")); } auto TextLvLabel() const -> TextBlock { return WrapText(STR("BP_PalTextBlock_LvText")); } auto CanvasRoot() const -> CanvasPanel { return WrapCanvas(STR("CanvasPanel_119")); } auto CanvasSelectFrame() const -> CanvasPanel { return WrapCanvas(STR("PalSelect_BaseTri")); } auto GaugeHP() const -> UObject* { return BoundObject(STR("Gauge_HP")); } auto GaugeHunger() const -> UObject* { return BoundObject(STR("Gauge_Hunger")); } auto ImageHPBar() const -> UObject* { return BoundObject(STR("Image_HP_Bar")); } auto ImageHungerBar() const -> UObject* { return BoundObject(STR("Image_Huger_Bar")); } // engine spelling auto ImageCheck() const -> UObject* { return BoundObject(STR("Image_Check")); } auto ImageLocked() const -> UObject* { return BoundObject(STR("Image_Icon_Locked")); } auto ImageListBar() const -> UObject* { return BoundObject(STR("Image_Pal_List_Bar")); } auto ImageEmpty() const -> UObject* { return BoundObject(STR("Empty")); } auto PalIcon() const -> UObject* { return BoundObject(STR("PalIcon")); } auto RetainerBox() const -> UObject* { return BoundObject(STR("RetainerBox_0")); } auto InvisibleButton() const -> UObject* { return BoundObject(STR("WBP_PalInvisibleButton")); } auto DynamicMaterial() const -> UObject* { return BoundObject(STR("dynamicMaterial")); } v auto AnimFocus() const -> UObject* { return BoundObject(STR("Anm_Focus")); } auto AnimNormal() const -> UObject* { return BoundObject(STR("Anm_Normal")); } auto AnimNormalToFocus() const -> UObject* { return BoundObject(STR("Anm_NormalToFocus")); } auto AnimPalAlive() const -> UObject* { return BoundObject(STR("Anm_Pal_Alive")); } auto AnimPalDead() const -> UObject* { return BoundObject(STR("Anm_Pal_Dead")); } // ---- plain properties ---------------------------------------- auto IsDragDropEnabled() const -> std::optional { return PropertyBoolValue(STR("bEnableDragDrop")); } private: auto WrapCanvas(const TCHAR* Name) const -> CanvasPanel { UObject* O = BoundObject(Name); return O ? CanvasPanel{ O } : CanvasPanel{}; } auto WrapText(const TCHAR* Name) const -> TextBlock { UObject* O = BoundObject(Name); return O ? TextBlock{ O } : TextBlock{}; } protected: PalBoxPalListWidget(UObject* Obj, UClass* Expected, const TCHAR* Tag) : UserWidget(Obj, Expected, Tag) {} }; }