Semi-working refactor of merch for multiple shelves
Code is now capable of loading merch onto multiple store shelves during load shop. Still need to fix refresh, loading merch after creating merch and making transactions, the shelf buttons, as well as saving the state of the shelves to the server.
This commit is contained in:
parent
e673ac4642
commit
d1849735b2
@ -76,6 +76,7 @@ void CreateInteriorRefListImpl(RE::BSFixedString api_url, RE::BSFixedString api_
|
||||
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>();
|
||||
failReg.Register(quest, RE::BSFixedString("OnCreateInteriorRefListFail"));
|
||||
|
||||
// TODO: may need to dynamically pass shop cell into this function
|
||||
RE::TESObjectCELL * cell = RE::TESObjectCELL::LookupByEditorID<RE::TESObjectCELL>("BREmpty");
|
||||
logger::info(FMT_STRING("CreateInteriorRefListImpl lookup cell override name: {} id: {:x}"), cell->GetName(), (uint32_t)cell->GetFormID());
|
||||
if (!cell) {
|
||||
@ -92,8 +93,13 @@ void CreateInteriorRefListImpl(RE::BSFixedString api_url, RE::BSFixedString api_
|
||||
for (auto entry = cell->references.begin(); entry != cell->references.end(); ++entry) {
|
||||
RE::TESObjectREFR * ref = (*entry).get();
|
||||
const char * name = ref->GetName();
|
||||
logger::info(FMT_STRING("CreateInteriorRefList ref: {}"), name);
|
||||
const RE::TESBoundObject * base = ref->GetBaseObject();
|
||||
RE::FormID ref_form_id = ref->GetFormID();
|
||||
logger::info(FMT_STRING("CreateInteriorRefList ref: {}, form_id: {:x}"), name, (uint32_t)ref_form_id);
|
||||
if (ref->IsDisabled()) {
|
||||
logger::info("CreateInteriorRefList skipping ref since it is disabled");
|
||||
continue;
|
||||
}
|
||||
RE::TESBoundObject * base = ref->GetBaseObject();
|
||||
if (base) {
|
||||
RE::FormID base_form_id = base->GetFormID();
|
||||
const RE::FormType form_type = base->GetFormType();
|
||||
@ -113,11 +119,9 @@ void CreateInteriorRefListImpl(RE::BSFixedString api_url, RE::BSFixedString api_
|
||||
logger::info(FMT_STRING("CreateInteriorRefList position: {:.2f}, {:.2f}, {:.2f} angle: {:.2f}, {:.2f}, {:.2f} scale: {:d}"), position_x, position_y, position_z, angle_x, angle_y, angle_z, scale);
|
||||
logger::info(FMT_STRING("CreateInteriorRefList deleted: {:d}, wants delete: {:d}"), ref->IsMarkedForDeletion(), ref->inGameFormFlags.all(RE::TESObjectREFR::InGameFormFlag::kWantsDelete));
|
||||
|
||||
RE::TESFile * base_file = base->GetFile(0);
|
||||
char * base_file_name = base_file->fileName;
|
||||
bool is_light = base_file->recordFlags.all(RE::TESFile::RecordFlag::kSmallFile);
|
||||
uint32_t base_local_form_id = is_light ? base_form_id & 0xfff : base_form_id & 0xFFFFFF;
|
||||
RE::FormID ref_form_id = ref->GetFormID();
|
||||
std::pair<uint32_t, const char*> id_parts = get_local_form_id_and_mod_name(base);
|
||||
uint32_t base_local_form_id = id_parts.first;
|
||||
const char * base_file_name = id_parts.second;
|
||||
uint16_t ref_mod_index = ref_form_id >> 24;
|
||||
char * ref_file_name = nullptr;
|
||||
uint32_t ref_local_form_id = ref_form_id & 0xFFFFFF;
|
||||
@ -133,7 +137,7 @@ void CreateInteriorRefListImpl(RE::BSFixedString api_url, RE::BSFixedString api_
|
||||
}
|
||||
}
|
||||
logger::info(FMT_STRING("CreateInteriorRefList ref_file_name: {}, base_file_name: {}"), ref_file_name, base_file_name);
|
||||
if (strcmp("Bazaar Realm.esp", base_file_name) == 0) {
|
||||
if (strcmp(base_file_name, MOD_NAME) == 0) {
|
||||
logger::info(FMT_STRING("CreateInteriorRefList ref base is in Bazaar Ream.esp: {:x}"), base_local_form_id);
|
||||
if (ignored_shelf_related_form_ids.find(base_local_form_id) != ignored_shelf_related_form_ids.end()) {
|
||||
logger::info("CreateInteriorRefList ref is an ignored shelf related form");
|
||||
@ -218,8 +222,8 @@ bool CreateInteriorRefList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE
|
||||
bool ClearCell(RE::StaticFunctionTag*) {
|
||||
logger::info("Entered ClearCell");
|
||||
|
||||
RE::TESDataHandler * data_handler = RE::TESDataHandler::GetSingleton();
|
||||
using func_t = bool(RE::TESObjectREFR* a_thisObj, void* a_param1, void* a_param2, double& a_result);
|
||||
// TODO: the cell will need to be dynamically passed in
|
||||
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) {
|
||||
@ -235,18 +239,7 @@ bool ClearCell(RE::StaticFunctionTag*) {
|
||||
|
||||
int mod_index = form_id >> 24;
|
||||
if (mod_index != 255) {
|
||||
RE::TESFile * file = ref->GetDescriptionOwnerFile();
|
||||
if (file) {
|
||||
bool is_light = file->recordFlags.all(RE::TESFile::RecordFlag::kSmallFile);
|
||||
uint32_t local_form_id = is_light ? ref->GetFormID() & 0xfff : form_id & 0xFFFFFF;
|
||||
if (!data_handler->LookupForm<RE::TESObjectREFR>(local_form_id, file->fileName)) {
|
||||
logger::info(FMT_STRING("ClearCell ref was not in mod file! {:x} {}"), local_form_id, ref->GetName());
|
||||
} else {
|
||||
logger::info(FMT_STRING("ClearCell ref in mod file {:x} {}"), local_form_id, ref->GetName());
|
||||
}
|
||||
} else {
|
||||
logger::info(FMT_STRING("ClearCell ref not in ANY file! {:x} {}"), (uint32_t)form_id, ref->GetName());
|
||||
}
|
||||
// TODO: recognize somehow that this ref was a pre-placed initially disabled furnature upgrade piece and disable it now if so
|
||||
++entry;
|
||||
} else {
|
||||
logger::info(FMT_STRING("ClearCell ref is a temp ref, deleting {:x} {}"), (uint32_t)form_id, ref->GetName());
|
||||
@ -267,6 +260,14 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
|
||||
return;
|
||||
}
|
||||
|
||||
// Testing to see what ExtraLinkedRefChildren stores
|
||||
RE::ExtraLinkedRefChildren* linkedChildren = (RE::ExtraLinkedRefChildren*)public_chest->extraList.GetByType(RE::ExtraDataType::kLinkedRefChildren);
|
||||
if (linkedChildren) {
|
||||
logger::info(FMT_STRING("CreateMerchandiseList public_chest has linkedChildren: size: {}"), linkedChildren->linkedChildren.size());
|
||||
} else {
|
||||
logger::info("CreateMerchandiseList public_chest has no linkedChildren");
|
||||
}
|
||||
|
||||
// Placing the refs must be done on the main thread otherwise calling MoveTo causes a crash
|
||||
auto task = SKSE::GetTaskInterface();
|
||||
task->AddTask([result, target_ref, private_chest, public_chest, quest]() {
|
||||
@ -277,6 +278,7 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
|
||||
using func_t2 = decltype(&MoveTo);
|
||||
REL::Relocation<func_t2> MoveTo_Native(RE::Offset::TESObjectREFR::MoveTo);
|
||||
REL::ID extra_linked_ref_vtbl(static_cast<std::uint64_t>(229564));
|
||||
std::vector<RE::TESObjectREFR*> shelves;
|
||||
|
||||
RE::BGSKeyword* shelf_keyword = data_handler->LookupForm<RE::BGSKeyword>(KEYWORD_SHELF, MOD_NAME);
|
||||
RE::BGSKeyword* chest_keyword = data_handler->LookupForm<RE::BGSKeyword>(KEYWORD_CHEST, MOD_NAME);
|
||||
@ -285,7 +287,7 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
|
||||
RE::BGSKeyword* next_keyword = data_handler->LookupForm<RE::BGSKeyword>(KEYWORD_NEXT, MOD_NAME);
|
||||
RE::BGSKeyword* prev_keyword = data_handler->LookupForm<RE::BGSKeyword>(KEYWORD_PREV, MOD_NAME);
|
||||
|
||||
SKSE::RegistrationMap<bool> successReg = SKSE::RegistrationMap<bool>();
|
||||
SKSE::RegistrationMap<bool, std::vector<RE::TESObjectREFR*>> successReg = SKSE::RegistrationMap<bool, std::vector<RE::TESObjectREFR*>>();
|
||||
successReg.Register(quest, RE::BSFixedString("OnLoadInteriorRefListSuccess"));
|
||||
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>();
|
||||
failReg.Register(quest, RE::BSFixedString("OnLoadInteriorRefListFail"));
|
||||
@ -344,6 +346,10 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
|
||||
game_ref = data_handler->LookupForm<RE::TESObjectREFR>(ref.ref_local_form_id, ref.ref_mod_name);
|
||||
if (game_ref) {
|
||||
logger::info(FMT_STRING("LoadInteriorRefList lookup ref name: {}, form_id: {:x}"), game_ref->GetName(), (uint32_t)game_ref->GetFormID());
|
||||
if (game_ref->IsDisabled()) {
|
||||
logger::info("LoadInteriorRefList lookup ref is disabled, enabling");
|
||||
game_ref->formFlags &= ~RE::TESObjectREFR::RecordFlags::kInitiallyDisabled;
|
||||
}
|
||||
} else {
|
||||
logger::info(FMT_STRING("LoadInteriorRefList lookup ref not found, ref_mod_name: {}, ref_local_form_id: {:x}"), ref.ref_mod_name, ref.ref_local_form_id);
|
||||
}
|
||||
@ -392,7 +398,8 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
|
||||
RE::TESObjectREFR* shelf_ref = PlaceAtMe_Native(a_vm, 0, target_ref, form, 1, false, false);
|
||||
MoveTo_Native(shelf_ref, shelf_ref->CreateRefHandle(), cell, cell->worldSpace, position, angle);
|
||||
shelf_ref->data.angle = angle; // set angle directly to fix bug with MoveTo in an unloaded target cell
|
||||
RE::ExtraLinkedRef* shelf_extra_linked_ref = (RE::ExtraLinkedRef*)RE::BSExtraData::Create(sizeof(RE::ExtraLinkedRef), extra_linked_ref_vtbl.address());
|
||||
shelves.push_back(shelf_ref);
|
||||
RE::ExtraLinkedRef* shelf_extra_linked_ref = RE::BSExtraData::Create<RE::ExtraLinkedRef>(extra_linked_ref_vtbl.address());
|
||||
shelf_extra_linked_ref->linkedRefs.push_back({public_chest_keyword, public_chest});
|
||||
shelf_extra_linked_ref->linkedRefs.push_back({chest_keyword, private_chest});
|
||||
shelf_ref->extraList.Add(shelf_extra_linked_ref);
|
||||
@ -429,7 +436,7 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
|
||||
button_ref->data.angle = button_angle; // set angle directly to fix bug with MoveTo in an unloaded target cell
|
||||
button_ref->refScale = button.position.scale;
|
||||
|
||||
RE::ExtraLinkedRef* button_extra_linked_ref = (RE::ExtraLinkedRef*)RE::BSExtraData::Create(sizeof(RE::ExtraLinkedRef), extra_linked_ref_vtbl.address());
|
||||
RE::ExtraLinkedRef* button_extra_linked_ref = RE::BSExtraData::Create<RE::ExtraLinkedRef>(extra_linked_ref_vtbl.address());
|
||||
button_extra_linked_ref->linkedRefs.push_back({shelf_keyword, shelf_ref});
|
||||
button_ref->extraList.Add(button_extra_linked_ref);
|
||||
|
||||
@ -459,7 +466,7 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
|
||||
return;
|
||||
}
|
||||
|
||||
successReg.SendEvent(true);
|
||||
successReg.SendEvent(true, shelves);
|
||||
successReg.Unregister(quest);
|
||||
failReg.Unregister(quest);
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,81 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
bool ToggleMerchandise(
|
||||
RE::StaticFunctionTag*,
|
||||
RE::BSFixedString api_url,
|
||||
RE::BSFixedString api_key,
|
||||
int32_t shop_id,
|
||||
RE::TESObjectREFR* merchant_shelf,
|
||||
RE::TESForm* activator_static,
|
||||
RE::BGSKeyword* shelf_keyword,
|
||||
RE::BGSKeyword* chest_keyword,
|
||||
RE::BGSKeyword* item_keyword,
|
||||
RE::BGSKeyword* activator_keyword,
|
||||
RE::BGSKeyword* toggle_keyword,
|
||||
RE::BGSKeyword* next_keyword,
|
||||
RE::BGSKeyword* prev_keyword
|
||||
);
|
||||
bool LoadNextMerchandise(
|
||||
RE::StaticFunctionTag*,
|
||||
RE::BSFixedString api_url,
|
||||
RE::BSFixedString api_key,
|
||||
int32_t shop_id,
|
||||
RE::TESObjectREFR* merchant_shelf,
|
||||
RE::TESForm* activator_static,
|
||||
RE::BGSKeyword* shelf_keyword,
|
||||
RE::BGSKeyword* chest_keyword,
|
||||
RE::BGSKeyword* item_keyword,
|
||||
RE::BGSKeyword* activator_keyword,
|
||||
RE::BGSKeyword* toggle_keyword,
|
||||
RE::BGSKeyword* next_keyword,
|
||||
RE::BGSKeyword* prev_keyword
|
||||
);
|
||||
bool LoadPrevMerchandise(
|
||||
RE::StaticFunctionTag*,
|
||||
RE::BSFixedString api_url,
|
||||
RE::BSFixedString api_key,
|
||||
int32_t shop_id,
|
||||
RE::TESObjectREFR* merchant_shelf,
|
||||
RE::TESForm* activator_static,
|
||||
RE::BGSKeyword* shelf_keyword,
|
||||
RE::BGSKeyword* chest_keyword,
|
||||
RE::BGSKeyword* item_keyword,
|
||||
RE::BGSKeyword* activator_keyword,
|
||||
RE::BGSKeyword* toggle_keyword,
|
||||
RE::BGSKeyword* next_keyword,
|
||||
RE::BGSKeyword* prev_keyword
|
||||
);
|
||||
//bool ToggleMerchandise(
|
||||
// RE::StaticFunctionTag*,
|
||||
// RE::BSFixedString api_url,
|
||||
// RE::BSFixedString api_key,
|
||||
// int32_t shop_id,
|
||||
// RE::TESObjectREFR* merchant_shelf
|
||||
//);
|
||||
//bool LoadNextMerchandise(
|
||||
// RE::StaticFunctionTag*,
|
||||
// RE::BSFixedString api_url,
|
||||
// RE::BSFixedString api_key,
|
||||
// int32_t shop_id,
|
||||
// RE::TESObjectREFR* merchant_shelf
|
||||
//);
|
||||
//bool LoadPrevMerchandise(
|
||||
// RE::StaticFunctionTag*,
|
||||
// RE::BSFixedString api_url,
|
||||
// RE::BSFixedString api_key,
|
||||
// int32_t shop_id,
|
||||
// RE::TESObjectREFR* merchant_shelf
|
||||
//);
|
||||
bool LoadMerchandiseByShopId(
|
||||
RE::StaticFunctionTag*,
|
||||
RE::BSFixedString api_url,
|
||||
RE::BSFixedString api_key,
|
||||
int32_t shop_id,
|
||||
RE::TESObjectREFR* merchant_shelf,
|
||||
RE::TESForm* activator_static,
|
||||
RE::BGSKeyword* shelf_keyword,
|
||||
RE::BGSKeyword* chest_keyword,
|
||||
RE::BGSKeyword* item_keyword,
|
||||
RE::BGSKeyword* activator_keyword,
|
||||
RE::BGSKeyword* toggle_keyword,
|
||||
RE::BGSKeyword* next_keyword,
|
||||
RE::BGSKeyword* prev_keyword
|
||||
RE::TESObjectCELL* cell,
|
||||
std::vector<RE::TESObjectREFR*> merchant_shelves,
|
||||
RE::TESObjectREFR* merchant_chest
|
||||
);
|
||||
bool RefreshMerchandise(
|
||||
RE::StaticFunctionTag*,
|
||||
RE::BSFixedString api_url,
|
||||
RE::BSFixedString api_key,
|
||||
int32_t shop_id,
|
||||
RE::TESObjectREFR* merchant_shelf,
|
||||
RE::TESForm* activator_static,
|
||||
RE::BGSKeyword* shelf_keyword,
|
||||
RE::BGSKeyword* chest_keyword,
|
||||
RE::BGSKeyword* item_keyword,
|
||||
RE::BGSKeyword* activator_keyword,
|
||||
RE::BGSKeyword* toggle_keyword,
|
||||
RE::BGSKeyword* next_keyword,
|
||||
RE::BGSKeyword* prev_keyword
|
||||
);
|
||||
bool ReplaceMerch3D(RE::StaticFunctionTag*, RE::TESObjectREFR* merchant_shelf, RE::TESForm* activator_static, RE::BGSKeyword* shelf_keyword, RE::BGSKeyword* item_keyword);
|
||||
//bool RefreshMerchandise(
|
||||
// RE::StaticFunctionTag*,
|
||||
// RE::BSFixedString api_url,
|
||||
// RE::BSFixedString api_key,
|
||||
// int32_t shop_id,
|
||||
// RE::TESObjectREFR* merchant_shelf
|
||||
//);
|
||||
bool ReplaceMerch3D(RE::StaticFunctionTag*, RE::TESObjectREFR* merchant_shelf);
|
||||
bool ReplaceAllMerch3D(RE::StaticFunctionTag*, RE::TESObjectCELL* cell);
|
||||
bool CreateMerchandiseList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, int32_t shop_id, RE::TESObjectREFR* merchant_chest);
|
||||
int GetMerchandiseQuantity(RE::StaticFunctionTag*, RE::TESObjectREFR* activator);
|
||||
int GetMerchandisePrice(RE::StaticFunctionTag*, RE::TESObjectREFR* activator);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "bindings.h"
|
||||
#include "utils.h"
|
||||
|
||||
void CreateTransactionImpl(
|
||||
RE::BSFixedString api_url,
|
||||
@ -33,10 +34,9 @@ void CreateTransactionImpl(
|
||||
RE::FormID form_id = merch_base->GetFormID();
|
||||
logger::info(FMT_STRING("CreateTransactionImpl merch_base form_id: {:x}, name: {}, type: {:x}"), (uint32_t)form_id, name, (uint32_t)form_type);
|
||||
|
||||
RE::TESFile * file = merch_base->GetFile(0);
|
||||
const char * mod_name = file->fileName;
|
||||
bool is_light = file->recordFlags.all(RE::TESFile::RecordFlag::kSmallFile);
|
||||
uint32_t local_form_id = is_light ? form_id & 0xfff : form_id & 0xFFFFFF;
|
||||
std::pair<uint32_t, const char*> id_parts = get_local_form_id_and_mod_name(merch_base);
|
||||
uint32_t local_form_id = id_parts.first;
|
||||
const char* mod_name = id_parts.second;
|
||||
logger::info(FMT_STRING("CreateTransactionImpl merch_base form file_name: {}, local_form_id: {:x}"), mod_name, local_form_id);
|
||||
|
||||
// TODO: implement is_food
|
||||
|
@ -1,10 +1,12 @@
|
||||
#pragma once
|
||||
const char* MOD_NAME = "Bazaar Realm.esp";
|
||||
const uint32_t KEYWORD_SHELF = 0x002fb1;
|
||||
const uint32_t KEYWORD_CHEST = 0x002fb2;
|
||||
const uint32_t KEYWORD_PUBLIC_CHEST = 0x00603e;
|
||||
const uint32_t KEYWORD_TOGGLE = 0x00351b;
|
||||
const uint32_t KEYWORD_NEXT = 0x00351c;
|
||||
const uint32_t KEYWORD_PREV = 0x00351d;
|
||||
const uint32_t KEYWORD_ITEM = 0x003517;
|
||||
const uint32_t KEYWORD_ACTIVATOR = 0x004AA8;
|
||||
constexpr const char* MOD_NAME = "Bazaar Realm.esp";
|
||||
constexpr uint32_t KEYWORD_SHELF = 0x002fb1;
|
||||
constexpr uint32_t KEYWORD_CHEST = 0x002fb2;
|
||||
constexpr uint32_t KEYWORD_PUBLIC_CHEST = 0x00603e;
|
||||
constexpr uint32_t KEYWORD_TOGGLE = 0x00351b;
|
||||
constexpr uint32_t KEYWORD_NEXT = 0x00351c;
|
||||
constexpr uint32_t KEYWORD_PREV = 0x00351d;
|
||||
constexpr uint32_t KEYWORD_ITEM = 0x003517;
|
||||
constexpr uint32_t KEYWORD_ACTIVATOR = 0x004AA8;
|
||||
|
||||
constexpr uint32_t ACTIVATOR_STATIC = 0x002a3b;
|
||||
|
@ -23,12 +23,13 @@ bool RegisterFuncs(RE::BSScript::IVirtualMachine* a_vm)
|
||||
a_vm->RegisterFunction("ClearCell", "BRInteriorRefList", ClearCell);
|
||||
a_vm->RegisterFunction("Load", "BRInteriorRefList", LoadInteriorRefList);
|
||||
a_vm->RegisterFunction("LoadByShopId", "BRInteriorRefList", LoadInteriorRefListByShopId);
|
||||
a_vm->RegisterFunction("Toggle", "BRMerchandiseList", ToggleMerchandise);
|
||||
a_vm->RegisterFunction("NextPage", "BRMerchandiseList", LoadNextMerchandise);
|
||||
a_vm->RegisterFunction("PrevPage", "BRMerchandiseList", LoadPrevMerchandise);
|
||||
//a_vm->RegisterFunction("Toggle", "BRMerchandiseList", ToggleMerchandise);
|
||||
//a_vm->RegisterFunction("NextPage", "BRMerchandiseList", LoadNextMerchandise);
|
||||
//a_vm->RegisterFunction("PrevPage", "BRMerchandiseList", LoadPrevMerchandise);
|
||||
a_vm->RegisterFunction("Load", "BRMerchandiseList", LoadMerchandiseByShopId);
|
||||
a_vm->RegisterFunction("Refresh", "BRMerchandiseList", RefreshMerchandise);
|
||||
//a_vm->RegisterFunction("Refresh", "BRMerchandiseList", RefreshMerchandise);
|
||||
a_vm->RegisterFunction("Replace3D", "BRMerchandiseList", ReplaceMerch3D);
|
||||
a_vm->RegisterFunction("ReplaceAll3D", "BRMerchandiseList", ReplaceAllMerch3D);
|
||||
a_vm->RegisterFunction("Create", "BRMerchandiseList", CreateMerchandiseList);
|
||||
a_vm->RegisterFunction("GetQuantity", "BRMerchandiseList", GetMerchandiseQuantity);
|
||||
a_vm->RegisterFunction("GetPrice", "BRMerchandiseList", GetMerchandisePrice);
|
||||
|
@ -19,3 +19,11 @@ RE::NiPoint3 rotate_point(RE::NiPoint3 point, RE::NiMatrix3 rotation_matrix) {
|
||||
(point.x * rotation_matrix.entry[0][2]) + (point.y * rotation_matrix.entry[1][2]) + (point.z * rotation_matrix.entry[2][2])
|
||||
);
|
||||
}
|
||||
|
||||
std::pair<uint32_t, const char*> get_local_form_id_and_mod_name(RE::TESForm* form) {
|
||||
RE::FormID form_id = form->GetFormID();
|
||||
RE::TESFile* file = form->GetFile(0);
|
||||
const char* mod_name = file->fileName;
|
||||
bool is_light = file->recordFlags.all(RE::TESFile::RecordFlag::kSmallFile);
|
||||
return std::pair(is_light ? form_id & 0xfff : form_id & 0xFFFFFF, mod_name);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
RE::NiMatrix3 get_rotation_matrix(RE::NiPoint3 rotation);
|
||||
RE::NiPoint3 rotate_point(RE::NiPoint3 point, RE::NiMatrix3 rotation_matrix);
|
||||
std::pair<uint32_t, const char*> get_local_form_id_and_mod_name(RE::TESForm* form);
|
||||
|
Loading…
Reference in New Issue
Block a user