Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mrowrpurr/3b61e776b48d1f875142b718dee5a99c to your computer and use it in GitHub Desktop.
Save mrowrpurr/3b61e776b48d1f875142b718dee5a99c to your computer and use it in GitHub Desktop.
Learning SKSE - Little bits of Reflection
namespace
{
class MyCallback : public RE::BSScript::IStackCallbackFunctor
{
public:
MyCallback() {}
void operator()(RE::BSScript::Variable a_result)
{
// DO SOMETHING!
}
bool CanSave() {
return false;
}
void SetObject(const RE::BSTSmartPointer<RE::BSScript::Object>&) {
}
};
// RE::TESForm::GetAllFormsByEditorID()
// RE::TESForm::LookupFormByEditorID()
// scriptName MyFirstSkse
//
// string function HelloSkse() global native
//
// string function GetScriptDescription(Quest q)
//
std::vector<std::string> HelloSkse(RE::StaticFunctionTag*, std::string editor_id)
{
auto* form = RE::TESForm::LookupByEditorID(editor_id);
if (!form) {
return {};
}
auto* vm = RE::BSScript::Internal::VirtualMachine::GetSingleton();
auto* policy = vm->GetObjectHandlePolicy();
auto handle = policy->GetHandleForObject(form->GetFormType(), form);
auto className = RE::BSFixedString("HelloMod");
auto functionName = RE::BSFixedString("RunMe");
auto args = RE::FunctionArguments<std::string>("I am c++");
auto callback = new MyCallback();
auto callbackPtr = RE::BSTSmartPointer<RE::BSScript::IStackCallbackFunctor>(callback);
vm->DispatchMethodCall(handle, className, functionName, &args, callbackPtr);
auto scriptsMap = vm->attachedScripts.find(handle);
if (scriptsMap == vm->attachedScripts.end()) {
return {};
}
auto& scripts = scriptsMap->second;
if (scripts.size() > 0) {
std::vector<std::string> scriptNames;
scriptNames.reserve(scripts.size());
for (auto& script : scripts) {
auto* typeInfo = script->GetTypeInfo();
scriptNames.emplace_back(typeInfo->GetName());
auto* properties = typeInfo->GetPropertyIter();
for (std::size_t i = 0; i < typeInfo->propertyCount; i++) {
scriptNames.emplace_back(properties[i].name);
}
}
return scriptNames;
} else {
return {};
}
}
bool RegisterFuncs(RE::BSScript::IVirtualMachine* a_vm)
{
a_vm->RegisterFunction("HelloSkse", "MyFirstSkse", HelloSkse);
return true;
}
#ifdef SKSE_1_6
extern "C" DLLEXPORT constinit auto SKSEPlugin_Version = []() {
SKSE::PluginVersionData v;
v.PluginVersion(Plugin::VERSION);
v.PluginName(Plugin::NAME);
v.UsesAddressLibrary(true);
v.CompatibleVersions({ SKSE::RUNTIME_LATEST });
return v;
}();
#endif
extern "C" DLLEXPORT bool SKSEAPI SKSEPlugin_Load(const SKSE::LoadInterface* a_skse)
{
SKSE::Init(a_skse);
auto papyrus = SKSE::GetPapyrusInterface();
papyrus->Register(RegisterFuncs);
return true;
}
extern "C" DLLEXPORT bool SKSEAPI SKSEPlugin_Query(const SKSE::QueryInterface* a_skse, SKSE::PluginInfo* a_info)
{
a_info->infoVersion = SKSE::PluginInfo::kVersion;
a_info->name = Plugin::NAME.data();
a_info->version = 1; // Plugin::VERSION.pack();
if (a_skse->IsEditor()) {
return false;
}
const auto ver = a_skse->RuntimeVersion();
if (ver < SKSE::RUNTIME_1_5_39) {
return false;
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment