Skip to content

Commit

Permalink
modtober integration
Browse files Browse the repository at this point in the history
  • Loading branch information
HJfod committed Oct 1, 2024
1 parent c68c31c commit 964624b
Show file tree
Hide file tree
Showing 18 changed files with 220 additions and 36 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.7.2
3.8.0
3 changes: 3 additions & 0 deletions loader/resources/mod.json.in
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
],
"BlankSheet": [
"blanks/*.png"
],
"EventSheet": [
"modtober/*.png"
]
}
},
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added loader/resources/modtober/modtober24-banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added loader/resources/modtober/modtober24-popup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added loader/resources/tag-modtober.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 21 additions & 13 deletions loader/src/ui/mods/GeodeStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,29 +184,37 @@ CircleButtonSprite* createGeodeCircleButton(CCSprite* top, float scale, CircleBa
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);
if (color) {
label->m_label->setColor(color->first);
label->m_BGSprite->setColor(color->second);
}
else {
auto def = geodeTagColor(text);
label->m_label->setColor(def.first);
label->m_BGSprite->setColor(def.second);
}
label->m_label->setColor(color.first);
label->m_BGSprite->setColor(color.second);
return label;
}

std::pair<ccColor3B, ccColor3B> geodeTagColor(std::string_view const& text) {
ButtonSprite* createGeodeTagLabel(std::string_view tag) {
return createTagLabel(geodeTagName(tag), geodeTagColors(tag));
}
std::pair<ccColor3B, ccColor3B> geodeTagColors(std::string_view tag) {
static std::array TAG_COLORS {
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(240, 252, 255), ccc3(123, 152, 163)),
std::make_pair(ccc3(255, 253, 240), ccc3(163, 157, 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) {
Expand Down
6 changes: 4 additions & 2 deletions loader/src/ui/mods/GeodeStyle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

ButtonSprite* createGeodeTagLabel(std::string const& text, std::optional<std::pair<ccColor3B, ccColor3B>> const& color = std::nullopt);
std::pair<ccColor3B, ccColor3B> geodeTagColor(std::string_view const& text);
ButtonSprite* createTagLabel(std::string const& text, std::pair<ccColor3B, ccColor3B> const& color);
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);

Expand Down
13 changes: 7 additions & 6 deletions loader/src/ui/mods/ModsLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,14 +430,15 @@ bool ModsLayer::init() {
// Increment touch priority so the mods in the list don't override
mainTabs->setTouchPriority(-150);

for (auto item : std::initializer_list<std::tuple<const char*, const char*, ModListSource*, const char*>> {
{ "download.png"_spr, "Installed", InstalledModListSource::get(InstalledModListType::All), "installed-button" },
{ "GJ_starsIcon_001.png", "Featured", ServerModListSource::get(ServerModListType::Featured), "featured-button" },
{ "globe.png"_spr, "Download", ServerModListSource::get(ServerModListType::Download), "download-button" },
{ "GJ_timeIcon_001.png", "Recent", ServerModListSource::get(ServerModListType::Recent), "recent-button" },
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", false },
{ "GJ_starsIcon_001.png", "Featured", ServerModListSource::get(ServerModListType::Featured), "featured-button", false },
{ "globe.png"_spr, "Download", ServerModListSource::get(ServerModListType::Download), "download-button", false },
{ "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(
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)
);
btn->setUserData(std::get<2>(item));
Expand Down
16 changes: 12 additions & 4 deletions loader/src/ui/mods/list/ModItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ bool ModItem::init(ModSource&& source) {
);
m_infoContainer->addChild(m_developers);

m_restartRequiredLabel = createGeodeTagLabel(
m_restartRequiredLabel = createTagLabel(
"Restart Required",
{{
{
to3B(ColorProvider::get()->color("mod-list-restart-required-label"_spr)),
to3B(ColorProvider::get()->color("mod-list-restart-required-label-bg"_spr))
}}
}
);
m_restartRequiredLabel->setID("restart-required-label");
m_restartRequiredLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(std::nullopt, .75f));
Expand Down Expand Up @@ -208,6 +208,11 @@ bool ModItem::init(ModSource&& source) {
paidModLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(.1f, .8f));
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
// on which mods to install
Expand Down Expand Up @@ -363,7 +368,10 @@ void ModItem::updateState() {
m_bg->setColor("mod-list-paid-color"_cc3b);
m_bg->setOpacity(55);
}

if (metadata.tags.contains("modtober24")) {
m_bg->setColor(ccc3(63, 91, 138));
m_bg->setOpacity(85);
}
if (isGeodeTheme() && metadata.featured) {
m_bg->setColor("mod-list-featured-color"_cc3b);
m_bg->setOpacity(65);
Expand Down
32 changes: 32 additions & 0 deletions loader/src/ui/mods/list/ModList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../popups/SortPopup.hpp"
#include "../GeodeStyle.hpp"
#include "../ModsLayer.hpp"
#include "../popups/ModtoberPopup.hpp"

bool ModList::init(ModListSource* src, CCSize const& size) {
if (!CCNode::init())
Expand Down Expand Up @@ -249,6 +250,34 @@ bool ModList::init(ModListSource* src, CCSize const& size) {

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(
ColumnLayout::create()
->setGap(0)
Expand Down Expand Up @@ -659,6 +688,9 @@ void ModList::onToggleErrors(CCObject*) {
void ModList::onUpdateAll(CCObject*) {
server::ModDownloadManager::get()->startUpdateAll();
}
void ModList::onModtoberInfo(CCObject*) {
ModtoberPopup::create()->show();
}

size_t ModList::getPage() const {
return m_page;
Expand Down
1 change: 1 addition & 0 deletions loader/src/ui/mods/list/ModList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class ModList : public CCNode {
void onToggleUpdates(CCObject*);
void onToggleErrors(CCObject*);
void onUpdateAll(CCObject*);
void onModtoberInfo(CCObject*);

public:
static ModList* create(ModListSource* src, CCSize const& size);
Expand Down
70 changes: 60 additions & 10 deletions loader/src/ui/mods/popups/ModPopup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "../settings/ModSettingsPopup.hpp"
#include "../../../internal/about.hpp"
#include "../../GeodeUIEvent.hpp"
#include "../popups/ModtoberPopup.hpp"

class FetchTextArea : public CCNode {
public:
Expand Down Expand Up @@ -300,12 +301,12 @@ bool ModPopup::setup(ModSource&& src) {
manageTitle->setOpacity(195);
manageContainer->addChildAtPosition(manageTitle, Anchor::Left, ccp(0, 0), ccp(0, .5f));

m_restartRequiredLabel = createGeodeTagLabel(
m_restartRequiredLabel = createTagLabel(
"Restart Required",
{{
{
to3B(ColorProvider::get()->color("mod-list-restart-required-label"_spr)),
to3B(ColorProvider::get()->color("mod-list-restart-required-label-bg"_spr))
}}
}
);
m_restartRequiredLabel->setScale(.3f);
manageContainer->addChildAtPosition(m_restartRequiredLabel, Anchor::Right, ccp(0, 0), ccp(1, .5f));
Expand Down Expand Up @@ -880,17 +881,55 @@ void ModPopup::onLoadTags(typename server::ServerRequest<std::unordered_set<std:
m_tags->removeAllChildren();

for (auto& tag : data) {
auto readable = tag;
readable[0] = std::toupper(readable[0]);
auto colors = geodeTagColor(tag);
m_tags->addChild(createGeodeTagLabel(readable));
m_tags->addChild(createGeodeTagLabel(tag));
}

if (data.empty()) {
auto label = CCLabelBMFont::create("No tags found", "bigFont.fnt");
label->setOpacity(120);
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();

Expand Down Expand Up @@ -920,12 +959,17 @@ void ModPopup::loadTab(ModPopup::Tab tab) {
btn.first->select(value == tab);
}

float modtoberBannerHeight = 0;
if (m_modtoberBanner) {
modtoberBannerHeight = 30;
}

if (auto existing = m_tabs.at(tab).second) {
m_currentTabPage = existing;
m_rightColumn->addChildAtPosition(existing, Anchor::Bottom);
m_rightColumn->addChildAtPosition(existing, Anchor::Bottom, ccp(0, modtoberBannerHeight));
}
else {
const auto size = (m_rightColumn->getContentSize() - ccp(0, 30));
const auto size = (m_rightColumn->getContentSize() - ccp(0, 30 + modtoberBannerHeight));
const float mdScale = .85f;
switch (tab) {
case Tab::Details: {
Expand Down Expand Up @@ -955,7 +999,7 @@ void ModPopup::loadTab(ModPopup::Tab tab) {
} break;
}
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;
}
}
Expand Down Expand Up @@ -1030,6 +1074,12 @@ void ModPopup::onLink(CCObject* sender) {
void ModPopup::onSupport(CCObject*) {
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) {
auto ret = new ModPopup();
Expand Down
2 changes: 2 additions & 0 deletions loader/src/ui/mods/popups/ModPopup.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class ModPopup : public GeodePopup<ModSource&&> {
ButtonSprite* m_restartRequiredLabel;
CCNode* m_rightColumn;
CCNode* m_currentTabPage = nullptr;
CCNode* m_modtoberBanner = nullptr;
std::unordered_map<Tab, std::pair<GeodeTabSprite*, Ref<CCNode>>> m_tabs;
EventListener<server::ServerRequest<server::ServerModMetadata>> m_statsListener;
EventListener<server::ServerRequest<std::unordered_set<std::string>>> m_tagsListener;
Expand Down Expand Up @@ -63,6 +64,7 @@ class ModPopup : public GeodePopup<ModSource&&> {
void onSettings(CCObject*);
void onLink(CCObject*);
void onSupport(CCObject*);
void onModtoberInfo(CCObject*);

public:
void loadTab(Tab tab);
Expand Down
44 changes: 44 additions & 0 deletions loader/src/ui/mods/popups/ModtoberPopup.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
Loading

0 comments on commit 964624b

Please sign in to comment.