#pragma once #include #include #include #include "UnrealWrapper.hpp" #include "UmgTypes.hpp" #include "Widget.hpp" #include "UserWidget.hpp" #include "WidgetTree.hpp" #include "CanvasPanel.hpp" #include "Overlay.hpp" #include "VerticalBox.hpp" #include "TextBlock.hpp" #include namespace PalUIExtension::Api { class MainMenuPalWidget : public UserWidget { public: static auto ClassPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/MainMenu/Pal/" "WBP_MainMenu_Pal_00.WBP_MainMenu_Pal_00_C"); } static auto DebugTag() -> const TCHAR* { return STR("MainMenuPal"); } MainMenuPalWidget() = default; explicit MainMenuPalWidget(UObject* Obj) : UserWidget(Obj, ClassOf(), DebugTag()) { } auto CanvasPalName() const -> CanvasPanel { return WrapCanvas(STR("Canvas_PalName")); } auto CanvasPalStatus() const -> CanvasPanel { return WrapCanvas(STR("Canvas_PalStatus")); } auto CanvasSkillInfo() const -> CanvasPanel { return WrapCanvas(STR("Canvas_SkillInfo")); } auto CanvasPartnerSkill() const -> CanvasPanel { return WrapCanvas(STR("CanvasPanel_PartnerSkill")); } auto CanvasPotencial() const -> CanvasPanel { return WrapCanvas(STR("CanvasPanel_Potencial")); } // engine spelling auto CanvasDebuff() const -> CanvasPanel { return WrapCanvas(STR("CanvasPanelDebuff")); } auto CanvasAwakening() const -> CanvasPanel { return WrapCanvas(STR("Canvas_Awakening")); } auto CanvasDropGuide() const -> CanvasPanel { return WrapCanvas(STR("Canvas_DropGuide")); } auto CanvasLocked() const -> CanvasPanel { return WrapCanvas(STR("Canvas_Locked")); } auto CanvasUnlocked() const -> CanvasPanel { return WrapCanvas(STR("Canvas_Unlocked")); } auto CanvasLock1() const -> CanvasPanel { return WrapCanvas(STR("CanvasPanelLock_1")); } auto CanvasLockText() const -> CanvasPanel { return WrapCanvas(STR("CanvasPanelLockText")); } auto CanvasLockText1() const -> CanvasPanel { return WrapCanvas(STR("CanvasPanelLockText_1")); } auto BoxPalList() const -> VerticalBox { return WrapVBox(STR("VerticalBox_Pal_List")); } auto BoxSkill() const -> VerticalBox { return WrapVBox(STR("VerticalBox_Skill")); } auto OverlayCircle() const -> Overlay { return WrapOverlay(STR("Overlay_Circle")); } auto OverlayIconCircle() const -> Overlay { return WrapOverlay(STR("Overlay_Icon_Circle")); } auto OverlayIconSquare() const -> Overlay { return WrapOverlay(STR("Overlay_Icon_sq")); } auto OverlaySquare() const -> Overlay { return WrapOverlay(STR("Overlay_sq")); } auto GridSuitability() const -> UObject* { return BoundObject(STR("UniformGrid_Suitability")); } auto FindCanvas(const TCHAR* Name) -> CanvasPanel { return Child(Name); } auto CachedHandle() const -> UObject* { return BoundObject(STR("CachedIndividualHandle")); } auto CachedSpecies() const -> std::optional { return Pal::PalIndividual::CharacterIdFromHandle(CachedHandle()); } auto CachedIdentity() const -> Pal::PalIdentity { return Pal::PalIndividual::Identify(CachedHandle()); } // ---- screen state -------------------------------------------- auto IsShowingStatusWithList() const -> std::optional { return PropertyBoolValue(STR("isShowStatusWithList")); } auto IsLocked() const -> std::optional { return PropertyBoolValue(STR("Is Lock")); } auto IsEditingNickName() const -> std::optional { return PropertyBoolValue(STR("IsEditingNickName")); } // ============================================================== // WIDGET ARRAYS // ============================================================== auto PalPanels() const -> std::vector { return ReadObjectArray(STR("PalPanels")); } auto ActiveSkillPanels() const -> std::vector { return ReadObjectArray(STR("ActiveSkillPanelArray")); } auto PassiveSkillPanels() const -> std::vector { return ReadObjectArray(STR("PassiveSkillPanelArray")); } auto ConditionWidgets() const -> std::vector { return ReadObjectArray(STR("ConditionWidgetArray")); } auto RarityWidgets() const -> std::vector { return ReadObjectArray(STR("RarityWidgetArray")); } // The engine's spelling of "SideInfo" is "SindeInfo". Lol. auto SideInfoConditionWidgets() const -> std::vector { return ReadObjectArray(STR("SindeInfoConditionWidgetArray")); } // ============================================================== // TEXT // ============================================================== auto TextNowHP() const -> TextBlock { return WrapText(STR("Text_NowHP")); } auto TextMaxHP() const -> TextBlock { return WrapText(STR("Text_MaxHP")); } auto TextNowHunger() const -> TextBlock { return WrapText(STR("Text_NowHunger")); } auto TextMaxHunger() const -> TextBlock { return WrapText(STR("Text_MaxHunger")); } auto TextNowSanity() const -> TextBlock { return WrapText(STR("Text_NowSanity")); } auto TextLevel() const -> TextBlock { return WrapText(STR("Text_LevelValue")); } auto TextNextExp() const -> TextBlock { return WrapText(STR("Text_NextExp")); } auto TextDefense() const -> TextBlock { return WrapText(STR("Text_DefenseValue")); } auto TextRangeAttack() const -> TextBlock { return WrapText(STR("Text_RangeAttackValue")); } auto TextWorkSpeed() const -> TextBlock { return WrapText(STR("Text_WorkSpeedValue")); } auto TextFriendship() const -> TextBlock { return WrapText(STR("Text_FriendshipRank_Num")); } auto TextNickName() const -> TextBlock { return WrapText(STR("BP_PalTextBlock_NickName")); } auto TextLvLabel() const -> TextBlock { return WrapText(STR("BP_PalTextBlock_LvText")); } auto TextSoulRank() const -> TextBlock { return WrapText(STR("BP_PalTextBlock_SoulRank")); } auto RichTextPartnerSkillName() const -> UObject* { return BoundObject(STR("RichText_PartnerSkillName")); } auto RichTextPartnerSkillDesc() const -> UObject* { return BoundObject(STR("RichText_PartnerSkillDesc")); } // ---- gauges, images, nested widgets: raw --------------------- auto GaugeHP() const -> UObject* { return BoundObject(STR("Gauge_HP")); } auto GaugeHunger() const -> UObject* { return BoundObject(STR("Gauge_Hunger")); } auto GaugeExp() const -> UObject* { return BoundObject(STR("Gauge_Exp")); } auto GaugeFriendship() const -> UObject* { return BoundObject(STR("Gauge_Friendship")); } auto ImageRare() const -> UObject* { return BoundObject(STR("Image_Rare")); } auto ImageStrong() const -> UObject* { return BoundObject(STR("Image_Strong")); } auto ImageMutant() const -> UObject* { return BoundObject(STR("Image_Mutant")); } auto ImageLocked() const -> UObject* { return BoundObject(STR("Image_Icon_Locked")); } auto ImageGlobalImport() const -> UObject* { return BoundObject(STR("Image_Icon_GlobalInport")); } // engine spelling auto FoodAmountWidget() const -> UObject* { return BoundObject(STR("WBP_MainMenu_Pal_FoodAmount")); } auto GenderIcon() const -> UObject* { return BoundObject(STR("WBP_PalGenderIcon")); } auto SkillInfoWidget() const -> UObject* { return BoundObject(STR("WBP_MainMenu_PalSkillInfo")); } auto PotencialWidget() const -> UObject* { return BoundObject(STR("WBP_Menu_Pal_Potencial")); } // engine spelling auto NoDataWidget() const -> UObject* { return BoundObject(STR("WBP_NoData")); } auto BuffTimers() const -> UObject* { return BoundObject(STR("WBP_StatusBuffTimerContainer")); } auto KeyGuideIcon() const -> UObject* { return BoundObject(STR("WBP_PalKeyGuideIcon")); } // ============================================================== // HOOK TARGETS // ============================================================== static auto BindFromHandlePath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/MainMenu/Pal/" "WBP_MainMenu_Pal_00.WBP_MainMenu_Pal_00_C:BindFromHandle"); } static auto SetPalHandlesPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/MainMenu/Pal/" "WBP_MainMenu_Pal_00.WBP_MainMenu_Pal_00_C:Set Pal Handles"); } static auto SetupStatusPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/MainMenu/Pal/" "WBP_MainMenu_Pal_00.WBP_MainMenu_Pal_00_C:Setup Status"); } static auto ListToStatusPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/MainMenu/Pal/" "WBP_MainMenu_Pal_00.WBP_MainMenu_Pal_00_C:ListToStatus"); } static auto OnClickedPalButtonPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/MainMenu/Pal/" "WBP_MainMenu_Pal_00.WBP_MainMenu_Pal_00_C:OnClickedPalButtonEvent"); } static auto OnHoveredPalButtonPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/MainMenu/Pal/" "WBP_MainMenu_Pal_00.WBP_MainMenu_Pal_00_C:OnHoveredPalButtonEvent"); } // The honest bookends for "this screen exists" and "your cached // pointers are now garbage." If you cache anything off this // class, hook Destruct. static auto ConstructPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/MainMenu/Pal/" "WBP_MainMenu_Pal_00.WBP_MainMenu_Pal_00_C:Construct"); } static auto DestructPath() -> const TCHAR* { return STR("/Game/Pal/Blueprint/UI/UserInterface/MainMenu/Pal/" "WBP_MainMenu_Pal_00.WBP_MainMenu_Pal_00_C:Destruct"); } // ---- frames -------------------------------------------------- struct BindFromHandleFrame { UObject* targetHandle; }; struct HandleFrame { UObject* Handle; }; struct SetPalHandlesFrame { UObject** Data; int32 Num; int32 Max; }; private: auto WrapCanvas(const TCHAR* Name) const -> CanvasPanel { UObject* O = BoundObject(Name); return O ? CanvasPanel{ O } : CanvasPanel{}; } auto WrapVBox(const TCHAR* Name) const -> VerticalBox { UObject* O = BoundObject(Name); return O ? VerticalBox{ O } : VerticalBox{}; } auto WrapOverlay(const TCHAR* Name) const -> Overlay { UObject* O = BoundObject(Name); return O ? Overlay{ O } : Overlay{}; } auto WrapText(const TCHAR* Name) const -> TextBlock { UObject* O = BoundObject(Name); return O ? TextBlock{ O } : TextBlock{}; } static constexpr int32 kMaxPlausibleEntries = 1024; auto ReadObjectArray(const TCHAR* PropertyName) const -> std::vector { std::vector Out; auto* Arr = TryPropertyPtr>(PropertyName); if (!Arr) return Out; if (!Arr->IsPlausible(kMaxPlausibleEntries)) { Output::send( STR("[{}] '{}' does not look like a live TArray (Num={}, Max={})\n"), m_tag, PropertyName, Arr->Num, Arr->Max); return Out; } Out.reserve(static_cast(Arr->Num)); for (int32 i = 0; i < Arr->Num; ++i) { if (UObject* Entry = Arr->Data[i]) Out.push_back(Entry); } return Out; } protected: MainMenuPalWidget(UObject* Obj, UClass* Expected, const TCHAR* Tag) : UserWidget(Obj, Expected, Tag) { } }; }