diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 5b056f83c..9f99ff600 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -180,8 +180,8 @@ void PluginList::refresh(const QString& profileName, auto gamePlugins = m_Organizer.gameFeatures().gameFeature(); const bool lightPluginsAreSupported = gamePlugins ? gamePlugins->lightPluginsAreSupported() : false; - const bool overridePluginsAreSupported = - gamePlugins ? gamePlugins->overridePluginsAreSupported() : false; + const bool mediumPluginsAreSupported = + gamePlugins ? gamePlugins->mediumPluginsAreSupported() : false; const bool loadOrderMechanismNone = m_GamePlugin->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::None; @@ -245,7 +245,7 @@ void PluginList::refresh(const QString& profileName, m_ESPs.emplace_back(filename, forceLoaded, forceEnabled, forceDisabled, originName, ToQString(current->getFullPath()), hasIni, loadedArchives, lightPluginsAreSupported, - overridePluginsAreSupported); + mediumPluginsAreSupported); m_ESPs.rbegin()->priority = -1; } catch (const std::exception& e) { reportError(tr("failed to update esp info for file %1 (source id: %2), error: %3") @@ -998,23 +998,23 @@ bool PluginList::isMasterFlagged(const QString& name) const } } -bool PluginList::isLightFlagged(const QString& name) const +bool PluginList::isMediumFlagged(const QString& name) const { auto iter = m_ESPsByName.find(name); if (iter == m_ESPsByName.end()) { return false; } else { - return m_ESPs[iter->second].isLightFlagged; + return m_ESPs[iter->second].isMediumFlagged; } } -bool PluginList::isOverlayFlagged(const QString& name) const +bool PluginList::isLightFlagged(const QString& name) const { auto iter = m_ESPsByName.find(name); if (iter == m_ESPsByName.end()) { return false; } else { - return m_ESPs[iter->second].isOverlayFlagged; + return m_ESPs[iter->second].isLightFlagged; } } @@ -1082,13 +1082,17 @@ void PluginList::updateIndices() void PluginList::generatePluginIndexes() { int numESLs = 0; + int numESHs = 0; int numSkipped = 0; auto gamePlugins = m_Organizer.gameFeatures().gameFeature(); const bool lightPluginsSupported = gamePlugins ? gamePlugins->lightPluginsAreSupported() : false; - const bool overridePluginsSupported = - gamePlugins ? gamePlugins->overridePluginsAreSupported() : false; + const bool mediumPluginsSupported = + gamePlugins ? gamePlugins->mediumPluginsAreSupported() : false; + + std::vector coreLightPlugins; + std::vector coreMediumPlugins; for (int l = 0; l < m_ESPs.size(); ++l) { int i = m_ESPsByPriority.at(l); @@ -1097,25 +1101,59 @@ void PluginList::generatePluginIndexes() ++numSkipped; continue; } - if (lightPluginsSupported && - (m_ESPs[i].hasLightExtension || m_ESPs[i].isLightFlagged)) { + if (mediumPluginsSupported && m_ESPs[i].isMediumFlagged) { + if (mediumPluginsSupported && m_ESPs[i].forceLoaded) { + // Starfield core medium plugins are loaded in memory addresses after custom + // medium plugins + coreMediumPlugins.push_back(i); + ++numSkipped; + continue; + } + int ESHpos = 253 + ((numESHs + 1) / 256); + m_ESPs[i].index = QString("%1:%2") + .arg(ESHpos, 2, 16, QChar('0')) + .arg(numESHs % 256, 2, 16, QChar('0')) + .toUpper(); + ++numESHs; + + } else if (lightPluginsSupported && + (m_ESPs[i].hasLightExtension || m_ESPs[i].isLightFlagged)) { + // Starfield core light plugins are loaded in memory addresses after custom light + // plugins + if (mediumPluginsSupported && m_ESPs[i].forceLoaded) { + coreLightPlugins.push_back(i); + ++numSkipped; + continue; + } + int ESLpos = 254 + ((numESLs + 1) / 4096); m_ESPs[i].index = QString("%1:%2") .arg(ESLpos, 2, 16, QChar('0')) - .arg((numESLs) % 4096, 3, 16, QChar('0')) + .arg(numESLs % 4096, 3, 16, QChar('0')) .toUpper(); ++numESLs; - // This logic may still be used if overlay plugins are fixed to longer consume a - // load order slot - // - //} else if (overridePluginsSupported && m_ESPs[i].isOverlayFlagged) { - // m_ESPs[i].index = QString("XX"); - // ++numSkipped; } else { - m_ESPs[i].index = - QString("%1").arg(l - numESLs - numSkipped, 2, 16, QChar('0')).toUpper(); + m_ESPs[i].index = QString("%1") + .arg(l - numESHs - numESLs - numSkipped, 2, 16, QChar('0')) + .toUpper(); } } + for (auto pluginIndex : coreMediumPlugins) { + int ESHpos = 253 + ((numESHs + 1) / 4096); + m_ESPs[pluginIndex].index = QString("%1:%2") + .arg(ESHpos, 2, 16, QChar('0')) + .arg(numESHs % 256, 2, 16, QChar('0')) + .toUpper(); + ++numESHs; + } + for (auto pluginIndex : coreLightPlugins) { + int ESLpos = 254 + ((numESLs + 1) / 4096); + m_ESPs[pluginIndex].index = QString("%1:%2") + .arg(ESLpos, 2, 16, QChar('0')) + .arg(numESLs % 4096, 3, 16, QChar('0')) + .toUpper(); + ++numESLs; + } emit esplist_changed(); } @@ -1245,6 +1283,8 @@ QVariant PluginList::fontData(const QModelIndex& modelIndex) const if (m_ESPs[index].hasMasterExtension || m_ESPs[index].isMasterFlagged || m_ESPs[index].hasLightExtension) result.setWeight(QFont::Bold); + if (m_ESPs[index].isMediumFlagged) + result.setUnderline(true); if (m_ESPs[index].isLightFlagged || m_ESPs[index].hasLightExtension) result.setItalic(true); @@ -1332,24 +1372,22 @@ QVariant PluginList::tooltipData(const QModelIndex& modelIndex) const "be added to your game settings, overwriting in case of conflicts."); } + if (esp.isMediumFlagged && esp.hasMasterExtension) { + toolTip += "

" + + tr("This ESM is flagged as a medium plugin (ESH). It adheres to the ESM " + "load order but loads records in ESH space (FD). You can have 256 " + "medium plugins in addition to other plugin types."); + } + if (esp.isLightFlagged && !esp.hasLightExtension) { QString type = esp.hasMasterExtension ? "ESM" : "ESP"; toolTip += - "

" + tr("This %1 is flagged as an ESL. It will adhere to the %1 load " - "order but the records will be loaded in ESL space.") - .arg(type); - } - - // This logic may still be used if overlay plugins are fixed to longer consume a load - // order slot - // - // if (esp.isOverlayFlagged) { - // toolTip += - // "

" + tr("This plugin is flagged as an overlay plugin. It contains - // only " - // "modified records and will overlay those changes onto the " - // "existing records in memory. It takes no memory space."); - // } + "

" + + tr("This %1 is flagged as a light plugin (ESL). It will adhere to the %1 load " + "order but the records will be loaded in ESL space (FE/FF). You can have up " + "to 4096 light plugins in addition to other plugin types.") + .arg(type); + } if (esp.hasNoRecords) { toolTip += "

" + tr("This is a dummy plugin. It contains no records and is " @@ -1477,6 +1515,10 @@ QVariant PluginList::iconData(const QModelIndex& modelIndex) const result.append(":/MO/gui/archive_conflict_neutral"); } + if (esp.isMediumFlagged) { + result.append(":/MO/gui/run"); + } + if (esp.isLightFlagged && !esp.hasLightExtension) { result.append(":/MO/gui/awaiting"); } @@ -1485,10 +1527,6 @@ QVariant PluginList::iconData(const QModelIndex& modelIndex) const result.append(":/MO/gui/unchecked-checkbox"); } - if (esp.isOverlayFlagged) { - result.append(":/MO/gui/instance_switch"); - } - if (info && !info->loot.dirty.empty()) { result.append(":/MO/gui/edit_clear"); } @@ -1801,7 +1839,7 @@ PluginList::ESPInfo::ESPInfo(const QString& name, bool forceLoaded, bool forceEn bool forceDisabled, const QString& originName, const QString& fullPath, bool hasIni, std::set archives, bool lightSupported, - bool overlaySupported) + bool mediumSupported) : name(name), fullPath(fullPath), enabled(forceLoaded), forceLoaded(forceLoaded), forceEnabled(forceEnabled), forceDisabled(forceDisabled), priority(0), loadOrder(-1), originName(originName), hasIni(hasIni), @@ -1813,9 +1851,9 @@ PluginList::ESPInfo::ESPInfo(const QString& name, bool forceLoaded, bool forceEn hasMasterExtension = (extension == "esm"); hasLightExtension = (extension == "esl"); isMasterFlagged = file.isMaster(); - isOverlayFlagged = overlaySupported && file.isOverlay(); + isMediumFlagged = mediumSupported && file.isMedium(); isLightFlagged = - lightSupported && !isOverlayFlagged && file.isLight(overlaySupported); + lightSupported && !isMediumFlagged && file.isLight(mediumSupported); hasNoRecords = file.isDummy(); author = QString::fromLatin1(file.author().c_str()); @@ -1829,7 +1867,7 @@ PluginList::ESPInfo::ESPInfo(const QString& name, bool forceLoaded, bool forceEn hasMasterExtension = false; hasLightExtension = false; isMasterFlagged = false; - isOverlayFlagged = false; + isMediumFlagged = false; isLightFlagged = false; hasNoRecords = false; } diff --git a/src/pluginlist.h b/src/pluginlist.h index 3f4542fc6..89c05141d 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -240,8 +240,8 @@ class PluginList : public QAbstractItemModel bool hasMasterExtension(const QString& name) const; bool hasLightExtension(const QString& name) const; bool isMasterFlagged(const QString& name) const; + bool isMediumFlagged(const QString& name) const; bool isLightFlagged(const QString& name) const; - bool isOverlayFlagged(const QString& name) const; bool hasNoRecords(const QString& name) const; boost::signals2::connection onRefreshed(const std::function& callback); @@ -317,7 +317,7 @@ public slots: ESPInfo(const QString& name, bool forceLoaded, bool forceEnabled, bool forceDisabled, const QString& originName, const QString& fullPath, bool hasIni, std::set archives, bool lightSupported, - bool overrideSupported); + bool mediumSupported); QString name; QString fullPath; @@ -333,8 +333,8 @@ public slots: bool hasMasterExtension; bool hasLightExtension; bool isMasterFlagged; + bool isMediumFlagged; bool isLightFlagged; - bool isOverlayFlagged; bool hasNoRecords; bool modSelected; QString author; diff --git a/src/pluginlistproxy.cpp b/src/pluginlistproxy.cpp index fa3960a84..8b826a818 100644 --- a/src/pluginlistproxy.cpp +++ b/src/pluginlistproxy.cpp @@ -114,14 +114,14 @@ bool PluginListProxy::isMasterFlagged(const QString& name) const return m_Proxied->isMasterFlagged(name); } -bool PluginListProxy::isLightFlagged(const QString& name) const +bool PluginListProxy::isMediumFlagged(const QString& name) const { - return m_Proxied->isLightFlagged(name); + return m_Proxied->isMediumFlagged(name); } -bool PluginListProxy::isOverlayFlagged(const QString& name) const +bool PluginListProxy::isLightFlagged(const QString& name) const { - return m_Proxied->isOverlayFlagged(name); + return m_Proxied->isLightFlagged(name); } bool PluginListProxy::hasNoRecords(const QString& name) const diff --git a/src/pluginlistproxy.h b/src/pluginlistproxy.h index 397d786d6..6865004a8 100644 --- a/src/pluginlistproxy.h +++ b/src/pluginlistproxy.h @@ -32,8 +32,8 @@ class PluginListProxy : public MOBase::IPluginList bool hasMasterExtension(const QString& name) const override; bool hasLightExtension(const QString& name) const override; bool isMasterFlagged(const QString& name) const override; + bool isMediumFlagged(const QString& name) const override; bool isLightFlagged(const QString& name) const override; - bool isOverlayFlagged(const QString& name) const override; bool hasNoRecords(const QString& name) const override; private: diff --git a/src/pluginlistview.cpp b/src/pluginlistview.cpp index 28f778218..8b34f75dd 100644 --- a/src/pluginlistview.cpp +++ b/src/pluginlistview.cpp @@ -56,15 +56,15 @@ QModelIndexList PluginListView::indexViewToModel(const QModelIndexList& index) c void PluginListView::updatePluginCount() { - int activeMasterCount = 0; - int activeLightMasterCount = 0; - int activeOverlayCount = 0; - int activeRegularCount = 0; - int masterCount = 0; - int lightMasterCount = 0; - int overlayCount = 0; - int regularCount = 0; - int activeVisibleCount = 0; + int activeMasterCount = 0; + int activeMediumMasterCount = 0; + int activeLightMasterCount = 0; + int activeRegularCount = 0; + int masterCount = 0; + int mediumMasterCount = 0; + int lightMasterCount = 0; + int regularCount = 0; + int activeVisibleCount = 0; PluginList* list = m_core->pluginList(); QString filter = ui.filter->text(); @@ -72,7 +72,11 @@ void PluginListView::updatePluginCount() for (QString plugin : list->pluginNames()) { bool active = list->isEnabled(plugin); bool visible = m_sortProxy->filterMatchesPlugin(plugin); - if (list->hasLightExtension(plugin) || list->isLightFlagged(plugin)) { + if (list->isMediumFlagged(plugin)) { + mediumMasterCount++; + activeMediumMasterCount += active; + activeVisibleCount += visible && active; + } else if (list->hasLightExtension(plugin) || list->isLightFlagged(plugin)) { lightMasterCount++; activeLightMasterCount += active; activeVisibleCount += visible && active; @@ -80,10 +84,6 @@ void PluginListView::updatePluginCount() masterCount++; activeMasterCount += active; activeVisibleCount += visible && active; - } else if (list->isOverlayFlagged(plugin)) { - overlayCount++; - activeOverlayCount += active; - activeVisibleCount += visible && active; } else { regularCount++; activeRegularCount += active; @@ -91,9 +91,9 @@ void PluginListView::updatePluginCount() } } - int activeCount = activeMasterCount + activeLightMasterCount + activeOverlayCount + - activeRegularCount; - int totalCount = masterCount + lightMasterCount + overlayCount + regularCount; + int activeCount = activeMasterCount + activeMediumMasterCount + + activeLightMasterCount + activeRegularCount; + int totalCount = masterCount + mediumMasterCount + lightMasterCount + regularCount; ui.counter->display(activeVisibleCount); ui.counter->setToolTip( @@ -105,8 +105,8 @@ void PluginListView::updatePluginCount() "ESPs:%7 %8" "ESMs+ESPs:%9 %10" + "ESHs:%11 %12" "ESLs:%5 %6" - "Overlay:%11 %12" "") .arg(activeCount) .arg(totalCount) @@ -118,8 +118,8 @@ void PluginListView::updatePluginCount() .arg(regularCount) .arg(activeMasterCount + activeRegularCount) .arg(masterCount + regularCount) - .arg(activeOverlayCount) - .arg(overlayCount)); + .arg(activeMediumMasterCount) + .arg(mediumMasterCount)); } void PluginListView::onFilterChanged(const QString& filter)