#pragma once #include static bool bMessageShown = false; static std::unordered_set aModNames; inline bool DataFileExists(std::string filename) { const auto path = std::format("Data\\{}", filename); return std::filesystem::exists(path); } inline bool DLCExists(std::string filename, int maxSize = 1000000) { const auto path = std::format("Data\\{}", filename); return std::filesystem::exists(path) && std::filesystem::file_size(path) > maxSize; } inline void NotifyInvalidForm(const RE::TESForm* form) { if (!form) { if (!bMessageShown) { bMessageShown = true; RE::DebugMessageBox("Some of the installed mods are incompatible with Enderal."); } return; } if (!bMessageShown) { bMessageShown = true; RE::DebugMessageBox(std::format("{} is incompatible with Enderal.\nCheck console for the list of flagged mods.", form->GetFile()->fileName).c_str()); RE::ConsoleLog::GetSingleton()->Print("Some of the installed mods are incompatible! This list is not exhaustive, always use xEdit to verify mod compatibility."); } if (!aModNames.contains(form->GetFile()->fileName)) { aModNames.insert(form->GetFile()->fileName); RE::ConsoleLog::GetSingleton()->Print(std::format("{} is incompatible", form->GetFile()->fileName).c_str()); } } inline void CheckWorldspaces() { auto* form = RE::TESForm::LookupByID(0x3C); // Tamriel if (form) { RE::TESWorldSpace* world = form->As(); if (!world || std::string(world->editorID) != "MQP01Home") { NotifyInvalidForm(form); } } else { if (!bMessageShown) { bMessageShown = true; RE::ConsoleLog::GetSingleton()->Print("Some of the installed mods are incompatible! This list is not exhaustive, always use xEdit to verify mod compatibility."); RE::DebugMessageBox("Some of the installed mods are incompatible with Enderal."); } } form = RE::TESForm::LookupByID(0x16BB4); // RiftenWorld RE::TESWorldSpace* world = form ? form->As() : nullptr; if (world) { NotifyInvalidForm(form); } } inline void CheckCCMods() { std::string filenames[73] = { "ccASVSSE001-ALMSIVI.esm", "ccBGSSSE002-ExoticArrows.esl", "ccBGSSSE003-Zombies.esl", "ccBGSSSE004-RuinsEdge.esl", "ccBGSSSE005-Goldbrand.esl", "ccBGSSSE006-StendarsHammer.esl", "ccBGSSSE007-Chrysamere.esl", "ccBGSSSE010-PetDwarvenArmoredMudcrab.esl", "ccBGSSSE011-HrsArmrElvn.esl", "ccBGSSSE012-HrsArmrStl.esl", "ccBGSSSE014-SpellPack01.esl", "ccBGSSSE019-StaffofSheogorath.esl", "ccBGSSSE020-GrayCowl.esl", "ccBGSSSE021-LordsMail.esl", "ccMTYSSE001-KnightsoftheNine.esl", "ccQDRSSE001-SurvivalMode.esl", "ccTWBSSE001-PuzzleDungeon.esm", "ccEEJSSE001-Hstead.esm", "ccQDRSSE002-Firewood.esl", "ccBGSSSE018-Shadowrend.esl", "ccBGSSSE035-PetNHound.esl", "ccFSVSSE001-Backpacks.esl", "ccEEJSSE002-Tower.esl", "ccEDHSSE001-NorJewel.esl", "ccVSVSSE002-Pets.esl", "ccBGSSSE037-Curios.esl", "ccBGSSSE034-MntUni.esl", "ccBGSSSE045-Hasedoki.esl", "ccBGSSSE008-Wraithguard.esl", "ccBGSSSE036-PetBWolf.esl", "ccFFBSSE001-ImperialDragon.esl", "ccMTYSSE002-VE.esl", "ccBGSSSE043-CrossElv.esl", "ccVSVSSE001-Winter.esl", "ccEEJSSE003-Hollow.esl", "ccBGSSSE016-Umbra.esm", "ccBGSSSE031-AdvCyrus.esm", "ccBGSSSE038-BowofShadows.esl", "ccBGSSSE040-AdvObGobs.esl", "ccBGSSSE050-BA_Daedric.esl", "ccBGSSSE052-BA_Iron.esl", "ccBGSSSE054-BA_Orcish.esl", "ccBGSSSE058-BA_Steel.esl", "ccBGSSSE059-BA_Dragonplate.esl", "ccBGSSSE061-BA_Dwarven.esl", "ccPEWSSE002-ArmsOfChaos.esl", "ccBGSSSE041-NetchLeather.esl", "ccEDHSSE002-SplKntSet.esl", "ccBGSSSE064-BA_Elven.esl", "ccBGSSSE063-BA_Ebony.esl", "ccBGSSSE062-BA_DwarvenMail.esl", "ccBGSSSE060-BA_Dragonscale.esl", "ccBGSSSE056-BA_Silver.esl", "ccBGSSSE055-BA_OrcishScaled.esl", "ccBGSSSE053-BA_Leather.esl", "ccBGSSSE051-BA_DaedricMail.esl", "ccBGSSSE057-BA_Stalhrim.esl", "ccBGSSSE066-Staves.esl", "ccBGSSSE067-DaedInv.esm", "ccBGSSSE068-Bloodfall.esl", "ccBGSSSE069-Contest.esl", "ccVSVSSE003-NecroArts.esl", "ccVSVSSE004-BeAFarmer.esl", "ccBGSSSE025-AdvDSGS.esm", "ccFFBSSE002-CrossbowPack.esl", "ccBGSSSE013-Dawnfang.esl", "ccRMSSSE001-NecroHouse.esl", "ccEDHSSE003-Redguard.esl", "ccEEJSSE004-Hall.esl", "ccEEJSSE005-Cave.esm", "ccKRTSSE001_Altar.esl", "ccCBHSSE001-Gaunt.esl", "ccAFDSSE001-DweSanctuary.esm", }; for (short i = 0; i < 73; i++) { if (DLCExists(filenames[i], 800)) { MessageBoxW(NULL, L"Creation Club mods are incompatible with Enderal.", L"Error", MB_OK | MB_ICONERROR); exit(EXIT_FAILURE); } } if (DLCExists("ccBGSSSE001-Fish.esm", 1200000)) { MessageBoxW(NULL, L"Fishing CC are incompatible with Enderal without a patch.", L"Error", MB_OK | MB_ICONERROR); exit(EXIT_FAILURE); } } inline void CheckUnconvertedMap() { auto* form = RE::TESForm::LookupByID(0x1D3C); // Vyn RE::TESWorldSpace* world = form ? form->As() : nullptr; if (!form || !world) { MessageBoxW(NULL, L"Unable to load Vyn, make sure you are not using EnderalSE.dll in Skyrim.", L"Error", MB_OK | MB_ICONERROR); exit(EXIT_FAILURE); } if (world->worldMapOffsetData.mapScale > 1.1) { if (!bMessageShown) { bMessageShown = true; RE::DebugMessageBox(std::format("{} is an Enderal LE mod, containing unconverted map data.\nCheck console for the list of flagged mods.", form->GetFile()->fileName).c_str()); RE::ConsoleLog::GetSingleton()->Print("Some of the installed mods are incompatible! This list is not exhaustive, always use xEdit to verify mod compatibility."); } if (!aModNames.contains(form->GetFile()->fileName)) { aModNames.insert(form->GetFile()->fileName); RE::ConsoleLog::GetSingleton()->Print(std::format("{} is unconverted", form->GetFile()->fileName).c_str()); } } }