mirror of
https://github.com/geode-sdk/geode.git
synced 2025-04-01 07:40:18 -04:00
Merge branch 'main' of https://github.com/geode-sdk/geode into main
This commit is contained in:
commit
6456a3fcc5
11 changed files with 552 additions and 166 deletions
|
@ -91,6 +91,10 @@ if (NOT EXISTS ${GEODE_BIN_PATH})
|
|||
make_directory(${GEODE_BIN_PATH})
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS ${GEODE_BIN_PATH}/${PROJECT_VERSION} AND EXISTS ${GEODE_BIN_PATH}/nightly/)
|
||||
set(GEODE_LINK_NIGHTLY 1)
|
||||
endif()
|
||||
|
||||
if (${GEODE_LINK_NIGHTLY})
|
||||
set(GEODE_PLATFORM_BIN_PATH ${GEODE_BIN_PATH}/nightly/${GEODE_PLATFORM_BINARY})
|
||||
else()
|
||||
|
|
|
@ -22,21 +22,54 @@ T* setIDSafe(CCNode* node, int index, const char* id) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static CCMenu* detachIntoOwnMenu(CCNode* parent, CCNode* node, const char* menuID, Layout* layout) {
|
||||
auto oldMenu = node->getParent();
|
||||
template <typename ...Args>
|
||||
void setIDs(CCNode* node, int startIndex, Args... args) {
|
||||
for (auto i : { args... }) {
|
||||
setIDSafe(node, startIndex, i);
|
||||
++startIndex;
|
||||
}
|
||||
}
|
||||
|
||||
static void switchToMenu(CCNode* node, CCMenu* menu) {
|
||||
auto worldPos = node->getParent()->convertToWorldSpace(node->getPosition());
|
||||
|
||||
node->retain();
|
||||
node->removeFromParent();
|
||||
|
||||
menu->addChild(node);
|
||||
node->setPosition(menu->convertToNodeSpace(worldPos));
|
||||
}
|
||||
|
||||
static void switchChildToMenu(CCNode* parent, int idx, CCMenu* menu) {
|
||||
switchToMenu(static_cast<CCNode*>(parent->getChildren()->objectAtIndex(idx)), menu);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
static void switchChildrenToMenu(CCNode* parent, CCMenu* menu, Args... args) {
|
||||
for (auto i : { args... }) {
|
||||
switchChildToMenu(parent, i, menu);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename ...Args>
|
||||
static CCMenu* detachAndCreateMenu(CCNode* parent, const char* menuID, Layout* layout, T first, Args... args) {
|
||||
auto oldMenu = first->getParent();
|
||||
|
||||
first->retain();
|
||||
first->removeFromParent();
|
||||
|
||||
auto newMenu = CCMenu::create();
|
||||
newMenu->setPosition(oldMenu->convertToWorldSpace(node->getPosition()));
|
||||
newMenu->setPosition(parent->convertToNodeSpace(oldMenu->convertToWorldSpace(first->getPosition())));
|
||||
newMenu->setID(menuID);
|
||||
node->setPosition(0, 0);
|
||||
newMenu->addChild(node);
|
||||
newMenu->setZOrder(oldMenu->getZOrder());
|
||||
newMenu->setLayout(layout);
|
||||
parent->addChild(newMenu);
|
||||
|
||||
node->release();
|
||||
first->setPosition(0, 0);
|
||||
newMenu->addChild(first);
|
||||
first->release();
|
||||
|
||||
(switchToMenu(args, newMenu), ...);
|
||||
|
||||
return newMenu;
|
||||
}
|
||||
}
|
|
@ -25,15 +25,17 @@ $register_ids(CreatorLayer) {
|
|||
|
||||
// move vault button to its own menu
|
||||
if (auto lockBtn = setIDSafe(menu, -2, "vault-button")) {
|
||||
detachIntoOwnMenu(this, lockBtn, "top-right-menu",
|
||||
ColumnLayout::create(5.f, 0.f)->setAlignment(Alignment::Begin)
|
||||
detachAndCreateMenu(this, "top-right-menu",
|
||||
ColumnLayout::create(5.f, 0.f)->setAlignment(Alignment::Begin),
|
||||
lockBtn
|
||||
);
|
||||
}
|
||||
|
||||
// move treasure room button to its own menu
|
||||
if (auto roomBtn = setIDSafe(menu, -1, "treasure-room-button")) {
|
||||
detachIntoOwnMenu(this, roomBtn, "bottom-right-menu",
|
||||
ColumnLayout::create(5.f, 0.f)->setAlignment(Alignment::End)
|
||||
detachAndCreateMenu(this, "bottom-right-menu",
|
||||
ColumnLayout::create(5.f, 0.f)->setAlignment(Alignment::End),
|
||||
roomBtn
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
219
loader/src/ids/EditorUI.cpp
Normal file
219
loader/src/ids/EditorUI.cpp
Normal file
|
@ -0,0 +1,219 @@
|
|||
#include <Geode/Modify.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include "AddIDs.hpp"
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
$register_ids(EditorUI) {
|
||||
|
||||
setIDSafe(this, 0, "position-slider");
|
||||
setIDSafe(this, this->getChildrenCount() - 2, "layer-index-label");
|
||||
setIDSafe(this, this->getChildrenCount() - 1, "object-info-label");
|
||||
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 0)) {
|
||||
menu->setID("toolbar-categories-menu");
|
||||
|
||||
setIDs(menu, 0,
|
||||
"build-button",
|
||||
"edit-button",
|
||||
"delete-button",
|
||||
|
||||
"swipe-button",
|
||||
"free-move-button",
|
||||
"snap-button",
|
||||
"rotate-button",
|
||||
|
||||
"undo-button",
|
||||
"redo-button",
|
||||
"delete-button",
|
||||
|
||||
"music-playback-button",
|
||||
|
||||
"playtest-button",
|
||||
"stop-playtest-button",
|
||||
|
||||
"zoom-in-button",
|
||||
"zoom-out-button",
|
||||
|
||||
"link-button",
|
||||
"unlink-button"
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"toolbar-toggles-menu",
|
||||
GridLayout::create(2, GridAlignment::Begin, GridDirection::Column),
|
||||
menu->getChildByID("swipe-button"),
|
||||
menu->getChildByID("free-move-button"),
|
||||
menu->getChildByID("snap-button"),
|
||||
menu->getChildByID("rotate-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"top-left-menu",
|
||||
RowLayout::create(),
|
||||
menu->getChildByID("undo-button"),
|
||||
menu->getChildByID("redo-button"),
|
||||
menu->getChildByID("delete-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"playback-menu",
|
||||
RowLayout::create(),
|
||||
menu->getChildByID("music-playback-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"playtest-menu",
|
||||
RowLayout::create(),
|
||||
menu->getChildByID("playtest-button"),
|
||||
menu->getChildByID("stop-playtest-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"zoom-menu",
|
||||
ColumnLayout::create(),
|
||||
menu->getChildByID("zoom-in-button"),
|
||||
menu->getChildByID("zoom-out-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"link-menu",
|
||||
ColumnLayout::create(),
|
||||
menu->getChildByID("link-button"),
|
||||
menu->getChildByID("unlink-button")
|
||||
);
|
||||
}
|
||||
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 1)) {
|
||||
menu->setID("delete-category-menu");
|
||||
|
||||
setIDs(menu, 0,
|
||||
"delete-button",
|
||||
"delete-startpos-button",
|
||||
"delete-all-of-button",
|
||||
|
||||
"delete-filter-none",
|
||||
"delete-filter-static",
|
||||
"delete-filter-detail",
|
||||
"delete-filter-custom",
|
||||
|
||||
"delete-help-icon"
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
menu,
|
||||
"delete-button-menu",
|
||||
GridLayout::create(2, GridAlignment::Begin, GridDirection::Column),
|
||||
menu->getChildByID("delete-button"),
|
||||
menu->getChildByID("delete-all-of-button"),
|
||||
menu->getChildByID("delete-startpos-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
menu,
|
||||
"delete-filter-menu",
|
||||
GridLayout::create(2, GridAlignment::Begin, GridDirection::Column),
|
||||
menu->getChildByID("delete-filter-none"),
|
||||
menu->getChildByID("delete-filter-static"),
|
||||
menu->getChildByID("delete-filter-detail"),
|
||||
menu->getChildByID("delete-filter-custom")
|
||||
);
|
||||
}
|
||||
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 2)) {
|
||||
menu->setID("build-tabs-menu");
|
||||
|
||||
setIDs(menu, 0,
|
||||
"static-tab-1",
|
||||
"static-tab-2",
|
||||
"static-tab-3",
|
||||
"slope-tab",
|
||||
"hazard-tab",
|
||||
"3d-tab",
|
||||
"portal-tab",
|
||||
"deco-tab-1",
|
||||
"deco-tab-2",
|
||||
"pulse-deco-tab",
|
||||
"sawblade-tab",
|
||||
"trigger-tab",
|
||||
"custom-tab"
|
||||
);
|
||||
}
|
||||
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 3)) {
|
||||
setIDs(menu, 0,
|
||||
"pause-button",
|
||||
"settings-button",
|
||||
"copy-paste-button",
|
||||
"copy-button",
|
||||
"paste-button",
|
||||
"hsv-button",
|
||||
"edit-special-button",
|
||||
"edit-object-button",
|
||||
"deselect-button",
|
||||
"edit-group-button",
|
||||
"portal-check",
|
||||
"copy-values-button",
|
||||
"paste-state-button",
|
||||
"paste-color-button",
|
||||
"go-to-layer-button",
|
||||
"next-layer-button",
|
||||
"prev-layer-button",
|
||||
"all-layers-button"
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"top-right-menu",
|
||||
RowLayout::create()->setAlignment(Alignment::End),
|
||||
menu->getChildByID("pause-button"),
|
||||
menu->getChildByID("settings-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"editor-buttons-menu",
|
||||
GridLayout::create(4, GridAlignment::End, GridDirection::Column),
|
||||
menu->getChildByID("copy-paste-button"),
|
||||
menu->getChildByID("edit-object-button"),
|
||||
menu->getChildByID("paste-color-button"),
|
||||
menu->getChildByID("deselect-button"),
|
||||
menu->getChildByID("paste-button"),
|
||||
menu->getChildByID("edit-group-button"),
|
||||
menu->getChildByID("paste-state-button"),
|
||||
menu->getChildByID("go-to-layer-button"),
|
||||
menu->getChildByID("copy-button"),
|
||||
menu->getChildByID("edit-special-button"),
|
||||
menu->getChildByID("copy-values-button"),
|
||||
menu->getChildByID("hsv-button")
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
this,
|
||||
"layer-menu",
|
||||
RowLayout::create(),
|
||||
menu->getChildByID("all-layers-button"),
|
||||
menu->getChildByID("prev-layer-button"),
|
||||
this->getChildByID("layer-index-label"),
|
||||
menu->getChildByID("next-layer-button")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class $modify(EditorUI) {
|
||||
bool init(LevelEditorLayer* lel) {
|
||||
if (!EditorUI::init(lel))
|
||||
return false;
|
||||
|
||||
NodeIDs::get()->provide(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
72
loader/src/ids/GJGarageLayer.cpp
Normal file
72
loader/src/ids/GJGarageLayer.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include <Geode/Modify.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include "AddIDs.hpp"
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
$register_ids(GJGarageLayer) {
|
||||
setIDSafe(this, 2, "username-label");
|
||||
setIDSafe(this, 6, "player-icon");
|
||||
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 0)) {
|
||||
menu->setID("icon-select-menu");
|
||||
|
||||
setIDs(menu, 0,
|
||||
"cube-button",
|
||||
"ship-button",
|
||||
"ball-button",
|
||||
"ufo-button",
|
||||
"wave-button",
|
||||
"robot-button",
|
||||
"spider-button",
|
||||
"trail-button",
|
||||
"death-effect-button"
|
||||
);
|
||||
}
|
||||
|
||||
setIDs(this, 10,
|
||||
"cube-selection-menu",
|
||||
"ship-selection-menu",
|
||||
"ball-selection-menu",
|
||||
"ufo-selection-menu",
|
||||
"wave-selection-menu",
|
||||
"robot-selection-menu",
|
||||
"spider-selection-menu",
|
||||
"trail-selection-menu",
|
||||
"death-effect-selection-menu",
|
||||
|
||||
"color-1-cursor",
|
||||
"color-2-cursor",
|
||||
|
||||
"color-selection-menu"
|
||||
);
|
||||
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 11)) {
|
||||
menu->setID("top-left-menu");
|
||||
|
||||
setIDs(menu, 0,
|
||||
"back-button",
|
||||
"shop-button",
|
||||
"shards-button"
|
||||
);
|
||||
|
||||
detachAndCreateMenu(
|
||||
menu,
|
||||
"shards-button-menu",
|
||||
ColumnLayout::create(),
|
||||
menu->getChildByID("shards-button")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class $modify(GJGarageLayer) {
|
||||
bool init() {
|
||||
if (!GJGarageLayer::init())
|
||||
return false;
|
||||
|
||||
NodeIDs::get()->provide(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
|
@ -17,8 +17,9 @@ $register_ids(LevelBrowserLayer) {
|
|||
setIDSafe(menu, 0, "new-level-button");
|
||||
|
||||
if (auto myLevelsBtn = setIDSafe(menu, 1, "my-levels-button")) {
|
||||
detachIntoOwnMenu(this, myLevelsBtn, "my-levels-menu",
|
||||
ColumnLayout::create(5.f, 0.f)->setAlignment(Alignment::End)
|
||||
detachAndCreateMenu(this, "my-levels-menu",
|
||||
ColumnLayout::create(5.f, 0.f)->setAlignment(Alignment::End),
|
||||
myLevelsBtn
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,9 +42,10 @@ $register_ids(LevelInfoLayer) {
|
|||
menu->setID("right-side-menu");
|
||||
|
||||
if (auto name = setIDSafe(menu, 0, "creator-name")) {
|
||||
detachIntoOwnMenu(
|
||||
this, name, "creator-info-menu",
|
||||
ColumnLayout::create()->setAlignment(Alignment::Begin)
|
||||
detachAndCreateMenu(
|
||||
this, "creator-info-menu",
|
||||
ColumnLayout::create()->setAlignment(Alignment::Begin),
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,8 +55,9 @@ $register_ids(MenuLayer) {
|
|||
// move daily chest to its own menu
|
||||
|
||||
if (auto dailyChest = setIDSafe(menu, -1, "daily-chest-button")) {
|
||||
detachIntoOwnMenu(this, dailyChest, "right-side-menu",
|
||||
ColumnLayout::create(0.f, 0.f)
|
||||
detachAndCreateMenu(this, "right-side-menu",
|
||||
ColumnLayout::create(0.f, 0.f),
|
||||
dailyChest
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -78,8 +79,9 @@ $register_ids(MenuLayer) {
|
|||
// move close button to its own menu
|
||||
|
||||
if (auto closeBtn = setIDSafe(menu, 1, "close-button")) {
|
||||
detachIntoOwnMenu(this, closeBtn, "close-menu",
|
||||
RowLayout::create(5.f, 0.f)->setAlignment(Alignment::Begin)
|
||||
detachAndCreateMenu(this, "close-menu",
|
||||
RowLayout::create(5.f, 0.f)->setAlignment(Alignment::Begin),
|
||||
closeBtn
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
34
loader/src/ids/UILayer.cpp
Normal file
34
loader/src/ids/UILayer.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include <Geode/Modify.hpp>
|
||||
#include <Geode/Bindings.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include "AddIDs.hpp"
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
$register_ids(UILayer) {
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 0)) {
|
||||
menu->setID("pause-button-menu");
|
||||
|
||||
setIDs(menu, 0, "pause-button");
|
||||
}
|
||||
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 1)) {
|
||||
menu->setID("checkpoint-menu");
|
||||
|
||||
setIDs(menu, 0,
|
||||
"add-checkpoint-button",
|
||||
"remove-checkpoint-button"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class $modify(UILayer) {
|
||||
bool init() {
|
||||
if (!UILayer::init())
|
||||
return false;
|
||||
|
||||
NodeIDs::get()->provide(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
|
@ -27,7 +27,13 @@ ghc::filesystem::path dirs::getSaveDir() {
|
|||
}
|
||||
|
||||
ghc::filesystem::path dirs::getGeodeDir() {
|
||||
#ifdef GEODE_IS_MACOS
|
||||
char cwd[PATH_MAX];
|
||||
getcwd(cwd, sizeof(cwd));
|
||||
return ghc::filesystem::path(cwd) / "geode";
|
||||
#else
|
||||
return dirs::getGameDir() / "geode";
|
||||
#endif
|
||||
}
|
||||
|
||||
ghc::filesystem::path dirs::getGeodeSaveDir() {
|
||||
|
|
|
@ -25,6 +25,88 @@ Loader::~Loader() {
|
|||
ghc::filesystem::remove_all(dirs::getTempDir());
|
||||
}
|
||||
|
||||
// Initialization
|
||||
|
||||
void Loader::createDirectories() {
|
||||
#ifdef GEODE_IS_MACOS
|
||||
ghc::filesystem::create_directory(dirs::getSaveDir());
|
||||
#endif
|
||||
|
||||
ghc::filesystem::create_directories(dirs::getGeodeResourcesDir());
|
||||
ghc::filesystem::create_directory(dirs::getModConfigDir());
|
||||
ghc::filesystem::create_directory(dirs::getModsDir());
|
||||
ghc::filesystem::create_directory(dirs::getGeodeLogDir());
|
||||
ghc::filesystem::create_directory(dirs::getTempDir());
|
||||
ghc::filesystem::create_directory(dirs::getModRuntimeDir());
|
||||
|
||||
if (!ranges::contains(m_modSearchDirectories, dirs::getModsDir())) {
|
||||
m_modSearchDirectories.push_back(dirs::getModsDir());
|
||||
}
|
||||
}
|
||||
|
||||
Result<> Loader::setup() {
|
||||
if (m_isSetup) {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
log::Logs::setup();
|
||||
|
||||
if (crashlog::setupPlatformHandler()) {
|
||||
log::debug("Set up platform crash logger");
|
||||
}
|
||||
else {
|
||||
log::debug("Unable to set up platform crash logger");
|
||||
}
|
||||
|
||||
log::debug("Setting up Loader...");
|
||||
|
||||
this->createDirectories();
|
||||
auto sett = this->loadData();
|
||||
if (!sett) {
|
||||
log::warn("Unable to load loader settings: {}", sett.unwrapErr());
|
||||
}
|
||||
GEODE_UNWRAP(this->refreshModsList());
|
||||
|
||||
this->queueInGDThread([]() {
|
||||
Loader::get()->addSearchPaths();
|
||||
});
|
||||
|
||||
m_isSetup = true;
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
void Loader::addSearchPaths() {
|
||||
CCFileUtils::get()->addPriorityPath(dirs::getGeodeResourcesDir().string().c_str());
|
||||
CCFileUtils::get()->addPriorityPath(dirs::getModRuntimeDir().string().c_str());
|
||||
}
|
||||
|
||||
void Loader::updateResources() {
|
||||
log::debug("Adding resources");
|
||||
|
||||
// add own spritesheets
|
||||
this->updateModResources(InternalMod::get());
|
||||
|
||||
// add mods' spritesheets
|
||||
for (auto const& [_, mod] : m_mods) {
|
||||
this->updateModResources(mod);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Mod*> Loader::getAllMods() {
|
||||
return map::values(m_mods);
|
||||
}
|
||||
|
||||
Mod* Loader::getInternalMod() {
|
||||
return InternalMod::get();
|
||||
}
|
||||
|
||||
std::vector<InvalidGeodeFile> Loader::getFailedMods() const {
|
||||
return m_invalidMods;
|
||||
}
|
||||
|
||||
// Version info
|
||||
|
||||
VersionInfo Loader::getVersion() {
|
||||
return LOADER_VERSION;
|
||||
}
|
||||
|
@ -48,22 +130,7 @@ bool Loader::isModVersionSupported(VersionInfo const& version) {
|
|||
version <= Loader::maxModVersion();
|
||||
}
|
||||
|
||||
void Loader::createDirectories() {
|
||||
#ifdef GEODE_IS_MACOS
|
||||
ghc::filesystem::create_directory(dirs::getSaveDir());
|
||||
#endif
|
||||
|
||||
ghc::filesystem::create_directories(dirs::getGeodeResourcesDir());
|
||||
ghc::filesystem::create_directory(dirs::getModConfigDir());
|
||||
ghc::filesystem::create_directory(dirs::getModsDir());
|
||||
ghc::filesystem::create_directory(dirs::getGeodeLogDir());
|
||||
ghc::filesystem::create_directory(dirs::getTempDir());
|
||||
ghc::filesystem::create_directory(dirs::getModRuntimeDir());
|
||||
|
||||
if (!ranges::contains(m_modSearchDirectories, dirs::getModsDir())) {
|
||||
m_modSearchDirectories.push_back(dirs::getModsDir());
|
||||
}
|
||||
}
|
||||
// Data saving
|
||||
|
||||
Result<> Loader::saveData() {
|
||||
// save mods' data
|
||||
|
@ -93,37 +160,7 @@ Result<> Loader::loadData() {
|
|||
return Ok();
|
||||
}
|
||||
|
||||
Result<> Loader::setup() {
|
||||
if (m_isSetup) {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
log::Logs::setup();
|
||||
|
||||
if (crashlog::setupPlatformHandler()) {
|
||||
log::debug("Set up platform crash logger");
|
||||
}
|
||||
else {
|
||||
log::debug("Unable to set up platform crash logger");
|
||||
}
|
||||
|
||||
log::debug("Setting up Loader...");
|
||||
|
||||
this->createDirectories();
|
||||
auto sett = this->loadData();
|
||||
if (!sett) {
|
||||
log::warn("Unable to load loader settings: {}", sett.unwrapErr());
|
||||
}
|
||||
(void)this->refreshModsList();
|
||||
|
||||
this->queueInGDThread([]() {
|
||||
Loader::get()->addSearchPaths();
|
||||
});
|
||||
|
||||
m_isSetup = true;
|
||||
|
||||
return Ok();
|
||||
}
|
||||
// Mod loading
|
||||
|
||||
Result<Mod*> Loader::loadModFromInfo(ModInfo const& info) {
|
||||
if (m_mods.count(info.id)) {
|
||||
|
@ -162,6 +199,79 @@ Result<Mod*> Loader::loadModFromFile(ghc::filesystem::path const& file) {
|
|||
return this->loadModFromInfo(res.unwrap());
|
||||
}
|
||||
|
||||
bool Loader::isModInstalled(std::string const& id) const {
|
||||
return m_mods.count(id) && !m_mods.at(id)->isUninstalled();
|
||||
}
|
||||
|
||||
Mod* Loader::getInstalledMod(std::string const& id) const {
|
||||
if (m_mods.count(id) && !m_mods.at(id)->isUninstalled()) {
|
||||
return m_mods.at(id);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Loader::isModLoaded(std::string const& id) const {
|
||||
return m_mods.count(id) && m_mods.at(id)->isLoaded();
|
||||
}
|
||||
|
||||
Mod* Loader::getLoadedMod(std::string const& id) const {
|
||||
if (m_mods.count(id)) {
|
||||
auto mod = m_mods.at(id);
|
||||
if (mod->isLoaded()) {
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Loader::dispatchScheduledFunctions(Mod* mod) {
|
||||
std::lock_guard _(m_scheduledFunctionsMutex);
|
||||
for (auto& func : m_scheduledFunctions) {
|
||||
func();
|
||||
}
|
||||
m_scheduledFunctions.clear();
|
||||
}
|
||||
|
||||
void Loader::scheduleOnModLoad(Mod* mod, ScheduledFunction func) {
|
||||
std::lock_guard _(m_scheduledFunctionsMutex);
|
||||
if (mod) {
|
||||
return func();
|
||||
}
|
||||
m_scheduledFunctions.push_back(func);
|
||||
}
|
||||
|
||||
void Loader::updateModResources(Mod* mod) {
|
||||
if (!mod->m_info.m_spritesheets.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto searchPath = dirs::getModRuntimeDir() / mod->getID() / "resources";
|
||||
|
||||
log::debug("Adding resources for {}", mod->getID());
|
||||
|
||||
// add spritesheets
|
||||
for (auto const& sheet : mod->m_info.m_spritesheets) {
|
||||
log::debug("Adding sheet {}", sheet);
|
||||
auto png = sheet + ".png";
|
||||
auto plist = sheet + ".plist";
|
||||
auto ccfu = CCFileUtils::get();
|
||||
|
||||
if (png == std::string(ccfu->fullPathForFilename(png.c_str(), false)) ||
|
||||
plist == std::string(ccfu->fullPathForFilename(plist.c_str(), false))) {
|
||||
log::warn(
|
||||
"The resource dir of \"{}\" is missing \"{}\" png and/or plist files",
|
||||
mod->m_info.m_id, sheet
|
||||
);
|
||||
}
|
||||
else {
|
||||
CCTextureCache::get()->addImage(png.c_str(), false);
|
||||
CCSpriteFrameCache::get()->addSpriteFramesWithFile(plist.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dependencies and refreshing
|
||||
|
||||
Result<> Loader::loadModsFromDirectory(
|
||||
ghc::filesystem::path const& dir,
|
||||
bool recursive
|
||||
|
@ -249,43 +359,6 @@ Result<> Loader::refreshModsList() {
|
|||
return Ok();
|
||||
}
|
||||
|
||||
bool Loader::isModInstalled(std::string const& id) const {
|
||||
return m_mods.count(id) && !m_mods.at(id)->isUninstalled();
|
||||
}
|
||||
|
||||
Mod* Loader::getInstalledMod(std::string const& id) const {
|
||||
if (m_mods.count(id) && !m_mods.at(id)->isUninstalled()) {
|
||||
return m_mods.at(id);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Loader::isModLoaded(std::string const& id) const {
|
||||
return m_mods.count(id) && m_mods.at(id)->isLoaded();
|
||||
}
|
||||
|
||||
Mod* Loader::getLoadedMod(std::string const& id) const {
|
||||
if (m_mods.count(id)) {
|
||||
auto mod = m_mods.at(id);
|
||||
if (mod->isLoaded()) {
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Mod*> Loader::getAllMods() {
|
||||
return map::values(m_mods);
|
||||
}
|
||||
|
||||
Mod* Loader::getInternalMod() {
|
||||
return InternalMod::get();
|
||||
}
|
||||
|
||||
std::vector<InvalidGeodeFile> Loader::getFailedMods() const {
|
||||
return m_invalidMods;
|
||||
}
|
||||
|
||||
void Loader::updateAllDependencies() {
|
||||
for (auto const& [_, mod] : m_mods) {
|
||||
(void)mod->updateDependencies();
|
||||
|
@ -296,26 +369,12 @@ void Loader::waitForModsToBeLoaded() {
|
|||
while (!m_earlyLoadFinished) {}
|
||||
}
|
||||
|
||||
void Loader::dispatchScheduledFunctions(Mod* mod) {
|
||||
std::lock_guard _(m_scheduledFunctionsMutex);
|
||||
for (auto& func : m_scheduledFunctions) {
|
||||
func();
|
||||
}
|
||||
m_scheduledFunctions.clear();
|
||||
}
|
||||
// Misc
|
||||
|
||||
void Loader::queueInGDThread(ScheduledFunction func) {
|
||||
InternalLoader::get()->queueInGDThread(func);
|
||||
}
|
||||
|
||||
void Loader::scheduleOnModLoad(Mod* mod, ScheduledFunction func) {
|
||||
std::lock_guard _(m_scheduledFunctionsMutex);
|
||||
if (mod) {
|
||||
return func();
|
||||
}
|
||||
m_scheduledFunctions.push_back(func);
|
||||
}
|
||||
|
||||
bool Loader::didLastLaunchCrash() const {
|
||||
return crashlog::didLastLaunchCrash();
|
||||
}
|
||||
|
@ -327,50 +386,3 @@ void Loader::openPlatformConsole() {
|
|||
void Loader::closePlatfromConsole() {
|
||||
InternalLoader::get()->closePlatformConsole();
|
||||
}
|
||||
|
||||
void Loader::updateModResources(Mod* mod) {
|
||||
if (!mod->m_info.spritesheets.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto searchPath = dirs::getModRuntimeDir() / mod->getID() / "resources";
|
||||
|
||||
log::debug("Adding resources for {}", mod->getID());
|
||||
|
||||
// add spritesheets
|
||||
for (auto const& sheet : mod->m_info.spritesheets) {
|
||||
log::debug("Adding sheet {}", sheet);
|
||||
auto png = sheet + ".png";
|
||||
auto plist = sheet + ".plist";
|
||||
auto ccfu = CCFileUtils::get();
|
||||
|
||||
if (png == std::string(ccfu->fullPathForFilename(png.c_str(), false)) ||
|
||||
plist == std::string(ccfu->fullPathForFilename(plist.c_str(), false))) {
|
||||
log::warn(
|
||||
"The resource dir of \"{}\" is missing \"{}\" png and/or plist files",
|
||||
mod->m_info.id, sheet
|
||||
);
|
||||
}
|
||||
else {
|
||||
CCTextureCache::get()->addImage(png.c_str(), false);
|
||||
CCSpriteFrameCache::get()->addSpriteFramesWithFile(plist.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Loader::addSearchPaths() {
|
||||
CCFileUtils::get()->addPriorityPath(dirs::getGeodeResourcesDir().string().c_str());
|
||||
CCFileUtils::get()->addPriorityPath(dirs::getModRuntimeDir().string().c_str());
|
||||
}
|
||||
|
||||
void Loader::updateResources() {
|
||||
log::debug("Adding resources");
|
||||
|
||||
// add own spritesheets
|
||||
this->updateModResources(InternalMod::get());
|
||||
|
||||
// add mods' spritesheets
|
||||
for (auto const& [_, mod] : m_mods) {
|
||||
this->updateModResources(mod);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue