Skip to content

Commit

Permalink
feat(skymp5-server): add Quest.GetStage stub & disable some bad scrip…
Browse files Browse the repository at this point in the history
…ts (#2256)
  • Loading branch information
Pospelove authored Dec 9, 2024
1 parent f1aaff4 commit e1235f0
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
18 changes: 18 additions & 0 deletions skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1689,6 +1689,7 @@ void MpObjectReference::InitScripts()

// A hardcoded hack to remove all scripts except SweetPie scripts from
// exterior objects
// TODO: make is a server setting with proper conditions or an API
if (GetParent() && GetParent()->disableVanillaScriptsInExterior &&
GetFormId() < 0x05000000) {
auto cellOrWorld = GetCellOrWorld().ToFormId(GetParent()->espmFiles);
Expand All @@ -1708,6 +1709,23 @@ void MpObjectReference::InitScripts()
}
}

// A hardcoded hack to remove unsupported scripts
// TODO: make is a server setting with proper conditions or an API
auto isScriptEraseNeeded = [](const std::string& val) {
// 1. GetStage in OnTrigger
// 2. Unable to determine Actor for 'Game.GetPlayer' in 'OnLoad'
const bool isRemoveNeeded =
!Utils::stricmp(val.data(), "DA06PreRitualSceneTriggerScript") ||
!Utils::stricmp(val.data(), "CritterSpawn");

spdlog::info("Skipping script {}", val);

return isRemoveNeeded;
};
scriptNames.erase(std::remove_if(scriptNames.begin(), scriptNames.end(),
isScriptEraseNeeded),
scriptNames.end());

if (!scriptNames.empty()) {
pImpl->scriptState = std::make_unique<ScriptState>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "PapyrusNetImmerse.h"
#include "PapyrusObjectReference.h"
#include "PapyrusPotion.h"
#include "PapyrusQuest.h"
#include "PapyrusSkymp.h"
#include "PapyrusSound.h"
#include "PapyrusUtility.h"
Expand Down Expand Up @@ -42,6 +43,7 @@ PapyrusClassesFactory::CreateAndRegister(
result.emplace_back(std::make_unique<PapyrusNetImmerse>());
result.emplace_back(std::make_unique<PapyrusPotion>());
result.emplace_back(std::make_unique<PapyrusVisualEffect>());
result.emplace_back(std::make_unique<PapyrusQuest>());

for (auto& papyrusClass : result) {
papyrusClass->Register(vm, compatibilityPolicy);
Expand Down
37 changes: 37 additions & 0 deletions skymp5-server/cpp/server_guest_lib/script_classes/PapyrusQuest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "PapyrusQuest.h"
#include "script_objects/EspmGameObject.h"

VarValue PapyrusQuest::GetStage(VarValue self,
const std::vector<VarValue>& arguments)
{
return GetCurrentStageID(self, arguments);
}

VarValue PapyrusQuest::GetCurrentStageID(
VarValue self, const std::vector<VarValue>& arguments)
{
static std::once_flag g_flag;

std::call_once(g_flag, [&] {
espm::CompressedFieldsCache cache;

const auto& quest = GetRecordPtr(self);
const char* editorId =
quest.rec ? quest.rec->GetEditorId(cache) : "<null>";

spdlog::warn(
"GetCurrentStageID - Not implemented, returning 0 (quest was {})",
editorId ? editorId : "<null>");
spdlog::warn("GetCurrentStageID - Won't output further warnings due to "
"performance reasons");
});

return VarValue(0);
}

void PapyrusQuest::Register(
VirtualMachine& vm, std::shared_ptr<IPapyrusCompatibilityPolicy> policy)
{
AddMethod(vm, "GetStage", &PapyrusQuest::GetStage);
AddMethod(vm, "GetCurrentStageID", &PapyrusQuest::GetCurrentStageID);
}
20 changes: 20 additions & 0 deletions skymp5-server/cpp/server_guest_lib/script_classes/PapyrusQuest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once
#include "IPapyrusClass.h"
#include "SpSnippetFunctionGen.h"

class PapyrusQuest final : public IPapyrusClass<PapyrusQuest>
{
public:
const char* GetName() override { return "Quest"; }

// Non-native in original Papyrus, just a wrapper around GetCurrentStageID
VarValue GetStage(VarValue self, const std::vector<VarValue>& arguments);

VarValue GetCurrentStageID(VarValue self,
const std::vector<VarValue>& arguments);

void Register(VirtualMachine& vm,
std::shared_ptr<IPapyrusCompatibilityPolicy> policy) override;

std::shared_ptr<IPapyrusCompatibilityPolicy> compatibilityPolicy;
};

0 comments on commit e1235f0

Please sign in to comment.