1
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

114 lines
2.9 KiB

#include "BookCheck.h"
// Mostly borrowed from Fix Note icon for SkyUI by 0xC0000005
namespace BookCheck
{
const char* ExtractFileName(const char* const path, size_t& fileNameLength)
{
if (!path) {
fileNameLength = 0;
return NULL;
}
const char* ptr = path;
const char* fileNameStart = NULL;
while (*ptr != 0) {
char value = *ptr;
if (value == '\\' || value == '/') {
fileNameStart = ptr + 1;
}
ptr++;
}
const char* result = fileNameStart ? fileNameStart : path;
fileNameLength = ptr - result;
return result;
}
// Performs a case-sensitive search for 'needle' in the specified string,
// excluding any matches that are part of a larger word.
bool ContainsWholeWord(const char* const haystack, const size_t haystackLength,
const char* const needle, const size_t needleLength)
{
if (haystackLength >= needleLength) {
for (size_t i = 0; i < haystackLength; i++) {
if (haystack[i] != needle[0]) {
continue;
}
size_t j = i + 1;
size_t k = 1;
while (j < haystackLength && k < needleLength && haystack[j] == needle[k]) {
j++;
k++;
}
if (k == needleLength) {
// Check that the match is not part of a larger word.
char next = haystack[j];
return !(next >= 'a' && next <= 'z');
}
}
}
return false;
}
bool StartsWith(const char* haystack, size_t haystackLength,
const char* needle, size_t needleLength)
{
return haystackLength >= needleLength && memcmp(haystack, needle, needleLength) == 0;
}
bool IsNote(const char* const modelFileName, size_t modelFileNameLength)
{
// Most items will use one of the note models from the base game, e.g. Note01.nif.
return ContainsWholeWord(modelFileName, modelFileNameLength, "Note", 4);
}
bool IsJournal(const char* const modelFileName, size_t modelFileNameLength)
{
return ContainsWholeWord(modelFileName, modelFileNameLength, "Journal", 7);
}
bool IsBook(RE::TESObjectBOOK* book)
{
if (!book || !book->inventoryModel) {
return false;
}
size_t modelFileNameLength;
const char* const modelFileName = BookCheck::ExtractFileName(book->inventoryModel->GetModel(), modelFileNameLength);
if (modelFileNameLength == 0) {
return false;
}
RE::BGSSoundDescriptorForm* pickupSound = book->As<RE::BGSPickupPutdownSounds>()->pickupSound;
if (pickupSound && pickupSound->formID == 0xC7A54) { // ITMNoteUp
// The Creation Club Fishing mod does not include 'Note' the inventory art model names for the
// regional fishing maps, instead those items use the following format: FishMap<region>.
if (modelFileNameLength >= 11 && StartsWith(modelFileName, modelFileNameLength, "FishMap", 7)) {
return true;
}
return false;
}
if (IsNote(modelFileName, modelFileNameLength) || IsJournal(modelFileName, modelFileNameLength)) {
return false;
}
return true;
}
}