270 lines
12 KiB
C++
270 lines
12 KiB
C++
#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) {
|
|
}
|
|
};
|
|
} |