initial commit; cv 0.0.3
This commit is contained in:
270
Api/PalDetailWidget.hpp
Normal file
270
Api/PalDetailWidget.hpp
Normal file
@@ -0,0 +1,270 @@
|
||||
#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) {
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user