Files
PalUIExtension/Api/PalDetailWidget.hpp

270 lines
12 KiB
C++
Raw Normal View History

2026-09-07 19:33:58 -04:00
#pragma once
#include <optional>
#include <cstring>
#include <Unreal/FText.hpp>
#include <Unreal/NameTypes.hpp>
#include "UmgTypes.hpp"
#include "UnrealWrapper.hpp"
#include "Widget.hpp"
#include "UserWidget.hpp"
#include "WidgetTree.hpp"
#include "TextBlock.hpp"
#include "CanvasPanel.hpp"
#include <Api/Pal/PalIndividual.hpp>
#include <Api/Pal/PalIndividualCharacterHandle.hpp>
#include <Api/Pal/PalIndividualCharacterParameter.hpp>
using namespace PalUIExtension::Api::Pal;
namespace PalUIExtension::Api
{
class PalDetailWidget : public UserWidget
{
public:
static auto ClassPath() -> const TCHAR* {
return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalDetail.WBP_IngameMenu_PalBox_PalDetail_C");
}
static auto WidgetTreePath() -> const TCHAR* {
return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalDetail.WBP_IngameMenu_PalBox_PalDetail_C:WidgetTree");
}
static auto DebugTag() -> const TCHAR* { return STR("PalDetail"); }
PalDetailWidget() = default;
explicit PalDetailWidget(UObject* Obj) : UserWidget(Obj, ClassOf<PalDetailWidget>(), DebugTag()) {
}
struct GetBindedHandleFrame
{
UObject* targetHandle; // 0x00 out
bool bValidSoftRef; // 0x08
uint8 Pad09[7]; // 0x09
UObject* SoftRefAsObject; // 0x10
UObject* CastAsHandle; // 0x18
bool bCastSucceeded; // 0x20
uint8 Pad21[7]; // 0x21
};
static_assert(sizeof(GetBindedHandleFrame) == 40,
"GetBindedHandle frame is 40 bytes on the dumped build");
struct GetBindedIndividualParameterFrame
{
UObject* IndividualParameter; // 0x00 out
UObject* Handle; // 0x08
UObject* TryGetResult; // 0x10
bool bValid0; // 0x18
bool bValid1; // 0x19
uint8 Pad1A[6]; // 0x1A
};
static_assert(sizeof(GetBindedIndividualParameterFrame) == 32,
"GetBindedIndividualParameter frame is 32 bytes on the dumped build");
auto GetBindedHandle() -> UObject*
{
GetBindedHandleFrame p{};
if (!Call(STR("GetBindedHandle"), p)) return nullptr;
return p.targetHandle;
}
auto GetBindedIndividualParameter() -> UObject*
{
GetBindedIndividualParameterFrame p{};
if (!Call(STR("GetBindedIndividualParameter"), p)) return nullptr;
return p.IndividualParameter;
}
auto CurrentHandle() -> PalIndividualCharacterHandle
{
UObject* H = GetBindedHandle();
return H ? PalIndividualCharacterHandle{ H } : PalIndividualCharacterHandle{};
}
auto CurrentParameter() -> PalIndividualCharacterParameter
{
UObject* P = GetBindedIndividualParameter();
return P ? PalIndividualCharacterParameter{ P } : PalIndividualCharacterParameter{};
}
auto ResolveIdentity() -> PalIdentity
{
if (UObject* Param = GetBindedIndividualParameter())
{
return PalIndividual::IdentifyFromParameter(Param);
}
return PalIndividual::Identify(GetBindedHandle());
}
auto CurrentCharacterId() -> std::optional<FName>
{
if (UObject* Param = GetBindedIndividualParameter())
{
return PalIndividual::CharacterId(Param);
}
return PalIndividual::CharacterIdFromHandle(GetBindedHandle());
}
auto CanvasBase() const -> CanvasPanel { return WrapCanvas(STR("Canvas_Base")); }
auto CanvasBaseToolTip() const -> CanvasPanel { return WrapCanvas(STR("Canvas_Base_ToolTip")); }
auto CanvasInfo() const -> CanvasPanel { return WrapCanvas(STR("Canvas_Info")); }
auto CanvasFood() const -> CanvasPanel { return WrapCanvas(STR("Canvas_Food")); }
auto CanvasPartnerSkill() const -> CanvasPanel { return WrapCanvas(STR("Canvas_PartnerSkill")); }
auto CanvasPotencial() const -> CanvasPanel { return WrapCanvas(STR("CanvasPanel_Potencial")); }
auto CanvasDebuff() const -> CanvasPanel { return WrapCanvas(STR("CanvasPanelDebuff")); }
auto CanvasStatePalWork() const -> CanvasPanel { return WrapCanvas(STR("CanvasPanelStatePalWork")); }
auto TextPalName() const -> TextBlock { return WrapText(STR("Text_PalName")); }
auto TextLevel() const -> TextBlock { return WrapText(STR("Text_LevelValue")); }
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 TextMaxSanity() const -> TextBlock { return WrapText(STR("Text_MaxSanity")); }
auto TextAttack() const -> TextBlock { return WrapText(STR("Text_AttackValue")); }
auto TextDefense() const -> TextBlock { return WrapText(STR("Text_DefenseValue")); }
auto TextWorkValue() const -> TextBlock { return WrapText(STR("Text_WorkValue")); }
auto TextWorkTypeName() const -> TextBlock { return WrapText(STR("Text_WorkTypeName")); }
auto TextNextExp() const -> TextBlock { return WrapText(STR("Text_NextExp")); }
auto TextFriendshipRank() const -> TextBlock { return WrapText(STR("Text_FriendshipRank_Num")); }
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 CharacterIcon() const -> UObject* { return BoundObject(STR("WBP_PalCommonCharacterIcon")); }
auto ElementIcon0() const -> UObject* { return BoundObject(STR("WBP_PalElementIcon")); }
auto ElementIcon1() const -> UObject* { return BoundObject(STR("WBP_PalElementIcon_1")); }
// ---- plain properties ----------------------------------------
auto SavedMaxHunger() const -> std::optional<float> { return PropertyValue<float>(STR("savedMaxHunger")); }
auto SavedMaxSanity() const -> std::optional<float> { return PropertyValue<float>(STR("savedMaxSanity")); }
auto HidePassive() const -> std::optional<bool> { return PropertyValue<bool>(STR("HidePassive")); }
// ---- calls ---------------------------------------------------
auto SetEmpty() -> bool { return CallVoid(STR("SetEmpty")); }
auto SetupPartnerSkillInfo() -> bool { return CallVoid(STR("SetupPartnerSkillInfo")); }
auto ToggleSkillInfo() -> bool { return CallVoid(STR("ToggleSKillInfo")); } // engine spelling
auto OverrideHideTalent() -> bool { return CallVoid(STR("OverrideHideTalent")); }
auto SetVisiblePartnerSkillInfo(bool bVisible) -> bool
{
struct P { bool bVisible; } p{ bVisible };
return Call(STR("SetVisiblePartnerSkillInfo"), p);
}
auto SetVisibleToggleSkillInfoKeyGuide(bool bVisible) -> bool
{
struct P { bool bVisible; } p{ bVisible };
return Call(STR("SetVisibleToggleSkillInfoKeyGuide"), p);
}
auto SetAwakening(bool bAwaked) -> bool
{
struct P { bool bAwaked; } p{ bAwaked };
return Call(STR("SetAwakening"), p);
}
auto SetImportedFlag(bool bImportedFlag) -> bool
{
struct P { bool bImportedFlag; } p{ bImportedFlag };
return Call(STR("SetImportedFlag"), p);
}
auto SetDetailMode(bool IsTip) -> bool
{
struct P { bool IsTip; } p{ IsTip };
return Call(STR("Set Detail Mode"), p); // the spaces are real
}
auto SetRarity(bool IsBoss, bool IsRare) -> bool
{
struct P { bool IsBoss; bool IsRare; } p{ IsBoss, IsRare };
return Call(STR("SetRarity"), p);
}
auto SetRank(int32 Rank) -> bool
{
struct P { int32 Rank; } p{ Rank };
return Call(STR("SetRank"), p);
}
auto SetSoulRank(int32 Rank) -> bool
{
struct P { int32 Rank; } p{ Rank };
return Call(STR("SetSoulRank"), p);
}
auto SetFoodAmount(int32 FoodAmount) -> bool
{
struct P { int32 FoodAmount; } p{ FoodAmount };
return Call(STR("SetFoodAmount"), p);
}
auto SetFriendShip(int32 FriendshipRank, int32 FriendshipPoint) -> bool
{
struct P { int32 FriendshipRank; int32 FriendshipPoint; } p{ FriendshipRank, FriendshipPoint };
return Call(STR("SetFriendShip"), p);
}
auto SetGender(EPalGenderType_ GenderType) -> bool
{
struct P { EPalGenderType_ GenderType; } p{ GenderType };
return Call(STR("SetGender"), p);
}
auto SetElementType(EPalElementType_ Type1, EPalElementType_ Type2) -> bool
{
struct P { EPalElementType_ type1; EPalElementType_ type2; } p{ Type1, Type2 };
return Call(STR("SetElementType"), p);
}
struct WorkSuitabilityCheck { bool bValid{}; EPalWorkSuitability_ Out{}; };
auto CheckValidWorkSuitability(EPalWorkSuitability_ In) -> std::optional<WorkSuitabilityCheck>
{
struct P
{
EPalWorkSuitability_ InWorkSuitability;
bool IsValid;
EPalWorkSuitability_ OutWorkSuitability;
} p{ In, false, EPalWorkSuitability_::None };
if (!Call(STR("Check Valid Work Suitability"), p)) return std::nullopt;
return WorkSuitabilityCheck{ p.IsValid, p.OutWorkSuitability };
}
// ---- hook targets --------------------------------------------
static auto BindFromHandlePath() -> const TCHAR*
{
return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalDetail.WBP_IngameMenu_PalBox_PalDetail_C:BindFromHandle");
}
static auto SetEmptyPath() -> const TCHAR*
{
return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalDetail.WBP_IngameMenu_PalBox_PalDetail_C:SetEmpty");
}
static auto UpdateStatusParameterPath() -> const TCHAR*
{
return STR("/Game/Pal/Blueprint/UI/UserInterface/IngameMenu/PalBox/WBP_IngameMenu_PalBox_PalDetail.WBP_IngameMenu_PalBox_PalDetail_C:Update Status Parameter");
}
struct BindFromHandleFrame { UObject* targetHandle; }; // UPalIndividualCharacterHandle*
struct UpdateStatusParameterFrame { UObject* individualParam; }; // UPalIndividualCharacterParameter*
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:
PalDetailWidget(UObject* Obj, UClass* Expected, const TCHAR* Tag)
: UserWidget(Obj, Expected, Tag) {
}
};
}