enderalse/source/fs.dll/skse64/skse64/PapyrusActorValueInfo.cpp

380 lines
13 KiB
C++

#include "PapyrusActorValueInfo.h"
#include "GameObjects.h"
#include "GameData.h"
#include "GameSettings.h"
#include "PapyrusArgs.h"
class MatchSkillPerks : public BGSSkillPerkTreeNode::PerkVisitor
{
Actor * m_actor;
bool m_unowned; // Only perks the actor doesn't own, or only perks the actor does own
bool m_allRanks; // Walk all ranks for all perks
public:
MatchSkillPerks(Actor * actor, bool unowned, bool allRanks) : m_actor(actor), m_unowned(unowned), m_allRanks(allRanks) {}
virtual bool Accept(BGSPerk * perk)
{
if(perk)
{
bool addPerk = true;
if(m_actor) {
if(!CALL_MEMBER_FN(m_actor, HasPerk)(perk))
addPerk = m_unowned;
else
addPerk = !m_unowned;
}
if(addPerk) {
AddPerk(perk);
}
if(m_allRanks) {
BGSPerk * nextPerk = perk->nextPerk;
while(nextPerk) {
addPerk = true;
if(m_actor) {
if(!CALL_MEMBER_FN(m_actor, HasPerk)(nextPerk))
addPerk = m_unowned;
else
addPerk = !m_unowned;
}
if(addPerk) {
AddPerk(nextPerk);
}
nextPerk = nextPerk->nextPerk;
}
}
}
return false;
}
virtual void AddPerk(BGSPerk * perk) = 0;
};
class PerkFormListVisitor : public MatchSkillPerks
{
BGSListForm * m_formList;
public:
PerkFormListVisitor::PerkFormListVisitor(BGSListForm * list, Actor * actor, bool unowned, bool allRanks) : MatchSkillPerks(actor, unowned, allRanks)
{
m_formList = list;
}
virtual void AddPerk(BGSPerk * perk)
{
CALL_MEMBER_FN(m_formList, AddFormToList)(perk);
}
};
class PerkArrayVisitor : public MatchSkillPerks
{
VMResultArray<BGSPerk*> * m_perks;
public:
PerkArrayVisitor::PerkArrayVisitor(VMResultArray<BGSPerk*> * perkArray, Actor * actor, bool unowned, bool allRanks) : MatchSkillPerks(actor, unowned, allRanks)
{
m_perks = perkArray;
}
virtual void AddPerk(BGSPerk * perk)
{
m_perks->push_back(perk);
}
};
namespace papyrusActorValueInfo
{
ActorValueInfo * GetActorValueInfoByName(StaticFunctionTag * base, BSFixedString avName)
{
UInt32 actorValue = LookupActorValueByName(avName.data);
ActorValueList * avList = ActorValueList::GetSingleton();
if(!avList)
return NULL;
return avList->GetActorValue(actorValue);
}
ActorValueInfo * GetActorValueInfoByID(StaticFunctionTag * base, UInt32 actorValue)
{
ActorValueList * avList = ActorValueList::GetSingleton();
if(!avList)
return NULL;
return avList->GetActorValue(actorValue);
}
bool IsSkill(ActorValueInfo * info)
{
return (info && info->skillUsages) ? true : false;
}
float GetSkillUseMult(ActorValueInfo * info)
{
return (info && info->skillUsages) ? info->skillUsages[ActorValueInfo::kSkillUseMult] : 0.0;
}
void SetSkillUseMult(ActorValueInfo * info, float value)
{
if(info && info->skillUsages)
info->skillUsages[ActorValueInfo::kSkillUseMult] = value;
}
float GetSkillOffsetMult(ActorValueInfo * info)
{
return (info && info->skillUsages) ? info->skillUsages[ActorValueInfo::kSkillOffsetMult] : 0.0;
}
void SetSkillOffsetMult(ActorValueInfo * info, float value)
{
if(info && info->skillUsages)
info->skillUsages[ActorValueInfo::kSkillOffsetMult] = value;
}
float GetSkillImproveMult(ActorValueInfo * info)
{
return (info && info->skillUsages) ? info->skillUsages[ActorValueInfo::kSkillImproveMult] : 0.0;
}
void SetSkillImproveMult(ActorValueInfo * info, float value)
{
if(info && info->skillUsages)
info->skillUsages[ActorValueInfo::kSkillImproveMult] = value;
}
float GetSkillImproveOffset(ActorValueInfo * info)
{
return (info && info->skillUsages) ? info->skillUsages[ActorValueInfo::kSkillImproveOffset] : 0.0;
}
void SetSkillImproveOffset(ActorValueInfo * info, float value)
{
if(info && info->skillUsages)
info->skillUsages[ActorValueInfo::kSkillImproveOffset] = value;
}
float GetSkillExperience(ActorValueInfo * info)
{
PlayerCharacter* pPC = (*g_thePlayer);
return (info && pPC->skills) ? pPC->skills->GetSkillPoints(info->name) : 0.0;
}
void SetSkillExperience(ActorValueInfo * info, float points)
{
PlayerCharacter* pPC = (*g_thePlayer);
if(info && pPC->skills) {
pPC->skills->SetSkillPoints(info->name, points);
}
}
void AddSkillExperience(ActorValueInfo * info, float points)
{
if(info) {
UInt32 actorValue = LookupActorValueByName(info->name);
if(actorValue < ActorValueList::kNumActorValues) {
PlayerCharacter* pPC = (*g_thePlayer);
pPC->AdvanceSkill(actorValue, points, 0, 0);
}
}
}
float GetExperienceForLevel(ActorValueInfo * info, UInt32 level)
{
if(!info || !info->skillUsages)
return 0.0;
double fSkillUseCurve = 0.0;
SettingCollectionMap * settings = *g_gameSettingCollection;
if(!settings)
return 0.0;
Setting * skillUseCurve = settings->Get("fSkillUseCurve");
if(skillUseCurve)
skillUseCurve->GetDouble(&fSkillUseCurve);
return info->skillUsages[ActorValueInfo::kSkillImproveMult] * pow(level, fSkillUseCurve) + info->skillUsages[ActorValueInfo::kSkillImproveOffset];
}
SInt32 GetSkillLegendaryLevel(ActorValueInfo * info)
{
PlayerCharacter* pPC = (*g_thePlayer);
if(pPC && info && pPC->skills) {
return pPC->skills->GetSkillLegendaryLevel(info->name);
}
return -1;
}
void SetSkillLegendaryLevel(ActorValueInfo * info, UInt32 level)
{
PlayerCharacter* pPC = (*g_thePlayer);
if(pPC && info && pPC->skills) {
pPC->skills->SetSkillLegendaryLevel(info->name, level);
}
}
void GetPerkTree(ActorValueInfo * info, BGSListForm * formList, Actor * actor, bool unowned, bool allRanks)
{
if(info && formList) {
BGSSkillPerkTreeNode * root = info->perkTree;
if(root) {
PerkFormListVisitor matcher(formList, actor, unowned, allRanks);
root->VisitPerks(matcher);
}
}
}
VMResultArray<BGSPerk*> GetPerks(ActorValueInfo * info, Actor * actor, bool unowned, bool allRanks)
{
VMResultArray<BGSPerk*> result;
if(info) {
BGSSkillPerkTreeNode * root = info->perkTree;
if(root) {
PerkArrayVisitor matcher(&result, actor, unowned, allRanks);
root->VisitPerks(matcher);
}
}
return result;
}
float GetCurrentValue(ActorValueInfo * info, Actor * actor)
{
if(info && actor) {
UInt32 actorValue = LookupActorValueByName(info->name);
if(actorValue < ActorValueList::kNumActorValues) {
return actor->actorValueOwner.GetCurrent(actorValue);
}
}
return 0.0;
}
float GetBaseValue(ActorValueInfo * info, Actor * actor)
{
if(info && actor) {
UInt32 actorValue = LookupActorValueByName(info->name);
if(actorValue < ActorValueList::kNumActorValues) {
return actor->actorValueOwner.GetBase(actorValue);
}
}
return 0.0;
}
float GetMaximumValue(ActorValueInfo * info, Actor * actor)
{
if(info && actor) {
UInt32 actorValue = LookupActorValueByName(info->name);
if(actorValue < ActorValueList::kNumActorValues) {
return actor->actorValueOwner.GetMaximum(actorValue);
}
}
return 0.0;
}
}
#include "PapyrusVM.h"
#include "PapyrusNativeFunctions.h"
void papyrusActorValueInfo::RegisterFuncs(VMClassRegistry* registry)
{
registry->RegisterForm(ActorValueInfo::kTypeID, "ActorValueInfo");
registry->RegisterFunction(
new NativeFunction1<StaticFunctionTag, ActorValueInfo*, BSFixedString>("GetActorValueInfoByName", "ActorValueInfo", papyrusActorValueInfo::GetActorValueInfoByName, registry));
registry->RegisterFunction(
new NativeFunction1<StaticFunctionTag, ActorValueInfo*, UInt32>("GetActorValueInfoByID", "ActorValueInfo", papyrusActorValueInfo::GetActorValueInfoByID, registry));
registry->RegisterFunction(
new NativeFunction0<ActorValueInfo, bool>("IsSkill", "ActorValueInfo", papyrusActorValueInfo::IsSkill, registry));
// Skill Usage
registry->RegisterFunction(
new NativeFunction0<ActorValueInfo, float>("GetSkillUseMult", "ActorValueInfo", papyrusActorValueInfo::GetSkillUseMult, registry));
registry->RegisterFunction(
new NativeFunction1<ActorValueInfo, void, float>("SetSkillUseMult", "ActorValueInfo", papyrusActorValueInfo::SetSkillUseMult, registry));
registry->RegisterFunction(
new NativeFunction0<ActorValueInfo, float>("GetSkillOffsetMult", "ActorValueInfo", papyrusActorValueInfo::GetSkillOffsetMult, registry));
registry->RegisterFunction(
new NativeFunction1<ActorValueInfo, void, float>("SetSkillOffsetMult", "ActorValueInfo", papyrusActorValueInfo::SetSkillOffsetMult, registry));
registry->RegisterFunction(
new NativeFunction0<ActorValueInfo, float>("GetSkillImproveMult", "ActorValueInfo", papyrusActorValueInfo::GetSkillImproveMult, registry));
registry->RegisterFunction(
new NativeFunction1<ActorValueInfo, void, float>("SetSkillImproveMult", "ActorValueInfo", papyrusActorValueInfo::SetSkillImproveMult, registry));
registry->RegisterFunction(
new NativeFunction0<ActorValueInfo, float>("GetSkillImproveOffset", "ActorValueInfo", papyrusActorValueInfo::GetSkillImproveOffset, registry));
registry->RegisterFunction(
new NativeFunction1<ActorValueInfo, void, float>("SetSkillImproveOffset", "ActorValueInfo", papyrusActorValueInfo::SetSkillImproveOffset, registry));
// Skills
registry->RegisterFunction(
new NativeFunction0<ActorValueInfo, float>("GetSkillExperience", "ActorValueInfo", papyrusActorValueInfo::GetSkillExperience, registry));
registry->RegisterFunction(
new NativeFunction1<ActorValueInfo, void, float>("SetSkillExperience", "ActorValueInfo", papyrusActorValueInfo::SetSkillExperience, registry));
registry->RegisterFunction(
new NativeFunction1<ActorValueInfo, void, float>("AddSkillExperience", "ActorValueInfo", papyrusActorValueInfo::AddSkillExperience, registry));
registry->RegisterFunction(
new NativeFunction1 <ActorValueInfo, float, UInt32>("GetExperienceForLevel", "ActorValueInfo", papyrusActorValueInfo::GetExperienceForLevel, registry));
registry->RegisterFunction(
new NativeFunction0 <ActorValueInfo, SInt32>("GetSkillLegendaryLevel", "ActorValueInfo", papyrusActorValueInfo::GetSkillLegendaryLevel, registry));
registry->RegisterFunction(
new NativeFunction1 <ActorValueInfo, void, UInt32>("SetSkillLegendaryLevel", "ActorValueInfo", papyrusActorValueInfo::SetSkillLegendaryLevel, registry));
// Perk Tree
registry->RegisterFunction(
new NativeFunction4 <ActorValueInfo, void, BGSListForm*, Actor*, bool, bool>("GetPerkTree", "ActorValueInfo", papyrusActorValueInfo::GetPerkTree, registry));
registry->RegisterFunction(
new NativeFunction3 <ActorValueInfo, VMResultArray<BGSPerk*>, Actor*, bool, bool>("GetPerks", "ActorValueInfo", papyrusActorValueInfo::GetPerks, registry));
// Value Info
registry->RegisterFunction(
new NativeFunction1 <ActorValueInfo, float, Actor*>("GetCurrentValue", "ActorValueInfo", papyrusActorValueInfo::GetCurrentValue, registry));
registry->RegisterFunction(
new NativeFunction1 <ActorValueInfo, float, Actor*>("GetBaseValue", "ActorValueInfo", papyrusActorValueInfo::GetBaseValue, registry));
registry->RegisterFunction(
new NativeFunction1 <ActorValueInfo, float, Actor*>("GetMaximumValue", "ActorValueInfo", papyrusActorValueInfo::GetMaximumValue, registry));
registry->SetFunctionFlags("ActorValueInfo", "GetActorValueInfoByName", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "GetActorValueInfoByID", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "GetSkillUseMult", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "SetSkillUseMult", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "GetSkillOffsetMult", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "SetSkillOffsetMult", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "GetSkillImproveMult", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "SetSkillImproveMult", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "GetSkillImproveOffset", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "SetSkillImproveOffset", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "GetSkillLegendaryLevel", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "SetSkillLegendaryLevel", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "GetSkillExperience", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "SetSkillExperience", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "AddSkillExperience", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "GetExperienceForLevel", VMClassRegistry::kFunctionFlag_NoWait);
registry->SetFunctionFlags("ActorValueInfo", "GetPerkTree", VMClassRegistry::kFunctionFlag_NoWait);
}