mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-26 01:18:01 -05:00
modtober integration
This commit is contained in:
parent
c68c31c2d8
commit
964624b974
18 changed files with 220 additions and 36 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
3.7.2
|
3.8.0
|
||||||
|
|
|
@ -60,6 +60,9 @@
|
||||||
],
|
],
|
||||||
"BlankSheet": [
|
"BlankSheet": [
|
||||||
"blanks/*.png"
|
"blanks/*.png"
|
||||||
|
],
|
||||||
|
"EventSheet": [
|
||||||
|
"modtober/*.png"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
BIN
loader/resources/modtober/modtober24-banner-2.png
Normal file
BIN
loader/resources/modtober/modtober24-banner-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 101 KiB |
BIN
loader/resources/modtober/modtober24-banner.png
Normal file
BIN
loader/resources/modtober/modtober24-banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
BIN
loader/resources/modtober/modtober24-popup.png
Normal file
BIN
loader/resources/modtober/modtober24-popup.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1 MiB |
BIN
loader/resources/tag-modtober.png
Normal file
BIN
loader/resources/tag-modtober.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
|
@ -184,21 +184,16 @@ CircleButtonSprite* createGeodeCircleButton(CCSprite* top, float scale, CircleBa
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonSprite* createGeodeTagLabel(std::string const& text, std::optional<std::pair<ccColor3B, ccColor3B>> const& color) {
|
ButtonSprite* createTagLabel(std::string const& text, std::pair<ccColor3B, ccColor3B> const& color) {
|
||||||
auto label = ButtonSprite::create(text.c_str(), "bigFont.fnt", "white-square.png"_spr, .8f);
|
auto label = ButtonSprite::create(text.c_str(), "bigFont.fnt", "white-square.png"_spr, .8f);
|
||||||
if (color) {
|
label->m_label->setColor(color.first);
|
||||||
label->m_label->setColor(color->first);
|
label->m_BGSprite->setColor(color.second);
|
||||||
label->m_BGSprite->setColor(color->second);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto def = geodeTagColor(text);
|
|
||||||
label->m_label->setColor(def.first);
|
|
||||||
label->m_BGSprite->setColor(def.second);
|
|
||||||
}
|
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
ButtonSprite* createGeodeTagLabel(std::string_view tag) {
|
||||||
std::pair<ccColor3B, ccColor3B> geodeTagColor(std::string_view const& text) {
|
return createTagLabel(geodeTagName(tag), geodeTagColors(tag));
|
||||||
|
}
|
||||||
|
std::pair<ccColor3B, ccColor3B> geodeTagColors(std::string_view tag) {
|
||||||
static std::array TAG_COLORS {
|
static std::array TAG_COLORS {
|
||||||
std::make_pair(ccc3(240, 233, 255), ccc3(130, 123, 163)),
|
std::make_pair(ccc3(240, 233, 255), ccc3(130, 123, 163)),
|
||||||
std::make_pair(ccc3(234, 255, 245), ccc3(123, 163, 136)),
|
std::make_pair(ccc3(234, 255, 245), ccc3(123, 163, 136)),
|
||||||
|
@ -206,7 +201,20 @@ std::pair<ccColor3B, ccColor3B> geodeTagColor(std::string_view const& text) {
|
||||||
std::make_pair(ccc3(255, 253, 240), ccc3(163, 157, 123)),
|
std::make_pair(ccc3(255, 253, 240), ccc3(163, 157, 123)),
|
||||||
std::make_pair(ccc3(255, 242, 240), ccc3(163, 128, 123)),
|
std::make_pair(ccc3(255, 242, 240), ccc3(163, 128, 123)),
|
||||||
};
|
};
|
||||||
return TAG_COLORS[hash(text) % 5932 % TAG_COLORS.size()];
|
if (tag == "modtober24") {
|
||||||
|
return std::make_pair(ccc3(225, 236, 245), ccc3(82, 139, 201));
|
||||||
|
}
|
||||||
|
return TAG_COLORS[hash(tag) % 5932 % TAG_COLORS.size()];
|
||||||
|
}
|
||||||
|
std::string geodeTagName(std::string_view tag) {
|
||||||
|
// todo in v4: rework tags to use a server-provided display name instead
|
||||||
|
if (tag == "modtober24") {
|
||||||
|
return "Modtober 2024";
|
||||||
|
}
|
||||||
|
// Everything else just capitalize and that's it
|
||||||
|
auto readable = std::string(tag);
|
||||||
|
readable[0] = std::toupper(readable[0]);
|
||||||
|
return readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBorders* createGeodeListBorders(CCSize const& size) {
|
ListBorders* createGeodeListBorders(CCSize const& size) {
|
||||||
|
|
|
@ -80,8 +80,10 @@ ButtonSprite* createGeodeButton(std::string const& text, bool gold = false, Geod
|
||||||
|
|
||||||
CircleButtonSprite* createGeodeCircleButton(CCSprite* top, float scale = 1.f, CircleBaseSize size = CircleBaseSize::Medium, bool altColor = false);
|
CircleButtonSprite* createGeodeCircleButton(CCSprite* top, float scale = 1.f, CircleBaseSize size = CircleBaseSize::Medium, bool altColor = false);
|
||||||
|
|
||||||
ButtonSprite* createGeodeTagLabel(std::string const& text, std::optional<std::pair<ccColor3B, ccColor3B>> const& color = std::nullopt);
|
ButtonSprite* createTagLabel(std::string const& text, std::pair<ccColor3B, ccColor3B> const& color);
|
||||||
std::pair<ccColor3B, ccColor3B> geodeTagColor(std::string_view const& text);
|
ButtonSprite* createGeodeTagLabel(std::string_view tag);
|
||||||
|
std::pair<ccColor3B, ccColor3B> geodeTagColors(std::string_view tag);
|
||||||
|
std::string geodeTagName(std::string_view tag);
|
||||||
|
|
||||||
ListBorders* createGeodeListBorders(CCSize const& size);
|
ListBorders* createGeodeListBorders(CCSize const& size);
|
||||||
|
|
||||||
|
|
|
@ -430,14 +430,15 @@ bool ModsLayer::init() {
|
||||||
// Increment touch priority so the mods in the list don't override
|
// Increment touch priority so the mods in the list don't override
|
||||||
mainTabs->setTouchPriority(-150);
|
mainTabs->setTouchPriority(-150);
|
||||||
|
|
||||||
for (auto item : std::initializer_list<std::tuple<const char*, const char*, ModListSource*, const char*>> {
|
for (auto item : std::initializer_list<std::tuple<const char*, const char*, ModListSource*, const char*, bool>> {
|
||||||
{ "download.png"_spr, "Installed", InstalledModListSource::get(InstalledModListType::All), "installed-button" },
|
{ "download.png"_spr, "Installed", InstalledModListSource::get(InstalledModListType::All), "installed-button", false },
|
||||||
{ "GJ_starsIcon_001.png", "Featured", ServerModListSource::get(ServerModListType::Featured), "featured-button" },
|
{ "GJ_starsIcon_001.png", "Featured", ServerModListSource::get(ServerModListType::Featured), "featured-button", false },
|
||||||
{ "globe.png"_spr, "Download", ServerModListSource::get(ServerModListType::Download), "download-button" },
|
{ "globe.png"_spr, "Download", ServerModListSource::get(ServerModListType::Download), "download-button", false },
|
||||||
{ "GJ_timeIcon_001.png", "Recent", ServerModListSource::get(ServerModListType::Recent), "recent-button" },
|
{ "GJ_timeIcon_001.png", "Recent", ServerModListSource::get(ServerModListType::Recent), "recent-button", false },
|
||||||
|
{ "d_artCloud_03_001.png", "Modtober", ServerModListSource::get(ServerModListType::Modtober24), "modtober-button", true },
|
||||||
}) {
|
}) {
|
||||||
auto btn = CCMenuItemSpriteExtra::create(
|
auto btn = CCMenuItemSpriteExtra::create(
|
||||||
GeodeTabSprite::create(std::get<0>(item), std::get<1>(item), 120),
|
GeodeTabSprite::create(std::get<0>(item), std::get<1>(item), 100, std::get<4>(item)),
|
||||||
this, menu_selector(ModsLayer::onTab)
|
this, menu_selector(ModsLayer::onTab)
|
||||||
);
|
);
|
||||||
btn->setUserData(std::get<2>(item));
|
btn->setUserData(std::get<2>(item));
|
||||||
|
|
|
@ -84,12 +84,12 @@ bool ModItem::init(ModSource&& source) {
|
||||||
);
|
);
|
||||||
m_infoContainer->addChild(m_developers);
|
m_infoContainer->addChild(m_developers);
|
||||||
|
|
||||||
m_restartRequiredLabel = createGeodeTagLabel(
|
m_restartRequiredLabel = createTagLabel(
|
||||||
"Restart Required",
|
"Restart Required",
|
||||||
{{
|
{
|
||||||
to3B(ColorProvider::get()->color("mod-list-restart-required-label"_spr)),
|
to3B(ColorProvider::get()->color("mod-list-restart-required-label"_spr)),
|
||||||
to3B(ColorProvider::get()->color("mod-list-restart-required-label-bg"_spr))
|
to3B(ColorProvider::get()->color("mod-list-restart-required-label-bg"_spr))
|
||||||
}}
|
}
|
||||||
);
|
);
|
||||||
m_restartRequiredLabel->setID("restart-required-label");
|
m_restartRequiredLabel->setID("restart-required-label");
|
||||||
m_restartRequiredLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(std::nullopt, .75f));
|
m_restartRequiredLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(std::nullopt, .75f));
|
||||||
|
@ -208,6 +208,11 @@ bool ModItem::init(ModSource&& source) {
|
||||||
paidModLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(.1f, .8f));
|
paidModLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(.1f, .8f));
|
||||||
m_titleContainer->addChild(paidModLabel);
|
m_titleContainer->addChild(paidModLabel);
|
||||||
}
|
}
|
||||||
|
if (metadata.tags.contains("modtober24")) {
|
||||||
|
auto modtoberLabel = CCSprite::createWithSpriteFrameName("tag-modtober.png"_spr);
|
||||||
|
modtoberLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(.1f, .8f));
|
||||||
|
m_titleContainer->addChild(modtoberLabel);
|
||||||
|
}
|
||||||
|
|
||||||
// Show mod download count here already so people can make informed decisions
|
// Show mod download count here already so people can make informed decisions
|
||||||
// on which mods to install
|
// on which mods to install
|
||||||
|
@ -363,7 +368,10 @@ void ModItem::updateState() {
|
||||||
m_bg->setColor("mod-list-paid-color"_cc3b);
|
m_bg->setColor("mod-list-paid-color"_cc3b);
|
||||||
m_bg->setOpacity(55);
|
m_bg->setOpacity(55);
|
||||||
}
|
}
|
||||||
|
if (metadata.tags.contains("modtober24")) {
|
||||||
|
m_bg->setColor(ccc3(63, 91, 138));
|
||||||
|
m_bg->setOpacity(85);
|
||||||
|
}
|
||||||
if (isGeodeTheme() && metadata.featured) {
|
if (isGeodeTheme() && metadata.featured) {
|
||||||
m_bg->setColor("mod-list-featured-color"_cc3b);
|
m_bg->setColor("mod-list-featured-color"_cc3b);
|
||||||
m_bg->setOpacity(65);
|
m_bg->setOpacity(65);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../popups/SortPopup.hpp"
|
#include "../popups/SortPopup.hpp"
|
||||||
#include "../GeodeStyle.hpp"
|
#include "../GeodeStyle.hpp"
|
||||||
#include "../ModsLayer.hpp"
|
#include "../ModsLayer.hpp"
|
||||||
|
#include "../popups/ModtoberPopup.hpp"
|
||||||
|
|
||||||
bool ModList::init(ModListSource* src, CCSize const& size) {
|
bool ModList::init(ModListSource* src, CCSize const& size) {
|
||||||
if (!CCNode::init())
|
if (!CCNode::init())
|
||||||
|
@ -249,6 +250,34 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
|
||||||
|
|
||||||
m_topContainer->addChild(m_searchMenu);
|
m_topContainer->addChild(m_searchMenu);
|
||||||
|
|
||||||
|
// Modtober banner; this can be removed after Modtober 2024 is over!
|
||||||
|
if (
|
||||||
|
auto src = typeinfo_cast<ServerModListSource*>(m_source);
|
||||||
|
src && src->getType() == ServerModListType::Modtober24
|
||||||
|
) {
|
||||||
|
auto menu = CCMenu::create();
|
||||||
|
menu->setID("modtober-banner");
|
||||||
|
menu->ignoreAnchorPointForPosition(false);
|
||||||
|
menu->setContentSize({ size.width, 30 });
|
||||||
|
|
||||||
|
auto banner = CCSprite::createWithSpriteFrameName("modtober24-banner.png"_spr);
|
||||||
|
limitNodeWidth(banner, size.width, 1.f, .1f);
|
||||||
|
menu->addChildAtPosition(banner, Anchor::Center);
|
||||||
|
|
||||||
|
auto label = CCLabelBMFont::create("Modtober 2024 is Here!", "bigFont.fnt");
|
||||||
|
label->setScale(.5f);
|
||||||
|
menu->addChildAtPosition(label, Anchor::Left, ccp(10, 0), ccp(0, .5f));
|
||||||
|
|
||||||
|
auto aboutSpr = createGeodeButton("About");
|
||||||
|
aboutSpr->setScale(.5f);
|
||||||
|
auto aboutBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
aboutSpr, this, menu_selector(ModList::onModtoberInfo)
|
||||||
|
);
|
||||||
|
menu->addChildAtPosition(aboutBtn, Anchor::Right, ccp(-35, 0));
|
||||||
|
|
||||||
|
m_topContainer->addChild(menu);
|
||||||
|
}
|
||||||
|
|
||||||
m_topContainer->setLayout(
|
m_topContainer->setLayout(
|
||||||
ColumnLayout::create()
|
ColumnLayout::create()
|
||||||
->setGap(0)
|
->setGap(0)
|
||||||
|
@ -659,6 +688,9 @@ void ModList::onToggleErrors(CCObject*) {
|
||||||
void ModList::onUpdateAll(CCObject*) {
|
void ModList::onUpdateAll(CCObject*) {
|
||||||
server::ModDownloadManager::get()->startUpdateAll();
|
server::ModDownloadManager::get()->startUpdateAll();
|
||||||
}
|
}
|
||||||
|
void ModList::onModtoberInfo(CCObject*) {
|
||||||
|
ModtoberPopup::create()->show();
|
||||||
|
}
|
||||||
|
|
||||||
size_t ModList::getPage() const {
|
size_t ModList::getPage() const {
|
||||||
return m_page;
|
return m_page;
|
||||||
|
|
|
@ -71,6 +71,7 @@ protected:
|
||||||
void onToggleUpdates(CCObject*);
|
void onToggleUpdates(CCObject*);
|
||||||
void onToggleErrors(CCObject*);
|
void onToggleErrors(CCObject*);
|
||||||
void onUpdateAll(CCObject*);
|
void onUpdateAll(CCObject*);
|
||||||
|
void onModtoberInfo(CCObject*);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ModList* create(ModListSource* src, CCSize const& size);
|
static ModList* create(ModListSource* src, CCSize const& size);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "../settings/ModSettingsPopup.hpp"
|
#include "../settings/ModSettingsPopup.hpp"
|
||||||
#include "../../../internal/about.hpp"
|
#include "../../../internal/about.hpp"
|
||||||
#include "../../GeodeUIEvent.hpp"
|
#include "../../GeodeUIEvent.hpp"
|
||||||
|
#include "../popups/ModtoberPopup.hpp"
|
||||||
|
|
||||||
class FetchTextArea : public CCNode {
|
class FetchTextArea : public CCNode {
|
||||||
public:
|
public:
|
||||||
|
@ -300,12 +301,12 @@ bool ModPopup::setup(ModSource&& src) {
|
||||||
manageTitle->setOpacity(195);
|
manageTitle->setOpacity(195);
|
||||||
manageContainer->addChildAtPosition(manageTitle, Anchor::Left, ccp(0, 0), ccp(0, .5f));
|
manageContainer->addChildAtPosition(manageTitle, Anchor::Left, ccp(0, 0), ccp(0, .5f));
|
||||||
|
|
||||||
m_restartRequiredLabel = createGeodeTagLabel(
|
m_restartRequiredLabel = createTagLabel(
|
||||||
"Restart Required",
|
"Restart Required",
|
||||||
{{
|
{
|
||||||
to3B(ColorProvider::get()->color("mod-list-restart-required-label"_spr)),
|
to3B(ColorProvider::get()->color("mod-list-restart-required-label"_spr)),
|
||||||
to3B(ColorProvider::get()->color("mod-list-restart-required-label-bg"_spr))
|
to3B(ColorProvider::get()->color("mod-list-restart-required-label-bg"_spr))
|
||||||
}}
|
}
|
||||||
);
|
);
|
||||||
m_restartRequiredLabel->setScale(.3f);
|
m_restartRequiredLabel->setScale(.3f);
|
||||||
manageContainer->addChildAtPosition(m_restartRequiredLabel, Anchor::Right, ccp(0, 0), ccp(1, .5f));
|
manageContainer->addChildAtPosition(m_restartRequiredLabel, Anchor::Right, ccp(0, 0), ccp(1, .5f));
|
||||||
|
@ -880,10 +881,7 @@ void ModPopup::onLoadTags(typename server::ServerRequest<std::unordered_set<std:
|
||||||
m_tags->removeAllChildren();
|
m_tags->removeAllChildren();
|
||||||
|
|
||||||
for (auto& tag : data) {
|
for (auto& tag : data) {
|
||||||
auto readable = tag;
|
m_tags->addChild(createGeodeTagLabel(tag));
|
||||||
readable[0] = std::toupper(readable[0]);
|
|
||||||
auto colors = geodeTagColor(tag);
|
|
||||||
m_tags->addChild(createGeodeTagLabel(readable));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.empty()) {
|
if (data.empty()) {
|
||||||
|
@ -891,6 +889,47 @@ void ModPopup::onLoadTags(typename server::ServerRequest<std::unordered_set<std:
|
||||||
label->setOpacity(120);
|
label->setOpacity(120);
|
||||||
m_tags->addChild(label);
|
m_tags->addChild(label);
|
||||||
}
|
}
|
||||||
|
// This should probably be kept even after modtober ends,
|
||||||
|
// so the banner sprite must be kept
|
||||||
|
// If the build times from the cool popup become too long then we can
|
||||||
|
// probably move that to a normal FLAlert that explains "Modtober was
|
||||||
|
// this contest blah blah this mod was made for it"
|
||||||
|
else if (data.contains("modtober24")) {
|
||||||
|
auto menu = CCMenu::create();
|
||||||
|
menu->setID("modtober-banner");
|
||||||
|
menu->ignoreAnchorPointForPosition(false);
|
||||||
|
menu->setContentSize({ m_rightColumn->getContentWidth(), 25 });
|
||||||
|
|
||||||
|
auto banner = CCSprite::createWithSpriteFrameName("modtober24-banner-2.png"_spr);
|
||||||
|
limitNodeWidth(banner, m_rightColumn->getContentWidth(), 1.f, .1f);
|
||||||
|
menu->addChildAtPosition(banner, Anchor::Center);
|
||||||
|
|
||||||
|
auto label = CCLabelBMFont::create("Entry for Modtober 2024", "bigFont.fnt");
|
||||||
|
label->setScale(.35f);
|
||||||
|
menu->addChildAtPosition(label, Anchor::Left, ccp(10, 0), ccp(0, .5f));
|
||||||
|
|
||||||
|
auto aboutSpr = createGeodeButton("About");
|
||||||
|
aboutSpr->setScale(.35f);
|
||||||
|
auto aboutBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
aboutSpr, this, menu_selector(ModPopup::onModtoberInfo)
|
||||||
|
);
|
||||||
|
menu->addChildAtPosition(aboutBtn, Anchor::Right, ccp(-25, 0));
|
||||||
|
|
||||||
|
m_rightColumn->addChildAtPosition(menu, Anchor::Bottom, ccp(0, 0), ccp(.5f, 0));
|
||||||
|
|
||||||
|
m_modtoberBanner = menu;
|
||||||
|
|
||||||
|
// Force reload of all the tabs since otherwise their contents will overflow
|
||||||
|
for (auto& [_, tab] : m_tabs) {
|
||||||
|
if (tab.second && tab.second->getParent()) {
|
||||||
|
tab.second->removeFromParent();
|
||||||
|
}
|
||||||
|
tab.second = nullptr;
|
||||||
|
}
|
||||||
|
// This might cause a minor inconvenience to someone who opens the popup and
|
||||||
|
// immediately switches to changelog but is then forced back into details
|
||||||
|
this->loadTab(Tab::Details);
|
||||||
|
}
|
||||||
|
|
||||||
m_tags->updateLayout();
|
m_tags->updateLayout();
|
||||||
|
|
||||||
|
@ -920,12 +959,17 @@ void ModPopup::loadTab(ModPopup::Tab tab) {
|
||||||
btn.first->select(value == tab);
|
btn.first->select(value == tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float modtoberBannerHeight = 0;
|
||||||
|
if (m_modtoberBanner) {
|
||||||
|
modtoberBannerHeight = 30;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto existing = m_tabs.at(tab).second) {
|
if (auto existing = m_tabs.at(tab).second) {
|
||||||
m_currentTabPage = existing;
|
m_currentTabPage = existing;
|
||||||
m_rightColumn->addChildAtPosition(existing, Anchor::Bottom);
|
m_rightColumn->addChildAtPosition(existing, Anchor::Bottom, ccp(0, modtoberBannerHeight));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const auto size = (m_rightColumn->getContentSize() - ccp(0, 30));
|
const auto size = (m_rightColumn->getContentSize() - ccp(0, 30 + modtoberBannerHeight));
|
||||||
const float mdScale = .85f;
|
const float mdScale = .85f;
|
||||||
switch (tab) {
|
switch (tab) {
|
||||||
case Tab::Details: {
|
case Tab::Details: {
|
||||||
|
@ -955,7 +999,7 @@ void ModPopup::loadTab(ModPopup::Tab tab) {
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
m_currentTabPage->setAnchorPoint({ .5f, .0f });
|
m_currentTabPage->setAnchorPoint({ .5f, .0f });
|
||||||
m_rightColumn->addChildAtPosition(m_currentTabPage, Anchor::Bottom);
|
m_rightColumn->addChildAtPosition(m_currentTabPage, Anchor::Bottom, ccp(0, modtoberBannerHeight));
|
||||||
m_tabs.at(tab).second = m_currentTabPage;
|
m_tabs.at(tab).second = m_currentTabPage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1030,6 +1074,12 @@ void ModPopup::onLink(CCObject* sender) {
|
||||||
void ModPopup::onSupport(CCObject*) {
|
void ModPopup::onSupport(CCObject*) {
|
||||||
openSupportPopup(m_source.getMetadata());
|
openSupportPopup(m_source.getMetadata());
|
||||||
}
|
}
|
||||||
|
void ModPopup::onModtoberInfo(CCObject*) {
|
||||||
|
// todo: if we want to get rid of the modtober popup sprite (because it's fucking massive)
|
||||||
|
// then we can just replace this with a normal FLAlert explaining
|
||||||
|
// "this mod was an entry for modtober 2024 blah blah blah"
|
||||||
|
ModtoberPopup::create()->show();
|
||||||
|
}
|
||||||
|
|
||||||
ModPopup* ModPopup::create(ModSource&& src) {
|
ModPopup* ModPopup::create(ModSource&& src) {
|
||||||
auto ret = new ModPopup();
|
auto ret = new ModPopup();
|
||||||
|
|
|
@ -35,6 +35,7 @@ protected:
|
||||||
ButtonSprite* m_restartRequiredLabel;
|
ButtonSprite* m_restartRequiredLabel;
|
||||||
CCNode* m_rightColumn;
|
CCNode* m_rightColumn;
|
||||||
CCNode* m_currentTabPage = nullptr;
|
CCNode* m_currentTabPage = nullptr;
|
||||||
|
CCNode* m_modtoberBanner = nullptr;
|
||||||
std::unordered_map<Tab, std::pair<GeodeTabSprite*, Ref<CCNode>>> m_tabs;
|
std::unordered_map<Tab, std::pair<GeodeTabSprite*, Ref<CCNode>>> m_tabs;
|
||||||
EventListener<server::ServerRequest<server::ServerModMetadata>> m_statsListener;
|
EventListener<server::ServerRequest<server::ServerModMetadata>> m_statsListener;
|
||||||
EventListener<server::ServerRequest<std::unordered_set<std::string>>> m_tagsListener;
|
EventListener<server::ServerRequest<std::unordered_set<std::string>>> m_tagsListener;
|
||||||
|
@ -63,6 +64,7 @@ protected:
|
||||||
void onSettings(CCObject*);
|
void onSettings(CCObject*);
|
||||||
void onLink(CCObject*);
|
void onLink(CCObject*);
|
||||||
void onSupport(CCObject*);
|
void onSupport(CCObject*);
|
||||||
|
void onModtoberInfo(CCObject*);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void loadTab(Tab tab);
|
void loadTab(Tab tab);
|
||||||
|
|
44
loader/src/ui/mods/popups/ModtoberPopup.cpp
Normal file
44
loader/src/ui/mods/popups/ModtoberPopup.cpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#include "ModtoberPopup.hpp"
|
||||||
|
#include <Geode/utils/web.hpp>
|
||||||
|
#include <Geode/loader/Mod.hpp>
|
||||||
|
#include <Geode/binding/ButtonSprite.hpp>
|
||||||
|
|
||||||
|
bool ModtoberPopup::setup() {
|
||||||
|
m_bgSprite->setVisible(false);
|
||||||
|
|
||||||
|
auto bg = CCSprite::createWithSpriteFrameName("modtober24-popup.png"_spr);
|
||||||
|
m_mainLayer->addChildAtPosition(bg, Anchor::Center);
|
||||||
|
|
||||||
|
auto supportSpr = createGeodeButton("Join");
|
||||||
|
supportSpr->setScale(.8f);
|
||||||
|
auto supportBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
supportSpr, this, menu_selector(ModtoberPopup::onDiscord)
|
||||||
|
);
|
||||||
|
m_buttonMenu->addChildAtPosition(supportBtn, Anchor::BottomRight, ccp(-65, 50));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModtoberPopup::onDiscord(CCObject*) {
|
||||||
|
createQuickPopup(
|
||||||
|
"Join Modtober",
|
||||||
|
"<cf>Modtober</c> is being hosted on the <cg>GD Programming</c> <ca>Discord Server</c>.\n"
|
||||||
|
"To participate, join GDP and read the rules for the contest in <co>#modtober-2024</c>",
|
||||||
|
"Cancel", "Join Discord",
|
||||||
|
[](auto, bool btn2) {
|
||||||
|
if (btn2) {
|
||||||
|
web::openLinkInBrowser("https://discord.gg/gd-programming-646101505417674758");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModtoberPopup* ModtoberPopup::create() {
|
||||||
|
auto ret = new ModtoberPopup();
|
||||||
|
if (ret && ret->init(410, 270)) {
|
||||||
|
ret->autorelease();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
CC_SAFE_DELETE(ret);
|
||||||
|
return nullptr;
|
||||||
|
}
|
16
loader/src/ui/mods/popups/ModtoberPopup.hpp
Normal file
16
loader/src/ui/mods/popups/ModtoberPopup.hpp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Geode/ui/Popup.hpp>
|
||||||
|
#include "../GeodeStyle.hpp"
|
||||||
|
|
||||||
|
using namespace geode::prelude;
|
||||||
|
|
||||||
|
class ModtoberPopup : public GeodePopup<> {
|
||||||
|
protected:
|
||||||
|
bool setup() override;
|
||||||
|
|
||||||
|
void onDiscord(CCObject*);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static ModtoberPopup* create();
|
||||||
|
};
|
|
@ -143,6 +143,7 @@ enum class ServerModListType {
|
||||||
Featured,
|
Featured,
|
||||||
Trending,
|
Trending,
|
||||||
Recent,
|
Recent,
|
||||||
|
Modtober24,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ServerModListSource : public ModListSource {
|
class ServerModListSource : public ModListSource {
|
||||||
|
@ -165,6 +166,7 @@ public:
|
||||||
server::ModsQuery const& getQuery() const;
|
server::ModsQuery const& getQuery() const;
|
||||||
InvalidateQueryAfter<server::ModsQuery> getQueryMut();
|
InvalidateQueryAfter<server::ModsQuery> getQueryMut();
|
||||||
bool isDefaultQuery() const override;
|
bool isDefaultQuery() const override;
|
||||||
|
ServerModListType getType() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModPackListSource : public ModListSource {
|
class ModPackListSource : public ModListSource {
|
||||||
|
|
|
@ -23,6 +23,12 @@ void ServerModListSource::resetQuery() {
|
||||||
.sorting = server::ModsSort::RecentlyPublished,
|
.sorting = server::ModsSort::RecentlyPublished,
|
||||||
};
|
};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case ServerModListType::Modtober24: {
|
||||||
|
m_query = server::ModsQuery {
|
||||||
|
.tags = { "modtober24" },
|
||||||
|
};
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +82,11 @@ ServerModListSource* ServerModListSource::get(ServerModListType type) {
|
||||||
static auto inst = new ServerModListSource(ServerModListType::Recent);
|
static auto inst = new ServerModListSource(ServerModListType::Recent);
|
||||||
return inst;
|
return inst;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case ServerModListType::Modtober24: {
|
||||||
|
static auto inst = new ServerModListSource(ServerModListType::Modtober24);
|
||||||
|
return inst;
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,3 +119,7 @@ bool ServerModListSource::isDefaultQuery() const {
|
||||||
m_query.tags.empty() &&
|
m_query.tags.empty() &&
|
||||||
!m_query.developer.has_value();
|
!m_query.developer.has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerModListType ServerModListSource::getType() const {
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue