Make functions with external calls async

Except for LoadInteriorRefList which seems to be causing a crash if I make it async.
This commit is contained in:
Tyler Hallada 2020-10-15 23:41:39 -04:00
parent 7fb30a892d
commit 5afc919f03
11 changed files with 210 additions and 36 deletions

View File

@ -15,11 +15,34 @@ std::string GenerateApiKey(RE::StaticFunctionTag*)
return api_key;
}
bool StatusCheck(RE::StaticFunctionTag*, RE::BSFixedString api_url)
bool StatusCheckImpl(RE::BSFixedString api_url, RE::TESQuest* quest)
{
logger::info("Entered StatusCheck");
logger::info("Entered StatusCheckImpl");
if (!quest) {
logger::error("StatusCheck quest is null!");
return false;
}
SKSE::RegistrationMap<bool> regMap = SKSE::RegistrationMap<bool>();
regMap.Register(quest, RE::BSFixedString("OnStatusCheck"));
logger::info(FMT_STRING("StatusCheck api_url: {}"), api_url);
bool result = status_check(api_url.c_str());
logger::info(FMT_STRING("StatusCheck result: {}"), result ? "true" : "false");
regMap.SendEvent(result);
regMap.Unregister(quest);
return result;
}
bool StatusCheck(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::TESQuest* quest) {
logger::info("Entered StatusCheck");
if (!quest) {
logger::error("StatusCheck quest is null!");
return false;
}
std::thread thread(StatusCheckImpl, api_url, quest);
thread.detach();
return true;
}

View File

@ -2,4 +2,4 @@
void Init(RE::StaticFunctionTag*);
std::string GenerateApiKey(RE::StaticFunctionTag*);
bool StatusCheck(RE::StaticFunctionTag*, RE::BSFixedString api_url);
bool StatusCheck(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::TESQuest* quest);

View File

