initial commit; cv 0.0.3
This commit is contained in:
136
Api/Pal/PalCharacter.hpp
Normal file
136
Api/Pal/PalCharacter.hpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <Unreal/NameTypes.hpp>
|
||||
|
||||
#include <Api/UnrealWrapper.hpp>
|
||||
#include "PalIndividual.hpp"
|
||||
#include "PalTypes.hpp"
|
||||
|
||||
namespace PalUIExtension::Api::Pal
|
||||
{
|
||||
|
||||
class PalCharacter : public UnrealWrapper
|
||||
{
|
||||
|
||||
public:
|
||||
static auto ClassPath() -> const TCHAR* { return STR("/Script/Pal.PalCharacter"); }
|
||||
static auto DebugTag() -> const TCHAR* { return STR("PalCharacter"); }
|
||||
|
||||
PalCharacter() = default;
|
||||
explicit PalCharacter(UObject* Obj) : UnrealWrapper(Obj, ClassOf<PalCharacter>(), DebugTag()) {}
|
||||
|
||||
// ---- components ------------------------------------------------
|
||||
|
||||
auto GetCharacterParameterComponent() -> UObject* { return ObjectGetter(STR("GetCharacterParameterComponent")); }
|
||||
auto GetActionComponent() -> UObject* { return ObjectGetter(STR("GetActionComponent")); }
|
||||
auto GetPalCharacterMovementComponent() -> UObject* { return ObjectGetter(STR("GetPalCharacterMovementComponent")); }
|
||||
auto GetMainMesh() -> UObject* { return ObjectGetter(STR("GetMainMesh")); }
|
||||
auto GetCurrentReservedMontage() -> UObject* { return ObjectGetter(STR("GetCurrentReservedMontage")); }
|
||||
|
||||
auto GetOverrideFaceMesh() -> UObject* { return ObjectGetter(STR("GetOverrideFaceMesh")); }
|
||||
auto GetHandAttachMesh() -> UObject* { return ObjectGetter(STR("GetHandAttachMesh")); }
|
||||
|
||||
// ---- identity --------------------------------------------------
|
||||
|
||||
auto GetIndividualParameterObject() -> UObject*
|
||||
{
|
||||
UObject* Comp = GetCharacterParameterComponent();
|
||||
if (!Comp) return nullptr;
|
||||
LooseObject C{ Comp, STR("PalCharacterParameterComponent") };
|
||||
return C.CallForReturn<UObject*>(STR("GetIndividualParameter")).value_or(nullptr);
|
||||
}
|
||||
|
||||
auto Identify() -> PalIdentity
|
||||
{
|
||||
return PalIndividual::IdentifyFromParameter(GetIndividualParameterObject());
|
||||
}
|
||||
|
||||
auto CharacterId() -> std::optional<FName>
|
||||
{
|
||||
return PalIndividual::CharacterId(GetIndividualParameterObject());
|
||||
}
|
||||
|
||||
auto BlueprintClassName() const -> std::optional<StringType>
|
||||
{
|
||||
if (!m_obj) return std::nullopt;
|
||||
UClass* Cls = m_obj->GetClassPrivate();
|
||||
if (!Cls) return std::nullopt;
|
||||
return Cls->GetName();
|
||||
}
|
||||
|
||||
// ---- state queries ---------------------------------------------
|
||||
|
||||
auto IsInitialized() -> std::optional<bool> { return CallForReturn<bool>(STR("IsInitialized")); }
|
||||
auto IsPart() -> std::optional<bool> { return CallForReturn<bool>(STR("IsPart")); }
|
||||
auto IsCooping() -> std::optional<bool> { return CallForReturn<bool>(STR("IsCooping")); }
|
||||
auto IsPreCooping() -> std::optional<bool> { return CallForReturn<bool>(STR("IsPreCooping")); }
|
||||
auto IsLocalHiddenForCutscene() -> std::optional<bool> { return CallForReturn<bool>(STR("IsLocalHiddenForCutscene")); }
|
||||
auto IsUseCustomAutoAimTarget() -> std::optional<bool> { return CallForReturn<bool>(STR("IsUseCustomAutoAimTarget")); }
|
||||
auto IsAllActiveSkillCooldownFinished() -> std::optional<bool> { return CallForReturn<bool>(STR("IsAllActiveSkillCooldownFinished")); }
|
||||
auto GetBattleMode() -> std::optional<bool> { return CallForReturn<bool>(STR("GetBattleMode")); }
|
||||
auto GetTalkMode() -> std::optional<bool> { return CallForReturn<bool>(STR("GetTalkMode")); }
|
||||
auto GetActiveActorFlag() -> std::optional<bool> { return CallForReturn<bool>(STR("GetActiveActorFlag")); }
|
||||
|
||||
auto IsActiveSkillCooldownFinished(EPalWazaID_ WazaID) -> std::optional<bool>
|
||||
{
|
||||
struct P { EPalWazaID_ WazaID; bool ReturnValue; } p{ WazaID, false };
|
||||
return CallForReturn(STR("IsActiveSkillCooldownFinished"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
// ---- local-only mutators ---------------------------------------
|
||||
|
||||
auto ForceResetJumpState() -> bool { return CallVoid(STR("ForceResetJumpState")); }
|
||||
auto RequestJump() -> bool { return CallVoid(STR("RequestJump")); }
|
||||
auto ResetTickInterval() -> bool { return CallVoid(STR("ResetTickInterval")); }
|
||||
auto LocalInitialized() -> bool { return CallVoid(STR("LocalInitialized")); }
|
||||
auto RefreshDungeonLightingChannels() -> bool { return CallVoid(STR("RefreshDungeonLightingChannels")); }
|
||||
auto RequestExecuteTickNextFrameForAction() -> bool { return CallVoid(STR("RequestExecuteTickNextFrameForAction")); }
|
||||
auto BroadcastOnCompleteInitializeParameter() -> bool { return CallVoid(STR("BroadcastOnCompleteInitializeParameter")); }
|
||||
|
||||
auto UpdateGroundRayCast(bool bImmediateApply) -> bool
|
||||
{
|
||||
struct P { bool bImmediateApply; } p{ bImmediateApply };
|
||||
return Call(STR("UpdateGroundRayCast"), p);
|
||||
}
|
||||
auto SetVisibleCharacterMesh(bool Active) -> bool
|
||||
{
|
||||
struct P { bool Active; } p{ Active };
|
||||
return Call(STR("SetVisibleCharacterMesh"), p);
|
||||
}
|
||||
auto SetVisibleHandAttachMesh(bool Active) -> bool
|
||||
{
|
||||
struct P { bool Active; } p{ Active };
|
||||
return Call(STR("SetVisibleHandAttachMesh"), p);
|
||||
}
|
||||
auto SetLocalHiddenForCutscene(bool bHide) -> bool
|
||||
{
|
||||
struct P { bool bHide; } p{ bHide };
|
||||
return Call(STR("SetLocalHiddenForCutscene"), p);
|
||||
}
|
||||
auto SetActiveCollisionMovement(bool Active) -> bool
|
||||
{
|
||||
struct P { bool Active; } p{ Active };
|
||||
return Call(STR("SetActiveCollisionMovement"), p);
|
||||
}
|
||||
auto ChangeBattleModeFlag(bool IsBattle) -> bool
|
||||
{
|
||||
struct P { bool IsBattle; } p{ IsBattle };
|
||||
return Call(STR("ChangeBattleModeFlag"), p);
|
||||
}
|
||||
auto SetDisableChangeIntervalByImportance(FName FlagName, bool bIsDisable) -> bool
|
||||
{
|
||||
struct P { FName flagName; bool isDisable; } p{ FlagName, bIsDisable };
|
||||
return Call(STR("SetDisableChangeIntervalByImportance"), p);
|
||||
}
|
||||
|
||||
private:
|
||||
auto ObjectGetter(const TCHAR* FunctionName) -> UObject*
|
||||
{
|
||||
struct P { UObject* ReturnValue; } p{ nullptr };
|
||||
auto Result = CallForReturn(FunctionName, p, &P::ReturnValue);
|
||||
return (Result && *Result) ? *Result : nullptr;
|
||||
}
|
||||
};
|
||||
}
|
||||
369
Api/Pal/PalDatabaseCharacterParameter.hpp
Normal file
369
Api/Pal/PalDatabaseCharacterParameter.hpp
Normal file
@@ -0,0 +1,369 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <Unreal/FText.hpp>
|
||||
#include <Unreal/NameTypes.hpp>
|
||||
|
||||
#include <Api/UnrealWrapper.hpp>
|
||||
#include <Static/LogGate.hpp>
|
||||
#include "PalIndividual.hpp"
|
||||
#include "PalTypes.hpp"
|
||||
|
||||
namespace PalUIExtension::Api::Pal
|
||||
{
|
||||
|
||||
class PalDatabaseCharacterParameter : public UnrealWrapper
|
||||
{
|
||||
public:
|
||||
static auto ClassPath() -> const TCHAR* { return STR("/Script/Pal.PalDatabaseCharacterParameter"); }
|
||||
static auto DebugTag() -> const TCHAR* { return STR("PalDatabase"); }
|
||||
|
||||
PalDatabaseCharacterParameter() = default;
|
||||
explicit PalDatabaseCharacterParameter(UObject* Obj) : UnrealWrapper(Obj, ClassOf<PalDatabaseCharacterParameter>(), DebugTag()) {}
|
||||
|
||||
|
||||
static auto StripVariantPrefix(FName CharacterId) -> std::optional<FName>
|
||||
{
|
||||
const StringType Id = CharacterId.ToString();
|
||||
|
||||
static const StringType Prefixes[] = {
|
||||
STR("BOSS_"), STR("PREDATOR_"), STR("RAID_"), STR("GYM_"),
|
||||
};
|
||||
|
||||
for (const StringType& Prefix : Prefixes)
|
||||
{
|
||||
if (Id.size() <= Prefix.size()) continue;
|
||||
if (!StartsWithNoCase(Id, Prefix)) continue;
|
||||
|
||||
return FName(StringViewType(Id).substr(Prefix.size()), FNAME_Add);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static auto ResolveBaseRowName(FName CharacterId) -> FName
|
||||
{
|
||||
return StripVariantPrefix(CharacterId).value_or(CharacterId);
|
||||
}
|
||||
|
||||
// ---- row lookups by species FName -----------------------------
|
||||
|
||||
auto GetZukanIndex(FName RowName) -> std::optional<int32>
|
||||
{
|
||||
struct P { FName RowName; int32 ReturnValue; } p{ RowName, 0 };
|
||||
return CallForReturn(STR("GetZukanIndex"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
auto GetZukanIndexResolved(FName CharacterId) -> std::optional<int32>
|
||||
{
|
||||
if (auto Direct = GetZukanIndex(CharacterId); Direct.has_value() && *Direct > 0)
|
||||
{
|
||||
return Direct;
|
||||
}
|
||||
|
||||
auto Base = StripVariantPrefix(CharacterId);
|
||||
if (!Base.has_value()) return std::nullopt;
|
||||
|
||||
auto Fallback = GetZukanIndex(*Base);
|
||||
if (!Fallback.has_value() || *Fallback <= 0) return std::nullopt;
|
||||
|
||||
if constexpr (Static::kVerboseLogging)
|
||||
{
|
||||
Output::send<LogLevel::Verbose>(
|
||||
STR("[PalDatabase] ZukanIndex: '{}' had none, resolved via base '{}' -> {}\n"),
|
||||
CharacterId.ToString(), Base->ToString(), *Fallback);
|
||||
}
|
||||
|
||||
return Fallback;
|
||||
}
|
||||
|
||||
|
||||
auto GetLocalizedBaseCharacterName(FName CharacterId) -> std::optional<FText>
|
||||
{
|
||||
return GetLocalizedCharacterName(ResolveBaseRowName(CharacterId));
|
||||
}
|
||||
|
||||
auto GetTribe(FName RowName) -> std::optional<EPalTribeID_>
|
||||
{
|
||||
struct P { FName RowName; EPalTribeID_ ReturnValue; } p{ RowName, 0 };
|
||||
return CallForReturn(STR("GetTribe"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetSize(FName RowName) -> std::optional<EPalSizeType_>
|
||||
{
|
||||
struct P { FName RowName; EPalSizeType_ ReturnValue; } p{ RowName, EPalSizeType_::None };
|
||||
return CallForReturn(STR("GetSize"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetGenusCategory(FName RowName) -> std::optional<EPalGenusCategoryType_>
|
||||
{
|
||||
struct P { FName RowName; EPalGenusCategoryType_ ReturnValue; } p{ RowName, EPalGenusCategoryType_::None };
|
||||
return CallForReturn(STR("GetGenusCategory"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetOrganizationType(FName RowName) -> std::optional<EPalOrganizationType_>
|
||||
{
|
||||
struct P { FName RowName; EPalOrganizationType_ ReturnValue; } p{ RowName, EPalOrganizationType_::None };
|
||||
return CallForReturn(STR("GetOrganizationType"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetWeaponType(FName RowName) -> std::optional<EPalWeaponType_>
|
||||
{
|
||||
struct P { FName RowName; EPalWeaponType_ ReturnValue; } p{ RowName, EPalWeaponType_::None };
|
||||
return CallForReturn(STR("GetWeaponType"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetBattleBGM(FName RowName) -> std::optional<EPalBattleBGMType_>
|
||||
{
|
||||
struct P { FName RowName; EPalBattleBGMType_ ReturnValue; } p{ RowName, EPalBattleBGMType_::None };
|
||||
return CallForReturn(STR("GetBattleBGM"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetPalAwakeningItemElement(FName ItemId) -> std::optional<EPalElementType_>
|
||||
{
|
||||
struct P { FName ItemId; EPalElementType_ ReturnValue; } p{ ItemId, EPalElementType_::None };
|
||||
return CallForReturn(STR("GetPalAwakeningItemElement"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
struct ElementTypePair { EPalElementType_ Primary{}; EPalElementType_ Secondary{}; };
|
||||
// void return, two out-params -- not CallForReturn's shape.
|
||||
auto GetElementType(FName RowName) -> std::optional<ElementTypePair>
|
||||
{
|
||||
struct P { FName RowName; EPalElementType_ Element1; EPalElementType_ Element2; }
|
||||
p{ RowName, EPalElementType_::None, EPalElementType_::None };
|
||||
if (!Call(STR("GetElementType"), p)) return std::nullopt;
|
||||
return ElementTypePair{ p.Element1, p.Element2 };
|
||||
}
|
||||
|
||||
// void return, one out-param.
|
||||
auto GetBestWorkSuitability(FName RowName) -> std::optional<EPalWorkSuitability_>
|
||||
{
|
||||
struct P { FName RowName; EPalWorkSuitability_ BestWorkSuitability; }
|
||||
p{ RowName, EPalWorkSuitability_::None };
|
||||
if (!Call(STR("GetBestWorkSuitability"), p)) return std::nullopt;
|
||||
return p.BestWorkSuitability;
|
||||
}
|
||||
|
||||
auto GetWeaponEquip(FName RowName) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName RowName; bool ReturnValue; } p{ RowName, false };
|
||||
return CallForReturn(STR("GetWeaponEquip"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetUseBossHPGauge(FName RowName) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName RowName; bool ReturnValue; } p{ RowName, false };
|
||||
return CallForReturn(STR("GetUseBossHPGauge"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetNocturnal(FName RowName) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName RowName; bool ReturnValue; } p{ RowName, false };
|
||||
return CallForReturn(STR("GetNocturnal"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetIsTowerBoss(FName RowName) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName RowName; bool ReturnValue; } p{ RowName, false };
|
||||
return CallForReturn(STR("GetIsTowerBoss"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetIsRaidBoss(FName RowName) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName RowName; bool ReturnValue; } p{ RowName, false };
|
||||
return CallForReturn(STR("GetIsRaidBoss"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetIsPredatorBoss(FName RowName) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName RowName; bool ReturnValue; } p{ RowName, false };
|
||||
return CallForReturn(STR("GetIsPredatorBoss"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetIsPal(FName RowName) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName RowName; bool ReturnValue; } p{ RowName, false };
|
||||
return CallForReturn(STR("GetIsPal"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetIsLegend(FName RowName) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName RowName; bool ReturnValue; } p{ RowName, false };
|
||||
return CallForReturn(STR("GetIsLegend"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetIsBoss(FName RowName) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName RowName; bool ReturnValue; } p{ RowName, false };
|
||||
return CallForReturn(STR("GetIsBoss"), p, &P::ReturnValue);
|
||||
}
|
||||
auto IsArenaUnusableItem(FName ItemId) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName ItemId; bool ReturnValue; } p{ ItemId, false };
|
||||
return CallForReturn(STR("IsArenaUnusableItem"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
auto GetViewingDistance_cm(FName RowName) -> std::optional<int32>
|
||||
{
|
||||
struct P { FName RowName; int32 ReturnValue; } p{ RowName, 0 };
|
||||
return CallForReturn(STR("GetViewingDistance_cm"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetViewingAngle_Degree(FName RowName) -> std::optional<int32>
|
||||
{
|
||||
struct P { FName RowName; int32 ReturnValue; } p{ RowName, 0 };
|
||||
return CallForReturn(STR("GetViewingAngle_Degree"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetRarity(FName RowName) -> std::optional<int32>
|
||||
{
|
||||
struct P { FName RowName; int32 ReturnValue; } p{ RowName, 0 };
|
||||
return CallForReturn(STR("GetRarity"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetFoodAmount(FName RowName) -> std::optional<int32>
|
||||
{
|
||||
struct P { FName RowName; int32 ReturnValue; } p{ RowName, 0 };
|
||||
return CallForReturn(STR("GetFoodAmount"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
auto GetPriceRate(FName RowName) -> std::optional<float>
|
||||
{
|
||||
struct P { FName RowName; float ReturnValue; } p{ RowName, 0.f };
|
||||
return CallForReturn(STR("GetPriceRate"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetHearingRate(FName RowName) -> std::optional<float>
|
||||
{
|
||||
struct P { FName RowName; float ReturnValue; } p{ RowName, 0.f };
|
||||
return CallForReturn(STR("GetHearingRate"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetExpRatio(FName RowName) -> std::optional<float>
|
||||
{
|
||||
struct P { FName RowName; float ReturnValue; } p{ RowName, 0.f };
|
||||
return CallForReturn(STR("GetExpRatio"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetCaptureRateCorrect(FName RowName) -> std::optional<float>
|
||||
{
|
||||
struct P { FName RowName; float ReturnValue; } p{ RowName, 0.f };
|
||||
return CallForReturn(STR("GetCaptureRateCorrect"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
auto GetBPClassName(FName RowName) -> std::optional<FName>
|
||||
{
|
||||
struct P { FName RowName; FName ReturnValue; } p{ RowName, {} };
|
||||
return CallForReturn(STR("GetBPClassName"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetFirstDefeatRewardItemID(FName CharacterID) -> std::optional<FName>
|
||||
{
|
||||
struct P { FName CharacterID; FName ReturnValue; } p{ CharacterID, {} };
|
||||
return CallForReturn(STR("GetFirstDefeatRewardItemID"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
// void return, FName out-param -- not a FString, no ownership question, just an index pair like every other FName here.
|
||||
auto GetPrefixNameMsgID(FName CharacterID) -> std::optional<FName>
|
||||
{
|
||||
struct P { FName CharacterID; FName OutMsgID; } p{ CharacterID, {} };
|
||||
if (!Call(STR("GetPrefixNameMsgID"), p)) return std::nullopt;
|
||||
return p.OutMsgID;
|
||||
}
|
||||
|
||||
auto GetLocalizedCharacterName(FName CharacterID) -> std::optional<FText>
|
||||
{
|
||||
struct P { FName CharacterID; FText OutText; } p{ CharacterID, {} };
|
||||
if (!Call(STR("GetLocalizedCharacterName"), p)) return std::nullopt;
|
||||
return p.OutText;
|
||||
}
|
||||
auto GetLocalizedUniqueNPCName(FName UniqueNPCID) -> std::optional<FText>
|
||||
{
|
||||
struct P { FName UniqueNPCID; FText OutText; } p{ UniqueNPCID, {} };
|
||||
if (!Call(STR("GetLocalizedUniqueNPCName"), p)) return std::nullopt;
|
||||
return p.OutText;
|
||||
}
|
||||
|
||||
// ---- friendship ------------------------------------------------
|
||||
|
||||
auto GetMinFriendshipRank() -> std::optional<int32> { return CallForReturn<int32>(STR("GetMinFriendshipRank")); }
|
||||
auto GetMaxFriendshipRank() -> std::optional<int32> { return CallForReturn<int32>(STR("GetMaxFriendshipRank")); }
|
||||
auto GetFriendshipRank(int32 FriendshipPoint) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 FriendshipPoint; int32 ReturnValue; } p{ FriendshipPoint, 0 };
|
||||
return CallForReturn(STR("GetFriendshipRank"), p, &P::ReturnValue);
|
||||
}
|
||||
auto CalcFriendshipProgress(int32 FriendshipPoint) -> std::optional<float>
|
||||
{
|
||||
struct P { int32 FriendshipPoint; float ReturnValue; } p{ FriendshipPoint, 0.f };
|
||||
return CallForReturn(STR("CalcFriendshipProgress"), p, &P::ReturnValue);
|
||||
}
|
||||
// bool return + int32& out-param.
|
||||
auto GetFriendshipRequiredPointByRank(int32 FriendshipRank) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 FriendshipRank; int32 OutRequiredPoint; bool ReturnValue; }
|
||||
p{ FriendshipRank, 0, false };
|
||||
if (!Call(STR("GetFriendshipRequiredPointByRank"), p) || !p.ReturnValue) return std::nullopt;
|
||||
return p.OutRequiredPoint;
|
||||
}
|
||||
|
||||
// ---- derived from a live UPalIndividualCharacterParameter* ---------
|
||||
|
||||
auto GetHP(UObject* IndividualParameter) -> std::optional<int32>
|
||||
{
|
||||
struct P { UObject* IndividualParameter; int32 ReturnValue; } p{ IndividualParameter, 0 };
|
||||
return CallForReturn(STR("GetHP"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetMeleeAttack(UObject* IndividualParameter) -> std::optional<int32>
|
||||
{
|
||||
struct P { UObject* IndividualParameter; int32 ReturnValue; } p{ IndividualParameter, 0 };
|
||||
return CallForReturn(STR("GetMeleeAttack"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetShotAttack(UObject* IndividualParameter) -> std::optional<int32>
|
||||
{
|
||||
struct P { UObject* IndividualParameter; int32 ReturnValue; } p{ IndividualParameter, 0 };
|
||||
return CallForReturn(STR("GetShotAttack"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDefense(UObject* IndividualParameter) -> std::optional<int32>
|
||||
{
|
||||
struct P { UObject* IndividualParameter; int32 ReturnValue; } p{ IndividualParameter, 0 };
|
||||
return CallForReturn(STR("GetDefense"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetCraftSpeed(UObject* IndividualParameter) -> std::optional<int32>
|
||||
{
|
||||
struct P { UObject* IndividualParameter; int32 ReturnValue; } p{ IndividualParameter, 0 };
|
||||
return CallForReturn(STR("GetCraftSpeed"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetSupport(UObject* IndividualParameter) -> std::optional<int32>
|
||||
{
|
||||
struct P { UObject* IndividualParameter; int32 ReturnValue; } p{ IndividualParameter, 0 };
|
||||
return CallForReturn(STR("GetSupport"), p, &P::ReturnValue);
|
||||
}
|
||||
auto HigherLevelOtomoFromTrainer(UObject* IndividualCharacterParameter) -> std::optional<int32>
|
||||
{
|
||||
struct P { UObject* IndividualCharacterParameter; int32 ReturnValue; } p{ IndividualCharacterParameter, 0 };
|
||||
return CallForReturn(STR("HigherLevelOtomoFromTrainer"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
auto UpdateApplyDatabaseToIndividualParameter(UObject* IndividualParameter) -> bool
|
||||
{
|
||||
struct P { UObject* IndividualParameter; } p{ IndividualParameter };
|
||||
return Call(STR("UpdateApplyDatabaseToIndividualParameter"), p);
|
||||
}
|
||||
|
||||
// Raw UObject* return -- UPalPettingPresset isn't modeled anywhere
|
||||
auto GetPettingPreset() -> UObject*
|
||||
{
|
||||
struct P { UObject* ReturnValue; } p{ nullptr };
|
||||
auto Result = CallForReturn(STR("GetPettingPreset"), p, &P::ReturnValue);
|
||||
return (Result && *Result) ? *Result : nullptr;
|
||||
}
|
||||
|
||||
// WorldContextObject is a plain UObject* at the native signature
|
||||
// level -- the meta=(WorldContext=...) annotation only affects
|
||||
// the Blueprint editor node, not the ProcessEvent frame. Pass
|
||||
// any live UObject with a valid world (a player controller, an
|
||||
// actor, etc.).
|
||||
auto CalcCorrectedLevel(int32 TrainerLevel, int32 TargetCharacterLevel, UObject* WorldContextObject) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 TrainerLevel; int32 TargetCharacterLevel; UObject* WorldContextObject; int32 ReturnValue; }
|
||||
p{ TrainerLevel, TargetCharacterLevel, WorldContextObject, 0 };
|
||||
return CallForReturn(STR("CalcCorrectedLevel"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static auto StartsWithNoCase(const StringType& Str, const StringType& Prefix) -> bool
|
||||
{
|
||||
if (Str.size() < Prefix.size()) return false;
|
||||
for (size_t i = 0; i < Prefix.size(); ++i)
|
||||
{
|
||||
CharType A = Str[i];
|
||||
CharType B = Prefix[i];
|
||||
if (A >= STR('a') && A <= STR('z')) A = static_cast<CharType>(A - STR('a') + STR('A'));
|
||||
if (B >= STR('a') && B <= STR('z')) B = static_cast<CharType>(B - STR('a') + STR('A'));
|
||||
if (A != B) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
301
Api/Pal/PalGameMode.hpp
Normal file
301
Api/Pal/PalGameMode.hpp
Normal file
@@ -0,0 +1,301 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <Unreal/FString.hpp>
|
||||
#include <Unreal/NameTypes.hpp>
|
||||
|
||||
#include <Api/UnrealWrapper.hpp>
|
||||
|
||||
namespace PalUIExtension::Api::Pal
|
||||
{
|
||||
using namespace RC;
|
||||
using namespace RC::Unreal;
|
||||
|
||||
// ==================================================================
|
||||
// EPalGameModeType -- confirmed from the dump, UENUM(BlueprintType)
|
||||
// over uint8, two values. Mirrored here for the same reason
|
||||
// ESlateVisibility_ is: a params struct needs a concrete type of the
|
||||
// right width, and pulling in the game's generated header is not an
|
||||
// option.
|
||||
// ==================================================================
|
||||
enum class EPalGameModeType_ : uint8
|
||||
{
|
||||
Title = 0,
|
||||
InGame = 1,
|
||||
};
|
||||
|
||||
// ==================================================================
|
||||
// APalGameModeBase.
|
||||
//
|
||||
// Two things exist on this class and one of them matters:
|
||||
// GameModeType, an FEnumProperty over uint8. Read it to tell the
|
||||
// title screen apart from a live world without inspecting the map
|
||||
// name.
|
||||
//
|
||||
// ---- THE THING TO INTERNALISE ABOUT GAME MODES -------------------
|
||||
//
|
||||
// A GameMode exists ONLY ON THE AUTHORITY. On a listen host and in
|
||||
// single-player that is the local process, so this class is
|
||||
// reachable. On a client connected to a dedicated server, no
|
||||
// APalGameMode is ever instantiated locally and nothing in this file
|
||||
// will ever resolve to anything.
|
||||
//
|
||||
// That is not a limitation of this wrapper, it is what a game mode
|
||||
// IS, and it decides what you may and may not build on top of it. A
|
||||
// client-side UI mod that depends on a game-mode hook for
|
||||
// correctness is broken for every dedicated-server player. Use these
|
||||
// as a supplement to an engine-level signal, never as the only one.
|
||||
// ==================================================================
|
||||
class PalGameModeBase : public UnrealWrapper
|
||||
{
|
||||
public:
|
||||
static auto ClassPath() -> const TCHAR* { return STR("/Script/Pal.PalGameModeBase"); }
|
||||
static auto DebugTag() -> const TCHAR* { return STR("PalGameModeBase"); }
|
||||
|
||||
PalGameModeBase() = default;
|
||||
explicit PalGameModeBase(UObject* Obj)
|
||||
: UnrealWrapper(Obj, ClassOf<PalGameModeBase>(), DebugTag()) {}
|
||||
|
||||
// FEnumProperty over uint8 -- GetSize() reports 1, and
|
||||
// EPalGameModeType_ is 1 byte, so the size check in PropertyPtr is
|
||||
// meaningful here rather than vacuous.
|
||||
auto GameModeType() const -> std::optional<EPalGameModeType_>
|
||||
{
|
||||
return PropertyValue<EPalGameModeType_>(STR("GameModeType"));
|
||||
}
|
||||
|
||||
auto IsInGame() const -> bool
|
||||
{
|
||||
const auto T = GameModeType();
|
||||
return T.has_value() && *T == EPalGameModeType_::InGame;
|
||||
}
|
||||
|
||||
auto IsTitle() const -> bool
|
||||
{
|
||||
const auto T = GameModeType();
|
||||
return T.has_value() && *T == EPalGameModeType_::Title;
|
||||
}
|
||||
|
||||
protected:
|
||||
PalGameModeBase(UObject* Obj, UClass* Expected, const TCHAR* Tag)
|
||||
: UnrealWrapper(Obj, Expected, Tag) {}
|
||||
};
|
||||
|
||||
// ==================================================================
|
||||
// APalGameMode -- the in-world game mode.
|
||||
//
|
||||
// ---- WHAT IS WORTH HOOKING HERE, AND WHAT IS NOT -----------------
|
||||
//
|
||||
// RestartGame is the one this tree cares about: it is the game
|
||||
// deciding the current world is finished, fired BEFORE the travel
|
||||
// that destroys it. That ordering is the whole value -- a cache of
|
||||
// widget pointers wants to be dropped while those pointers are still
|
||||
// merely useless, not after they are dangling.
|
||||
//
|
||||
// READ THE CAVEAT BLOCK ON RestartGamePath() BEFORE RELYING ON IT.
|
||||
// It has two failure modes that are invisible in testing if you only
|
||||
// test single-player.
|
||||
//
|
||||
// The session/auth callbacks (OnUpdateSession, OnCompleteAuth,
|
||||
// OnCompleteCreateSession, OnEOSLoginDedicatedServerComplete) are
|
||||
// dedicated-server plumbing. They are wrapped as PATHS ONLY, with
|
||||
// frames, because they are occasionally useful for diagnosing "why
|
||||
// did my server mod not initialise" -- but nothing in a client-side
|
||||
// UI mod should be reading them, and none of them fire in
|
||||
// single-player at all.
|
||||
//
|
||||
// ---- WHY THERE IS NO Current() -----------------------------------
|
||||
//
|
||||
// The obvious convenience -- a static that hands back the live game
|
||||
// mode -- is deliberately absent. Every way to get one without a
|
||||
// UWorld in hand goes through UObjectGlobals::FindObject or
|
||||
// FindObjects, and for a Blueprint-reachable native class that is a
|
||||
// linear walk of the entire GUObjectArray (see the note in
|
||||
// PalBoxNightWorkIndicator on what that cost actually is). A helper
|
||||
// that looks like a property read and is really a million-object scan
|
||||
// is the kind of convenience that ends up on a per-frame path.
|
||||
//
|
||||
// Get the instance from a hook that already has it instead: every
|
||||
// callback below receives it as Ctx.Context, and
|
||||
// Hook::RegisterInitGameStatePostCallback hands over an
|
||||
// AGameModeBase* directly at world start.
|
||||
// ==================================================================
|
||||
class PalGameMode : public PalGameModeBase
|
||||
{
|
||||
public:
|
||||
static auto ClassPath() -> const TCHAR* { return STR("/Script/Pal.PalGameMode"); }
|
||||
static auto DebugTag() -> const TCHAR* { return STR("PalGameMode"); }
|
||||
|
||||
PalGameMode() = default;
|
||||
explicit PalGameMode(UObject* Obj)
|
||||
: PalGameModeBase(Obj, ClassOf<PalGameMode>(), DebugTag()) {}
|
||||
|
||||
// ---- properties ------------------------------------------------
|
||||
|
||||
// APlayerStart*. No wrapper for it in this tree, so the raw
|
||||
// pointer is the honest return type.
|
||||
auto CachePlayerStart() const -> UObject*
|
||||
{
|
||||
return TryObjectProperty(STR("CachePlayerStart"));
|
||||
}
|
||||
|
||||
// ==============================================================
|
||||
// HOOK TARGETS
|
||||
// ==============================================================
|
||||
|
||||
// ==============================================================
|
||||
// RestartGame. READ THIS BEFORE BUILDING ON IT.
|
||||
//
|
||||
// Two failure modes, both silent, both invisible if you only
|
||||
// test single-player:
|
||||
//
|
||||
// 1. AUTHORITY ONLY. No APalGameMode is instantiated on a client
|
||||
// connected to a dedicated server, so this hook never installs
|
||||
// and never fires there. For a client-side UI mod that is the
|
||||
// majority multiplayer case.
|
||||
//
|
||||
// 2. REFLECTION ONLY. This is a native UFUNCTION(BlueprintCallable).
|
||||
// UE4SS hooks UFunction execution, which catches invocations
|
||||
// that go through ProcessEvent -- a Blueprint node, a console
|
||||
// exec, a reflected call. It does NOT catch native C++ code
|
||||
// calling APalGameMode::RestartGame() directly, because that
|
||||
// path never touches the reflection system. Whether Palworld
|
||||
// restarts via Blueprint or via C++ is not answerable from a
|
||||
// header dump; it has to be observed.
|
||||
//
|
||||
// The practical consequence: treat a RestartGame callback as an
|
||||
// OPPORTUNISTIC EARLY WARNING, not as the teardown signal. The
|
||||
// load-bearing one is Hook::RegisterLoadMapPreCallback, which is
|
||||
// engine-level, fires on every map transition regardless of what
|
||||
// triggered it, and works identically on clients and hosts.
|
||||
//
|
||||
// Wiring both is correct and costs nothing: teardown must be
|
||||
// idempotent anyway, since a restart that goes through both paths
|
||||
// will call it twice.
|
||||
// ==============================================================
|
||||
static auto RestartGamePath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameMode:RestartGame");
|
||||
}
|
||||
|
||||
static auto InitDedicatedServerPath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameMode:InitDedicatedServer");
|
||||
}
|
||||
|
||||
static auto OnServerLobbyUpdatePath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameMode:OnServerLobbyUpdate");
|
||||
}
|
||||
|
||||
static auto OnUpdateSessionPath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameMode:OnUpdateSession");
|
||||
}
|
||||
|
||||
static auto OnCompleteAuthPath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameMode:OnCompleteAuth");
|
||||
}
|
||||
|
||||
static auto OnCompleteCreateSessionPath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameMode:OnCompleteCreateSession");
|
||||
}
|
||||
|
||||
static auto OnEOSLoginDedicatedServerCompletePath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameMode:OnEOSLoginDedicatedServerComplete");
|
||||
}
|
||||
|
||||
static auto CreateSessionPath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameMode:CreateSession");
|
||||
}
|
||||
|
||||
static auto FindPlayerStartWithTagPath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameMode:FindPlayerStartWithTag");
|
||||
}
|
||||
|
||||
// ---- frames ---------------------------------------------------
|
||||
//
|
||||
// Leading parameters only, matching the convention in
|
||||
// PalCommonCharacterSlot.hpp: hook frames are NOT size-checked, so
|
||||
// reading past the declared parameters reads engine locals. On a
|
||||
// PRE hook those are uninitialised.
|
||||
//
|
||||
// The FString members are the part to be careful with. A
|
||||
// `const FString&` UFUNCTION parameter still occupies a full
|
||||
// FString in the frame (TArray<TCHAR>: 8-byte data pointer +
|
||||
// int32 Num + int32 Max = 16 bytes), so the layout below is what
|
||||
// the engine writes. It is NOT owned by you -- read it, do not
|
||||
// move from it, do not free it.
|
||||
//
|
||||
// RestartGame takes nothing, which is why there is no frame for
|
||||
// it and why its callback should not call Ctx.GetParams at all.
|
||||
|
||||
struct HttpResponseFrame
|
||||
{
|
||||
FString ResponseBody; // 0x00
|
||||
bool bResponseOK; // 0x10
|
||||
int32 ResponseCode; // 0x14 (after 3 bytes of padding)
|
||||
};
|
||||
|
||||
struct EOSLoginCompleteFrame
|
||||
{
|
||||
UObject* UserInfo; // 0x00 const UPocketpairUserInfo*
|
||||
bool bSuccess; // 0x08
|
||||
FString ErrorStr; // 0x10 (after 7 bytes of padding)
|
||||
};
|
||||
|
||||
struct CreateSessionFrame { FString Address; };
|
||||
struct FindPlayerStartWithTagFrame { FName Tag; UObject* ReturnValue; };
|
||||
|
||||
protected:
|
||||
PalGameMode(UObject* Obj, UClass* Expected, const TCHAR* Tag)
|
||||
: PalGameModeBase(Obj, Expected, Tag) {}
|
||||
};
|
||||
|
||||
// ==================================================================
|
||||
// APalGameModeLogin -- the title-screen game mode.
|
||||
//
|
||||
// Included because it is the OTHER half of the world-lifecycle
|
||||
// picture and it is easy to forget it exists: going from a save back
|
||||
// to the title is a map transition into THIS game mode, not a
|
||||
// RestartGame on the previous one. If teardown only fires on
|
||||
// APalGameMode, quitting to title leaves every cached pointer alive
|
||||
// and dangling.
|
||||
//
|
||||
// GoToTitle is BlueprintImplementableEvent -- no native body. It
|
||||
// dispatches through the object's class chain like anything else, so
|
||||
// it is hookable, but if no Blueprint subclass overrides it there is
|
||||
// nothing to hook and the registry will defer forever.
|
||||
// ==================================================================
|
||||
class PalGameModeLogin : public PalGameModeBase
|
||||
{
|
||||
public:
|
||||
static auto ClassPath() -> const TCHAR* { return STR("/Script/Pal.PalGameModeLogin"); }
|
||||
static auto DebugTag() -> const TCHAR* { return STR("PalGameModeLogin"); }
|
||||
|
||||
PalGameModeLogin() = default;
|
||||
explicit PalGameModeLogin(UObject* Obj)
|
||||
: PalGameModeBase(Obj, ClassOf<PalGameModeLogin>(), DebugTag()) {}
|
||||
|
||||
static auto OnCompletePath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameModeLogin:OnComplete");
|
||||
}
|
||||
static auto GoToTitlePath() -> const TCHAR*
|
||||
{
|
||||
return STR("/Script/Pal.PalGameModeLogin:GoToTitle");
|
||||
}
|
||||
|
||||
struct OnCompleteFrame { bool bCanPlayMulti; };
|
||||
|
||||
protected:
|
||||
PalGameModeLogin(UObject* Obj, UClass* Expected, const TCHAR* Tag)
|
||||
: PalGameModeBase(Obj, Expected, Tag) {}
|
||||
};
|
||||
}
|
||||
127
Api/Pal/PalIndividual.hpp
Normal file
127
Api/Pal/PalIndividual.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <cstring>
|
||||
|
||||
#include <Unreal/FText.hpp>
|
||||
#include <Unreal/NameTypes.hpp>
|
||||
|
||||
#include <Api\UmgTypes.hpp>
|
||||
#include <Api\UnrealWrapper.hpp>
|
||||
|
||||
#include "PalTypes.hpp"
|
||||
|
||||
namespace PalUIExtension::Api::Pal
|
||||
{
|
||||
|
||||
enum class EPalGenderType_ : uint8 { None = 0, Male = 1, Female = 2 };
|
||||
|
||||
enum class EPalElementType_ : uint8
|
||||
{
|
||||
None = 0, Normal = 1, Fire = 2, Water = 3, Leaf = 4,
|
||||
Electricity = 5, Ice = 6, Earth = 7, Dark = 8, Dragon = 9, MAX = 10,
|
||||
};
|
||||
|
||||
enum class EPalWorkSuitability_ : uint8
|
||||
{
|
||||
None = 0, EmitFlame = 1, Watering = 2, Seeding = 3,
|
||||
GenerateElectricity = 4, Handcraft = 5, Collection = 6, Deforest = 7,
|
||||
Mining = 8, OilExtraction = 9, ProductMedicine = 10, Cool = 11,
|
||||
Transport = 12, MonsterFarm = 13, Anyone = 14, MAX = 15,
|
||||
};
|
||||
|
||||
class LooseObject : public UnrealWrapper
|
||||
{
|
||||
public:
|
||||
LooseObject() = default;
|
||||
explicit LooseObject(UObject* Obj, const TCHAR* Tag = STR("Loose"))
|
||||
: UnrealWrapper(Obj, UncheckedTag{}, Tag) {
|
||||
}
|
||||
|
||||
using UnrealWrapper::Call;
|
||||
using UnrealWrapper::CallVoid;
|
||||
using UnrealWrapper::CallForReturn;
|
||||
using UnrealWrapper::PropertyPtr;
|
||||
using UnrealWrapper::PropertyValue;
|
||||
};
|
||||
|
||||
// this struct is now redundant. watch it never get removed.
|
||||
|
||||
struct FPalInstanceID {
|
||||
FGuid_ PlayerUID;
|
||||
FGuid_ InstanceID;
|
||||
FString DebugName;
|
||||
};
|
||||
|
||||
struct PalIdentity
|
||||
{
|
||||
UObject* Handle{};
|
||||
UObject* IndividualParameter{};
|
||||
|
||||
std::optional<FName> CharacterId; // the species. "SheepBall", etc.
|
||||
std::optional<int32> Level;
|
||||
std::optional<int32> Rank;
|
||||
std::optional<EPalGenderType_> Gender;
|
||||
std::optional<bool> bRare;
|
||||
|
||||
explicit operator bool() const { return CharacterId.has_value(); }
|
||||
};
|
||||
|
||||
class PalIndividual
|
||||
{
|
||||
public:
|
||||
static auto ParameterFromHandle(UObject* Handle) -> UObject*
|
||||
{
|
||||
if (!Handle) return nullptr;
|
||||
LooseObject H{ Handle, STR("PalIndividualCharacter") };
|
||||
return H.CallForReturn<UObject*>(STR("TryGetIndividualParameter")).value_or(nullptr);
|
||||
}
|
||||
|
||||
static auto CharacterId(UObject* Parameter) -> std::optional<FName>
|
||||
{
|
||||
if (!Parameter) return std::nullopt;
|
||||
LooseObject P{ Parameter, STR("PalIndividualCharacterParameter") };
|
||||
return P.CallForReturn<FName>(STR("GetCharacterID"));
|
||||
}
|
||||
|
||||
static auto CharacterIdFromHandle(UObject* Handle) -> std::optional<FName>
|
||||
{
|
||||
return CharacterId(ParameterFromHandle(Handle));
|
||||
}
|
||||
|
||||
static auto IdentifyFromParameter(UObject* Parameter) -> PalIdentity
|
||||
{
|
||||
PalIdentity Out{};
|
||||
Out.IndividualParameter = Parameter;
|
||||
if (!Parameter) return Out;
|
||||
|
||||
LooseObject P{ Parameter, STR("PalIndividualCharacterParameter") };
|
||||
Out.CharacterId = P.CallForReturn<FName>(STR("GetCharacterID"));
|
||||
Out.Level = P.CallForReturn<int32>(STR("GetLevel"));
|
||||
Out.Rank = P.CallForReturn<int32>(STR("GetRank"));
|
||||
Out.Gender = P.CallForReturn<EPalGenderType_>(STR("GetGenderType"));
|
||||
Out.bRare = P.CallForReturn<bool>(STR("IsRarePal"));
|
||||
return Out;
|
||||
}
|
||||
|
||||
static auto Identify(UObject* Handle) -> PalIdentity
|
||||
{
|
||||
PalIdentity Out = IdentifyFromParameter(ParameterFromHandle(Handle));
|
||||
Out.Handle = Handle;
|
||||
return Out;
|
||||
}
|
||||
|
||||
static auto GetInstanceIds(UObject* Handle) -> std::optional<FPalInstanceID>
|
||||
{
|
||||
if (!Handle) return std::nullopt;
|
||||
// FPalInstanceID
|
||||
LooseObject H{ Handle, STR("PalIndividualCharacterHandle") };
|
||||
auto _Out = H.CallForReturn<FPalInstanceID>(STR("GetIndividualID"));
|
||||
|
||||
if (!_Out.has_value()) return std::nullopt;
|
||||
return FPalInstanceID{ _Out.value().PlayerUID, _Out.value().InstanceID, _Out.value().DebugName };
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
56
Api/Pal/PalIndividualCharacterHandle.hpp
Normal file
56
Api/Pal/PalIndividualCharacterHandle.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <Api/UnrealWrapper.hpp>
|
||||
#include "PalIndividual.hpp"
|
||||
#include "PalCharacter.hpp"
|
||||
|
||||
namespace PalUIExtension::Api::Pal
|
||||
{
|
||||
class PalIndividualCharacterHandle : public UnrealWrapper
|
||||
{
|
||||
public:
|
||||
static auto ClassPath() -> const TCHAR* { return STR("/Script/Pal.PalIndividualCharacterHandle"); }
|
||||
static auto DebugTag() -> const TCHAR* { return STR("PalIndividualCharacterHandle"); }
|
||||
|
||||
PalIndividualCharacterHandle() = default;
|
||||
explicit PalIndividualCharacterHandle(UObject* Obj) : UnrealWrapper(Obj, ClassOf<PalIndividualCharacterHandle>(), DebugTag()) {}
|
||||
|
||||
auto TryGetIndividualParameterObject() -> UObject*
|
||||
{
|
||||
struct P { UObject* ReturnValue; } p{ nullptr };
|
||||
auto Result = CallForReturn(STR("TryGetIndividualParameter"), p, &P::ReturnValue);
|
||||
return (Result && *Result) ? *Result : nullptr;
|
||||
}
|
||||
|
||||
auto TryGetIndividualActorObject() -> UObject*
|
||||
{
|
||||
struct P { UObject* ReturnValue; } p{ nullptr };
|
||||
auto Result = CallForReturn(STR("TryGetIndividualActor"), p, &P::ReturnValue);
|
||||
return (Result && *Result) ? *Result : nullptr;
|
||||
}
|
||||
|
||||
auto TryGetIndividualActor() -> PalCharacter
|
||||
{
|
||||
UObject* A = TryGetIndividualActorObject();
|
||||
return A ? PalCharacter{ A } : PalCharacter{};
|
||||
}
|
||||
|
||||
auto TryGetPhantomActor(int32 PhantomId) -> UObject*
|
||||
{
|
||||
struct P { int32 PhantomId; UObject* ReturnValue; } p{ PhantomId, nullptr };
|
||||
auto Result = CallForReturn(STR("TryGetPhantomActor"), p, &P::ReturnValue);
|
||||
return (Result && *Result) ? *Result : nullptr;
|
||||
}
|
||||
|
||||
auto GetPhantomIDByActor(UObject* Character) -> std::optional<int32>
|
||||
{
|
||||
struct P { UObject* Character; int32 ReturnValue; } p{ Character, 0 };
|
||||
return CallForReturn(STR("GetPhantomIDByActor"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
auto GetInstanceIds() -> std::optional<FPalInstanceID>
|
||||
{
|
||||
return PalIndividual::GetInstanceIds(Get());
|
||||
}
|
||||
};
|
||||
}
|
||||
480
Api/Pal/PalIndividualCharacterParameter.hpp
Normal file
480
Api/Pal/PalIndividualCharacterParameter.hpp
Normal file
@@ -0,0 +1,480 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <Unreal/FText.hpp>
|
||||
#include <Unreal/NameTypes.hpp>
|
||||
|
||||
#include <Api/UnrealWrapper.hpp>
|
||||
#include "PalIndividual.hpp"
|
||||
#include "PalTypes.hpp"
|
||||
|
||||
namespace PalUIExtension::Api::Pal
|
||||
{
|
||||
|
||||
class PalIndividualCharacterParameter : public UnrealWrapper
|
||||
{
|
||||
public:
|
||||
static auto ClassPath() -> const TCHAR* { return STR("/Script/Pal.PalIndividualCharacterParameter"); }
|
||||
static auto DebugTag() -> const TCHAR* { return STR("PalIndividualCharacterParameter"); }
|
||||
|
||||
PalIndividualCharacterParameter() = default;
|
||||
explicit PalIndividualCharacterParameter(UObject* Obj) : UnrealWrapper(Obj, ClassOf<PalIndividualCharacterParameter>(), DebugTag()) {}
|
||||
|
||||
// ---- identity ---------------------------------------------------
|
||||
|
||||
auto GetCharacterID() -> std::optional<FName> { return CallForReturn<FName>(STR("GetCharacterID")); }
|
||||
auto GetUniqueNPCID() -> std::optional<FName> { return CallForReturn<FName>(STR("GetUniqueNPCID")); }
|
||||
auto GetSkinName() -> std::optional<FName> { return CallForReturn<FName>(STR("GetSkinName")); }
|
||||
|
||||
auto GetGenderType() -> std::optional<EPalGenderType_>
|
||||
{
|
||||
return CallForReturn<EPalGenderType_>(STR("GetGenderType"));
|
||||
}
|
||||
auto GetTribeID() -> std::optional<EPalTribeID_>
|
||||
{
|
||||
return CallForReturn<EPalTribeID_>(STR("GetTribeID"));
|
||||
}
|
||||
auto IsRarePal() -> std::optional<bool> { return CallForReturn<bool>(STR("IsRarePal")); }
|
||||
auto IsFavoritePal() -> std::optional<bool> { return CallForReturn<bool>(STR("IsFavoritePal")); }
|
||||
auto GetFavoriteIndex() -> std::optional<int32> { return CallForReturn<int32>(STR("GetFavoriteIndex")); }
|
||||
auto IsSkinApplied() -> std::optional<bool> { return CallForReturn<bool>(STR("IsSkinApplied")); }
|
||||
auto GetSkinAppliedCharacterId() -> std::optional<FGuid_>
|
||||
{
|
||||
return CallForReturn<FGuid_>(STR("GetSkinAppliedCharacterId"));
|
||||
}
|
||||
|
||||
auto GetPalId() -> std::optional<FPalInstanceID>
|
||||
{
|
||||
struct P { alignas(8) uint8 Frame[48]; } p{}; // FPalInstanceID
|
||||
if (!Call(STR("GetPalId"), p)) return std::nullopt;
|
||||
FPalInstanceID Out{};
|
||||
std::memcpy(&Out, p.Frame, sizeof(Out));
|
||||
return Out;
|
||||
}
|
||||
|
||||
// Nickname getters
|
||||
|
||||
auto GetNickname() -> std::optional<FString>
|
||||
{
|
||||
struct P { FString OutName; } p{};
|
||||
if (!Call(STR("GetNickname"), p)) return std::nullopt;
|
||||
return p.OutName;
|
||||
}
|
||||
auto GetNickNameWithOnlineID() -> std::optional<FString>
|
||||
{
|
||||
struct P { FString OutName; } p{};
|
||||
if (!Call(STR("GetNickNameWithOnlineID"), p)) return std::nullopt;
|
||||
return p.OutName;
|
||||
}
|
||||
auto GetNickNameByCheckBlockedUser() -> std::optional<FString>
|
||||
{
|
||||
struct P { FString OutName; } p{};
|
||||
if (!Call(STR("GetNickNameByCheckBlockedUser"), p)) return std::nullopt;
|
||||
return p.OutName;
|
||||
}
|
||||
|
||||
// ---- level / experience ------------------------------------------
|
||||
|
||||
auto GetLevel() -> std::optional<int32> { return CallForReturn<int32>(STR("GetLevel")); }
|
||||
auto IsLevelMax() -> std::optional<bool> { return CallForReturn<bool>(STR("IsLevelMax")); }
|
||||
auto GetExp() -> std::optional<int64> { return CallForReturn<int64>(STR("GetExp")); }
|
||||
auto GetRank() -> std::optional<int32> { return CallForReturn<int32>(STR("GetRank")); }
|
||||
auto GetRankUpExp() -> std::optional<int32> { return CallForReturn<int32>(STR("GetRankUpExp")); }
|
||||
auto GetPalSoulRank() -> std::optional<int32> { return CallForReturn<int32>(STR("GetPalSoulRank")); }
|
||||
auto IsOverrideLevel() -> std::optional<bool> { return CallForReturn<bool>(STR("IsOverrideLevel")); }
|
||||
auto GetOverrideLevel() -> std::optional<int32> { return CallForReturn<int32>(STR("GetOverrideLevel")); }
|
||||
|
||||
auto SetOverrideLevel(int32 OverrideLevel) -> bool
|
||||
{
|
||||
struct P { int32 OverrideLevel; } p{ OverrideLevel };
|
||||
return Call(STR("SetOverrideLevel"), p);
|
||||
}
|
||||
|
||||
// ---- HP / shield / death -----------------------------------------
|
||||
|
||||
auto GetHP() -> std::optional<FFixedPoint64_> { return CallForReturn<FFixedPoint64_>(STR("GetHP")); }
|
||||
auto GetMaxHP_withBuff() -> std::optional<FFixedPoint64_> { return CallForReturn<FFixedPoint64_>(STR("GetMaxHP_withBuff")); }
|
||||
auto GetMaxHP() -> std::optional<int32> { return CallForReturn<int32>(STR("GetMaxHP")); }
|
||||
auto GetHPRank() -> std::optional<int32> { return CallForReturn<int32>(STR("GetHPRank")); }
|
||||
|
||||
auto GetShieldHP() -> std::optional<FFixedPoint64_> { return CallForReturn<FFixedPoint64_>(STR("GetShieldHP")); }
|
||||
auto GetShieldMaxHP() -> std::optional<FFixedPoint64_> { return CallForReturn<FFixedPoint64_>(STR("GetShieldMaxHP")); }
|
||||
|
||||
auto GetCurrentPhaseHPLimit() -> std::optional<FFixedPoint64_>
|
||||
{
|
||||
struct P { FFixedPoint64_ OutPhaseHPLimit; bool ReturnValue; } p{ {}, false };
|
||||
auto Result = CallForReturn(STR("GetCurrentPhaseHPLimit"), p, &P::ReturnValue);
|
||||
if (!Result || !*Result) return std::nullopt;
|
||||
return p.OutPhaseHPLimit;
|
||||
}
|
||||
auto IsPhaseHPLimitValid() -> std::optional<bool> { return CallForReturn<bool>(STR("IsPhaseHPLimitValid")); }
|
||||
|
||||
auto AddHP(FFixedPoint64_ PlusHP) -> bool
|
||||
{
|
||||
struct P { FFixedPoint64_ PlusHP; } p{ PlusHP };
|
||||
return Call(STR("AddHP"), p);
|
||||
}
|
||||
auto FullRecoveryHP() -> bool { return CallVoid(STR("FullRecoveryHP")); }
|
||||
auto IsHPFullRecovered() -> std::optional<bool> { return CallForReturn<bool>(STR("IsHPFullRecovered")); }
|
||||
|
||||
auto SetShieldHP(FFixedPoint64_ NextShieldHP) -> bool
|
||||
{
|
||||
struct P { FFixedPoint64_ NextSheildHP; } p{ NextShieldHP }; // engine spelling
|
||||
return Call(STR("SetShieldHP"), p);
|
||||
}
|
||||
auto SetShieldMaxHP(FFixedPoint64_ NextShieldMaxHP) -> bool
|
||||
{
|
||||
struct P { FFixedPoint64_ NextSheildMaxHP; } p{ NextShieldMaxHP }; // engine spelling
|
||||
return Call(STR("SetShieldMaxHP"), p);
|
||||
}
|
||||
auto DecreaseShieldHPByDamage(int32 Damage) -> bool
|
||||
{
|
||||
struct P { int32 Damage; } p{ Damage };
|
||||
return Call(STR("DecreaseShieldHPByDamage"), p);
|
||||
}
|
||||
|
||||
auto IsDead() -> std::optional<bool> { return CallForReturn<bool>(STR("IsDead")); }
|
||||
auto GetPhysicalHealth() -> std::optional<EPalStatusPhysicalHealthType_>
|
||||
{
|
||||
return CallForReturn<EPalStatusPhysicalHealthType_>(STR("GetPhysicalHealth"));
|
||||
}
|
||||
auto SetPhysicalHealth(EPalStatusPhysicalHealthType_ PhysicalHealth) -> bool
|
||||
{
|
||||
struct P { EPalStatusPhysicalHealthType_ PhysicalHealth; } p{ PhysicalHealth };
|
||||
return Call(STR("SetPhysicalHealth"), p);
|
||||
}
|
||||
auto IsRespawnReady() -> std::optional<bool> { return CallForReturn<bool>(STR("IsRespawnReady")); }
|
||||
auto GetRespawnTime() -> std::optional<float> { return CallForReturn<float>(STR("GetRespawnTime")); }
|
||||
|
||||
// ---- combat stats -------------------------------------------------
|
||||
|
||||
auto GetMeleeAttack() -> std::optional<int32> { return CallForReturn<int32>(STR("GetMeleeAttack")); }
|
||||
auto GetMeleeAttack_withBuff() -> std::optional<int32> { return CallForReturn<int32>(STR("GetMeleeAttack_withBuff")); }
|
||||
auto GetShotAttack() -> std::optional<int32> { return CallForReturn<int32>(STR("GetShotAttack")); }
|
||||
auto GetShotAttack_withBuff() -> std::optional<int32> { return CallForReturn<int32>(STR("GetShotAttack_withBuff")); }
|
||||
auto GetDefense() -> std::optional<int32> { return CallForReturn<int32>(STR("GetDefense")); }
|
||||
auto GetDefense_withBuff() -> std::optional<int32> { return CallForReturn<int32>(STR("GetDefense_withBuff")); }
|
||||
auto GetAttackRank() -> std::optional<int32> { return CallForReturn<int32>(STR("GetAttackRank")); }
|
||||
auto GetDefenceRank() -> std::optional<int32> { return CallForReturn<int32>(STR("GetDefenceRank")); }
|
||||
|
||||
auto HasMasteredWaza(EPalWazaID_ WazaID) -> std::optional<bool>
|
||||
{
|
||||
struct P { EPalWazaID_ WazaID; bool ReturnValue; } p{ WazaID, false };
|
||||
return CallForReturn(STR("HasMasteredWaza"), p, &P::ReturnValue);
|
||||
}
|
||||
auto AddEquipWaza(EPalWazaID_ WazaID) -> bool
|
||||
{
|
||||
struct P { EPalWazaID_ WazaID; } p{ WazaID };
|
||||
return Call(STR("AddEquipWaza"), p);
|
||||
}
|
||||
auto RemoveEquipWaza(EPalWazaID_ WazaID) -> bool
|
||||
{
|
||||
struct P { EPalWazaID_ WazaID; } p{ WazaID };
|
||||
return Call(STR("RemoveEquipWaza"), p);
|
||||
}
|
||||
auto ClearEquipWaza() -> bool { return CallVoid(STR("ClearEquipWaza")); }
|
||||
|
||||
// ---- sanity / hunger / stomach ------------------------------------
|
||||
|
||||
auto GetSanityValue() -> std::optional<float> { return CallForReturn<float>(STR("GetSanityValue")); }
|
||||
auto GetMaxSanityValue() -> std::optional<float> { return CallForReturn<float>(STR("GetMaxSanityValue")); }
|
||||
auto GetSanityRate() -> std::optional<float> { return CallForReturn<float>(STR("GetSanityRate")); }
|
||||
auto GetAffectSanityValue() -> std::optional<float> { return CallForReturn<float>(STR("GetAffectSanityValue")); }
|
||||
|
||||
auto GetHungerType() -> std::optional<EPalStatusHungerType_>
|
||||
{
|
||||
return CallForReturn<EPalStatusHungerType_>(STR("GetHungerType"));
|
||||
}
|
||||
auto GetFullStomach() -> std::optional<float> { return CallForReturn<float>(STR("GetFullStomach")); }
|
||||
auto GetMaxFullStomach() -> std::optional<float> { return CallForReturn<float>(STR("GetMaxFullStomach")); }
|
||||
auto GetFullStomachRate() -> std::optional<float> { return CallForReturn<float>(STR("GetFullStomachRate")); }
|
||||
auto GetFullStomachDecreasingRate() -> std::optional<float> { return CallForReturn<float>(STR("GetFullStomachDecreasingRate")); }
|
||||
auto IsFullStomachDecreaseStoppedByFood() -> std::optional<bool>
|
||||
{
|
||||
return CallForReturn<bool>(STR("IsFullStomachDecreaseStoppedByFood"));
|
||||
}
|
||||
|
||||
auto SetFullStomach(float NextValue) -> bool
|
||||
{
|
||||
struct P { float NextValue; } p{ NextValue };
|
||||
return Call(STR("SetFullStomach"), p);
|
||||
}
|
||||
auto SetDecreaseFullStomachRates(FName Name, float Rate) -> bool
|
||||
{
|
||||
struct P { FName Name; float Rate; } p{ Name, Rate };
|
||||
return Call(STR("SetDecreaseFullStomachRates"), p);
|
||||
}
|
||||
auto RemoveDecreaseFullStomachRates(FName Name) -> bool
|
||||
{
|
||||
struct P { FName Name; } p{ Name };
|
||||
return Call(STR("RemoveDecreaseFullStomachRates"), p);
|
||||
}
|
||||
|
||||
auto GetEffectFoodName() -> std::optional<FName> { return CallForReturn<FName>(STR("GetEffectFoodName")); }
|
||||
auto GetEffectFoodName_FullStomachKeep() -> std::optional<FName> { return CallForReturn<FName>(STR("GetEffectFoodName_FullStomachKeep")); }
|
||||
auto GetEffectFoodTimeRate() -> std::optional<float> { return CallForReturn<float>(STR("GetEffectFoodTimeRate")); }
|
||||
auto GetEffectFoodTimeRate_FullStomachKeep() -> std::optional<float> { return CallForReturn<float>(STR("GetEffectFoodTimeRate_FullStomachKeep")); }
|
||||
auto GetFoodStatusRate(EPalFoodStatusEffectType_ EffectType) -> std::optional<float>
|
||||
{
|
||||
struct P { EPalFoodStatusEffectType_ EffectType; float ReturnValue; } p{ EffectType, 0.f };
|
||||
return CallForReturn(STR("GetFoodStatusRate"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
// ---- friendship -----------------------------------------------------
|
||||
|
||||
auto GetFriendshipRank() -> std::optional<int32> { return CallForReturn<int32>(STR("GetFriendshipRank")); }
|
||||
auto GetFriendshipPoint() -> std::optional<int32> { return CallForReturn<int32>(STR("GetFriendshipPoint")); }
|
||||
auto AddFriendShip(int32 Value, bool bApplyPassiveSkill) -> bool
|
||||
{
|
||||
struct P { int32 Value; bool bApplyPassiveSkill; } p{ Value, bApplyPassiveSkill };
|
||||
return Call(STR("AddFriendShip"), p);
|
||||
}
|
||||
|
||||
// ---- status points --------------------------------------------------
|
||||
|
||||
auto GetUnusedStatusPoint() -> std::optional<int32> { return CallForReturn<int32>(STR("GetUnusedStatusPoint")); }
|
||||
auto DecrementUnusedStatusPoint() -> bool { return CallVoid(STR("DecrementUnusedStatusPoint")); }
|
||||
auto IsStatusPointAllMax() -> std::optional<bool> { return CallForReturn<bool>(STR("IsStatusPointAllMax")); }
|
||||
|
||||
auto GetStatusPoint(FName StatusName) -> std::optional<int32>
|
||||
{
|
||||
struct P { FName StatusName; int32 ReturnValue; } p{ StatusName, 0 };
|
||||
return CallForReturn(STR("GetStatusPoint"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetTotalStatusPoint(FName StatusName) -> std::optional<int32>
|
||||
{
|
||||
struct P { FName StatusName; int32 ReturnValue; } p{ StatusName, 0 };
|
||||
return CallForReturn(STR("GetTotalStatusPoint"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetExStatusPoint(FName StatusName) -> std::optional<int32>
|
||||
{
|
||||
struct P { FName StatusName; int32 ReturnValue; } p{ StatusName, 0 };
|
||||
return CallForReturn(STR("GetExStatusPoint"), p, &P::ReturnValue);
|
||||
}
|
||||
auto SetStatusPoint(FName StatusName, int32 Point) -> bool
|
||||
{
|
||||
struct P { FName StatusName; int32 Point; } p{ StatusName, Point };
|
||||
return Call(STR("SetStatusPoint"), p);
|
||||
}
|
||||
auto SetExStatusPoint(FName StatusName, int32 Point) -> bool
|
||||
{
|
||||
struct P { FName StatusName; int32 Point; } p{ StatusName, Point };
|
||||
return Call(STR("SetExStatusPoint"), p);
|
||||
}
|
||||
// Two outputs (bool return + int32& out), same non-CallForReturn
|
||||
// shape as CheckValidWorkSuitability in PalDetailWidget.hpp.
|
||||
auto IsStatusPointAddable(FName StatusName) -> std::optional<int32>
|
||||
{
|
||||
struct P { FName StatusName; int32 AddablePoint; bool ReturnValue; } p{ StatusName, 0, false };
|
||||
if (!Call(STR("IsStatusPointAddable"), p) || !p.ReturnValue) return std::nullopt;
|
||||
return p.AddablePoint;
|
||||
}
|
||||
|
||||
// ---- work suitability -------------------------------------------------
|
||||
|
||||
auto GetCurrentWorkSuitability() -> std::optional<EPalWorkSuitability_>
|
||||
{
|
||||
return CallForReturn<EPalWorkSuitability_>(STR("GetCurrentWorkSuitability"));
|
||||
}
|
||||
auto GetWorkSpeedRank() -> std::optional<int32> { return CallForReturn<int32>(STR("GetWorkSpeedRank")); }
|
||||
auto GetCraftSpeed() -> std::optional<int32> { return CallForReturn<int32>(STR("GetCraftSpeed")); }
|
||||
auto GetCraftSpeed_withBuff() -> std::optional<int32> { return CallForReturn<int32>(STR("GetCraftSpeed_withBuff")); }
|
||||
auto GetCraftSpeedSickRate() -> std::optional<float> { return CallForReturn<float>(STR("GetCraftSpeedSickRate")); }
|
||||
auto GetBaseCampCraftSpeedBuffRate() -> std::optional<float> { return CallForReturn<float>(STR("GetBaseCampCraftSpeedBuffRate")); }
|
||||
auto GetWorkerSick() -> std::optional<EPalBaseCampWorkerSickType_>
|
||||
{
|
||||
return CallForReturn<EPalBaseCampWorkerSickType_>(STR("GetWorkerSick"));
|
||||
}
|
||||
auto GetBaseCampWorkerEventType() -> std::optional<EPalBaseCampWorkerEventType_>
|
||||
{
|
||||
return CallForReturn<EPalBaseCampWorkerEventType_>(STR("GetBaseCampWorkerEventType"));
|
||||
}
|
||||
|
||||
auto HasWorkSuitability(EPalWorkSuitability_ Suitability) -> std::optional<bool>
|
||||
{
|
||||
struct P { EPalWorkSuitability_ InWorkSuitability; bool ReturnValue; } p{ Suitability, false };
|
||||
return CallForReturn(STR("HasWorkSuitability"), p, &P::ReturnValue);
|
||||
}
|
||||
auto HasWorkSuitabilityRank(EPalWorkSuitability_ Suitability, int32 Rank) -> std::optional<bool>
|
||||
{
|
||||
struct P { EPalWorkSuitability_ InWorkSuitability; int32 SuitabilityRank; bool ReturnValue; }
|
||||
p{ Suitability, Rank, false };
|
||||
return CallForReturn(STR("HasWorkSuitabilityRank"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetWorkSuitabilityRank(EPalWorkSuitability_ Suitability) -> std::optional<int32>
|
||||
{
|
||||
struct P { EPalWorkSuitability_ InWorkSuitability; int32 ReturnValue; } p{ Suitability, 0 };
|
||||
return CallForReturn(STR("GetWorkSuitabilityRank"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetWorkSuitabilityRankWithCharacterRank(EPalWorkSuitability_ Suitability) -> std::optional<int32>
|
||||
{
|
||||
struct P { EPalWorkSuitability_ WorkSuitability; int32 ReturnValue; } p{ Suitability, 0 };
|
||||
return CallForReturn(STR("GetWorkSuitabilityRankWithCharacterRank"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetRankBasedWorkSuitabilityBonus(EPalWorkSuitability_ Suitability) -> std::optional<int32>
|
||||
{
|
||||
struct P { EPalWorkSuitability_ WorkSuitability; int32 ReturnValue; } p{ Suitability, 0 };
|
||||
return CallForReturn(STR("GetRankBasedWorkSuitabilityBonus"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetCraftSpeedByWorkSuitability(EPalWorkSuitability_ Suitability) -> std::optional<int32>
|
||||
{
|
||||
struct P { EPalWorkSuitability_ WorkSuitability; int32 ReturnValue; } p{ Suitability, 0 };
|
||||
return CallForReturn(STR("GetCraftSpeedByWorkSuitability"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetCraftSpeedBuffRate(EPalWorkSuitability_ Suitability) -> std::optional<float>
|
||||
{
|
||||
struct P { EPalWorkSuitability_ WorkSuitability; float ReturnValue; } p{ Suitability, 0.f };
|
||||
return CallForReturn(STR("GetCraftSpeedBuffRate"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetCraftSpeed_withBuff_WorkSuitability(EPalWorkSuitability_ Suitability) -> std::optional<int32>
|
||||
{
|
||||
struct P { EPalWorkSuitability_ Suitability; int32 ReturnValue; } p{ Suitability, 0 };
|
||||
return CallForReturn(STR("GetCraftSpeed_withBuff_WorkSuitability"), p, &P::ReturnValue);
|
||||
}
|
||||
auto SetWorkSuitabilityAddRank(EPalWorkSuitability_ Suitability, int32 AddRank) -> bool
|
||||
{
|
||||
struct P { EPalWorkSuitability_ WorkSuitability; int32 addRank; } p{ Suitability, AddRank };
|
||||
return Call(STR("SetWorkSuitabilityAddRank"), p);
|
||||
}
|
||||
|
||||
// ---- passive skills ---------------------------------------------------
|
||||
//
|
||||
// GetPassiveSkillList (TArray<FName>) is NOT wrapped -- see class
|
||||
// comment. Add/Remove take scalar FName params, no such problem.
|
||||
auto AddPassiveSkill(FName AddSkill, FName OverrideSkill) -> bool
|
||||
{
|
||||
struct P { FName AddSkill; FName OverrideSkill; } p{ AddSkill, OverrideSkill };
|
||||
return Call(STR("AddPassiveSkill"), p);
|
||||
}
|
||||
auto RemovePassiveSkill(FName SkillId) -> bool
|
||||
{
|
||||
struct P { FName SkillId; } p{ SkillId };
|
||||
return Call(STR("RemovePassiveSkill"), p);
|
||||
}
|
||||
auto GetPassiveRateBySkillEffect(EPalPassiveSkillEffectType_ EffectType) -> std::optional<float>
|
||||
{
|
||||
struct P { EPalPassiveSkillEffectType_ EffectType; float ReturnValue; } p{ EffectType, 0.f };
|
||||
return CallForReturn(STR("GetPassiveRateBySkillEffect"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetPassiveRateByEquipment(EPalPassiveSkillEffectType_ EffectType) -> std::optional<float>
|
||||
{
|
||||
struct P { EPalPassiveSkillEffectType_ EffectType; float ReturnValue; } p{ EffectType, 0.f };
|
||||
return CallForReturn(STR("GetPassiveRateByEquipment"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
// ---- classification / misc flags ---------------------------------------
|
||||
|
||||
auto GetSizeType() -> std::optional<EPalSizeType_> { return CallForReturn<EPalSizeType_>(STR("GetSizeType")); }
|
||||
auto GetGroupType() -> std::optional<EPalGroupType_> { return CallForReturn<EPalGroupType_>(STR("GetGroupType")); }
|
||||
auto GetGroupId() -> std::optional<FGuid_> { return CallForReturn<FGuid_>(STR("GetGroupId")); }
|
||||
auto GetBaseCampId() -> std::optional<FGuid_> { return CallForReturn<FGuid_>(STR("GetBaseCampId")); }
|
||||
auto GetArenaRank() -> std::optional<EPalArenaRank_> { return CallForReturn<EPalArenaRank_>(STR("GetArenaRank")); }
|
||||
auto GetArenaRankPoint() -> std::optional<int32> { return CallForReturn<int32>(STR("GetArenaRankPoint")); }
|
||||
auto IsInArena() -> std::optional<bool> { return CallForReturn<bool>(STR("IsInArena")); }
|
||||
auto IsInRaidArea() -> std::optional<bool> { return CallForReturn<bool>(STR("IsInRaidArea")); }
|
||||
auto IsUncapturable() -> std::optional<bool> { return CallForReturn<bool>(STR("IsUncapturable")); }
|
||||
auto IsForceCapturable() -> std::optional<bool> { return CallForReturn<bool>(STR("IsForceCapturable")); }
|
||||
auto IsAwakening() -> std::optional<bool> { return CallForReturn<bool>(STR("IsAwakening")); }
|
||||
auto IsPartBroken() -> std::optional<bool> { return CallForReturn<bool>(STR("IsPartBroken")); }
|
||||
auto IsParts() -> std::optional<bool> { return CallForReturn<bool>(STR("IsParts")); }
|
||||
auto GetParentParameterObject() -> UObject*
|
||||
{
|
||||
struct P { UObject* ReturnValue; } p{ nullptr };
|
||||
auto Result = CallForReturn(STR("GetParentParameter"), p, &P::ReturnValue);
|
||||
return (Result && *Result) ? *Result : nullptr;
|
||||
}
|
||||
auto IsAssignedToExpedition() -> std::optional<bool> { return CallForReturn<bool>(STR("IsAssignedToExpedition")); }
|
||||
auto IsAssignedToExpeditionIn(FGuid_ MapObjectId) -> std::optional<bool>
|
||||
{
|
||||
struct P { FGuid_ MapObjectConcreteInstanceId; bool ReturnValue; } p{ MapObjectId, false };
|
||||
return CallForReturn(STR("IsAssignedToExpeditionIn"), p, &P::ReturnValue);
|
||||
}
|
||||
auto IsExcludedFromTeamMission() -> std::optional<bool> { return CallForReturn<bool>(STR("IsExcludedFromTeamMission")); }
|
||||
auto CanTargetFromAI() -> std::optional<bool> { return CallForReturn<bool>(STR("CanTargetFromAI")); }
|
||||
auto HasGenusCategory(EPalGenusCategoryType_ Category) -> std::optional<bool>
|
||||
{
|
||||
struct P { EPalGenusCategoryType_ Category; bool ReturnValue; } p{ Category, false };
|
||||
return CallForReturn(STR("HasGenusCategory"), p, &P::ReturnValue);
|
||||
}
|
||||
auto CanAddTalentByItem(FName ItemName) -> std::optional<bool>
|
||||
{
|
||||
struct P { FName ItemName; bool ReturnValue; } p{ ItemName, false };
|
||||
return CallForReturn(STR("CanAddTalentByItem"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetNPCWeaponType() -> std::optional<EPalWeaponType_> { return CallForReturn<EPalWeaponType_>(STR("GetNPCWeaponType")); }
|
||||
auto GetEquipItemContainerId() -> std::optional<FPalContainerId_>
|
||||
{
|
||||
return CallForReturn<FPalContainerId_>(STR("GetEquipItemContainerId"));
|
||||
}
|
||||
|
||||
auto SetUncapturable(bool bInUncapturable) -> bool
|
||||
{
|
||||
struct P { bool bInUncapturable; } p{ bInUncapturable };
|
||||
return Call(STR("SetUncapturable"), p);
|
||||
}
|
||||
auto SetForceCapturable(bool bInForceCapturable) -> bool
|
||||
{
|
||||
struct P { bool bInForceCapturable; } p{ bInForceCapturable };
|
||||
return Call(STR("SetForceCapturable"), p);
|
||||
}
|
||||
auto SetInArena(bool InArena) -> bool
|
||||
{
|
||||
struct P { bool InArena; } p{ InArena };
|
||||
return Call(STR("SetInArena"), p);
|
||||
}
|
||||
auto SetInRaidArea(bool InRaidArea) -> bool
|
||||
{
|
||||
struct P { bool InRaidArea; } p{ InRaidArea };
|
||||
return Call(STR("SetInRaidArea"), p);
|
||||
}
|
||||
auto SetCanTargetFromAI(bool bInCanTargetFromAI) -> bool
|
||||
{
|
||||
struct P { bool bInCanTargetFromAI; } p{ bInCanTargetFromAI };
|
||||
return Call(STR("SetCanTargetFromAI"), p);
|
||||
}
|
||||
auto SetSkinName(FName InSkinName) -> bool
|
||||
{
|
||||
struct P { FName InSkinName; } p{ InSkinName };
|
||||
return Call(STR("SetSkinName"), p);
|
||||
}
|
||||
auto SetSkinAppliedCharacterId(FGuid_ InCharacterId) -> bool
|
||||
{
|
||||
struct P { FGuid_ InCharacterId; } p{ InCharacterId };
|
||||
return Call(STR("SetSkinAppliedCharacterId"), p);
|
||||
}
|
||||
auto SetSecurityPoliceTargetPlayerId(FGuid_ PlayerId) -> bool
|
||||
{
|
||||
struct P { FGuid_ PlayerId; } p{ PlayerId };
|
||||
return Call(STR("SetSecurityPoliceTargetPlayerId"), p);
|
||||
}
|
||||
auto SetInvaderData(EPalInvaderType_ InvaderType, FGuid_ InBaseCampId) -> bool
|
||||
{
|
||||
struct P { EPalInvaderType_ InvaderType; FGuid_ InBaseCampId; } p{ InvaderType, InBaseCampId };
|
||||
return Call(STR("SetInvaderData"), p);
|
||||
}
|
||||
auto SetDisableNaturalUpdate(FName Key, bool Disable) -> bool
|
||||
{
|
||||
struct P { FName Key; bool Disable; } p{ Key, Disable };
|
||||
return Call(STR("SetDisableNaturalUpdate"), p);
|
||||
}
|
||||
auto SetDisableNaturalHealing(FName Key, bool Disable) -> bool
|
||||
{
|
||||
struct P { FName Key; bool Disable; } p{ Key, Disable };
|
||||
return Call(STR("SetDisableNaturalHealing"), p);
|
||||
}
|
||||
auto NaturalUpdateSaveParameter(EPalCharacterNaturalUpdateType_ Type) -> bool
|
||||
{
|
||||
struct P { EPalCharacterNaturalUpdateType_ Type; } p{ Type };
|
||||
return Call(STR("NaturalUpdateSaveParameter"), p);
|
||||
}
|
||||
auto SetForcePartBreak() -> bool { return CallVoid(STR("SetForcePartBreak")); }
|
||||
|
||||
// ---- medical bed / misc actions -----------------------------------
|
||||
|
||||
auto StartRecuperatingInMedicalBed() -> bool { return CallVoid(STR("StartRecuperatingInMedicalBed")); }
|
||||
auto RecuperateInMedicalBed() -> bool { return CallVoid(STR("RecuperateInMedicalBed")); }
|
||||
auto EndRecuperatingInMedicalBed() -> bool { return CallVoid(STR("EndRecuperatingInMedicalBed")); }
|
||||
auto StartRemainderOfLifeTimer() -> bool { return CallVoid(STR("StartRemainderOfLifeTimer")); }
|
||||
};
|
||||
}
|
||||
110
Api/Pal/PalTypes.hpp
Normal file
110
Api/Pal/PalTypes.hpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace PalUIExtension::Api::Pal
|
||||
{
|
||||
|
||||
struct FGuid_ { uint32_t A{}, B{}, C{}, D{}; };
|
||||
|
||||
struct FFixedPoint64_ { int64_t Value{}; };
|
||||
|
||||
struct FPalContainerId_ { FGuid_ ID{}; };
|
||||
|
||||
using EPalTribeID_ = uint16_t;
|
||||
using EPalWazaID_ = uint16_t;
|
||||
using EPalPassiveSkillEffectType_ = uint8_t;
|
||||
|
||||
enum class EPalStatusPhysicalHealthType_ : uint8_t
|
||||
{
|
||||
Healthful = 0, MinorInjury = 1, Severe = 2,
|
||||
Dying = 3, DeadBody = 4, CloudCemetery = 5,
|
||||
};
|
||||
|
||||
enum class EPalGroupType_ : uint8_t
|
||||
{
|
||||
Undefined = 0, Neutral = 1, Organization = 2, IndependentGuild = 3,
|
||||
Guild = 4, ResidentEnemy = 5, RaidBoss = 6,
|
||||
};
|
||||
|
||||
enum class EPalArenaRank_ : uint8_t
|
||||
{
|
||||
Bronze = 0, Silver = 1, Gold = 2, Platinum = 3,
|
||||
Diamond = 4, Master = 5, Legend = 6,
|
||||
};
|
||||
|
||||
enum class EPalGenusCategoryType_ : uint8_t
|
||||
{
|
||||
None = 0, Humanoid = 1, FourLegged = 2, Dragon = 3,
|
||||
Fish = 4, Bird = 5, Monster = 6, Other = 7,
|
||||
};
|
||||
|
||||
enum class EPalExpCalcType_ : uint8_t { None = 0, Build = 1, Craft = 2 };
|
||||
|
||||
enum class EPalSizeType_ : uint8_t
|
||||
{
|
||||
None = 0, XS = 1, S = 2, M = 3, L = 4, XL = 5,
|
||||
};
|
||||
|
||||
enum class EPalStatusHungerType_ : uint8_t
|
||||
{
|
||||
Default = 0, Hunger = 1, Starvation = 2,
|
||||
};
|
||||
|
||||
enum class EPalWeaponType_ : uint8_t
|
||||
{
|
||||
None = 0, ThrowObject = 1, Handgun = 2, AssaultRifle = 3, Shotgun = 4,
|
||||
SniperRifle = 5, RocketLauncher = 6, MeleeWeapon = 7, Bow = 8,
|
||||
BowGun = 9, FlameThrower = 10, GatlingGun = 11, Liftup = 12,
|
||||
LaserRifle = 13, MissileLauncher = 14, GrenadeLauncher = 15,
|
||||
Katana = 16, MetalDetector = 17, GiantClub = 18, FishingRod = 19,
|
||||
LaserMiningTool = 20, MAX = 21,
|
||||
};
|
||||
|
||||
enum class EPalBaseCampWorkerEventType_ : uint8_t
|
||||
{
|
||||
None = 0, Escape = 1, OverworkDeath = 2, Sick = 3, DodgeWork = 4,
|
||||
DodgeWork_Short = 5, DodgeWork_Sleep = 6, EatTooMuch = 7,
|
||||
Trantrum = 8, FightWithFriend = 9, TurnFoodBox = 10, DestroyBuilding = 11,
|
||||
};
|
||||
|
||||
enum class EPalBaseCampWorkerSickType_ : uint8_t
|
||||
{
|
||||
None = 0, Cold = 1, Sprain = 2, Bulimia = 3, GastricUlcer = 4,
|
||||
Fracture = 5, Weakness = 6, DepressionSprain = 7, DisturbingElement = 8,
|
||||
};
|
||||
|
||||
enum class EPalInvaderType_ : uint8_t { None = 0, InvaderEnemy = 1, VisitorNPC = 2 };
|
||||
|
||||
enum class EPalFoodStatusEffectType_ : uint8_t
|
||||
{
|
||||
None = 0, Attack = 1, Defense = 2, HungerResist = 3, SANResist = 4,
|
||||
WorkSpeed = 5, Regene_Hp = 6, MaxSP = 7, Exp_Increase = 8,
|
||||
LeanBackInvalid = 9, KnockbackInvalid = 10, ExplosionResist = 11,
|
||||
LeanBackAndKnockbackInvalid = 12, FullStomachKeep = 13,
|
||||
};
|
||||
|
||||
enum class EPalCharacterNaturalUpdateType_ : uint8_t
|
||||
{
|
||||
Player = 0, OtomoPal = 1, BaseCampPal = 2,
|
||||
};
|
||||
|
||||
enum class EPalOrganizationType_ : uint8_t
|
||||
{
|
||||
None = 0, Guild = 1, Police = 2, City = 3, Brigade = 4,
|
||||
TeamBlackHunter = 5, TeamFireCult = 6, TeamWelfareGroup = 7,
|
||||
Ally = 8, MAX = 9,
|
||||
};
|
||||
|
||||
enum class EPalBattleBGMType_ : uint8_t
|
||||
{
|
||||
None = 0, Cute = 1, Cool = 2, Strong = 3, Human_Common = 4,
|
||||
Human_Villain = 5, FieldBoss_Tier_1 = 6, FieldBoss_Tier_2 = 7,
|
||||
FieldBoss_Tier_3 = 8, FieldBoss_Tier_4 = 9, FieldBoss_Tier_5 = 10,
|
||||
Predator = 11, EyeofCthulhu = 12, WildlifeSanctuaryDrone = 13,
|
||||
Machine = 14, Legend = 15, KingWhale = 16, RaidBoss = 17,
|
||||
TowerBoss = 18, RaidBoss_KingBahamut = 19, RaidBoss_DarkMechaDragon = 20,
|
||||
RaidBoss_MoonLord = 21, RaidBoss_LegendDeer = 22, RaidBoss_LegendDeer2 = 23,
|
||||
WorldTreeDragon = 24,
|
||||
};
|
||||
}
|
||||
155
Api/Pal/PalUIStatusModel.hpp
Normal file
155
Api/Pal/PalUIStatusModel.hpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <Unreal/FText.hpp>
|
||||
#include <Unreal/NameTypes.hpp>
|
||||
|
||||
#include <Api/UnrealWrapper.hpp>
|
||||
#include "PalIndividual.hpp" // EPalElementType_
|
||||
|
||||
namespace PalUIExtension::Api::Pal
|
||||
{
|
||||
class PalUIStatusModel : public UnrealWrapper
|
||||
{
|
||||
public:
|
||||
static auto ClassPath() -> const TCHAR* { return STR("/Script/Pal.PalUIStatusModel"); }
|
||||
static auto DebugTag() -> const TCHAR* { return STR("PalUIStatusModel"); }
|
||||
|
||||
PalUIStatusModel() = default;
|
||||
explicit PalUIStatusModel(UObject* Obj) : UnrealWrapper(Obj, ClassOf<PalUIStatusModel>(), DebugTag()) {}
|
||||
|
||||
|
||||
// Count of pals currently loaded into the model -- "pal number".
|
||||
auto GetDisplayPalNum() -> std::optional<uint8>
|
||||
{
|
||||
return CallForReturn<uint8>(STR("GetDisplayPalNum"));
|
||||
}
|
||||
|
||||
auto GetDisplayPalHandle(uint8 Index) -> UObject*
|
||||
{
|
||||
struct P { uint8 Index; UObject* ReturnValue; } p{ Index, nullptr };
|
||||
auto Result = CallForReturn(STR("GetDisplayPalHandle"), p, &P::ReturnValue);
|
||||
return (Result && *Result) ? *Result : nullptr;
|
||||
}
|
||||
|
||||
auto GetNowSelectedIndex() -> std::optional<uint8>
|
||||
{
|
||||
return CallForReturn<uint8>(STR("GetNowSelectedIndex"));
|
||||
}
|
||||
|
||||
auto ChangeIndex(uint8 Index) -> bool
|
||||
{
|
||||
struct P { uint8 Index; } p{ Index };
|
||||
return Call(STR("ChangeIndex"), p);
|
||||
}
|
||||
|
||||
auto OnClickedPalIcon(int32 Index) -> bool
|
||||
{
|
||||
struct P { int32 Index; } p{ Index };
|
||||
return Call(STR("OnClickedPalIcon"), p);
|
||||
}
|
||||
|
||||
// ---- extended: mechanical Index -> stat getters ----------------
|
||||
|
||||
auto GetDisplayLevel(int32 Index) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 Index; int32 ReturnValue; } p{ Index, 0 };
|
||||
return CallForReturn(STR("GetDisplayLevel"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplaySpeed(int32 Index) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 Index; int32 ReturnValue; } p{ Index, 0 };
|
||||
return CallForReturn(STR("GetDisplaySpeed"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayMeleeAttack(int32 Index) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 Index; int32 ReturnValue; } p{ Index, 0 };
|
||||
return CallForReturn(STR("GetDisplayMeleeAttack"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayShotAttack(int32 Index) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 Index; int32 ReturnValue; } p{ Index, 0 };
|
||||
return CallForReturn(STR("GetDisplayShotAttack"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayDefence(int32 Index) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 Index; int32 ReturnValue; } p{ Index, 0 };
|
||||
return CallForReturn(STR("GetDisplayDefence"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayEatingHabits(int32 Index) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 Index; int32 ReturnValue; } p{ Index, 0 };
|
||||
return CallForReturn(STR("GetDisplayEatingHabits"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayNowExp(int32 Index) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 Index; int32 ReturnValue; } p{ Index, 0 };
|
||||
return CallForReturn(STR("GetDisplayNowExp"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayNextExp(int32 Index) -> std::optional<int32>
|
||||
{
|
||||
struct P { int32 Index; int32 ReturnValue; } p{ Index, 0 };
|
||||
return CallForReturn(STR("GetDisplayNextExp"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayHunger(int32 Index) -> std::optional<float>
|
||||
{
|
||||
struct P { int32 Index; float ReturnValue; } p{ Index, 0.f };
|
||||
return CallForReturn(STR("GetDisplayHunger"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayMaxHunger(int32 Index) -> std::optional<float>
|
||||
{
|
||||
struct P { int32 Index; float ReturnValue; } p{ Index, 0.f };
|
||||
return CallForReturn(STR("GetDisplayMaxHunger"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
auto GetDisplayElementType1(int32 Index) -> std::optional<EPalElementType_>
|
||||
{
|
||||
struct P { int32 Index; EPalElementType_ ReturnValue; } p{ Index, EPalElementType_::None };
|
||||
return CallForReturn(STR("GetDisplayElementType1"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayElementType2(int32 Index) -> std::optional<EPalElementType_>
|
||||
{
|
||||
struct P { int32 Index; EPalElementType_ ReturnValue; } p{ Index, EPalElementType_::None };
|
||||
return CallForReturn(STR("GetDisplayElementType2"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
// Raw byte -- see class comment. Do not assume ordering/meaning.
|
||||
auto GetDisplayPhysicalHealthTypeRaw(int32 Index) -> std::optional<uint8>
|
||||
{
|
||||
struct P { int32 Index; uint8 ReturnValue; } p{ Index, 0 };
|
||||
return CallForReturn(STR("GetDisplayPhysicalHealthType"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
// ---- extended: FText / FString getters -------------------------
|
||||
|
||||
auto GetDisplayDefaultName(int32 Index) -> std::optional<FText>
|
||||
{
|
||||
struct P { int32 Index; FText ReturnValue; } p{ Index, {} };
|
||||
return CallForReturn(STR("GetDisplayDefaultName"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayCoopActionName(int32 Index) -> std::optional<FText>
|
||||
{
|
||||
struct P { int32 Index; FText ReturnValue; } p{ Index, {} };
|
||||
return CallForReturn(STR("GetDisplayCoopActionName"), p, &P::ReturnValue);
|
||||
}
|
||||
auto GetDisplayActiveSkillName(int32 Index, int32 SkillIndex) -> std::optional<FText>
|
||||
{
|
||||
struct P { int32 Index; int32 SkillIndex; FText ReturnValue; } p{ Index, SkillIndex, {} };
|
||||
return CallForReturn(STR("GetDisplayActiveSkillName"), p, &P::ReturnValue);
|
||||
}
|
||||
|
||||
auto GetDisplayNickName(int32 Index) -> std::optional<FString>
|
||||
{
|
||||
struct P { int32 Index; FString OutName; } p{ Index, {} };
|
||||
if (!Call(STR("GetDisplayNickName"), p)) return std::nullopt;
|
||||
return p.OutName;
|
||||
}
|
||||
|
||||
auto ChangeNickname(int32 Index, const TCHAR* NewNickName) -> bool
|
||||
{
|
||||
struct P { int32 Index; FString NewNickName; } p{ Index, FString(NewNickName) };
|
||||
return Call(STR("ChangeNickname"), p);
|
||||
}
|
||||
};
|
||||
}
|
||||
123
Api/Pal/PalUtility.hpp
Normal file
123
Api/Pal/PalUtility.hpp
Normal file
@@ -0,0 +1,123 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <Reflection/UnrealObjectRef.hpp>
|
||||
|
||||
#include <Api/UnrealWrapper.hpp>
|
||||
#include "PalDatabaseCharacterParameter.hpp"
|
||||
|
||||
namespace PalUIExtension::Api::Pal
|
||||
{
|
||||
|
||||
class PalUtility : public UnrealWrapper
|
||||
{
|
||||
public:
|
||||
static auto ClassPath() -> const TCHAR* { return STR("/Script/Pal.PalUtility"); }
|
||||
static auto CDOPath() -> const TCHAR* { return STR("/Script/Pal.Default__PalUtility"); }
|
||||
static auto DebugTag() -> const TCHAR* { return STR("PalUtility"); }
|
||||
|
||||
static auto Instance() -> PalUtility&
|
||||
{
|
||||
static PalUtility Singleton{};
|
||||
return Singleton;
|
||||
}
|
||||
|
||||
// ---- static getters -----------------------------------------
|
||||
//
|
||||
// Add more here as you need them -- see the class comment for
|
||||
// the one-line shape.
|
||||
|
||||
auto GetDatabaseCharacterParameter(UObject* WorldContextObject) -> PalDatabaseCharacterParameter
|
||||
{
|
||||
return GetSingleton<PalDatabaseCharacterParameter>(
|
||||
STR("GetDatabaseCharacterParameter"), WorldContextObject);
|
||||
}
|
||||
|
||||
|
||||
auto ZukanIndexFor(FName CharacterId, UObject* WorldContextObject) -> std::optional<int32>
|
||||
{
|
||||
const uint64_t Key = NameKey(CharacterId);
|
||||
|
||||
if (auto It = s_zukan_cache.find(Key); It != s_zukan_cache.end())
|
||||
{
|
||||
if (It->second == kNoZukanEntry) return std::nullopt;
|
||||
return It->second;
|
||||
}
|
||||
|
||||
PalDatabaseCharacterParameter DB = GetDatabaseCharacterParameter(WorldContextObject);
|
||||
if (!DB)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto Index = DB.GetZukanIndexResolved(CharacterId);
|
||||
s_zukan_cache.emplace(Key, Index.value_or(kNoZukanEntry));
|
||||
return Index;
|
||||
}
|
||||
|
||||
static auto ClearZukanCache() -> void { s_zukan_cache.clear(); }
|
||||
|
||||
auto NocturnalFor(FName CharacterId, UObject* WorldContextObject) -> std::optional<bool>
|
||||
{
|
||||
const uint64_t Key = NameKey(CharacterId);
|
||||
|
||||
if (auto It = s_nocturnal_cache.find(Key); It != s_nocturnal_cache.end())
|
||||
{
|
||||
return It->second != 0;
|
||||
}
|
||||
|
||||
PalDatabaseCharacterParameter DB = GetDatabaseCharacterParameter(WorldContextObject);
|
||||
if (!DB) return std::nullopt;
|
||||
|
||||
const FName RowName = PalDatabaseCharacterParameter::ResolveBaseRowName(CharacterId);
|
||||
|
||||
auto Nocturnal = DB.GetNocturnal(RowName);
|
||||
if (!Nocturnal.has_value()) return std::nullopt;
|
||||
|
||||
s_nocturnal_cache.emplace(Key, *Nocturnal ? uint8_t{ 1 } : uint8_t{ 0 });
|
||||
return Nocturnal;
|
||||
}
|
||||
|
||||
static auto ClearNocturnalCache() -> void { s_nocturnal_cache.clear(); }
|
||||
|
||||
private:
|
||||
PalUtility() : UnrealWrapper(ResolveCDO(), ClassOf<PalUtility>(), DebugTag()) {}
|
||||
|
||||
static constexpr int32 kNoZukanEntry = -1;
|
||||
static inline std::unordered_map<uint64_t, int32> s_zukan_cache{};
|
||||
|
||||
static inline std::unordered_map<uint64_t, uint8_t> s_nocturnal_cache{};
|
||||
|
||||
static auto NameKey(FName N) -> uint64_t
|
||||
{
|
||||
return (static_cast<uint64_t>(N.GetComparisonIndex().ToUnstableInt()) << 32)
|
||||
| static_cast<uint64_t>(static_cast<uint32_t>(N.GetNumber()));
|
||||
}
|
||||
|
||||
PalUtility(const PalUtility&) = delete;
|
||||
auto operator=(const PalUtility&) -> PalUtility & = delete;
|
||||
|
||||
static auto ResolveCDO() -> UObject*
|
||||
{
|
||||
static Reflection::UnrealObjectRef Ref{ CDOPath(), DebugTag() };
|
||||
return Ref.Get();
|
||||
}
|
||||
|
||||
auto CallStaticObjectGetter(const TCHAR* FunctionName, UObject* WorldContextObject) -> UObject*
|
||||
{
|
||||
struct P { UObject* WorldContextObject; UObject* ReturnValue; } p{ WorldContextObject, nullptr };
|
||||
auto Result = CallForReturn(FunctionName, p, &P::ReturnValue);
|
||||
return (Result && *Result) ? *Result : nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto GetSingleton(const TCHAR* FunctionName, UObject* WorldContextObject) -> T
|
||||
{
|
||||
UObject* Obj = CallStaticObjectGetter(FunctionName, WorldContextObject);
|
||||
return Obj ? T{ Obj } : T{};
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user