44#include < optional>
55#include < sstream>
66
7+ #include < Geode/cocos/actions/CCActionInterval.h>
78#include < Geode/cocos/cocoa/CCGeometry.h>
89#include < Geode/cocos/cocoa/CCObject.h>
910#include < Geode/cocos/label_nodes/CCLabelBMFont.h>
1415#include < Geode/binding/CCMenuItemSpriteExtra.hpp>
1516#include < Geode/binding/CustomSongWidget.hpp>
1617#include < Geode/binding/FLAlertLayer.hpp>
18+ #include < Geode/binding/GJGameLevel.hpp>
1719#include < Geode/binding/GameManager.hpp>
1820#include < Geode/binding/SongInfoObject.hpp>
1921#include < Geode/loader/Event.hpp>
2325#include < Geode/modify/LevelInfoLayer.hpp> // IWYU pragma: keep
2426#include < Geode/ui/GeodeUI.hpp>
2527#include < Geode/ui/Layout.hpp>
28+ #include < Geode/ui/SimpleAxisLayout.hpp>
2629#include < Geode/utils/cocos.hpp>
2730
2831#include < jukebox/events/song_state_changed.hpp>
@@ -43,13 +46,67 @@ class $modify(JBSongWidget, CustomSongWidget) {
4346 std::string sfxIds = " " ;
4447 bool firstRun = true ;
4548 bool searching = false ;
49+ CCSprite* sprRays = nullptr ;
50+ CCMenuItemSpriteExtra* btnDisc = nullptr ;
4651 std::unordered_map<int , Nongs*> assetNongData;
4752 EventListener<NongManager::MultiAssetSizeTask> m_multiAssetListener;
4853 std::unique_ptr<
4954 EventListener<EventFilter<jukebox::event::SongStateChanged>>>
5055 m_songStateListener;
56+ std::optional<int > levelID = std::nullopt ;
5157 };
5258
59+ std::optional<int > getLevelID () { return m_fields->levelID ; }
60+
61+ void setLevelID (int levelID) {
62+ m_fields->levelID = levelID;
63+
64+ this ->setVerifiedUI ();
65+ }
66+
67+ // Set the disc to show the song is verified.
68+ // The function only works if there is a verified song.
69+ void setVerifiedUI () {
70+ if (!m_fields->levelID .has_value ()) {
71+ return ;
72+ }
73+ std::vector<int > songIDs;
74+ // m_songs size + SongInfoObject id
75+ songIDs.reserve (m_songs.size () + 1 );
76+ for (auto const & kv : m_songs) {
77+ songIDs.push_back (kv.first );
78+ }
79+
80+ int id = m_songInfoObject->m_songID ;
81+ if (m_isRobtopSong) {
82+ id++;
83+ id = -id;
84+ }
85+ songIDs.push_back (id);
86+
87+ bool isVerified =
88+ !NongManager::get ()
89+ .getVerifiedNongsForLevel (m_fields->levelID .value (), songIDs)
90+ .empty ();
91+ if (!isVerified) {
92+ return ;
93+ }
94+
95+ if (m_fields->sprRays ) {
96+ m_fields->sprRays ->setVisible (true );
97+ }
98+ if (m_fields->btnDisc ) {
99+ CCSprite* sprDiscGold =
100+ CCSprite::createWithSpriteFrameName (" JB_PinDiscGold.png" _spr);
101+ if (m_isMusicLibrary) {
102+ sprDiscGold->setScale (0 .5f );
103+ } else {
104+ sprDiscGold->setScale (0 .7f );
105+ }
106+ m_fields->btnDisc ->setSprite (sprDiscGold);
107+ }
108+ }
109+
53110 bool init (SongInfoObject* songInfo, CustomSongDelegate* songDelegate,
54111 bool showSongSelect, bool showPlayMusic, bool showDownload,
55112 bool isRobtopSong, bool unk, bool isMusicLibrary, int unkInt) {
@@ -107,7 +164,8 @@ class $modify(JBSongWidget, CustomSongWidget) {
107164
108165 std::optional optPath = nongs->active ()->path ();
109166
110- if (auto found = m_songs.find (nongs->songID ()); found != m_songs.end ()) {
167+ if (auto found = m_songs.find (nongs->songID ());
168+ found != m_songs.end ()) {
111169 if (!optPath) {
112170 found->second = false ;
113171 } else {
@@ -476,14 +534,13 @@ class $modify(JBSongWidget, CustomSongWidget) {
476534 float labelScale = label->getScale ();
477535 m_fields->labelMenu ->addChild (btn);
478536 m_fields->labelMenu ->setAnchorPoint (m_songLabel->getAnchorPoint ());
479- m_fields->labelMenu ->setContentSize (
480- m_songLabel->getScaledContentSize ());
537+ m_fields->labelMenu ->setContentSize (m_songLabel-> getContentSize ());
538+ m_fields-> labelMenu -> setScale ( m_songLabel->getScale ());
481539 m_fields->labelMenu ->setPosition (m_songLabel->getPosition ());
482540 m_fields->labelMenu ->setLayout (
483- RowLayout::create ()
484- ->setDefaultScaleLimits (0 .1f , 1 .0f )
485- ->setAxisAlignment (AxisAlignment::Start));
486- m_fields->labelMenu ->updateLayout ();
541+ SimpleRowLayout::create ()
542+ ->setMainAxisScaling (AxisScaling::Scale)
543+ ->setCrossAxisScaling (AxisScaling::Scale));
487544 m_songLabel->setVisible (false );
488545 this ->addChild (m_fields->labelMenu );
489546 } else {
@@ -504,27 +561,48 @@ class $modify(JBSongWidget, CustomSongWidget) {
504561 m_fields->pinMenu = CCMenu::create ();
505562 m_fields->pinMenu ->setID (" nong-menu" _spr);
506563
507- CCSprite* spr =
564+ CCSprite* sprRays =
565+ CCSprite::createWithSpriteFrameName (" JB_PinDiscRays.png" _spr);
566+ CCSprite* sprDisc =
508567 CCSprite::createWithSpriteFrameName (" JB_PinDisc.png" _spr);
509568 if (m_isMusicLibrary) {
510- spr->setScale (0 .5f );
569+ sprDisc->setScale (0 .5f );
570+ sprRays->setScale (0 .5f * 1 .15f );
511571 } else {
512- spr->setScale (0 .7f );
572+ sprDisc->setScale (0 .7f );
573+ sprRays->setScale (0 .7f * 1 .15f );
513574 }
514- spr ->setID (" nong-pin" _spr);
575+ sprDisc ->setID (" nong-pin" _spr);
515576
516- CCMenuItemSpriteExtra* btn = CCMenuItemSpriteExtra::create (
517- spr, this , menu_selector (JBSongWidget::addNongLayer));
518- btn->setID (" nong-button" _spr);
577+ CCMenuItemSpriteExtra* btnDisc = CCMenuItemSpriteExtra::create (
578+ sprDisc, this , menu_selector (JBSongWidget::addNongLayer));
579+ btnDisc->setID (" nong-button" _spr);
580+
581+ sprRays->setID (" nong-pin-rays" _spr);
582+ sprRays->setZOrder (-1 );
583+ sprRays->setAnchorPoint ({0 .5f , 0 .5f });
584+ sprRays->setVisible (false );
585+
586+ m_fields->sprRays = sprRays;
587+ m_fields->btnDisc = btnDisc;
588+
589+ m_fields->pinMenu ->addChildAtPosition (sprRays, Anchor::Center);
590+
591+ static constexpr float rotationDuration = 80 .0f ;
592+ CCRepeatForever* rotateAction = CCRepeatForever::create (
593+ CCRotateBy::create (rotationDuration, 360 ));
594+ sprRays->runAction (rotateAction);
519595
520596 m_fields->pinMenu ->setAnchorPoint ({0 .5f , 0 .5f });
521597 m_fields->pinMenu ->ignoreAnchorPointForPosition (false );
522- m_fields->pinMenu ->addChild (btn );
523- m_fields->pinMenu ->setContentSize (btn ->getScaledContentSize ());
524- m_fields->pinMenu ->setLayout (RowLayout ::create ());
598+ m_fields->pinMenu ->addChildAtPosition (btnDisc, Anchor::Center );
599+ m_fields->pinMenu ->setContentSize (btnDisc ->getScaledContentSize ());
600+ m_fields->pinMenu ->setLayout (AnchorLayout ::create ());
525601
526602 m_fields->pinMenu ->setPosition (pos);
527603 this ->addChild (m_fields->pinMenu );
604+
605+ this ->setVerifiedUI ();
528606 }
529607 }
530608
@@ -554,7 +632,8 @@ class $modify(JBSongWidget, CustomSongWidget) {
554632 } else {
555633 ids.push_back (id);
556634 }
557- auto layer = NongDropdownLayer::create (ids, this , id);
635+ auto layer =
636+ NongDropdownLayer::create (ids, this , id, this ->getLevelID ());
558637 // based robtroll
559638 layer->setZOrder (106 );
560639 layer->show ();
@@ -578,6 +657,8 @@ class $modify(JBLevelInfoLayer, LevelInfoLayer) {
578657 popup->m_scene = this ;
579658 popup->show ();
580659 }
660+ static_cast <JBSongWidget*>(this ->m_songWidget )
661+ ->setLevelID (m_level->m_levelID .value ());
581662 return true ;
582663 }
583664};
0 commit comments