@ -2,11 +2,26 @@
#include "NativeFunctions.h"
int CreateInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t shop_id, RE::TESObjectCELL * cell)
int CreateInteriorRefListImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t shop_id, RE::TESQuest* quest)
{
logger::info("Entered CreateInteriorRefList");
if (!cell)
logger::info("Entered CreateInteriorRefListImpl");
if (!quest) {
logger::error("LoadInteriorRefList quest is null!");
return -1;
}
SKSE::RegistrationMap<int> regMap = SKSE::RegistrationMap<int>();
regMap.Register(quest, RE::BSFixedString("OnCreateInteriorRefList"));
RE::TESObjectCELL * cell = RE::TESObjectCELL::LookupByEditorID<RE::TESObjectCELL>("BREmpty");
logger::info(FMT_STRING("ClearCell lookup cell override name: {} id: {:x}"), cell->GetName(), (uint32_t)cell->GetFormID());
if (!cell) {
logger::error("ClearCell cell is null!");
regMap.SendEvent(-1);
regMap.Unregister(quest);
return -1;
}
RE::TESDataHandler * data_handler = RE::TESDataHandler::GetSingleton();
std::vector<RefRecord> ref_records;
@ -84,10 +99,25 @@ int CreateInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE:
int interior_ref_list_id = create_interior_ref_list(api_url.c_str(), api_key.c_str(), shop_id, &ref_records[0], ref_records.size());
logger::info(FMT_STRING("CreateInteriorRefList result: {}"), interior_ref_list_id);
regMap.SendEvent(interior_ref_list_id);
regMap.Unregister(quest);
return interior_ref_list_id;
}
bool ClearCell(RE::StaticFunctionTag*, RE::TESObjectCELL* cell_ignored)
bool CreateInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t shop_id, RE::TESQuest* quest) {
logger::info("Entered CreateInteriorRefList");
if (!quest) {
logger::error("LoadInteriorRefList quest is null!");
return false;
}
std::thread thread(CreateInteriorRefListImpl, api_url, api_key, shop_id, quest);
thread.detach();
return true;
}
bool ClearCell(RE::StaticFunctionTag*)
{
logger::info("Entered ClearCell");
@ -171,9 +201,17 @@ bool ClearCell(RE::StaticFunctionTag*, RE::TESObjectCELL* cell_ignored)
// Should split this up into GetInteriorRefList and LoadInteriorRefList.
// Get: makes the request to the api and stores the Result in a rust cache, returns id of Result
// Load: given id of interior ref list, gets the data from the rust cache, does the PlaceAtMe loop and returns an id of another Result
bool LoadInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t interior_ref_list_id, RE::TESObjectCELL* cell_ignored, RE::TESObjectREFR* target_ref)
bool LoadInteriorRefListImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t interior_ref_list_id, RE::TESObjectREFR* target_ref, RE::TESQuest* quest)
{
logger::info("Entered LoadInteriorRefList");
logger::info("Entered LoadInteriorRefListImpl");
if (!quest) {
logger::error("LoadInteriorRefList quest is null!");
return false;
}
SKSE::RegistrationMap<bool> regMap = SKSE::RegistrationMap<bool>();
regMap.Register(quest, RE::BSFixedString("OnLoadInteriorRefList"));
RE::TESDataHandler * data_handler = RE::TESDataHandler::GetSingleton();
RE::BSScript::Internal::VirtualMachine * a_vm = RE::BSScript::Internal::VirtualMachine::GetSingleton();
@ -196,6 +234,9 @@ bool LoadInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::
logger::info(FMT_STRING("LoadInteriorRefList lookup cell override name: {} id: {:x}"), cell->GetName(), (uint32_t)cell->GetFormID());
if (!cell) {
logger::error("LoadInteriorRefList cell is null!");
regMap.SendEvent(false);
regMap.Unregister(quest);
return false;
}
//RE::TESObjectREFR * x_marker = data_handler->LookupForm<RE::TESObjectREFR>(6628, "BazaarRealm.esp");
@ -248,21 +289,33 @@ bool LoadInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::
}
logger::info(FMT_STRING("LoadInteriorRefList lookup form name: {}, form_id: {:x}"), form->GetName(), (uint32_t)form->GetFormID());
game_ref = PlaceAtMe_Native(a_vm, 0, target_ref, form, 1, false, false);
if (!game_ref) {
logger::error("LoadInteriorRefList failed to place new ref in cell!");
regMap.SendEvent(false);
regMap.Unregister(quest);
return false;
}
}
MoveTo_Native(game_ref, game_ref->CreateRefHandle(), cell, cell->worldSpace, position, angle);
RE::ObjectRefHandle handle = game_ref->CreateRefHandle();
logger::info(FMT_STRING("LoadInteriorRefList ref handle: {:x}, game_ref: {:x}"), (uint32_t)handle.get().get(), (uint32_t)game_ref);
MoveTo_Native(game_ref, handle, cell, cell->worldSpace, position, angle);
game_ref->data.angle = angle; // set angle directly to fix bug with MoveTo in an unloaded target cell
}
}
else {
const char * error = result.AsErr();
logger::error(FMT_STRING("LoadInteriorRefList get_interior_ref_list error: {}"), error);
regMap.SendEvent(false);
regMap.Unregister(quest);
return false;
}
}
else {
logger::error("LoadInteriorRefList target_ref is null!");
regMap.SendEvent(false);
regMap.Unregister(quest);
return false;
}
@ -274,5 +327,26 @@ bool LoadInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::
//RE::TESObjectREFR * new_ref = func(RE::BSScript::Internal::VirtualMachine::GetSingleton(), 1, player, gold, 50, false, false);
//_MESSAGE("New ref initially disabled: %d", new_ref->IsDisabled());
//_MESSAGE("New ref persistent: %d", new_ref->loadedData->flags & RE::TESObjectREFR::RecordFlags::kPersistent);
regMap.SendEvent(true);
regMap.Unregister(quest);
return true;
}
bool LoadInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t interior_ref_list_id, RE::TESObjectREFR* target_ref, RE::TESQuest* quest) {
logger::info("Entered LoadInteriorRefList");
if (!target_ref) {
logger::error("LoadInteriorRefList target_ref is null!");
return false;
}
if (!quest) {
logger::error("LoadInteriorRefList quest is null!");
return false;
}
LoadInteriorRefListImpl(api_url, api_key, interior_ref_list_id, target_ref, quest);
// TODO: making this async causes a crash
// std::thread thread(LoadInteriorRefListImpl, api_url, api_key, interior_ref_list_id, target_ref, quest);
// thread.detach();
return true;
}

