change loadinglayer, fix macos spritesheet issue, separate user disabled & problem disabled, fix not enabling a disabled mod that has dependency disabled,

This commit is contained in:
altalk23 2023-09-12 18:12:46 +03:00
parent 54ec221ece
commit ef4764728b
8 changed files with 126 additions and 67 deletions

View file

@ -406,6 +406,8 @@ namespace geode {
bool isLoggingEnabled() const; bool isLoggingEnabled() const;
void setLoggingEnabled(bool enabled); void setLoggingEnabled(bool enabled);
bool shouldLoad() const;
friend class ModImpl; friend class ModImpl;
}; };
} }

View file

@ -8,68 +8,77 @@
using namespace geode::prelude; using namespace geode::prelude;
struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> { struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
CCLabelBMFont* m_loadedModsLabel; CCLabelBMFont* m_smallLabel = nullptr;
bool m_updatingResources; int m_geodeLoadStep = 0;
CustomLoadingLayer() : m_loadedModsLabel(nullptr), m_updatingResources(false) {}
void updateLoadedModsLabel() { void updateLoadedModsLabel() {
auto allMods = Loader::get()->getAllMods(); auto allMods = Loader::get()->getAllMods();
auto count = std::count_if(allMods.begin(), allMods.end(), [&](auto& item) { auto count = std::count_if(allMods.begin(), allMods.end(), [&](auto& item) {
return item->isEnabled(); return item->isEnabled();
}); });
auto str = fmt::format("Geode: Loaded {}/{} mods", count, allMods.size()); auto totalCount = std::count_if(allMods.begin(), allMods.end(), [&](auto& item) {
m_fields->m_loadedModsLabel->setCString(str.c_str()); return item->shouldLoad();
});
auto str = fmt::format("Geode: Loaded {}/{} mods", count, totalCount);
this->setSmallText(str);
} }
void setSmallText(std::string const& text) {
m_fields->m_smallLabel->setString(text.c_str());
}
// hook
bool init(bool fromReload) { bool init(bool fromReload) {
CCFileUtils::get()->updatePaths(); CCFileUtils::get()->updatePaths();
if (!LoadingLayer::init(fromReload)) return false; if (!LoadingLayer::init(fromReload)) return false;
if (fromReload) return true;
auto winSize = CCDirector::sharedDirector()->getWinSize(); auto winSize = CCDirector::sharedDirector()->getWinSize();
m_fields->m_loadedModsLabel = CCLabelBMFont::create("Geode: Loaded 0/0 mods", "goldFont.fnt"); m_fields->m_smallLabel = CCLabelBMFont::create("", "goldFont.fnt");
m_fields->m_loadedModsLabel->setPosition(winSize.width / 2, 30.f); m_fields->m_smallLabel->setPosition(winSize.width / 2, 30.f);
m_fields->m_loadedModsLabel->setScale(.45f); m_fields->m_smallLabel->setScale(.45f);
m_fields->m_loadedModsLabel->setID("geode-loaded-info"); m_fields->m_smallLabel->setID("geode-small-label");
this->addChild(m_fields->m_loadedModsLabel); this->addChild(m_fields->m_smallLabel);
this->updateLoadedModsLabel();
// fields have unpredictable destructors
this->addChild(EventListenerNode<ResourceDownloadFilter>::create(
this, &CustomLoadingLayer::updateResourcesProgress
));
// verify loader resources
if (!LoaderImpl::get()->verifyLoaderResources()) {
m_fields->m_updatingResources = true;
this->setUpdateText("Downloading Resources");
}
else {
LoaderImpl::get()->updateSpecialFiles();
}
return true; return true;
} }
void setUpdateText(std::string const& text) { void setupLoadingMods() {
m_textArea->setString(text.c_str()); if (Loader::get()->getLoadingState() != Loader::LoadingState::Done) {
this->updateLoadedModsLabel();
this->waitLoadAssets();
}
else {
this->continueLoadAssets();
}
}
void setupLoaderResources() {
// verify loader resources
if (!LoaderImpl::get()->verifyLoaderResources()) {
this->setSmallText("Downloading Loader Resources");
this->addChild(EventListenerNode<ResourceDownloadFilter>::create(
this, &CustomLoadingLayer::updateResourcesProgress
));
}
else {
this->setSmallText("Loading Loader Resources");
LoaderImpl::get()->updateSpecialFiles();
this->continueLoadAssets();
}
} }
void updateResourcesProgress(ResourceDownloadEvent* event) { void updateResourcesProgress(ResourceDownloadEvent* event) {
std::visit(makeVisitor { std::visit(makeVisitor {
[&](UpdateProgress const& progress) { [&](UpdateProgress const& progress) {
this->setUpdateText(fmt::format( this->setSmallText(fmt::format(
"Downloading Resources: {}%", progress.first "Downloading Loader Resources: {}%", progress.first
)); ));
}, },
[&](UpdateFinished) { [&](UpdateFinished) {
this->setUpdateText("Resources Downloaded"); this->setSmallText("Downloaded Loader Resources");
m_fields->m_updatingResources = false; this->continueLoadAssets();
this->loadAssets();
}, },
[&](UpdateFailed const& error) { [&](UpdateFailed const& error) {
LoaderImpl::get()->platformMessageBox( LoaderImpl::get()->platformMessageBox(
@ -81,24 +90,70 @@ struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
"The game will be loaded as normal, but please be aware " "The game will be loaded as normal, but please be aware "
"that it is very likely to crash. " "that it is very likely to crash. "
); );
this->setUpdateText("Resource Download Failed"); this->setSmallText("Failed Loader Resources");
m_fields->m_updatingResources = false; this->continueLoadAssets();
this->loadAssets();
} }
}, event->status); }, event->status);
} }
void loadAssets() { void setupModResources() {
if (Loader::get()->getLoadingState() != Loader::LoadingState::Done) { log::debug("Loading mod resources");
this->updateLoadedModsLabel(); this->setSmallText("Loading mod resources");
Loader::get()->updateResources(true);
this->continueLoadAssets();
}
int getCurrentStep() {
return m_fields->m_geodeLoadStep + m_loadStep + 1;
}
int getTotalStep() {
return 18;
}
void updateLoadingBar() {
auto length = m_sliderGrooveXPos * this->getCurrentStep() / this->getTotalStep();
m_sliderBar->setTextureRect({0, 0, length, m_sliderGrooveHeight});
}
void waitLoadAssets() {
Loader::get()->queueInMainThread([this]() { Loader::get()->queueInMainThread([this]() {
this->loadAssets(); this->loadAssets();
}); });
return;
} }
if (m_fields->m_updatingResources) {
return; void continueLoadAssets() {
++m_fields->m_geodeLoadStep;
Loader::get()->queueInMainThread([this]() {
this->loadAssets();
});
} }
bool skipOnRefresh() {
if (m_fromRefresh) {
this->continueLoadAssets();
}
return !m_fromRefresh;
}
// hook
void loadAssets() {
switch (m_fields->m_geodeLoadStep) {
case 0:
if (this->skipOnRefresh()) this->setupLoadingMods();
break;
case 1:
if (this->skipOnRefresh()) this->setupLoaderResources();
break;
case 2:
this->setupModResources();
break;
case 3:
default:
this->setSmallText("Loading game resources");
LoadingLayer::loadAssets(); LoadingLayer::loadAssets();
break;
}
this->updateLoadingBar();
} }
}; };

