From 7f36752c2e2f7aa91b0c1cbfe94e78b8ea2c57d8 Mon Sep 17 00:00:00 2001 From: Vladimir Ulrich Date: Sun, 16 Feb 2025 23:51:21 +0300 Subject: [PATCH] refact(skymp5-server): eliminate duplicated code and remove macro definitions for Papyrus Classes (#2324) --- .../server_guest_lib/SpSnippetFunctionGen.h | 30 --------- .../script_classes/IPapyrusClass.cpp | 23 +++++++ .../script_classes/IPapyrusClass.h | 11 +++- .../script_classes/PapyrusActor.cpp | 30 ++++++++- .../script_classes/PapyrusActor.h | 12 ++-- .../script_classes/PapyrusCell.cpp | 2 + .../script_classes/PapyrusCell.h | 4 -- .../script_classes/PapyrusClassesFactory.cpp | 4 ++ .../script_classes/PapyrusDebug.cpp | 15 +++++ .../script_classes/PapyrusDebug.h | 8 +-- .../script_classes/PapyrusEffectBase.cpp | 62 +++++++++++++++++++ .../script_classes/PapyrusEffectBase.h | 21 +++++++ .../script_classes/PapyrusEffectShader.cpp | 48 +------------- .../script_classes/PapyrusEffectShader.h | 20 +----- .../script_classes/PapyrusFaction.cpp | 16 +++++ .../script_classes/PapyrusFaction.h | 19 ++---- .../script_classes/PapyrusForm.cpp | 3 +- .../script_classes/PapyrusForm.h | 4 -- .../script_classes/PapyrusFormList.cpp | 8 +++ .../script_classes/PapyrusFormList.h | 7 +-- .../script_classes/PapyrusGame.cpp | 45 ++++++++------ .../script_classes/PapyrusGame.h | 14 ++--- .../script_classes/PapyrusKeyword.cpp | 15 +++++ .../script_classes/PapyrusKeyword.h | 19 ++---- .../script_classes/PapyrusLeveledActor.cpp | 6 ++ .../script_classes/PapyrusLeveledActor.h | 8 +++ .../script_classes/PapyrusLeveledBase.cpp | 46 ++++++++++++++ .../script_classes/PapyrusLeveledBase.h | 17 +++++ .../script_classes/PapyrusLeveledItem.cpp | 40 +----------- .../script_classes/PapyrusLeveledItem.h | 13 +--- .../script_classes/PapyrusLeveledSpell.cpp | 6 ++ .../script_classes/PapyrusLeveledSpell.h | 8 +++ .../script_classes/PapyrusMessage.cpp | 7 +++ .../script_classes/PapyrusMessage.h | 5 +- .../script_classes/PapyrusNetImmerse.cpp | 1 + .../script_classes/PapyrusNetImmerse.h | 3 - .../script_classes/PapyrusObjectReference.cpp | 1 - .../script_classes/PapyrusObjectReference.h | 2 - .../script_classes/PapyrusPotion.h | 3 - .../script_classes/PapyrusQuest.cpp | 1 + .../script_classes/PapyrusQuest.h | 3 - .../script_classes/PapyrusSkymp.cpp | 12 +++- .../script_classes/PapyrusSkymp.h | 12 +--- .../script_classes/PapyrusSound.h | 2 - .../script_classes/PapyrusUtility.h | 2 - .../script_classes/PapyrusVisualEffect.cpp | 48 +------------- .../script_classes/PapyrusVisualEffect.h | 19 +----- unit/PapyrusSkympTest.cpp | 10 +-- 48 files changed, 389 insertions(+), 326 deletions(-) create mode 100644 skymp5-server/cpp/server_guest_lib/script_classes/IPapyrusClass.cpp create mode 100644 skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectBase.cpp create mode 100644 skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectBase.h create mode 100644 skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledActor.cpp create mode 100644 skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledActor.h create mode 100644 skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledBase.cpp create mode 100644 skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledBase.h create mode 100644 skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledSpell.cpp create mode 100644 skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledSpell.h diff --git a/skymp5-server/cpp/server_guest_lib/SpSnippetFunctionGen.h b/skymp5-server/cpp/server_guest_lib/SpSnippetFunctionGen.h index 481be00b4c..f128200ddd 100644 --- a/skymp5-server/cpp/server_guest_lib/SpSnippetFunctionGen.h +++ b/skymp5-server/cpp/server_guest_lib/SpSnippetFunctionGen.h @@ -1,7 +1,6 @@ #pragma once #include "MpActor.h" #include "SpSnippet.h" -#include "SpSnippetFunctionGen.h" #include "papyrus-vm/VirtualMachine.h" #include @@ -13,32 +12,3 @@ class SpSnippetFunctionGen static uint32_t GetFormId(VarValue varValue); }; - -// TODO: unhardcode mode -#define DEFINE_STATIC_SPSNIPPET(name) \ - VarValue name(VarValue self, const std::vector& arguments) \ - { \ - if (auto actor = compatibilityPolicy->GetDefaultActor( \ - GetName(), #name, self.GetMetaStackId())) { \ - auto s = SpSnippetFunctionGen::SerializeArguments(arguments, actor); \ - SpSnippet(GetName(), (#name), s.data()) \ - .Execute(actor, SpSnippetMode::kNoReturnResult); \ - } \ - return VarValue::None(); \ - } - -// TODO: unhardcode mode -#define DEFINE_METHOD_SPSNIPPET(name) \ - VarValue name(VarValue self, const std::vector& arguments) \ - { \ - if (auto actor = compatibilityPolicy->GetDefaultActor( \ - GetName(), #name, self.GetMetaStackId())) { \ - auto s = SpSnippetFunctionGen::SerializeArguments(arguments, actor); \ - auto promise = SpSnippet(GetName(), (#name), s.data(), \ - SpSnippetFunctionGen::GetFormId(self)) \ - .Execute(actor, SpSnippetMode::kReturnResult); \ - return VarValue(promise); \ - } \ - \ - return VarValue::None(); \ - } diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/IPapyrusClass.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/IPapyrusClass.cpp new file mode 100644 index 0000000000..10ae3b3b40 --- /dev/null +++ b/skymp5-server/cpp/server_guest_lib/script_classes/IPapyrusClass.cpp @@ -0,0 +1,23 @@ +#include "IPapyrusClass.h" +#include "SpSnippetFunctionGen.h" + +VarValue IPapyrusClassBase::MakeSPSnippetPromise( + const char* script, const char* name, + std::shared_ptr policy, VarValue self, + const std::vector& arguments, bool method, bool returns, + VarValue defaultResult) +{ + if (auto actor = + policy->GetDefaultActor(script, name, self.GetMetaStackId())) { + auto s = SpSnippetFunctionGen::SerializeArguments(arguments, actor); + auto promise = + SpSnippet(script, name, s.data(), + method ? SpSnippetFunctionGen::GetFormId(self) : 0) + .Execute(actor, + (returns ? SpSnippetMode::kReturnResult + : SpSnippetMode::kNoReturnResult)); + if (returns) + return VarValue(promise); + } + return defaultResult; +} diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/IPapyrusClass.h b/skymp5-server/cpp/server_guest_lib/script_classes/IPapyrusClass.h index 4ed87aee0a..a6c74db0f2 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/IPapyrusClass.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/IPapyrusClass.h @@ -1,4 +1,5 @@ #pragma once +#include "SpSnippetFunctionGen.h" #include "papyrus-vm/VirtualMachine.h" #include "script_compatibility_policies/IPapyrusCompatibilityPolicy.h" @@ -9,9 +10,17 @@ class IPapyrusClassBase virtual void Register( VirtualMachine& vm, - std::shared_ptr compatibilityPolicy) = 0; + std::shared_ptr policy) = 0; virtual ~IPapyrusClassBase() = default; + static VarValue MakeSPSnippetPromise( + const char* script, const char* name, + std::shared_ptr policy, VarValue self, + const std::vector& arguments, bool method = false, + bool returns = false, VarValue defaultResult = VarValue::None()); + +public: + std::shared_ptr compatibilityPolicy; }; template diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusActor.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusActor.cpp index 607c7828fc..8d21421460 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusActor.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusActor.cpp @@ -1,11 +1,11 @@ #include "PapyrusActor.h" #include "MpActor.h" +#include "SpSnippetFunctionGen.h" #include "script_objects/EspmGameObject.h" #include "script_objects/MpFormGameObject.h" #include "EvaluateTemplate.h" -#include "SpSnippetFunctionGen.h" #include "papyrus-vm/CIString.h" #include @@ -25,6 +25,34 @@ espm::ActorValue ConvertToAV(CIString actorValueName) } } +VarValue PapyrusActor::DrawWeapon(VarValue self, + const std::vector& arguments) +{ + return MakeSPSnippetPromise(GetName(), "DrawWeapon", compatibilityPolicy, + self, arguments, true, true); +} + +VarValue PapyrusActor::UnequipAll(VarValue self, + const std::vector& arguments) +{ + return MakeSPSnippetPromise(GetName(), "UnequipAll", compatibilityPolicy, + self, arguments, true, true); +} + +VarValue PapyrusActor::PlayIdle(VarValue self, + const std::vector& arguments) +{ + return MakeSPSnippetPromise(GetName(), "PlayIdle", compatibilityPolicy, self, + arguments, true, true); +} + +VarValue PapyrusActor::GetSitState(VarValue self, + const std::vector& arguments) +{ + return MakeSPSnippetPromise(GetName(), "GetSitState", compatibilityPolicy, + self, arguments, true, true); +} + VarValue PapyrusActor::IsWeaponDrawn(VarValue self, const std::vector& arguments) { diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusActor.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusActor.h index 437006628d..2d29f13677 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusActor.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusActor.h @@ -1,17 +1,15 @@ #pragma once #include "IPapyrusClass.h" -#include "SpSnippetFunctionGen.h" -#include "script_objects/EspmGameObject.h" class PapyrusActor final : public IPapyrusClass { public: const char* GetName() override { return "Actor"; } - DEFINE_METHOD_SPSNIPPET(DrawWeapon); - DEFINE_METHOD_SPSNIPPET(UnequipAll); - DEFINE_METHOD_SPSNIPPET(PlayIdle); - DEFINE_METHOD_SPSNIPPET(GetSitState); + VarValue DrawWeapon(VarValue self, const std ::vector& arguments); + VarValue UnequipAll(VarValue self, const std ::vector& arguments); + VarValue PlayIdle(VarValue self, const std ::vector& arguments); + VarValue GetSitState(VarValue self, const std ::vector& arguments); VarValue IsWeaponDrawn(VarValue self, const std::vector& arguments); @@ -68,6 +66,4 @@ class PapyrusActor final : public IPapyrusClass void Register(VirtualMachine& vm, std::shared_ptr policy) override; - - std::shared_ptr compatibilityPolicy; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusCell.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusCell.cpp index c9a85908e3..b7159728d6 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusCell.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusCell.cpp @@ -1,4 +1,6 @@ #include "PapyrusCell.h" +#include "script_objects/EspmGameObject.h" +#include "spdlog/spdlog.h" VarValue PapyrusCell::IsAttached(VarValue self, const std::vector& arguments) diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusCell.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusCell.h index bd70e6dd63..e6b7f82b62 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusCell.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusCell.h @@ -1,7 +1,5 @@ #pragma once #include "IPapyrusClass.h" -#include "SpSnippetFunctionGen.h" -#include "script_objects/EspmGameObject.h" class PapyrusCell final : public IPapyrusClass { @@ -14,6 +12,4 @@ class PapyrusCell final : public IPapyrusClass void Register(VirtualMachine& vm, std::shared_ptr policy) override; - - std::shared_ptr compatibilityPolicy; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusClassesFactory.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusClassesFactory.cpp index 135848c237..e88cb606b4 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusClassesFactory.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusClassesFactory.cpp @@ -9,7 +9,9 @@ #include "PapyrusFormList.h" #include "PapyrusGame.h" #include "PapyrusKeyword.h" +#include "PapyrusLeveledActor.h" #include "PapyrusLeveledItem.h" +#include "PapyrusLeveledSpell.h" #include "PapyrusMessage.h" #include "PapyrusNetImmerse.h" #include "PapyrusObjectReference.h" @@ -45,7 +47,9 @@ PapyrusClassesFactory::CreateAndRegister( result.emplace_back(std::make_unique()); result.emplace_back(std::make_unique()); result.emplace_back(std::make_unique()); + result.emplace_back(std::make_unique()); result.emplace_back(std::make_unique()); + result.emplace_back(std::make_unique()); for (auto& papyrusClass : result) { papyrusClass->Register(vm, compatibilityPolicy); diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusDebug.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusDebug.cpp index 74afca3a81..3af01dab4f 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusDebug.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusDebug.cpp @@ -1,8 +1,23 @@ #include "PapyrusDebug.h" #include "MpActor.h" +#include "SpSnippetFunctionGen.h" #include "script_objects/MpFormGameObject.h" +VarValue PapyrusDebug::Notification(VarValue self, + const std::vector& arguments) +{ + return MakeSPSnippetPromise(GetName(), "Notification", compatibilityPolicy, + self, arguments); +} + +VarValue PapyrusDebug::MessageBox(VarValue self, + const std::vector& arguments) +{ + return MakeSPSnippetPromise(GetName(), "MessageBox", compatibilityPolicy, + self, arguments); +} + VarValue PapyrusDebug::SendAnimationEvent( VarValue, const std::vector& arguments) { diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusDebug.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusDebug.h index 23a865b0d6..2bf1bb5a74 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusDebug.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusDebug.h @@ -1,14 +1,14 @@ #pragma once #include "IPapyrusClass.h" -#include "SpSnippetFunctionGen.h" class PapyrusDebug final : public IPapyrusClass { public: const char* GetName() override { return "Debug"; } - DEFINE_STATIC_SPSNIPPET(Notification); - DEFINE_STATIC_SPSNIPPET(MessageBox); + VarValue Notification(VarValue self, + const std ::vector& arguments); + VarValue MessageBox(VarValue self, const std ::vector& arguments); VarValue SendAnimationEvent(VarValue self, const std::vector& arguments); @@ -17,6 +17,4 @@ class PapyrusDebug final : public IPapyrusClass void Register(VirtualMachine& vm, std::shared_ptr policy) override; - - std::shared_ptr compatibilityPolicy; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectBase.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectBase.cpp new file mode 100644 index 0000000000..98bea26cae --- /dev/null +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectBase.cpp @@ -0,0 +1,62 @@ +#include "PapyrusEffectBase.h" + +#include "SpSnippetFunctionGen.h" +#include "WorldState.h" +#include "script_objects/EspmGameObject.h" +#include "script_objects/MpFormGameObject.h" + +PapyrusEffectBase::PapyrusEffectBase(const std::string& name) + : strName(name) +{ +} + +VarValue PapyrusEffectBase::Play(VarValue self, + const std::vector& arguments) +{ + Helper(self, "Play", arguments); + return VarValue::None(); +} + +VarValue PapyrusEffectBase::Stop(VarValue self, + const std::vector& arguments) +{ + Helper(self, "Stop", arguments); + return VarValue::None(); +} + +void PapyrusEffectBase::Register( + VirtualMachine& vm, std::shared_ptr policy) +{ + AddMethod(vm, "Play", &PapyrusEffectBase::Play); + AddMethod(vm, "Stop", &PapyrusEffectBase::Stop); +} + +void PapyrusEffectBase::Helper(VarValue& self, const char* funcName, + const std::vector& arguments) +{ + const auto& selfRec = GetRecordPtr(self); + if (selfRec.rec) { + if (arguments.size() < 1) { + throw std::runtime_error(std::string(funcName) + + " requires at least one argument"); + } + if (auto actorForm = GetFormPtr(arguments[0])) { + for (auto listener : actorForm->GetActorListeners()) { + SpSnippet( + GetName(), funcName, + SpSnippetFunctionGen::SerializeArguments(arguments, listener).data(), + selfRec.ToGlobalId(selfRec.rec->GetId())) + .Execute(listener, SpSnippetMode::kNoReturnResult); + // Workaround to use this function on player clone + if (actorForm->GetFormId() == listener->GetFormId()) { + SpSnippet(GetName(), funcName, + SpSnippetFunctionGen::SerializeArguments(arguments).data(), + selfRec.ToGlobalId(selfRec.rec->GetId())) + .Execute(listener, SpSnippetMode::kNoReturnResult); + } + } + } + } else { + throw std::runtime_error(std::string(funcName) + ": can't get object!"); + } +} diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectBase.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectBase.h new file mode 100644 index 0000000000..e87f12dde6 --- /dev/null +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectBase.h @@ -0,0 +1,21 @@ +#pragma once +#include "IPapyrusClass.h" + +class PapyrusEffectBase : public IPapyrusClass +{ +public: + PapyrusEffectBase(const std::string& name); + const char* GetName() override { return strName.c_str(); } + VarValue Play(VarValue self, const std::vector& arguments); + VarValue Stop(VarValue self, const std::vector& arguments); + + void Register(VirtualMachine& vm, + std::shared_ptr policy) override; + +private: + void Helper(VarValue& self, const char* funcName, + const std::vector& arguments); + +private: + std::string strName; +}; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectShader.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectShader.cpp index 1afdea5b35..5d7eb06e6a 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectShader.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectShader.cpp @@ -1,50 +1,6 @@ #include "PapyrusEffectShader.h" -#include "WorldState.h" -#include "script_objects/EspmGameObject.h" -#include "script_objects/MpFormGameObject.h" - -VarValue PapyrusEffectShader::Play(VarValue self, - const std::vector& arguments) -{ - Helper(self, "Play", arguments); - return VarValue::None(); -} - -VarValue PapyrusEffectShader::Stop(VarValue self, - const std::vector& arguments) -{ - Helper(self, "Stop", arguments); - return VarValue::None(); -} - -// This is exact copy of PapyrusVisualEffect::Helper -void PapyrusEffectShader::Helper(VarValue& self, const char* funcName, - const std::vector& arguments) +PapyrusEffectShader::PapyrusEffectShader() + : PapyrusEffectBase("EffectShader") { - const auto& selfRec = GetRecordPtr(self); - if (selfRec.rec) { - if (arguments.size() < 1) { - throw std::runtime_error(std::string(funcName) + - " requires at least one argument"); - } - if (auto actorForm = GetFormPtr(arguments[0])) { - for (auto listener : actorForm->GetActorListeners()) { - SpSnippet( - GetName(), funcName, - SpSnippetFunctionGen::SerializeArguments(arguments, listener).data(), - selfRec.ToGlobalId(selfRec.rec->GetId())) - .Execute(listener, SpSnippetMode::kNoReturnResult); - // Workaround to use this function on player clone - if (actorForm->GetFormId() == listener->GetFormId()) { - SpSnippet(GetName(), funcName, - SpSnippetFunctionGen::SerializeArguments(arguments).data(), - selfRec.ToGlobalId(selfRec.rec->GetId())) - .Execute(listener, SpSnippetMode::kNoReturnResult); - } - } - } - } else { - throw std::runtime_error(std::string(funcName) + ": can't get object!"); - } } diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectShader.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectShader.h index f02c6de564..e10d536ae0 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectShader.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusEffectShader.h @@ -1,22 +1,8 @@ #pragma once -#include "IPapyrusClass.h" -#include "SpSnippetFunctionGen.h" +#include "PapyrusEffectBase.h" -class PapyrusEffectShader final : public IPapyrusClass +class PapyrusEffectShader final : public PapyrusEffectBase { public: - const char* GetName() override { return "EffectShader"; } - VarValue Play(VarValue self, const std::vector& arguments); - VarValue Stop(VarValue self, const std::vector& arguments); - - void Register(VirtualMachine& vm, - std::shared_ptr policy) override - { - AddMethod(vm, "Play", &PapyrusEffectShader::Play); - AddMethod(vm, "Stop", &PapyrusEffectShader::Stop); - } - -private: - void Helper(VarValue& self, const char* funcName, - const std::vector& arguments); + PapyrusEffectShader(); }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFaction.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFaction.cpp index cbfc1565d2..f81f3141e4 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFaction.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFaction.cpp @@ -1,5 +1,8 @@ #include "PapyrusFaction.h" +#include "WorldState.h" +#include "script_objects/EspmGameObject.h" + VarValue PapyrusFaction::GetReaction(VarValue self, const std::vector& arguments) { @@ -27,3 +30,16 @@ VarValue PapyrusFaction::GetReaction(VarValue self, return VarValue(reaction); } + +void PapyrusFaction::Register( + VirtualMachine& vm, std::shared_ptr policy) +{ + compatibilityPolicy = policy; + + factions = compatibilityPolicy->GetWorldState() + ->GetEspm() + .GetBrowser() + .GetRecordsByType("FACT"); + + AddMethod(vm, "GetReaction", &PapyrusFaction::GetReaction); +} diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFaction.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFaction.h index aa93a5e856..896e7eb71a 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFaction.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFaction.h @@ -1,7 +1,9 @@ #pragma once #include "IPapyrusClass.h" -#include "WorldState.h" -#include "script_objects/EspmGameObject.h" + +namespace espm { +class RecordHeader; +} class PapyrusFaction final : public IPapyrusClass { @@ -12,18 +14,7 @@ class PapyrusFaction final : public IPapyrusClass // SetReaction ignored, because no way to edit factions forever? void Register(VirtualMachine& vm, - std::shared_ptr policy) override - { - compatibilityPolicy = policy; - - factions = compatibilityPolicy->GetWorldState() - ->GetEspm() - .GetBrowser() - .GetRecordsByType("FACT"); - - AddMethod(vm, "GetReaction", &PapyrusFaction::GetReaction); - } + std::shared_ptr policy) override; - std::shared_ptr compatibilityPolicy; std::vector*> factions; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusForm.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusForm.cpp index 048e6adf79..2cbc7e6639 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusForm.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusForm.cpp @@ -4,11 +4,10 @@ #include "MpActor.h" #include "TimeUtils.h" #include "WorldState.h" -#include "papyrus-vm/Structures.h" #include "script_objects/EspmGameObject.h" #include "script_objects/MpFormGameObject.h" +#include "spdlog/spdlog.h" -#include #include #include diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusForm.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusForm.h index 57ef2f44de..ab9be70502 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusForm.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusForm.h @@ -1,6 +1,5 @@ #pragma once #include "IPapyrusClass.h" -#include "papyrus-vm/Structures.h" class PapyrusForm final : public IPapyrusClass { @@ -21,7 +20,4 @@ class PapyrusForm final : public IPapyrusClass void Register(VirtualMachine& vm, std::shared_ptr policy) override; - -private: - std::shared_ptr compatibilityPolicy; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFormList.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFormList.cpp index fcef502ffc..ab64cb5dbf 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFormList.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFormList.cpp @@ -58,3 +58,11 @@ VarValue PapyrusFormList::Find(VarValue self, return VarValue::None(); } + +void PapyrusFormList::Register( + VirtualMachine& vm, std::shared_ptr policy) +{ + AddMethod(vm, "GetSize", &PapyrusFormList::GetSize); + AddMethod(vm, "GetAt", &PapyrusFormList::GetAt); + AddMethod(vm, "Find", &PapyrusFormList::Find); +} diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFormList.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFormList.h index f2cdffab9b..d49aa9e5c6 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFormList.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusFormList.h @@ -11,10 +11,5 @@ class PapyrusFormList final : public IPapyrusClass VarValue Find(VarValue self, const std::vector& arguments) const; void Register(VirtualMachine& vm, - std::shared_ptr policy) override - { - AddMethod(vm, "GetSize", &PapyrusFormList::GetSize); - AddMethod(vm, "GetAt", &PapyrusFormList::GetAt); - AddMethod(vm, "Find", &PapyrusFormList::Find); - } + std::shared_ptr policy) override; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusGame.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusGame.cpp index 36a5c08b7e..95a09ca516 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusGame.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusGame.cpp @@ -1,11 +1,33 @@ #include "PapyrusGame.h" #include "PapyrusFormList.h" +#include "SpSnippetFunctionGen.h" #include "WorldState.h" #include "libespm/Combiner.h" #include "script_objects/EspmGameObject.h" #include "script_objects/MpFormGameObject.h" +VarValue PapyrusGame::ForceThirdPerson(VarValue self, + const std::vector& arguments) +{ + return MakeSPSnippetPromise(GetName(), "ForceThirdPerson", + compatibilityPolicy, self, arguments); +} + +VarValue PapyrusGame::DisablePlayerControls( + VarValue self, const std::vector& arguments) +{ + return MakeSPSnippetPromise(GetName(), "DisablePlayerControls", + compatibilityPolicy, self, arguments); +} + +VarValue PapyrusGame::EnablePlayerControls( + VarValue self, const std::vector& arguments) +{ + return MakeSPSnippetPromise(GetName(), "EnablePlayerControls", + compatibilityPolicy, self, arguments); +} + VarValue PapyrusGame::IncrementStat(VarValue self, const std::vector& arguments) { @@ -138,15 +160,8 @@ VarValue PapyrusGame::ShowLimitedRaceMenu( VarValue PapyrusGame::GetCameraState(VarValue self, const std::vector& arguments) { - auto serializedArgs = SpSnippetFunctionGen::SerializeArguments(arguments); - if (auto actor = compatibilityPolicy->GetDefaultActor( - GetName(), "GetCameraState", self.GetMetaStackId())) { - Viet::Promise promise = - SpSnippet(GetName(), "GetCameraState", serializedArgs.data()) - .Execute(actor, SpSnippetMode::kReturnResult); - return VarValue(Viet::Promise(promise)); - } - return VarValue(-1); + return MakeSPSnippetPromise(GetName(), "GetCameraState", compatibilityPolicy, + self, arguments, false, true, VarValue(-1)); } void PapyrusGame::RaceMenuHelper(VarValue& self, const char* funcName, @@ -204,16 +219,8 @@ VarValue PapyrusGame::GetFormEx( VarValue PapyrusGame::ShakeController(VarValue self, const std::vector& arguments) { - auto funcName = "ShakeController"; - - auto serializedArgs = SpSnippetFunctionGen::SerializeArguments(arguments); - if (auto actor = compatibilityPolicy->GetDefaultActor( - GetName(), funcName, self.GetMetaStackId())) { - SpSnippet(GetName(), funcName, serializedArgs.data()) - .Execute(actor, SpSnippetMode::kNoReturnResult); - } - - return VarValue::None(); + return MakeSPSnippetPromise(GetName(), "ShakeController", + compatibilityPolicy, self, arguments); } void PapyrusGame::Register(VirtualMachine& vm, diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusGame.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusGame.h index 7fb49ddb2a..d0b22e7cd7 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusGame.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusGame.h @@ -1,16 +1,17 @@ #pragma once #include "IPapyrusClass.h" -#include "SpSnippetFunctionGen.h" class PapyrusGame final : public IPapyrusClass { public: const char* GetName() override { return "Game"; } - DEFINE_STATIC_SPSNIPPET(ForceThirdPerson); - DEFINE_STATIC_SPSNIPPET(DisablePlayerControls); - DEFINE_STATIC_SPSNIPPET(EnablePlayerControls); - + VarValue ForceThirdPerson(VarValue self, + const std ::vector& arguments); + VarValue DisablePlayerControls(VarValue self, + const std ::vector& arguments); + VarValue EnablePlayerControls(VarValue self, + const std ::vector& arguments); VarValue IncrementStat(VarValue self, const std::vector& arguments); @@ -42,9 +43,6 @@ class PapyrusGame final : public IPapyrusClass void Register(VirtualMachine& vm, std::shared_ptr policy) override; -public: - std::shared_ptr compatibilityPolicy; - private: void RaceMenuHelper(VarValue& self, const char* funcName, const std::vector& arguments); diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusKeyword.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusKeyword.cpp index 98d3088b51..54acd61661 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusKeyword.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusKeyword.cpp @@ -1,4 +1,6 @@ #include "PapyrusKeyword.h" +#include "WorldState.h" +#include "script_objects/EspmGameObject.h" VarValue PapyrusKeyword::GetKeyword(VarValue self, const std::vector& arguments) @@ -29,3 +31,16 @@ VarValue PapyrusKeyword::GetKeyword(VarValue self, return VarValue::None(); } + +void PapyrusKeyword::Register( + VirtualMachine& vm, std::shared_ptr policy) +{ + compatibilityPolicy = policy; + + keywords = compatibilityPolicy->GetWorldState() + ->GetEspm() + .GetBrowser() + .GetRecordsByType("KYWD"); + + AddStatic(vm, "GetKeyword", &PapyrusKeyword::GetKeyword); +} diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusKeyword.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusKeyword.h index 8f49474d6b..c10d4d4861 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusKeyword.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusKeyword.h @@ -1,7 +1,9 @@ #pragma once #include "IPapyrusClass.h" -#include "WorldState.h" -#include "script_objects/EspmGameObject.h" + +namespace espm { +class RecordHeader; +} class PapyrusKeyword final : public IPapyrusClass { @@ -11,18 +13,7 @@ class PapyrusKeyword final : public IPapyrusClass VarValue GetKeyword(VarValue self, const std::vector& arguments); void Register(VirtualMachine& vm, - std::shared_ptr policy) override - { - compatibilityPolicy = policy; - - keywords = compatibilityPolicy->GetWorldState() - ->GetEspm() - .GetBrowser() - .GetRecordsByType("KYWD"); - - AddStatic(vm, "GetKeyword", &PapyrusKeyword::GetKeyword); - } + std::shared_ptr policy) override; - std::shared_ptr compatibilityPolicy; std::vector*> keywords; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledActor.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledActor.cpp new file mode 100644 index 0000000000..248b0198e2 --- /dev/null +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledActor.cpp @@ -0,0 +1,6 @@ +#include "PapyrusLeveledActor.h" + +PapyrusLeveledActor::PapyrusLeveledActor() + : PapyrusLeveledBase("LeveledActor") +{ +} diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledActor.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledActor.h new file mode 100644 index 0000000000..6d03c9499d --- /dev/null +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledActor.h @@ -0,0 +1,8 @@ +#pragma once +#include "PapyrusLeveledBase.h" + +class PapyrusLeveledActor final : public PapyrusLeveledBase +{ +public: + PapyrusLeveledActor(); +}; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledBase.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledBase.cpp new file mode 100644 index 0000000000..099e4c84d3 --- /dev/null +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledBase.cpp @@ -0,0 +1,46 @@ +#include "PapyrusLeveledBase.h" + +#include "WorldState.h" +#include "script_objects/EspmGameObject.h" + +VarValue PapyrusLeveledBase::GetNthForm(VarValue self, + const std::vector& arguments) +{ + if (arguments.size() < 1) { + throw std::runtime_error( + "LeveledItem.GetNthForm requires at least 1 argument"); + } + + auto itemRecord = GetRecordPtr(self); + if (!itemRecord.rec) { + throw std::runtime_error("Self not found"); + } + auto& loader = compatibilityPolicy->GetWorldState()->GetEspm(); + auto leveledItem = espm::Convert(itemRecord.rec); + if (leveledItem) { + auto data = leveledItem->GetData( + compatibilityPolicy->GetWorldState()->GetEspmCache()); + int index = static_cast(arguments[0]); + if (data.numEntries > static_cast(index)) { + auto formId = itemRecord.ToGlobalId(data.entries[index].formId); + auto lookupRes = loader.GetBrowser().LookupById(formId); + if (lookupRes.rec) { + return VarValue(std::make_shared(lookupRes)); + } + } + } + return VarValue::None(); +} + +void PapyrusLeveledBase::Register( + VirtualMachine& vm, std::shared_ptr policy) +{ + compatibilityPolicy = policy; + + AddMethod(vm, "GetNthForm", &PapyrusLeveledBase::GetNthForm); +} + +PapyrusLeveledBase::PapyrusLeveledBase(const std::string& name) + : strName(name) +{ +} diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledBase.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledBase.h new file mode 100644 index 0000000000..ea8263ad95 --- /dev/null +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledBase.h @@ -0,0 +1,17 @@ +#pragma once +#include "IPapyrusClass.h" + +class PapyrusLeveledBase : public IPapyrusClass +{ +public: + PapyrusLeveledBase(const std::string& name); + const char* GetName() override { return strName.c_str(); } + + VarValue GetNthForm(VarValue self, const std::vector& arguments); + + void Register(VirtualMachine& vm, + std::shared_ptr policy) override; + +private: + std::string strName; +}; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledItem.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledItem.cpp index 405e8cfcc1..64ead07c68 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledItem.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledItem.cpp @@ -1,42 +1,6 @@ #include "PapyrusLeveledItem.h" -#include "LeveledListUtils.h" -#include "WorldState.h" -#include "script_objects/EspmGameObject.h" - -VarValue PapyrusLeveledItem::GetNthForm(VarValue self, - const std::vector& arguments) -{ - if (arguments.size() < 1) { - throw std::runtime_error( - "LeveledItem.GetNthForm requires at least 1 argument"); - } - - auto itemRecord = GetRecordPtr(self); - if (!itemRecord.rec) { - throw std::runtime_error("Self not found"); - } - auto& loader = compatibilityPolicy->GetWorldState()->GetEspm(); - auto leveledItem = espm::Convert(itemRecord.rec); - if (leveledItem) { - auto data = leveledItem->GetData( - compatibilityPolicy->GetWorldState()->GetEspmCache()); - int index = static_cast(arguments[0]); - if (data.numEntries > static_cast(index)) { - auto formId = itemRecord.ToGlobalId(data.entries[index].formId); - auto lookupRes = loader.GetBrowser().LookupById(formId); - if (lookupRes.rec) { - return VarValue(std::make_shared(lookupRes)); - } - } - } - return VarValue::None(); -} - -void PapyrusLeveledItem::Register( - VirtualMachine& vm, std::shared_ptr policy) +PapyrusLeveledItem::PapyrusLeveledItem() + : PapyrusLeveledBase("LeveledItem") { - compatibilityPolicy = policy; - - AddMethod(vm, "GetNthForm", &PapyrusLeveledItem::GetNthForm); } diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledItem.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledItem.h index be486a73e2..4787ae4310 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledItem.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledItem.h @@ -1,15 +1,8 @@ #pragma once -#include "IPapyrusClass.h" +#include "PapyrusLeveledBase.h" -class PapyrusLeveledItem final : public IPapyrusClass +class PapyrusLeveledItem final : public PapyrusLeveledBase { public: - const char* GetName() override { return "LeveledItem"; } - - VarValue GetNthForm(VarValue self, const std::vector& arguments); - - void Register(VirtualMachine& vm, - std::shared_ptr policy) override; - - std::shared_ptr compatibilityPolicy; + PapyrusLeveledItem(); }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledSpell.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledSpell.cpp new file mode 100644 index 0000000000..ea4dcd89b1 --- /dev/null +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledSpell.cpp @@ -0,0 +1,6 @@ +#include "PapyrusLeveledSpell.h" + +PapyrusLeveledSpell::PapyrusLeveledSpell() + : PapyrusLeveledBase("LeveledSpell") +{ +} diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledSpell.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledSpell.h new file mode 100644 index 0000000000..07b06c8e78 --- /dev/null +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusLeveledSpell.h @@ -0,0 +1,8 @@ +#pragma once +#include "PapyrusLeveledBase.h" + +class PapyrusLeveledSpell final : public PapyrusLeveledBase +{ +public: + PapyrusLeveledSpell(); +}; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusMessage.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusMessage.cpp index bb6735a93c..7ff5ceb942 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusMessage.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusMessage.cpp @@ -1,5 +1,12 @@ #include "PapyrusMessage.h" +VarValue PapyrusMessage::Show(VarValue self, + const std::vector& arguments) +{ + return MakeSPSnippetPromise(GetName(), "Show", compatibilityPolicy, self, + arguments, true, true); +} + void PapyrusMessage::Register( VirtualMachine& vm, std::shared_ptr policy) { diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusMessage.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusMessage.h index 46d11a5b61..359c043f0c 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusMessage.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusMessage.h @@ -1,16 +1,13 @@ #pragma once #include "IPapyrusClass.h" -#include "SpSnippetFunctionGen.h" class PapyrusMessage final : public IPapyrusClass { public: const char* GetName() override { return "Message"; } - DEFINE_METHOD_SPSNIPPET(Show); + VarValue Show(VarValue self, const std::vector& arguments); void Register(VirtualMachine& vm, std::shared_ptr policy) override; - - std::shared_ptr compatibilityPolicy; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusNetImmerse.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusNetImmerse.cpp index b529b1b384..89c546d1d5 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusNetImmerse.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusNetImmerse.cpp @@ -1,4 +1,5 @@ #include "PapyrusNetImmerse.h" +#include "SpSnippetFunctionGen.h" #include "script_objects/EspmGameObject.h" #include "script_objects/MpFormGameObject.h" diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusNetImmerse.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusNetImmerse.h index b4cb03846d..77b6d43f45 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusNetImmerse.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusNetImmerse.h @@ -1,6 +1,5 @@ #pragma once #include "IPapyrusClass.h" -#include "SpSnippetFunctionGen.h" class PapyrusNetImmerse final : public IPapyrusClass { @@ -14,6 +13,4 @@ class PapyrusNetImmerse final : public IPapyrusClass void Register(VirtualMachine& vm, std::shared_ptr policy) override; - - std::shared_ptr compatibilityPolicy; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp index 94abb4c989..e132be0a05 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp @@ -8,7 +8,6 @@ #include "SpSnippetFunctionGen.h" #include "TimeUtils.h" #include "WorldState.h" -#include "papyrus-vm/Structures.h" #include "script_objects/EspmGameObject.h" #include "script_objects/MpFormGameObject.h" #include diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.h index d780420769..3cdc9871bc 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.h @@ -1,7 +1,5 @@ #pragma once #include "IPapyrusClass.h" -#include "papyrus-vm/Structures.h" -#include class PapyrusObjectReference final : public IPapyrusClass diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusPotion.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusPotion.h index 743dffdae3..40b7a75d3c 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusPotion.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusPotion.h @@ -1,6 +1,5 @@ #pragma once #include "IPapyrusClass.h" -#include "SpSnippetFunctionGen.h" class PapyrusPotion final : public IPapyrusClass { @@ -11,6 +10,4 @@ class PapyrusPotion final : public IPapyrusClass void Register(VirtualMachine& vm, std::shared_ptr policy) override; - - std::shared_ptr compatibilityPolicy; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusQuest.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusQuest.cpp index 6d1ca7b79c..2fcb4f4223 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusQuest.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusQuest.cpp @@ -1,5 +1,6 @@ #include "PapyrusQuest.h" #include "script_objects/EspmGameObject.h" +#include "spdlog/spdlog.h" VarValue PapyrusQuest::GetStage(VarValue self, const std::vector& arguments) diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusQuest.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusQuest.h index 08345e5e89..eb19cbb0f7 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusQuest.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusQuest.h @@ -1,6 +1,5 @@ #pragma once #include "IPapyrusClass.h" -#include "SpSnippetFunctionGen.h" class PapyrusQuest final : public IPapyrusClass { @@ -15,6 +14,4 @@ class PapyrusQuest final : public IPapyrusClass void Register(VirtualMachine& vm, std::shared_ptr policy) override; - - std::shared_ptr compatibilityPolicy; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSkymp.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSkymp.cpp index 9d550b1b65..c401b40641 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSkymp.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSkymp.cpp @@ -7,9 +7,17 @@ VarValue PapyrusSkymp::SetDefaultActor(VarValue self, const std::vector& arguments) { if (arguments.size() >= 1) { - policy->SetDefaultActor(self.GetMetaStackId(), - GetFormPtr(arguments[0])); + compatibilityPolicy->SetDefaultActor(self.GetMetaStackId(), + GetFormPtr(arguments[0])); } return VarValue::None(); } + +void PapyrusSkymp::Register( + VirtualMachine& vm, std::shared_ptr policy) +{ + compatibilityPolicy = policy; + + AddStatic(vm, "SetDefaultActor", &PapyrusSkymp::SetDefaultActor); +} diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSkymp.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSkymp.h index 5656e714b0..2c4708d95b 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSkymp.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSkymp.h @@ -9,14 +9,6 @@ class PapyrusSkymp final : public IPapyrusClass VarValue SetDefaultActor(VarValue self, const std::vector& arguments); - void Register( - VirtualMachine& vm, - std::shared_ptr compatibilityPolicy) override - { - policy = compatibilityPolicy; - - AddStatic(vm, "SetDefaultActor", &PapyrusSkymp::SetDefaultActor); - } - - std::shared_ptr policy; + void Register(VirtualMachine& vm, + std::shared_ptr policy) override; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSound.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSound.h index 03fa1f880c..970d87662a 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSound.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusSound.h @@ -10,6 +10,4 @@ class PapyrusSound final : public IPapyrusClass void Register(VirtualMachine& vm, std::shared_ptr policy) override; - - std::shared_ptr compatibilityPolicy; }; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusUtility.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusUtility.h index 2b1715f295..24dcdd9cd1 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusUtility.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusUtility.h @@ -42,8 +42,6 @@ class PapyrusUtility final : public IPapyrusClass void Register(VirtualMachine& vm, std::shared_ptr policy) override; - std::shared_ptr compatibilityPolicy; - private: VarValue WaitHelper(VarValue& self, const char* funcName, const std::vector& arguments); diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusVisualEffect.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusVisualEffect.cpp index a2929193c9..3d1c0b863f 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusVisualEffect.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusVisualEffect.cpp @@ -1,50 +1,6 @@ #include "PapyrusVisualEffect.h" -#include "MpActor.h" -#include "SpSnippetFunctionGen.h" -#include "script_objects/EspmGameObject.h" -#include "script_objects/MpFormGameObject.h" -VarValue PapyrusVisualEffect::Play(VarValue self, - const std::vector& arguments) +PapyrusVisualEffect::PapyrusVisualEffect() + : PapyrusEffectBase("VisualEffect") { - Helper(self, "Play", arguments); - return VarValue::None(); -} - -VarValue PapyrusVisualEffect::Stop(VarValue self, - const std::vector& arguments) -{ - Helper(self, "Stop", arguments); - return VarValue::None(); -} - -// This is exact copy of PapyrusEffectShader::Helper -void PapyrusVisualEffect::Helper(VarValue& self, const char* funcName, - const std::vector& arguments) -{ - const auto& selfRec = GetRecordPtr(self); - if (selfRec.rec) { - if (arguments.size() < 1) { - throw std::runtime_error(std::string(funcName) + - " requires at least one argument"); - } - if (auto actorForm = GetFormPtr(arguments[0])) { - for (auto listener : actorForm->GetActorListeners()) { - SpSnippet( - GetName(), funcName, - SpSnippetFunctionGen::SerializeArguments(arguments, listener).data(), - selfRec.ToGlobalId(selfRec.rec->GetId())) - .Execute(listener, SpSnippetMode::kNoReturnResult); - // Workaround to use this function on player clone - if (actorForm->GetFormId() == listener->GetFormId()) { - SpSnippet(GetName(), funcName, - SpSnippetFunctionGen::SerializeArguments(arguments).data(), - selfRec.ToGlobalId(selfRec.rec->GetId())) - .Execute(listener, SpSnippetMode::kNoReturnResult); - } - } - } - } else { - throw std::runtime_error(std::string(funcName) + ": can't get object!"); - } } diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusVisualEffect.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusVisualEffect.h index d2748eb84f..5bfe5a5b63 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusVisualEffect.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusVisualEffect.h @@ -1,21 +1,8 @@ #pragma once -#include "IPapyrusClass.h" +#include "PapyrusEffectBase.h" -class PapyrusVisualEffect final : public IPapyrusClass +class PapyrusVisualEffect final : public PapyrusEffectBase { public: - const char* GetName() override { return "VisualEffect"; } - VarValue Play(VarValue self, const std::vector& arguments); - VarValue Stop(VarValue self, const std::vector& arguments); - - void Register(VirtualMachine& vm, - std::shared_ptr policy) override - { - AddMethod(vm, "Play", &PapyrusVisualEffect::Play); - AddMethod(vm, "Stop", &PapyrusVisualEffect::Stop); - } - -private: - void Helper(VarValue& self, const char* funcName, - const std::vector& arguments); + PapyrusVisualEffect(); }; diff --git a/unit/PapyrusSkympTest.cpp b/unit/PapyrusSkympTest.cpp index 70d0f42512..4b0e8fdf35 100644 --- a/unit/PapyrusSkympTest.cpp +++ b/unit/PapyrusSkympTest.cpp @@ -12,7 +12,7 @@ TEST_CASE("SetDefaultActor should store actor per stack", "[Papyrus][Skymp]") auto logger = std::make_shared("empty logger"); PapyrusSkymp skymp; - skymp.policy = std::make_shared(&p.worldState); + skymp.compatibilityPolicy = std::make_shared(&p.worldState); skymp.SetDefaultActor(VarValue::AttachTestStackId(VarValue::None(), 0), { ac.ToVarValue() }); @@ -20,13 +20,13 @@ TEST_CASE("SetDefaultActor should store actor per stack", "[Papyrus][Skymp]") skymp.SetDefaultActor(VarValue::AttachTestStackId(VarValue::None(), 1), { VarValue::None() }); - REQUIRE(skymp.policy->GetDefaultActor("", "", 0) == &ac); - REQUIRE(skymp.policy->GetDefaultActor("", "", 1) == nullptr); + REQUIRE(skymp.compatibilityPolicy->GetDefaultActor("", "", 0) == &ac); + REQUIRE(skymp.compatibilityPolicy->GetDefaultActor("", "", 1) == nullptr); REQUIRE_THROWS_WITH( - skymp.policy->GetDefaultActor("", "", 91298), + skymp.compatibilityPolicy->GetDefaultActor("", "", 91298), Catch::Matchers::ContainsSubstring( "Invalid stackId was passed to GetDefaultActor (91298)")); - REQUIRE_THROWS_WITH(skymp.policy->GetDefaultActor("", "", -1), + REQUIRE_THROWS_WITH(skymp.compatibilityPolicy->GetDefaultActor("", "", -1), Catch::Matchers::ContainsSubstring( "Invalid stackId was passed to GetDefaultActor (-1)")); }