View File

@ -1,5 +1,5 @@
#pragma once
int CreateInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t shop_id, RE::TESObjectCELL * cell);
bool ClearCell(RE::StaticFunctionTag*, RE::TESObjectCELL* cell_ignored);
bool LoadInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t interior_ref_list_id, RE::TESObjectCELL* cell_ignored, RE::TESObjectREFR* target_ref);
bool CreateInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t shop_id, RE::TESQuest* quest);
bool ClearCell(RE::StaticFunctionTag*);
bool LoadInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t interior_ref_list_id, RE::TESObjectREFR* target_ref, RE::TESQuest* quest);

View File

@ -5,7 +5,7 @@
// TODO: replace "placeholder" with "buy_activator" and "ref" with "item_ref"
bool ClearMerchandiseImpl(RE::TESObjectREFR* merchant_chest, RE::TESObjectREFR* merchant_shelf, RE::TESForm* placeholder_static, RE::BGSKeyword * shelf_keyword, RE::BGSKeyword * item_keyword)
{
logger::info("Entered ClearMerchandise");
logger::info("Entered ClearMerchandiseImpl");
if (merchant_chest && merchant_shelf) {
RE::TESObjectCELL * cell = merchant_shelf->GetParentCell();
@ -86,7 +86,7 @@ bool LoadMerchandiseImpl(
RE::BGSKeyword* prev_keyword,
int page)
{
logger::info("Entered LoadMerchandise");
logger::info("Entered LoadMerchandiseImpl");
logger::info(FMT_STRING("LoadMerchandise page: {:d}"), page);
RE::TESDataHandler * data_handler = RE::TESDataHandler::GetSingleton();
@ -101,11 +101,7 @@ bool LoadMerchandiseImpl(
logger::error("LoadMerchandise merchant_shelf is null!");
return false;
}
RE::TESObjectREFR * merchant_chest = merchant_shelf->GetLinkedRef(chest_keyword);
if (!merchant_chest) {
logger::error("LoadMerchandise merchant_chest is null!");
return false;
}
RE::TESObjectCELL * cell = merchant_shelf->GetParentCell();
RE::TESObjectREFR * toggle_ref = merchant_shelf->GetLinkedRef(toggle_keyword);
if (!toggle_ref) {
@ -117,6 +113,14 @@ bool LoadMerchandiseImpl(
SKSE::RegistrationMap<bool> regMap = SKSE::RegistrationMap<bool>();
regMap.Register(toggle_ref, RE::BSFixedString("OnLoadMerchandise"));
RE::TESObjectREFR * merchant_chest = merchant_shelf->GetLinkedRef(chest_keyword);
if (!merchant_chest) {
logger::error("LoadMerchandise merchant_chest is null!");
regMap.SendEvent(false);
regMap.Unregister(toggle_ref);
return false;
}
FFIResult<MerchRecordVec> result = get_merchandise_list(api_url.c_str(), api_key.c_str(), merchandise_list_id);
if (result.IsOk()) {
logger::info("LoadMerchandise get_merchandise_list result OK");
@ -127,6 +131,7 @@ bool LoadMerchandiseImpl(
if (vec.len > 0 && page > max_page) {
logger::info(FMT_STRING("LoadMerchandise page {:d} is greater than max_page {:d}, doing nothing"), page, max_page);
regMap.SendEvent(true);
regMap.Unregister(toggle_ref);
return true;
}
@ -230,7 +235,6 @@ bool LoadMerchandiseImpl(
else if (i % 9 == 8) {
ref_position = RE::NiPoint3(shelf_position.x - 40 + x_imbalance, shelf_position.y + y_imbalance, shelf_position.z + 20 + z_imbalance);
}
RE::TESObjectCELL * cell = merchant_shelf->GetParentCell();
MoveTo_Native(ref, ref->CreateRefHandle(), cell, cell->worldSpace, ref_position - RE::NiPoint3(10000, 10000, 10000), ref_angle);
MoveTo_Native(placeholder_ref, placeholder_ref->CreateRefHandle(), cell, cell->worldSpace, ref_position, ref_angle);
// ref->Load3D(false);
@ -337,12 +341,14 @@ bool LoadMerchandiseImpl(
if (!next_ref) {
logger::error("LoadMerchandise next_ref is null!");
regMap.SendEvent(false);
regMap.Unregister(toggle_ref);
return false;
}
RE::TESObjectREFR * prev_ref = merchant_shelf->GetLinkedRef(prev_keyword);
if (!prev_ref) {
logger::error("LoadMerchandise prev_ref is null!");
regMap.SendEvent(false);
regMap.Unregister(toggle_ref);
return false;
}
toggle_ref->SetDisplayName("Clear merchandise", true);
@ -367,10 +373,12 @@ bool LoadMerchandiseImpl(
const char * error = result.AsErr();
logger::error(FMT_STRING("LoadMerchandise get_merchandise_list error: {}"), error);
regMap.SendEvent(false);
regMap.Unregister(toggle_ref);
return false;
}
regMap.SendEvent(true);
regMap.Unregister(toggle_ref);
return true;
}
@ -430,8 +438,8 @@ bool ToggleMerchandise(
else {
// Load merchandise
int page = merchant_shelf->extraList.GetCount();
std::thread t(LoadMerchandiseImpl, api_url, api_key, merchandise_list_id, merchant_shelf, placeholder_static, shelf_keyword, chest_keyword, item_keyword, toggle_keyword, next_keyword, prev_keyword, page);
t.detach();
std::thread thread(LoadMerchandiseImpl, api_url, api_key, merchandise_list_id, merchant_shelf, placeholder_static, shelf_keyword, chest_keyword, item_keyword, toggle_keyword, next_keyword, prev_keyword, page);
thread.detach();
return true;
}
}
@ -462,7 +470,9 @@ bool LoadNextMerchandise(
page = page + 1;
}
return LoadMerchandiseImpl(api_url, api_key, merchandise_list_id, merchant_shelf, placeholder_static, shelf_keyword, chest_keyword, item_keyword, toggle_keyword, next_keyword, prev_keyword, page);
std::thread thread(LoadMerchandiseImpl, api_url, api_key, merchandise_list_id, merchant_shelf, placeholder_static, shelf_keyword, chest_keyword, item_keyword, toggle_keyword, next_keyword, prev_keyword, page);
thread.detach();
return true;
}
bool LoadPrevMerchandise(
@ -495,7 +505,9 @@ bool LoadPrevMerchandise(
page = page - 1;
}
return LoadMerchandiseImpl(api_url, api_key, merchandise_list_id, merchant_shelf, placeholder_static, shelf_keyword, chest_keyword, item_keyword, toggle_keyword, next_keyword, prev_keyword, page);
std::thread thread(LoadMerchandiseImpl, api_url, api_key, merchandise_list_id, merchant_shelf, placeholder_static, shelf_keyword, chest_keyword, item_keyword, toggle_keyword, next_keyword, prev_keyword, page);
thread.detach();
return true;
}
bool ReplaceMerch3D(RE::StaticFunctionTag*, RE::TESObjectREFR* merchant_shelf, RE::TESForm* placeholder_static, RE::BGSKeyword* shelf_keyword, RE::BGSKeyword* item_keyword) {
@ -554,19 +566,25 @@ RE::TESForm * BuyMerchandise(RE::StaticFunctionTag*, RE::TESObjectREFR * merchan
// -2: No changes to save, no create request was made
// -1: Error occured
// >= 0: ID of created MerchandiseList returned by API
int CreateMerchandiseList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t shop_id, RE::TESObjectREFR* merchant_chest)
int CreateMerchandiseListImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t shop_id, RE::TESObjectREFR* merchant_chest)
{
logger::info("Entered CreateMerchandiseList");
logger::info("Entered CreateMerchandiseListImpl");
RE::TESDataHandler * data_handler = RE::TESDataHandler::GetSingleton();
std::vector<MerchRecord> merch_records;
if (!merchant_chest) {
logger::error("CreateMerchandiseList merchant_chest is null!");
return -1;
}
SKSE::RegistrationMap<int> regMap = SKSE::RegistrationMap<int>();
regMap.Register(merchant_chest, RE::BSFixedString("OnCreateMerchandise"));
RE::InventoryChanges * inventory_changes = merchant_chest->GetInventoryChanges();
if (inventory_changes == nullptr) {
logger::info("CreateMerchandiseList container empty, nothing to save");
regMap.SendEvent(-2);
regMap.Unregister(merchant_chest);
return -2;
}
@ -637,5 +655,21 @@ int CreateMerchandiseList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE:
int merchandise_list_id = create_merchandise_list(api_url.c_str(), api_key.c_str(), shop_id, &merch_records[0], merch_records.size());
logger::info(FMT_STRING("CreateMerchandiseList create_merchandise_list result: {:d}"), merchandise_list_id);
regMap.SendEvent(merchandise_list_id);
regMap.Unregister(merchant_chest);
return merchandise_list_id;
}
bool CreateMerchandiseList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t shop_id, RE::TESObjectREFR* merchant_chest) {
logger::info("Entered CreateMerchandiseList");
if (!merchant_chest) {
logger::error("CreateMerchandiseList merchant_chest is null!");
return false;
}
std::thread thread(CreateMerchandiseListImpl, api_url, api_key, shop_id, merchant_chest);
thread.detach();
return true;
}

View File

@ -1,6 +1,5 @@
#pragma once
bool ClearMerchandiseImpl(RE::TESObjectREFR* merchant_chest, RE::TESObjectREFR* merchant_shelf, RE::TESForm* placeholder_static, RE::BGSKeyword * shelf_keyword, RE::BGSKeyword * item_keyword);
bool ToggleMerchandise(
RE::StaticFunctionTag*,
RE::BSFixedString api_url,
@ -42,4 +41,4 @@ bool LoadPrevMerchandise(
RE::BGSKeyword* prev_keyword);
bool ReplaceMerch3D(RE::StaticFunctionTag*, RE::TESObjectREFR* merchant_shelf, RE::TESForm* placeholder_static, RE::BGSKeyword* shelf_keyword, RE::BGSKeyword* item_keyword);
RE::TESForm * BuyMerchandise(RE::StaticFunctionTag*, RE::TESObjectREFR * merchandise_placeholder);
int CreateMerchandiseList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t shop_id, RE::TESObjectREFR* merchant_chest);
bool CreateMerchandiseList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, uint32_t shop_id, RE::TESObjectREFR* merchant_chest);

View File

@ -1,13 +1,35 @@
#include "bindings.h"
int CreateOwner(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BSFixedString name, uint32_t mod_version)
int CreateOwnerImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BSFixedString name, uint32_t mod_version, RE::TESQuest* quest)
{
logger::info("Entered CreateOwner");
logger::info("Entered CreateOwnerImpl");
if (!quest) {
logger::error("CreateOwner quest is null!");
return -1;
}
SKSE::RegistrationMap<int> regMap = SKSE::RegistrationMap<int>();
regMap.Register(quest, RE::BSFixedString("OnCreateOwner"));
logger::info(FMT_STRING("CreateOwner api_url: {}"), api_url);
logger::info(FMT_STRING("CreateOwner api_key: {}"), api_key);
logger::info(FMT_STRING("CreateOwner name: {}"), name);
logger::info(FMT_STRING("CreateOwner mod_version: {}"), mod_version);
int owner_id = create_owner(api_url.c_str(), api_key.c_str(), name.c_str(), mod_version);
logger::info(FMT_STRING("CreateOwner result: {}"), owner_id);
regMap.SendEvent(owner_id);
regMap.Unregister(quest);
return owner_id;
}
bool CreateOwner(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BSFixedString name, uint32_t mod_version, RE::TESQuest* quest) {
logger::info("Entered CreateOwner");
if (!quest) {
logger::error("CreateOwner quest is null!");
return false;
}
std::thread thread(CreateOwnerImpl, api_url, api_key, name, mod_version, quest);
thread.detach();
return true;
}

View File

@ -1,3 +1,3 @@
#pragma once
int CreateOwner(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BSFixedString name, uint32_t mod_version);
bool CreateOwner(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BSFixedString name, uint32_t mod_version, RE::TESQuest* quest);

View File

@ -1,13 +1,35 @@
#include "bindings.h"
int CreateShop(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BSFixedString name, RE::BSFixedString description)
int CreateShopImpl(RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BSFixedString name, RE::BSFixedString description, RE::TESQuest* quest)
{
logger::info("Entered CreateShop");
logger::info("Entered CreateShopImpl");
if (!quest) {
logger::error("CreateShop quest is null!");
return -1;
}
SKSE::RegistrationMap<int> regMap = SKSE::RegistrationMap<int>();
regMap.Register(quest, RE::BSFixedString("OnCreateShop"));
logger::info(FMT_STRING("CreateShop api_url: {}"), api_url);
logger::info(FMT_STRING("CreateShop api_key: {}"), api_key);
logger::info(FMT_STRING("CreateShop name: {}"), name);
logger::info(FMT_STRING("CreateShop description: {}"), description);
int shop_id = create_shop(api_url.c_str(), api_key.c_str(), name.c_str(), description.c_str());
logger::info(FMT_STRING("CreateShop result: {}"), shop_id);
regMap.SendEvent(shop_id);
regMap.Unregister(quest);
return shop_id;
}
bool CreateShop(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BSFixedString name, RE::BSFixedString description, RE::TESQuest* quest) {
logger::info("Entered CreateShop");
if (!quest) {
logger::error("CreateShop quest is null!");
return false;
}
std::thread thread(CreateShopImpl, api_url, api_key, name, description, quest);
thread.detach();
return true;
}

View File

@ -1,3 +1,3 @@
#pragma once
int CreateShop(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BSFixedString name, RE::BSFixedString description);
bool CreateShop(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, RE::BSFixedString name, RE::BSFixedString description, RE::TESQuest* quest);

View File

@ -1,4 +1,4 @@
#pragma once
RE::TESObjectREFR* PlaceAtMe(RE::BSScript::IVirtualMachine* a_vm, int something, RE::TESObjectREFR* ref, RE::TESForm* form, int count, bool forcePersist, bool initiallyDisabled);
void MoveTo(RE::TESObjectREFR * ref, const RE::ObjectRefHandle& a_targetHandle, RE::TESObjectCELL* a_targetCell, RE::TESWorldSpace* a_selfWorldSpace, const RE::NiPoint3& a_position, const RE::NiPoint3& a_rotation);
void MoveTo(RE::TESObjectREFR* ref, const RE::ObjectRefHandle& a_targetHandle, RE::TESObjectCELL* a_targetCell, RE::TESWorldSpace* a_selfWorldSpace, const RE::NiPoint3& a_position, const RE::NiPoint3& a_rotation);