View file

@ -1,15 +0,0 @@
#include <Geode/loader/Loader.hpp>
#include <Geode/modify/LoadingLayer.hpp>
#include <Geode/modify/GameManager.hpp>
using namespace geode::prelude;
struct ResourcesUpdate : Modify<ResourcesUpdate, LoadingLayer> {
void loadAssets() {
LoadingLayer::loadAssets();
// this is in case the user refreshes texture quality at runtime
if (m_loadStep == 10) {
Loader::get()->updateResources(true);
}
}
};

View file

@ -408,7 +408,7 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
return; return;
} }
if (Mod::get()->getSavedValue<bool>("should-load-" + node->getID(), true)) { if (node->shouldLoad()) {
log::debug("Load"); log::debug("Load");
auto res = node->m_impl->loadBinary(); auto res = node->m_impl->loadBinary();
if (!res) { if (!res) {
@ -432,6 +432,10 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
void Loader::Impl::findProblems() { void Loader::Impl::findProblems() {
for (auto const& [id, mod] : m_mods) { for (auto const& [id, mod] : m_mods) {
if (!mod->shouldLoad()) {
log::debug("{} is not enabled", id);
continue;
}
log::debug(id); log::debug(id);
log::pushNest(); log::pushNest();
@ -492,7 +496,7 @@ void Loader::Impl::findProblems() {
Mod* myEpicMod = mod; // clang fix Mod* myEpicMod = mod; // clang fix
// if the mod is not loaded but there are no problems related to it // if the mod is not loaded but there are no problems related to it
if (!mod->isEnabled() && if (!mod->isEnabled() &&
Mod::get()->getSavedValue<bool>("should-load-" + mod->getID(), true) && mod->shouldLoad() &&
!std::any_of(m_problems.begin(), m_problems.end(), [myEpicMod](auto& item) { !std::any_of(m_problems.begin(), m_problems.end(), [myEpicMod](auto& item) {
return std::holds_alternative<ModMetadata>(item.cause) && return std::holds_alternative<ModMetadata>(item.cause) &&
std::get<ModMetadata>(item.cause).getID() == myEpicMod->getID() || std::get<ModMetadata>(item.cause).getID() == myEpicMod->getID() ||

View file

@ -245,3 +245,7 @@ void Mod::setLoggingEnabled(bool enabled) {
bool Mod::hasSavedValue(std::string const& key) { bool Mod::hasSavedValue(std::string const& key) {
return this->getSaveContainer().contains(key); return this->getSaveContainer().contains(key);
} }
bool Mod::shouldLoad() const {
return m_impl->shouldLoad();
}

View file

@ -43,7 +43,9 @@ Result<> Mod::Impl::setup() {
log::warn("Unable to load data for \"{}\": {}", m_metadata.getID(), loadRes.unwrapErr()); log::warn("Unable to load data for \"{}\": {}", m_metadata.getID(), loadRes.unwrapErr());
} }
if (!m_resourcesLoaded) { if (!m_resourcesLoaded) {
LoaderImpl::get()->updateModResources(m_self); auto searchPathRoot = dirs::getModRuntimeDir() / m_metadata.getID() / "resources";
CCFileUtils::get()->addSearchPath(searchPathRoot.string().c_str());
m_resourcesLoaded = true; m_resourcesLoaded = true;
} }
@ -633,6 +635,10 @@ void Mod::Impl::setLoggingEnabled(bool enabled) {
m_loggingEnabled = enabled; m_loggingEnabled = enabled;
} }
bool Mod::Impl::shouldLoad() const {
return Mod::get()->getSavedValue<bool>("should-load-" + m_metadata.getID(), true);
}
static Result<ModMetadata> getModImplInfo() { static Result<ModMetadata> getModImplInfo() {
std::string err; std::string err;
json::Value json; json::Value json;

View file

@ -137,6 +137,8 @@ namespace geode {
bool isLoggingEnabled() const; bool isLoggingEnabled() const;
void setLoggingEnabled(bool enabled); void setLoggingEnabled(bool enabled);
bool shouldLoad() const;
}; };
class ModImpl : public Mod::Impl { class ModImpl : public Mod::Impl {

View file

@ -250,9 +250,10 @@ void ModCell::onRestart(CCObject*) {
void ModCell::updateState() { void ModCell::updateState() {
bool unresolved = m_mod->hasUnresolvedDependencies(); bool unresolved = m_mod->hasUnresolvedDependencies();
bool shouldLoad = m_mod->shouldLoad();
if (m_enableToggle) { if (m_enableToggle) {
m_enableToggle->toggle(m_mod->isEnabled()); m_enableToggle->toggle(m_mod->isEnabled());
m_enableToggle->setEnabled(!unresolved); m_enableToggle->setEnabled(!unresolved || shouldLoad);
m_enableToggle->m_offButton->setOpacity(unresolved ? 100 : 255); m_enableToggle->m_offButton->setOpacity(unresolved ? 100 : 255);
m_enableToggle->m_offButton->setColor(unresolved ? cc3x(155) : cc3x(255)); m_enableToggle->m_offButton->setColor(unresolved ? cc3x(155) : cc3x(255));
m_enableToggle->m_onButton->setOpacity(unresolved ? 100 : 255); m_enableToggle->m_onButton->setOpacity(unresolved ? 100 : 255);