mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-27 01:45:35 -05:00
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:
parent
54ec221ece
commit
ef4764728b
8 changed files with 126 additions and 67 deletions
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -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() ||
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue