@@ -14,14 +14,17 @@ import states.editors.ChartingState;
1414import options .GameplayChangersSubstate ;
1515import substates .ResetScoreSubState ;
1616import states .freeplay .osu .DifficultySelectorSubState ;
17-
1817import states .freeplay .osu .SongBox ;
1918
2019import sys .FileSystem ;
2120import sys .io .File ;
2221
2322import haxe .Json ;
2423
24+ #if ARCHIPELAGO_ALLOWED
25+ import archipelago .* ;
26+ #end
27+
2528class OsuFreeplayState extends MusicBeatState
2629{
2730 public static var instance : OsuFreeplayState ;
@@ -50,7 +53,7 @@ class OsuFreeplayState extends MusicBeatState
5053 var inSub : Bool = false ;
5154
5255 var staleBg : FlxSprite ;
53-
56+ var ticketCounter : FlxText = null ;
5457 override function create ()
5558 {
5659 instance = this ; // For Archipelago
@@ -138,12 +141,29 @@ class OsuFreeplayState extends MusicBeatState
138141
139142 changeSong ();
140143
144+ if (APEntryState .apGame != null && APEntryState .apGame .info () != null ) {
145+ ticketCounter = new FlxText (FlxG .width - 470 , FlxG .height - 630 , 0 , " 0/0" , 32 );
146+ ticketCounter .setFormat (Paths .font (" fnf1.ttf" ), 32 , FlxColor .WHITE , CENTER , FlxTextBorderStyle .OUTLINE , FlxColor .BLACK );
147+ ticketCounter .scrollFactor .set ();
148+ add (ticketCounter );
149+ new FlxTimer ().start (1 , function (tmr : FlxTimer ) {
150+ archipelago. APGameState .haventranyet = false ;
151+ });
152+ }
153+
154+ if (archipelago. APItem .activeItem ?. condition .type == archipelago. APItem .ConditionType. PlayState )
155+ archipelago. APItem .activeItem = null ;
156+
141157 super .create ();
142158 }
143159
144160 var holdTime : Float = 0 ;
161+ var stopMusicPlay : Bool = false ;
162+ var victoryColor : FlxColor ;
163+ var e : Int = 0 ;
145164 override public function update (elapsed : Float )
146165 {
166+ e ++ ;
147167 FlxG .watch .addQuick (' Search Text' , searchTypeText .text );
148168
149169 for (item in songBox )
@@ -158,6 +178,10 @@ class OsuFreeplayState extends MusicBeatState
158178 item .x = FlxMath .lerp (item. ID == curSelected ? 280 : 320 - coolEffect , item .x , CoolUtil .boundTo (1 - (elapsed * 9 ), 0 , 1 ));
159179 }
160180
181+ #if ARCHIPELAGO_ALLOWED
182+ victoryColor = FlxColor .fromHSL (((e / 2 ) / 300 * 360 ) % 360 , 1.0 , 0.5 * 1.0 );
183+ #end
184+
161185 for (icon in iconGrp )
162186 {
163187 var theY : Float = 0 ;
@@ -252,6 +276,30 @@ class OsuFreeplayState extends MusicBeatState
252276
253277 if (controls. ACCEPT )
254278 {
279+ var vicCheck : Bool = FreeplayManager .isVictorySong (FreeplayManager .songList [curSelected ].songName , FreeplayManager .songList [curSelected ].folder ) && APInfo .ticketCount >= APInfo .ticketWinCount ;
280+ // You need the song AND the tickets.
281+ trace (' can play victory song: ${vicCheck }' );
282+ if (FreeplayManager .isVictorySong (FreeplayManager .songList [curSelected ].songName , FreeplayManager .songList [curSelected ].folder ) && ! vicCheck ) {
283+ FlxG .camera .shake (0.005 , 0.5 );
284+ FlxG .sound .play (Paths .sound (" badnoise" + FlxG .random .int (1 ,3 )), 1 );
285+ songBox .forEach (function (item : FlxSprite )
286+ {
287+ if (item. ID == curSelected ) FlxTween .color (item , 1 , 0xffcc0002 , 0xffffffff , {ease : FlxEase .sineIn });
288+ });
289+ FlxTween .color (ticketCounter , 1 , 0xffcc0002 , 0xffffffff , {ease : FlxEase .sineIn });
290+ return ;
291+ }
292+
293+ if (FreeplayManager .trueMissing .contains (FreeplayManager .songList [curSelected ].songName ) && ! FreeplayManager .unplayedList .contains (FreeplayManager .songList [curSelected ].songName )) {
294+ FlxG .camera .shake (0.005 , 0.5 );
295+ FlxG .sound .play (Paths .sound (" badnoise" + FlxG .random .int (1 ,3 )), 1 );
296+ songBox .forEach (function (item : FlxSprite )
297+ {
298+ if (item. ID == curSelected ) FlxTween .color (item , 1 , 0xffcc0002 , 0xffffffff , {ease : FlxEase .sineIn });
299+ });
300+ return ;
301+ }
302+
255303 inSub = true ;
256304 openSubState (new DifficultySelectorSubState (FreeplayManager .songList [curSelected ]));
257305 }
@@ -301,6 +349,16 @@ class OsuFreeplayState extends MusicBeatState
301349 }
302350
303351 super .update (elapsed );
352+
353+ if (ticketCounter != null ) {
354+ ticketCounter .text = ' Current ticket amount: ${APInfo .ticketCount }\n ' +
355+ ' Tickets Needed: ${APInfo .ticketWinCount }\n ' +
356+ ' Tickets Left: ${Std .int (APInfo .ticketWinCount - APInfo .ticketCount )}\n ' +
357+ ' Hint Points Available: ${APInfo .hintPoints }\n ' +
358+ ' Hint Cost: ${APInfo .hintCost }\n ' +
359+ ' (L) to release song\n ' +
360+ ' (H) to hint song' ;
361+ }
304362 }
305363
306364 override function closeSubState () {
@@ -390,7 +448,11 @@ class OsuFreeplayState extends MusicBeatState
390448 }
391449
392450 override function destroy () {
451+ super .destroy ();
393452 FlxG .mouse .visible = false ;
453+ instance = null ;
454+ if (! FlxG .sound .music .playing && ! stopMusicPlay )
455+ MusicManager .playMenuMusic (0 );
394456 }
395457
396458 function loadSongArray (reset : Bool , searching : Bool = false , searchQuery : String = ' ' )
@@ -408,18 +470,49 @@ class OsuFreeplayState extends MusicBeatState
408470
409471 for (i in 0 ... FreeplayManager .songList .length )
410472 {
473+ var songName : String = ' ' ;
474+ var modName : String = ' ' ;
475+ var isMissing : Bool = false ;
476+ var locationId : Array <Int > = [];
477+ var color : FlxColor = 0xFFFFFFFF ;
478+ var someLocationsNotMissing : Bool = false ;
479+
480+ if (APEntryState .inArchipelagoMode ) {
481+ songName = FreeplayManager .songList [i ].songName ;
482+ modName = FreeplayManager .songList [i ].folder ;
483+ locationId = APEntryState .apGame .locationData (songName , modName ).concat (APEntryState .apGame .noteData (songName , modName ));
484+ isMissing = [for (ID in locationId ) APEntryState .apGame .isLocationMissing (APEntryState .apGame .info ().get_location_name (ID ))].indexOf (true ) != - 1 || locationId .length == 0 ;
485+ color = isMissing ? FlxColor .RED : FlxColor .GREEN ;
486+ }
487+
488+ Mods .currentModDirectory = FreeplayManager .songList [i ].folder ;
489+
411490 var songBox : SongBox = new SongBox (320 , 100 );
412491 songBox .loadGraphic (Paths .image (' OSUState/bars/background2' ));
413492 songBox .setGraphicSize (650 , 100 );
414- songBox .setColorTransform (- 1 , - 1 , - 1 , 1 , FreeplayManager .songList [i ].color [0 ][0 ], FreeplayManager .songList [i ].color [0 ][1 ], FreeplayManager .songList [i ].color [0 ][2 ], 1 );
415- songBox. ID = trueInt ;
493+
494+ if (APEntryState .inArchipelagoMode ) {
495+ var isBronze : Bool = FlxG .random .bool (50 ); // Randomly decide between orange and bronze
496+ var bronzeOrOrangeColor : Int = isBronze ? 0xFFCD7F32 : 0xFFFFA500 ; // Bronze or Orange color
497+ songBox .color = FreeplayManager .isVictorySong (songName , modName ) ?
498+ (isMissing ?
499+ (someLocationsNotMissing ?
500+ songBox .color = bronzeOrOrangeColor
501+ : songBox .color = victoryColor )
502+ : songBox .color = 0xFFFFD700 )
503+ : songBox .color = color ;
504+ } else {
505+ songBox .setColorTransform (- 1 , - 1 , - 1 , 1 , FreeplayManager .songList [i ].color [0 ][0 ], FreeplayManager .songList [i ].color [0 ][1 ], FreeplayManager .songList [i ].color [0 ][2 ], 1 );
506+ }
507+ songBox. ID = i ;
416508 this .songBox .add (songBox );
417509
418- var icon : HealthIcon = new HealthIcon (FreeplayManager .songList [i ].songCharacter , false );
510+ var isLock : Bool = APEntryState .inArchipelagoMode && CategoryState .loadWeekForce == " all" && isMissing && ! FreeplayManager .unplayedList .contains (songName );
511+ var icon : HealthIcon = new HealthIcon (isLock ? " lock" : FreeplayManager .songList [i ].songCharacter , false );
419512 icon .setPosition (320 , 100 );
420- icon. ID = trueInt ;
513+ icon. ID = i ;
421514 icon .setGraphicSize (Std .int (icon .width / 1.7 ), Std .int (icon .height / 1.7 ));
422- this . iconGrp .add (icon );
515+ iconGrp .add (icon );
423516
424517 try {metadata = FreeplayManager .metadata .get (FreeplayManager .songList [i ].songName .toLowerCase ());}
425518 catch (e ) {metadata = null ;}
@@ -430,8 +523,8 @@ class OsuFreeplayState extends MusicBeatState
430523 else
431524 text .text = FreeplayManager .songList [i ].songName + ' \n By Unknown' ;
432525 text .alignment = ' left' ;
433- text. ID = trueInt ;
434- this . textGrp .add (text );
526+ text. ID = i ;
527+ textGrp .add (text );
435528
436529 /* var week:WeekData = WeekData.weeksLoaded.get(WeekData.weeksList[FreeplayManager.songList[i].week]);
437530 Difficulty.loadFromWeek(week);
0 commit comments