mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-17 13:57:05 +02:00
In-game Mods page: official mods are listed as official, not as deleted folders
They load from Mods/.reskate-official, outside the Mods folder's list, so the page took the ones in effect for mods whose folder was gone: "Folder deleted / APPLY TO UNLOAD", a change pending, and an Apply that reloaded the level for nothing. - Each official mod has a tile of its own after the installed mods: OFFICIAL while in effect, SET ASIDE while Board Break has another deck in the game, APPLY TO LOAD for one put in place since the game started. No Enable/Disable: the launcher keeps them. - live_mods::preview leaves built-in and official content out of what applying would unload.
This commit is contained in:
1 parent
a2d6daffbc
commit
a14a6f44b5
2 files changed
+41
-1
No files matched your search
@@ -8,6 +8,7 @@
|
||||
#include "Engine/Core/Platform/path_text.h"
|
||||
#include "Engine/Game/Build/20260929/live_mods.h"
|
||||
#include "Engine/Game/Build/addresses.h"
|
||||
#include "Engine/Vfs/builtin_packs.h"
|
||||
#include "Engine/Vfs/mod_catalog.h"
|
||||
#include "Engine/Vfs/mod_scoring.h"
|
||||
#include "Extension/World/loading_screen.h"
|
||||
@@ -508,6 +509,8 @@ ApplyEffect preview(const mods::ModList &list) {
|
||||
// One of a Board Break deck pack's decks stands for the pack (mod_catalog.h).
|
||||
if (const auto pack = mods::board_break_pack_of(name); named(now, pack.empty() ? name : pack)) continue;
|
||||
const auto *entry = entry_of(name);
|
||||
// Content ReSkate keeps itself (builtin_packs.h) is in no mod list, and stays.
|
||||
if (!entry && (name.starts_with("reskate-builtin-") || mods::kept_by_reskate(list.root, name))) continue;
|
||||
// A folder deleted since: what it held is unknown, so assume the worst.
|
||||
if (!entry) {
|
||||
reload = true;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "modding_menu.h"
|
||||
#include "skate_menu.h"
|
||||
#include "skate_menu_internal.h"
|
||||
#include "Engine/Vfs/builtin_packs.h"
|
||||
#include "Engine/Vfs/initfs.h"
|
||||
#include "Engine/Vfs/mod_catalog.h"
|
||||
#include "Extension/Assets/live_mods.h"
|
||||
@@ -151,6 +152,7 @@ std::string mod_contents(const mods::Mod& mod) {
|
||||
// mod folder added since launch.
|
||||
void draw_installed_mods(SkateMenu& menu) {
|
||||
static auto* scans = new FolderRead<mods::ModList>; // process lifetime, as the threads that fill it
|
||||
static auto* officials = new FolderRead<std::vector<mods::BuiltinPack>>;
|
||||
static std::string action_error;
|
||||
const auto scanned = scans->get([] { return mods::scan_mods(mods::engine_data_root()); }, 1500);
|
||||
if (!scanned) {
|
||||
@@ -160,6 +162,17 @@ void draw_installed_mods(SkateMenu& menu) {
|
||||
const auto& list = *scanned;
|
||||
const auto& launch = mods::catalog();
|
||||
const auto applied = live_mods::applied_mods();
|
||||
// Official mods (builtin_packs.h) live outside the Mods folder's list: ReSkate keeps them,
|
||||
// always on. Without them here, the ones in effect read as mods whose folder was deleted.
|
||||
const auto official_read = officials->get([root = list.root] { return mods::official_packs(root); }, 1500);
|
||||
const auto official = official_read ? *official_read : std::vector<mods::BuiltinPack>{};
|
||||
const auto kept = [&](const std::string& name) {
|
||||
const auto pack = mods::board_break_pack_of(name);
|
||||
const auto& base = pack.empty() ? name : pack;
|
||||
return base.starts_with("reskate-builtin-") || std::ranges::any_of(official, [&](const mods::BuiltinPack& other) {
|
||||
return _stricmp(other.name.c_str(), base.c_str()) == 0;
|
||||
});
|
||||
};
|
||||
// A Board Break deck pack is in effect when one of the decks inside it is (mod_catalog.h).
|
||||
const auto in_effect = [&](const std::string& name) {
|
||||
return std::ranges::any_of(applied, [&](const std::string& other) {
|
||||
@@ -182,10 +195,17 @@ void draw_installed_mods(SkateMenu& menu) {
|
||||
if (effect) ++loaded;
|
||||
if (entry.enabled != effect && !excluded(entry.mod.name) && !set_aside(entry)) ++pending;
|
||||
}
|
||||
const auto official_aside = [&](const std::string& name) {
|
||||
return !in_effect(name) && std::ranges::any_of(aside, [&](const std::string& other) { return _stricmp(other.c_str(), name.c_str()) == 0; });
|
||||
};
|
||||
for (const auto& pack : official) {
|
||||
if (in_effect(pack.name)) ++loaded;
|
||||
else if (!official_aside(pack.name)) ++pending; // put in place since the game started: applying loads it
|
||||
}
|
||||
// Mods still in effect whose folder has been deleted: applying unloads them.
|
||||
std::vector<std::string> removed;
|
||||
for (const auto& name : applied)
|
||||
if (mods::board_break_pack_of(name).empty() &&
|
||||
if (mods::board_break_pack_of(name).empty() && !kept(name) &&
|
||||
std::ranges::none_of(list.entries, [&](const mods::ModEntry& entry) { return _stricmp(entry.mod.name.c_str(), name.c_str()) == 0; }))
|
||||
removed.push_back(name);
|
||||
pending += removed.size();
|
||||
@@ -300,6 +320,23 @@ void draw_installed_mods(SkateMenu& menu) {
|
||||
entry.enabled ? "Disable" : "Enable"))
|
||||
toggle = i;
|
||||
}
|
||||
for (const auto& pack : official) {
|
||||
const auto* known = [&]() -> const mods::Mod* {
|
||||
for (const auto& mod : launch.mods)
|
||||
if (_stricmp(mod.name.c_str(), pack.name.c_str()) == 0) return &mod;
|
||||
return nullptr;
|
||||
}();
|
||||
auto title = known && !known->title.empty() ? known->title : pack.name.substr(pack.name.find('-') + 1);
|
||||
if (!known) std::replace(title.begin(), title.end(), '_', ' ');
|
||||
auto line = known ? byline(*known) : "by " + pack.name.substr(0, pack.name.find('-'));
|
||||
line += " - always on";
|
||||
const bool effect = in_effect(pack.name), set_by_deck = official_aside(pack.name);
|
||||
tile(index++, title, line, effect ? "OFFICIAL" : set_by_deck ? "SET ASIDE" : "APPLY TO LOAD",
|
||||
effect ? skate_theme::good : set_by_deck ? skate_theme::tile_light : skate_theme::danger,
|
||||
known ? mod_contents(*known) : "",
|
||||
"An official mod: ReSkate keeps it for every player at its latest version, always on. "
|
||||
"The launcher installs and updates it, so it cannot be disabled here.", nullptr);
|
||||
}
|
||||
for (const auto& name : removed)
|
||||
tile(index++, name, "Folder deleted", "APPLY TO UNLOAD", skate_theme::danger, "",
|
||||
"This mod's folder is gone, but it stays loaded until you apply.", nullptr);
|
||||
|
||||
Reference in new issue
Block a user