#include <Geode/Geode.hpp>
#include <Geode/binding/FMODAudioEngine.hpp>
#include <Geode/modify/MenuLayer.hpp>
#include <Geode/modify/AccountRegisterLayer.hpp>
#include <Geode/modify/CCNode.hpp>
#include <Geode/modify/GJBaseGameLayer.hpp>
#include <Geode/modify/GameStatsManager.hpp>
#include <Geode/modify/GameManager.hpp>
#include <Geode/modify/GameLevelManager.hpp>
#include <Geode/modify/MoreSearchLayer.hpp>
#include <Geode/modify/SongSelectNode.hpp>
#include <Geode/modify/EditorUI.hpp>
#include <Geode/modify/LoadingLayer.hpp>
#include <Geode/modify/PlayLayer.hpp>
#include <Geode/ui/Layout.hpp>
#include <Geode/ui/GeodeUI.hpp>
using namespace geode::prelude;
class $modify(SNMenuLayer, MenuLayer) {
bool init() {
if (!MenuLayer::init()) return false;
auto win = CCDirector::sharedDirector()->getWinSize();
if (auto rem = this->getChildByID("main-menu-bg")) { rem->setVisible(false); }
if (auto rem = this->getChildByID("right-side-menu")) { rem->setVisible(false); }
if (auto rem = this->getChildByID("main-title")) { rem->setVisible(false); }
if (auto rem = this->getChildByID("social-media-menu")) { rem->setVisible(false); }
if (auto rem = this->getChildByID("more-games-menu")) { rem->setVisible(false); }
if (auto rem = this->getChildByID("close-menu")) { rem->setVisible(false); }
if (auto rem = this->getChildByID("player-username")) { rem->setVisible(false); }
if (auto rem = this->getChildByID("profile-menu")) { rem->setVisible(false); }
if (auto rem = this->getChildByID("bottom-menu")) {
if (auto btn = rem->getChildByID("geode.loader/geode-button")) { btn->removeFromParent(); }
if (auto btn = rem->getChildByID("newgrounds-button")) { btn->removeFromParent(); }
rem->setLayout(
geode::ColumnLayout::create()
->setGap(32.0f)
->setAxisAlignment(geode::AxisAlignment::Center)
->setCrossAxisAlignment(geode::AxisAlignment::Center)
->setAxisReverse(true)
);
auto win = CCDirector::sharedDirector()->getWinSize();
rem->setPosition({ win.width * 0.95f, win.height * 0.30f });
rem->setContentSize({ 40.0f, 150.0f });
rem->updateLayout();
auto box = cocos2d::CCDrawNode::create();
box->setID("bottom-menu-bg");
box->setPosition({ win.width * 0.96f, win.height * 0.08f });
box->drawRect({-30, -30}, {30, rem->getContentSize().height + 20}, {0,0,0,0.75f}, true, {0,0,0,0.75f});
this->addChild(box, -1);
}
if (auto accountID = GJAccountManager::sharedState()->m_accountID) {
if (auto menu = this->getChildByID("bottom-menu")) {
auto profile = CCMenuItemSpriteExtra::create(
CCSprite::createWithSpriteFrameName("GJ_profileButton_001.png"),
this, menu_selector(MenuLayer::onMyProfile)
);
profile->setID("starnight-button");
menu->addChild(profile);
menu->updateLayout();
}
} else {
if (auto menu = this->getChildByID("bottom-menu")) {
auto profile = CCMenuItemSpriteExtra::create(
CCSprite::createWithSpriteFrameName("GJ_profileButton_001.png"),
this, menu_selector(SNMenuLayer::openAccount)
);
profile->setID("starnight-profile");
menu->addChild(profile);
menu->updateLayout();
}
}
auto bmenu = this->getChildByID("bottom-menu");
auto snSettings = CCMenuItemSpriteExtra::create(
CCSprite::createWithSpriteFrameName("geode.loader/geode-logo-outline-gold.png"),
this, menu_selector(SNMenuLayer::onSettings)
);
snSettings->setID("starnight-settings");
bmenu->addChild(snSettings);
bmenu->updateLayout();
if (auto m = this->getChildByID("main-menu")) {
m->setPositionY(m->getPositionY() - 20.f);
}
auto bg = CCSprite::create("background.png"_spr);
bg->setID("starnight-background");
bg->setPosition({ win.width / 2, win.height / 2 });
bg->setScale(1.25f);
this->addChild(bg, -100);
auto title = CCSprite::create("title.png"_spr);
title->setID("starnight-title");
title->setPosition({ win.width / 2, win.height - 70.f });
this->addChild(title, 10);
auto sideMenu = CCMenu::create();
sideMenu->setID("starnight-menu");
sideMenu->setPosition({ 25.f, win.height / 2 });
this->addChild(sideMenu, 10);
auto creditSpr = CCSprite::createWithSpriteFrameName("GJ_infoBtn_001.png");
creditSpr->setScale(0.75f);
auto credits = CCMenuItemSpriteExtra::create(
creditSpr, this, menu_selector(SNMenuLayer::openCredits)
);
credits->setID("starnight-credits");
sideMenu->addChild(credits, 10);
auto feedbackSpr = CCSprite::createWithSpriteFrameName("GJ_infoBtn_001.png");
feedbackSpr->setScale(0.75f);
feedbackSpr->setColor({ 0, 255, 0 });
auto feedback = CCMenuItemSpriteExtra::create(
feedbackSpr, this, menu_selector(SNMenuLayer::onFeedback)
);
feedback->setID("starnight-feedback");
feedback->setPositionY(sideMenu->getChildByID("starnight-credits")->getPositionY() - 40.f);
sideMenu->addChild(feedback, 10);
std::string ver = "Version " + Mod::get()->getVersion().toNonVString(true);
auto version = CCLabelBMFont::create(
ver.c_str(), "goldFont.fnt"
);
version->setID("starnight-version");
version->setPosition({ win.width / 2, 30.f });
version->setScale(0.5f);
this->addChild(version, 10);
return true;
}
void onSettings(CCObject*) {
geode::openSettingsPopup(Mod::get(), true);
}
void openCredits(CCObject*) {
FLAlertLayer::create(
"Credits",
"<cy>Starnight</c> by: <co>jarvisdevil</c>\n"
"<cf>Most textures made using Asterveila's PackGen</c>\n"
"<cp>Built-in hacks provided by Eclipse Menu</c>\n"
"<cc>Built from Cvolton's GDPS core.</c>",
"OK"
)->show();
}
void onFeedback(CCObject*) {
geode::createQuickPopup(
"Feedback",
"<cy>Starnight is still a work in progress.</c>\n"
"<cf>If you have suggestions or find issues/bugs, let me know please!</c>",
"Nah", "Yeah",
[](auto, bool btn2) {
if (btn2) {
geode::utils::web::openLinkInBrowser("https://localhost/feedback");
}
}
);
}
void openAccount(CCObject*) {
FLAlertLayer::create(
"Hey!",
"<cy>You must login to view your profile.</c>\n<cg>Login by going into [Settings] -> [Account] -> [Log in]</c>",
"OK"
)->show();
}
};
class $modify(SNLoadingLayer, LoadingLayer) {
bool init(bool refresh) {
if (!LoadingLayer::init(refresh)) return false;
auto win = CCDirector::sharedDirector()->getWinSize();
if (auto rem = this->getChildByID("gd-logo")) { rem->setVisible(false); }
if (auto rem = this->getChildByID("robtop-logo")) { rem->setVisible(false); }
if (auto rem = this->getChildByID("bg-texture")) { rem->setVisible(false); }
return true;
}
};
class $modify(SNAccountRegisterLayer, AccountRegisterLayer) {
void registerAccountFinished() {
AccountRegisterLayer::registerAccountFinished();
geode::utils::web::openLinkInBrowser("http://localhost/starnightdatabase/tools/account/activateAccount.php");
}
};
class $modify(SNCCNode, CCNode) {
void onEnter() {
CCNode::onEnter();
auto allowed = std::vector<std::string> {
"background", "bg", "main-menu-bg",
"GJCommentListLayer", "icon-background"
};
for (const auto& name : allowed) {
auto bg = this->getChildByID(name);
if (!bg) continue;
auto sprite = typeinfo_cast<CCSprite*>(bg);
auto sprite2 = typeinfo_cast<CCScale9Sprite*>(bg);
if (!sprite && !sprite2) continue;
if (sprite) sprite->setColor({27, 0, 51});
//if (sprite2) sprite2->setColor({27, 0, 51});
}
}
};
class $modify(SNBaseGameLayer, GJBaseGameLayer) {
bool shouldExitHackedLevel() {
return false;
}
};
class $modify(SNGameManager, GameManager) {
bool isColorUnlocked(int key, UnlockType type) {
if (GameManager::isColorUnlocked(key, type)) return true;
return true;
}
bool isIconUnlocked(int key, IconType type) {
if (GameManager::isIconUnlocked(key, type)) return true;
return true;
}
bool getUGV(const char* key) {
if (GameManager::getUGV(key)) return true;
return strcmp(key, "11") == 0 || strcmp(key, "20") == 0
|| strcmp(key, "34") == 0 || strcmp(key, "35") == 0;
}
gd::string getMenuMusicFile() {
auto selected = Mod::get()->getSettingValue<std::string>("menuLoop");
if (selected == "Anamanaguchi - Helix Nebula") {
return "menuLoop.mp3";
}
if (selected == "Renard - Sinisterrrrrrrr") {
return "menuLoop2.mp3";
}
if (selected == "Kisma - We Are") {
return "menuLoop3.mp3";
}
if (selected == "Toby Fox - CORE") {
return "menuLoop4.mp3";
}
if (selected == "Nintendo - Todays Results (Pikmin 3 OST)") {
return "menuLoop5.mp3";
}
return GameManager::getMenuMusicFile();
}
};
class $modify(SNGameStatsManager, GameStatsManager) {
bool isItemUnlocked(UnlockType type, int key) {
if (GameStatsManager::isItemUnlocked(type, key)) return true;
return true;
}
};
class $modify(SNGameLevelManager, GameLevelManager) {
GJGameLevel* getMainLevel(int levelID, bool dontGetLevelString) {
auto level = GameLevelManager::getMainLevel(levelID, dontGetLevelString);
level->m_requiredCoins = 0;
return level;
}
};
class $modify(SNPlayLayer, PlayLayer) {
void levelComplete() {
auto selected = Mod::get()->getSettingValue<bool>("clearSFX");
if (selected) {
FMODAudioEngine::sharedEngine()->playEffect("clear.mp3"_spr);
}
PlayLayer::levelComplete();
}
};