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>();
|
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>();
|
||||||
failReg.Register(quest, RE::BSFixedString("OnCreateInteriorRefListFail"));
|
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");
|
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());
|
logger::info(FMT_STRING("CreateInteriorRefListImpl lookup cell override name: {} id: {:x}"), cell->GetName(), (uint32_t)cell->GetFormID());
|
||||||
if (!cell) {
|
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) {
|
for (auto entry = cell->references.begin(); entry != cell->references.end(); ++entry) {
|
||||||
RE::TESObjectREFR * ref = (*entry).get();
|
RE::TESObjectREFR * ref = (*entry).get();
|
||||||
const char * name = ref->GetName();
|
const char * name = ref->GetName();
|
||||||
logger::info(FMT_STRING("CreateInteriorRefList ref: {}"), name);
|
RE::FormID ref_form_id = ref->GetFormID();
|
||||||
const RE::TESBoundObject * base = ref->GetBaseObject();
|
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) {
|
if (base) {
|
||||||
RE::FormID base_form_id = base->GetFormID();
|
RE::FormID base_form_id = base->GetFormID();
|
||||||
const RE::FormType form_type = base->GetFormType();
|
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 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));
|
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);
|
std::pair<uint32_t, const char*> id_parts = get_local_form_id_and_mod_name(base);
|
||||||
char * base_file_name = base_file->fileName;
|
uint32_t base_local_form_id = id_parts.first;
|
||||||
bool is_light = base_file->recordFlags.all(RE::TESFile::RecordFlag::kSmallFile);
|
const char * base_file_name = id_parts.second;
|
||||||
uint32_t base_local_form_id = is_light ? base_form_id & 0xfff : base_form_id & 0xFFFFFF;
|
|
||||||
RE::FormID ref_form_id = ref->GetFormID();
|
|
||||||
uint16_t ref_mod_index = ref_form_id >> 24;
|
uint16_t ref_mod_index = ref_form_id >> 24;
|
||||||
char * ref_file_name = nullptr;
|
char * ref_file_name = nullptr;
|
||||||
uint32_t ref_local_form_id = ref_form_id & 0xFFFFFF;
|
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);
|
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);
|
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()) {
|
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");
|
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*) {
|
bool ClearCell(RE::StaticFunctionTag*) {
|
||||||
logger::info("Entered ClearCell");
|
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);
|
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");
|
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());
|
logger::info(FMT_STRING("ClearCell lookup cell override name: {} id: {:x}"), cell->GetName(), (uint32_t)cell->GetFormID());
|
||||||
if (!cell) {
|
if (!cell) {
|
||||||
@ -235,18 +239,7 @@ bool ClearCell(RE::StaticFunctionTag*) {
|
|||||||
|
|
||||||
int mod_index = form_id >> 24;
|
int mod_index = form_id >> 24;
|
||||||
if (mod_index != 255) {
|
if (mod_index != 255) {
|
||||||
RE::TESFile * file = ref->GetDescriptionOwnerFile();
|
// TODO: recognize somehow that this ref was a pre-placed initially disabled furnature upgrade piece and disable it now if so
|
||||||
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());
|
|
||||||
}
|
|
||||||
++entry;
|
++entry;
|
||||||
} else {
|
} else {
|
||||||
logger::info(FMT_STRING("ClearCell ref is a temp ref, deleting {:x} {}"), (uint32_t)form_id, ref->GetName());
|
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;
|
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
|
// Placing the refs must be done on the main thread otherwise calling MoveTo causes a crash
|
||||||
auto task = SKSE::GetTaskInterface();
|
auto task = SKSE::GetTaskInterface();
|
||||||
task->AddTask([result, target_ref, private_chest, public_chest, quest]() {
|
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);
|
using func_t2 = decltype(&MoveTo);
|
||||||
REL::Relocation<func_t2> MoveTo_Native(RE::Offset::TESObjectREFR::MoveTo);
|
REL::Relocation<func_t2> MoveTo_Native(RE::Offset::TESObjectREFR::MoveTo);
|
||||||
REL::ID extra_linked_ref_vtbl(static_cast<std::uint64_t>(229564));
|
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* shelf_keyword = data_handler->LookupForm<RE::BGSKeyword>(KEYWORD_SHELF, MOD_NAME);
|
||||||
RE::BGSKeyword* chest_keyword = data_handler->LookupForm<RE::BGSKeyword>(KEYWORD_CHEST, 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* next_keyword = data_handler->LookupForm<RE::BGSKeyword>(KEYWORD_NEXT, MOD_NAME);
|
||||||
RE::BGSKeyword* prev_keyword = data_handler->LookupForm<RE::BGSKeyword>(KEYWORD_PREV, 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"));
|
successReg.Register(quest, RE::BSFixedString("OnLoadInteriorRefListSuccess"));
|
||||||
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>();
|
SKSE::RegistrationMap<RE::BSFixedString> failReg = SKSE::RegistrationMap<RE::BSFixedString>();
|
||||||
failReg.Register(quest, RE::BSFixedString("OnLoadInteriorRefListFail"));
|
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);
|
game_ref = data_handler->LookupForm<RE::TESObjectREFR>(ref.ref_local_form_id, ref.ref_mod_name);
|
||||||
if (game_ref) {
|
if (game_ref) {
|
||||||
logger::info(FMT_STRING("LoadInteriorRefList lookup ref name: {}, form_id: {:x}"), game_ref->GetName(), (uint32_t)game_ref->GetFormID());
|
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 {
|
} 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);
|
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);
|
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);
|
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
|
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({public_chest_keyword, public_chest});
|
||||||
shelf_extra_linked_ref->linkedRefs.push_back({chest_keyword, private_chest});
|
shelf_extra_linked_ref->linkedRefs.push_back({chest_keyword, private_chest});
|
||||||
shelf_ref->extraList.Add(shelf_extra_linked_ref);
|
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->data.angle = button_angle; // set angle directly to fix bug with MoveTo in an unloaded target cell
|
||||||
button_ref->refScale = button.position.scale;
|
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_extra_linked_ref->linkedRefs.push_back({shelf_keyword, shelf_ref});
|
||||||
button_ref->extraList.Add(button_extra_linked_ref);
|
button_ref->extraList.Add(button_extra_linked_ref);
|
||||||
|
|
||||||
@ -459,7 +466,7 @@ void LoadRefsTask(FFIResult<RawInteriorRefData> result, RE::TESObjectREFR* targe
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
successReg.SendEvent(true);
|
successReg.SendEvent(true, shelves);
|
||||||
successReg.Unregister(quest);
|
successReg.Unregister(quest);
|
||||||
failReg.Unregister(quest);
|
failReg.Unregister(quest);
|
||||||
});
|
});
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,81 +1,44 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
bool ToggleMerchandise(
|
//bool ToggleMerchandise(
|
||||||
RE::StaticFunctionTag*,
|
// RE::StaticFunctionTag*,
|
||||||
RE::BSFixedString api_url,
|
// RE::BSFixedString api_url,
|
||||||
RE::BSFixedString api_key,
|
// RE::BSFixedString api_key,
|
||||||
int32_t shop_id,
|
// int32_t shop_id,
|
||||||
RE::TESObjectREFR* merchant_shelf,
|
// RE::TESObjectREFR* merchant_shelf
|
||||||
RE::TESForm* activator_static,
|
//);
|
||||||
RE::BGSKeyword* shelf_keyword,
|
//bool LoadNextMerchandise(
|
||||||
RE::BGSKeyword* chest_keyword,
|
// RE::StaticFunctionTag*,
|
||||||
RE::BGSKeyword* item_keyword,
|
// RE::BSFixedString api_url,
|
||||||
RE::BGSKeyword* activator_keyword,
|
// RE::BSFixedString api_key,
|
||||||
RE::BGSKeyword* toggle_keyword,
|
// int32_t shop_id,
|
||||||
RE::BGSKeyword* next_keyword,
|
// RE::TESObjectREFR* merchant_shelf
|
||||||
RE::BGSKeyword* prev_keyword
|
//);
|
||||||
);
|
//bool LoadPrevMerchandise(
|
||||||
bool LoadNextMerchandise(
|
// RE::StaticFunctionTag*,
|
||||||
RE::StaticFunctionTag*,
|
// RE::BSFixedString api_url,
|
||||||
RE::BSFixedString api_url,
|
// RE::BSFixedString api_key,
|
||||||
RE::BSFixedString api_key,
|
// int32_t shop_id,
|
||||||
int32_t shop_id,
|
// RE::TESObjectREFR* merchant_shelf
|
||||||
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 LoadMerchandiseByShopId(
|
bool LoadMerchandiseByShopId(
|
||||||
RE::StaticFunctionTag*,
|
RE::StaticFunctionTag*,
|
||||||
RE::BSFixedString api_url,
|
RE::BSFixedString api_url,
|
||||||
RE::BSFixedString api_key,
|
RE::BSFixedString api_key,
|
||||||
int32_t shop_id,
|
int32_t shop_id,
|
||||||
RE::TESObjectREFR* merchant_shelf,
|
RE::TESObjectCELL* cell,
|
||||||
RE::TESForm* activator_static,
|
std::vector<RE::TESObjectREFR*> merchant_shelves,
|
||||||
RE::BGSKeyword* shelf_keyword,
|
RE::TESObjectREFR* merchant_chest
|
||||||
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 RefreshMerchandise(
|
//bool RefreshMerchandise(
|
||||||
RE::StaticFunctionTag*,
|
// RE::StaticFunctionTag*,
|
||||||
RE::BSFixedString api_url,
|
// RE::BSFixedString api_url,
|
||||||
RE::BSFixedString api_key,
|
// RE::BSFixedString api_key,
|
||||||
int32_t shop_id,
|
// int32_t shop_id,
|
||||||
RE::TESObjectREFR* merchant_shelf,
|
// RE::TESObjectREFR* merchant_shelf
|
||||||
RE::TESForm* activator_static,
|
//);
|
||||||
RE::BGSKeyword* shelf_keyword,
|
bool ReplaceMerch3D(RE::StaticFunctionTag*, RE::TESObjectREFR* merchant_shelf);
|
||||||
RE::BGSKeyword* chest_keyword,
|
bool ReplaceAllMerch3D(RE::StaticFunctionTag*, RE::TESObjectCELL* cell);
|
||||||
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 CreateMerchandiseList(RE::StaticFunctionTag*, RE::BSFixedString api_url, RE::BSFixedString api_key, int32_t shop_id, RE::TESObjectREFR* merchant_chest);
|
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 GetMerchandiseQuantity(RE::StaticFunctionTag*, RE::TESObjectREFR* activator);
|
||||||
int GetMerchandisePrice(RE::StaticFunctionTag*, RE::TESObjectREFR* activator);
|
int GetMerchandisePrice(RE::StaticFunctionTag*, RE::TESObjectREFR* activator);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "bindings.h"
|
#include "bindings.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
void CreateTransactionImpl(
|
void CreateTransactionImpl(
|
||||||
RE::BSFixedString api_url,
|
RE::BSFixedString api_url,
|
||||||
@ -33,10 +34,9 @@ void CreateTransactionImpl(
|
|||||||
RE::FormID form_id = merch_base->GetFormID();
|
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);
|
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);
|
std::pair<uint32_t, const char*> id_parts = get_local_form_id_and_mod_name(merch_base);
|
||||||
const char * mod_name = file->fileName;
|
uint32_t local_form_id = id_parts.first;
|
||||||
bool is_light = file->recordFlags.all(RE::TESFile::RecordFlag::kSmallFile);
|
const char* mod_name = id_parts.second;
|
||||||
uint32_t local_form_id = is_light ? form_id & 0xfff : form_id & 0xFFFFFF;
|
|
||||||
logger::info(FMT_STRING("CreateTransactionImpl merch_base form file_name: {}, local_form_id: {:x}"), mod_name, local_form_id);
|
logger::info(FMT_STRING("CreateTransactionImpl merch_base form file_name: {}, local_form_id: {:x}"), mod_name, local_form_id);
|
||||||
|
|
||||||
// TODO: implement is_food
|
// TODO: implement is_food
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
const char* MOD_NAME = "Bazaar Realm.esp";
|
constexpr const char* MOD_NAME = "Bazaar Realm.esp";
|
||||||
const uint32_t KEYWORD_SHELF = 0x002fb1;
|
constexpr uint32_t KEYWORD_SHELF = 0x002fb1;
|
||||||
const uint32_t KEYWORD_CHEST = 0x002fb2;
|
constexpr uint32_t KEYWORD_CHEST = 0x002fb2;
|
||||||
const uint32_t KEYWORD_PUBLIC_CHEST = 0x00603e;
|
constexpr uint32_t KEYWORD_PUBLIC_CHEST = 0x00603e;
|
||||||
const uint32_t KEYWORD_TOGGLE = 0x00351b;
|
constexpr uint32_t KEYWORD_TOGGLE = 0x00351b;
|
||||||
const uint32_t KEYWORD_NEXT = 0x00351c;
|
constexpr uint32_t KEYWORD_NEXT = 0x00351c;
|
||||||
const uint32_t KEYWORD_PREV = 0x00351d;
|
constexpr uint32_t KEYWORD_PREV = 0x00351d;
|
||||||
const uint32_t KEYWORD_ITEM = 0x003517;
|
constexpr uint32_t KEYWORD_ITEM = 0x003517;
|
||||||
const uint32_t KEYWORD_ACTIVATOR = 0x004AA8;
|
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("ClearCell", "BRInteriorRefList", ClearCell);
|
||||||
a_vm->RegisterFunction("Load", "BRInteriorRefList", LoadInteriorRefList);
|
a_vm->RegisterFunction("Load", "BRInteriorRefList", LoadInteriorRefList);
|
||||||
a_vm->RegisterFunction("LoadByShopId", "BRInteriorRefList", LoadInteriorRefListByShopId);
|
a_vm->RegisterFunction("LoadByShopId", "BRInteriorRefList", LoadInteriorRefListByShopId);
|
||||||
a_vm->RegisterFunction("Toggle", "BRMerchandiseList", ToggleMerchandise);
|
//a_vm->RegisterFunction("Toggle", "BRMerchandiseList", ToggleMerchandise);
|
||||||
a_vm->RegisterFunction("NextPage", "BRMerchandiseList", LoadNextMerchandise);
|
//a_vm->RegisterFunction("NextPage", "BRMerchandiseList", LoadNextMerchandise);
|
||||||
a_vm->RegisterFunction("PrevPage", "BRMerchandiseList", LoadPrevMerchandise);
|
//a_vm->RegisterFunction("PrevPage", "BRMerchandiseList", LoadPrevMerchandise);
|
||||||
a_vm->RegisterFunction("Load", "BRMerchandiseList", LoadMerchandiseByShopId);
|
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("Replace3D", "BRMerchandiseList", ReplaceMerch3D);
|
||||||
|
a_vm->RegisterFunction("ReplaceAll3D", "BRMerchandiseList", ReplaceAllMerch3D);
|
||||||
a_vm->RegisterFunction("Create", "BRMerchandiseList", CreateMerchandiseList);
|
a_vm->RegisterFunction("Create", "BRMerchandiseList", CreateMerchandiseList);
|
||||||
a_vm->RegisterFunction("GetQuantity", "BRMerchandiseList", GetMerchandiseQuantity);
|
a_vm->RegisterFunction("GetQuantity", "BRMerchandiseList", GetMerchandiseQuantity);
|
||||||
a_vm->RegisterFunction("GetPrice", "BRMerchandiseList", GetMerchandisePrice);
|
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])
|
(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
|
#pragma once
|
||||||
RE::NiMatrix3 get_rotation_matrix(RE::NiPoint3 rotation);
|
RE::NiMatrix3 get_rotation_matrix(RE::NiPoint3 rotation);
|
||||||
RE::NiPoint3 rotate_point(RE::NiPoint3 point, RE::NiMatrix3 rotation_matrix);
|
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