aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Mansfield <jmansfield@cadixdev.org>2021-05-28 23:10:02 +0100
committerJamie Mansfield <jmansfield@cadixdev.org>2021-06-21 16:29:16 +0100
commit4ba0c9c2986d9fb133db923d2da60de9272ccc0a (patch)
treea406fe6c6578170f03c9b20720399e9a559916e0
parent74311a54cf2f423a160ce0999bd5ad7e5c62f243 (diff)
downloadPrismLauncher-4ba0c9c2986d9fb133db923d2da60de9272ccc0a.tar.gz
PrismLauncher-4ba0c9c2986d9fb133db923d2da60de9272ccc0a.tar.bz2
PrismLauncher-4ba0c9c2986d9fb133db923d2da60de9272ccc0a.zip
NOISSUE Support mod grouping and dependencies
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackManifest.cpp13
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackManifest.h8
-rw-r--r--application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp83
-rw-r--r--application/pages/modplatform/atlauncher/AtlOptionalModDialog.h6
4 files changed, 103 insertions, 7 deletions
diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp
index 149cb9c1..f28fd35c 100644
--- a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp
+++ b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp
@@ -147,7 +147,20 @@ static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) {
p.optional = Json::ensureBoolean(obj, QString("optional"), false);
p.recommended = Json::ensureBoolean(obj, QString("recommended"), false);
p.selected = Json::ensureBoolean(obj, QString("selected"), false);
+ p.hidden = Json::ensureBoolean(obj, QString("hidden"), false);
+ p.library = Json::ensureBoolean(obj, QString("library"), false);
+ p.group = Json::ensureString(obj, QString("group"), "");
+ if(obj.contains("depends")) {
+ auto dependsArr = Json::requireArray(obj, "depends");
+ for (const auto depends : dependsArr) {
+ p.depends.append(Json::requireString(depends));
+ }
+ }
+
p.client = Json::ensureBoolean(obj, QString("client"), false);
+
+ // computed
+ p.effectively_hidden = p.hidden || p.library;
}
void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj)
diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.h b/api/logic/modplatform/atlauncher/ATLPackManifest.h
index 48e1d344..376587b0 100644
--- a/api/logic/modplatform/atlauncher/ATLPackManifest.h
+++ b/api/logic/modplatform/atlauncher/ATLPackManifest.h
@@ -90,7 +90,15 @@ struct VersionMod
bool optional;
bool recommended;
bool selected;
+ bool hidden;
+ bool library;
+ QString group;
+ QVector<QString> depends;
+
bool client;
+
+ // computed
+ bool effectively_hidden;
};
struct PackVersion
diff --git a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
index 129d9fed..cffe5d55 100644
--- a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
+++ b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
@@ -4,8 +4,16 @@
AtlOptionalModListModel::AtlOptionalModListModel(QWidget *parent, QVector<ATLauncher::VersionMod> mods)
: QAbstractListModel(parent), m_mods(mods) {
- for (const auto& mod : mods) {
- m_selection[mod.name] = mod.selected;
+ // fill mod index
+ for (int i = 0; i < m_mods.size(); i++) {
+ auto mod = m_mods.at(i);
+ m_index[mod.name] = i;
+ }
+ // set initial state
+ for (int i = 0; i < m_mods.size(); i++) {
+ auto mod = m_mods.at(i);
+ m_selection[mod.name] = false;
+ setMod(mod, i, mod.selected, false);
}
}
@@ -61,11 +69,7 @@ bool AtlOptionalModListModel::setData(const QModelIndex &index, const QVariant &
auto row = index.row();
auto mod = m_mods.at(row);
- // toggle the state
- m_selection[mod.name] = !m_selection[mod.name];
-
- emit dataChanged(AtlOptionalModListModel::index(index.row(), EnabledColumn),
- AtlOptionalModListModel::index(index.row(), EnabledColumn));
+ toggleMod(mod, row);
return true;
}
@@ -113,6 +117,71 @@ void AtlOptionalModListModel::clearAll() {
AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn));
}
+void AtlOptionalModListModel::toggleMod(ATLauncher::VersionMod mod, int index) {
+ setMod(mod, index, !m_selection[mod.name]);
+}
+
+void AtlOptionalModListModel::setMod(ATLauncher::VersionMod mod, int index, bool enable, bool shouldEmit) {
+ if (m_selection[mod.name] == enable) return;
+
+ m_selection[mod.name] = enable;
+
+ // disable other mods in the group, if applicable
+ if (enable && !mod.group.isEmpty()) {
+ for (int i = 0; i < m_mods.size(); i++) {
+ if (index == i) continue;
+ auto other = m_mods.at(i);
+
+ if (mod.group == other.group) {
+ setMod(other, i, false, shouldEmit);
+ }
+ }
+ }
+
+ for (const auto& dependencyName : mod.depends) {
+ auto dependencyIndex = m_index[dependencyName];
+ auto dependencyMod = m_mods.at(dependencyIndex);
+
+ // enable/disable dependencies
+ if (enable) {
+ setMod(dependencyMod, dependencyIndex, true, shouldEmit);
+ }
+
+ // if the dependency is 'effectively hidden', then track which mods
+ // depend on it - so we can efficiently disable it when no more dependents
+ // depend on it.
+ auto dependants = m_dependants[dependencyName];
+
+ if (enable) {
+ dependants.append(mod.name);
+ }
+ else {
+ dependants.removeAll(mod.name);
+
+ // if there are no longer any dependents, let's disable the mod
+ if (dependencyMod.effectively_hidden && dependants.isEmpty()) {
+ setMod(dependencyMod, dependencyIndex, false, shouldEmit);
+ }
+ }
+ }
+
+ // disable mods that depend on this one, if disabling
+ if (!enable) {
+ auto dependants = m_dependants[mod.name];
+ for (const auto& dependencyName : dependants) {
+ auto dependencyIndex = m_index[dependencyName];
+ auto dependencyMod = m_mods.at(dependencyIndex);
+
+ setMod(dependencyMod, dependencyIndex, false, shouldEmit);
+ }
+ }
+
+ if (shouldEmit) {
+ emit dataChanged(AtlOptionalModListModel::index(index, EnabledColumn),
+ AtlOptionalModListModel::index(index, EnabledColumn));
+ }
+}
+
AtlOptionalModDialog::AtlOptionalModDialog(QWidget *parent, QVector<ATLauncher::VersionMod> mods)
: QDialog(parent), ui(new Ui::AtlOptionalModDialog) {
diff --git a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.h b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.h
index 8b0dbdb6..a1df43f6 100644
--- a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.h
+++ b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.h
@@ -38,8 +38,14 @@ public slots:
void clearAll();
private:
+ void toggleMod(ATLauncher::VersionMod mod, int index);
+ void setMod(ATLauncher::VersionMod mod, int index, bool enable, bool shouldEmit = true);
+
+private:
QVector<ATLauncher::VersionMod> m_mods;
QMap<QString, bool> m_selection;
+ QMap<QString, int> m_index;
+ QMap<QString, QVector<QString>> m_dependants;
};
class AtlOptionalModDialog : public QDialog {