@@ -159,6 +159,8 @@ class APAdvancedSettingsState extends MusicBeatState
159159 // Sanity settings
160160 var stagesanity : Bool = false ;
161161 var charactersanity : Bool = false ;
162+ var enable_sanity_locations : Bool = false ;
163+ var sanity_completion_type : String = " on_getting" ;
162164
163165 // Filler/Trap weight settings
164166 var bbcWeight : Int = 3 ;
@@ -189,6 +191,12 @@ class APAdvancedSettingsState extends MusicBeatState
189191 var isAnimating : Bool = false ;
190192 var transitionTime : Float = 0.3 ;
191193
194+ // Refresh queue system - waits for all tweens to complete
195+ var refreshQueued : Bool = false ;
196+ var activeTweens : Array <FlxTween > = [];
197+ var tweenCheckTimer : Float = 0 ;
198+ var tweenCheckInterval : Float = 0.1 ; // Check every 100ms
199+
192200 // Temporary save system for state navigation
193201 static var tempSave : FlxSave ;
194202 static var tempSaveData : Dynamic ;
@@ -428,6 +436,21 @@ class APAdvancedSettingsState extends MusicBeatState
428436 MHPWeight = value ;
429437 case " MHPDWeight" :
430438 MHPDWeight = value ;
439+ // Sanity settings
440+ case " enable_sanity_locations" :
441+ enable_sanity_locations = value == true ;
442+ case " sanity_completion_type" :
443+ var completionType = Std .string (value );
444+ if ([" on_getting" , " on_playing" , " on_beating" ].indexOf (completionType ) != - 1 ) {
445+ sanity_completion_type = completionType ;
446+ } else {
447+ trace (' Invalid sanity_completion_type: $completionType , using default: on_getting' );
448+ sanity_completion_type = " on_getting" ;
449+ }
450+ case " stagesanity" :
451+ stagesanity = value == true ;
452+ case " charactersanity" :
453+ charactersanity = value == true ;
431454 // Handle any other potential fields that might exist
432455 default :
433456 trace (' Unknown YAML field during import: $field = $value ' );
@@ -788,33 +811,60 @@ class APAdvancedSettingsState extends MusicBeatState
788811 }
789812 ];
790813
791- // Sanity Options Page
792- var sanityOptions : Array <SettingsOption > = [
793- {
794- name : " Stagesanity" ,
795- description : " Enable stage-based items. Creates location checks for stages used in songs." ,
796- callback : function () {
797- stagesanity = ! stagesanity ;
798- refreshCurrentPage ();
799- },
800- locked : false ,
801- contextMenu : createBoolContextMenu (stagesanity , function (value : Bool ) {
802- stagesanity = value ;
803- })
814+ // Sanity Options Page - dynamically build based on enabled sanity types
815+ var sanityOptions : Array <SettingsOption > = [];
816+
817+ // Always show the individual sanity type toggles first
818+ sanityOptions .push ({
819+ name : " Stagesanity" ,
820+ description : " Enable stage-based items. Creates location checks for stages used in songs." ,
821+ callback : function () {
822+ stagesanity = ! stagesanity ;
823+ refreshCurrentPage ();
804824 },
805- {
806- name : " Charactersanity" ,
807- description : " Enable character-based items. Creates location checks for characters used in songs." ,
808- callback : function () {
809- charactersanity = ! charactersanity ;
810- refreshCurrentPage ();
811- },
812- locked : false ,
813- contextMenu : createBoolContextMenu (charactersanity , function (value : Bool ) {
814- charactersanity = value ;
815- })
816- }
817- ];
825+ locked : false ,
826+ contextMenu : createBoolContextMenu (stagesanity , function (value : Bool ) {
827+ stagesanity = value ;
828+ // Don't refresh here - the main callback will handle it
829+ })
830+ });
831+
832+ sanityOptions .push ({
833+ name : " Charactersanity" ,
834+ description : " Enable character-based items. Creates location checks for characters used in songs." ,
835+ callback : function () {
836+ charactersanity = ! charactersanity ;
837+ refreshCurrentPage ();
838+ },
839+ locked : false ,
840+ contextMenu : createBoolContextMenu (charactersanity , function (value : Bool ) {
841+ charactersanity = value ;
842+ // Don't refresh here - the main callback will handle it
843+ })
844+ });
845+
846+ // Always show location options (they control whether locations are created)
847+ // The user should be able to configure these even if no sanity types are currently enabled
848+ sanityOptions .push ({
849+ name : " Enable Sanity Locations" ,
850+ description : " Enable or disable all sanity location types globally" ,
851+ callback : function () {
852+ enable_sanity_locations = ! enable_sanity_locations ;
853+ refreshCurrentPage ();
854+ },
855+ locked : false ,
856+ contextMenu : createBoolContextMenu (enable_sanity_locations , function (value : Bool ) {
857+ enable_sanity_locations = value ;
858+ })
859+ });
860+
861+ sanityOptions .push ({
862+ name : " Sanity Completion Type" ,
863+ description : " How sanity locations are accessed: on_getting, on_playing, or on_beating" ,
864+ callback : () -> cycleSanityCompletionType (),
865+ locked : false ,
866+ contextMenu : createEnumContextMenu ([" on_getting" , " on_playing" , " on_beating" ], sanity_completion_type , (value ) -> sanity_completion_type = value )
867+ });
818868
819869 // Example state options (you can add actual complex settings states here)
820870 var exampleStateOptions : Array <StateOption > = [
@@ -1439,6 +1489,8 @@ class APAdvancedSettingsState extends MusicBeatState
14391489 case " Max HP Up Weight" : Std .string (MHPWeight );
14401490 case " Max HP Down Weight" : Std .string (MHPDWeight );
14411491 case " Extra Life Weight" : Std .string (exLifeWeight );
1492+ case " Enable Sanity Locations" : enable_sanity_locations ? " ON" : " OFF" ;
1493+ case " Sanity Completion Type" : sanity_completion_type ;
14421494 case " Stagesanity" : stagesanity ? " ON" : " OFF" ;
14431495 case " Charactersanity" : charactersanity ? " ON" : " OFF" ;
14441496 default : " " ;
@@ -1490,17 +1542,18 @@ class APAdvancedSettingsState extends MusicBeatState
14901542 targetX = 100 ;
14911543 }
14921544
1493- FlxTween .tween (button , {x : targetX }, transitionTime + (i * 0.05 ), {
1545+ trackTween ( FlxTween .tween (button , {x : targetX }, transitionTime + (i * 0.05 ), {
14941546 ease : FlxEase .backOut ,
1495- onComplete : function (_ )
1547+ onComplete : function (tween : FlxTween )
14961548 {
14971549 completedAnimations ++ ;
1550+ activeTweens .remove (tween ); // Remove from tracking when complete
14981551 if (completedAnimations == totalAnimations )
14991552 {
15001553 isAnimating = false ;
15011554 }
15021555 }
1503- });
1556+ })) ;
15041557 }
15051558 }
15061559
@@ -1546,9 +1599,9 @@ class APAdvancedSettingsState extends MusicBeatState
15461599 }
15471600 }
15481601
1549- FlxTween .tween (text , {x : targetX }, transitionTime + (i * 0.05 ), {
1602+ trackTween ( FlxTween .tween (text , {x : targetX }, transitionTime + (i * 0.05 ), {
15501603 ease : FlxEase .backOut
1551- });
1604+ })) ;
15521605 }
15531606 }
15541607 }
@@ -1557,20 +1610,20 @@ class APAdvancedSettingsState extends MusicBeatState
15571610 {
15581611 // Animate UI elements in
15591612 titleText .y = - 100 ;
1560- FlxTween .tween (titleText , {y : 30 }, 0.8 , {ease : FlxEase .backOut });
1613+ trackTween ( FlxTween .tween (titleText , {y : 30 }, 0.8 , {ease : FlxEase .backOut }) );
15611614
15621615 descriptionText .alpha = 0 ;
1563- FlxTween .tween (descriptionText , {alpha : 1 }, 1.2 , {ease : FlxEase .sineOut });
1616+ trackTween ( FlxTween .tween (descriptionText , {alpha : 1 }, 1.2 , {ease : FlxEase .sineOut }) );
15641617
15651618 leftArrow .x = - 100 ;
15661619 rightArrow .x = FlxG .width + 100 ;
1567- FlxTween .tween (leftArrow , {x : 30 }, 1 , {ease : FlxEase .backOut });
1568- FlxTween .tween (rightArrow , {x : FlxG .width - 80 }, 1 , {ease : FlxEase .backOut });
1620+ trackTween ( FlxTween .tween (leftArrow , {x : 30 }, 1 , {ease : FlxEase .backOut }) );
1621+ trackTween ( FlxTween .tween (rightArrow , {x : FlxG .width - 80 }, 1 , {ease : FlxEase .backOut }) );
15691622
15701623 exportButton .y = FlxG .height + 50 ;
15711624 closeButton .y = FlxG .height + 50 ;
1572- FlxTween .tween (exportButton , {y : FlxG .height - 80 }, 1.2 , {ease : FlxEase .backOut });
1573- FlxTween .tween (closeButton , {y : FlxG .height - 80 }, 1.2 , {ease : FlxEase .backOut });
1625+ trackTween ( FlxTween .tween (exportButton , {y : FlxG .height - 80 }, 1.2 , {ease : FlxEase .backOut }) );
1626+ trackTween ( FlxTween .tween (closeButton , {y : FlxG .height - 80 }, 1.2 , {ease : FlxEase .backOut }) );
15741627 }
15751628
15761629 // Settings adjustment functions
@@ -1617,6 +1670,14 @@ class APAdvancedSettingsState extends MusicBeatState
16171670 accRequirement = options [(current + 1 ) % options .length ];
16181671 }
16191672
1673+ function cycleSanityCompletionType ()
1674+ {
1675+ var options = [" on_getting" , " on_playing" , " on_beating" ];
1676+ var current = options .indexOf (sanity_completion_type );
1677+ sanity_completion_type = options [(current + 1 ) % options .length ];
1678+ refreshCurrentPage ();
1679+ }
1680+
16201681 function openPlayerNameInput ()
16211682 {
16221683 var nameInput = new TextInputSubstate (" Player Name" , playerName , function (newName : String )
@@ -2055,12 +2116,32 @@ class APAdvancedSettingsState extends MusicBeatState
20552116 }
20562117 }
20572118
2119+ function trackTween (tween : FlxTween ): FlxTween
2120+ {
2121+ activeTweens .push (tween );
2122+ return tween ;
2123+ }
2124+
20582125 function refreshCurrentPage ()
20592126 {
2127+ // Check if tweens are active or refresh already queued
2128+ if (activeTweens .length > 0 )
2129+ {
2130+ if (! refreshQueued )
2131+ {
2132+ refreshQueued = true ;
2133+ trace (' Refresh queued - waiting for ${activeTweens .length } active tweens to complete' );
2134+ }
2135+ return ;
2136+ }
2137+
20602138 // Only refresh if UI has been set up
20612139 if (statsText == null )
20622140 return ;
20632141
2142+ // Clear queue flag since we're executing now
2143+ refreshQueued = false ;
2144+
20642145 loadPage (currentPage );
20652146 updateSongStats ();
20662147 saveTempData (); // Save changes
@@ -2552,6 +2633,8 @@ class APAdvancedSettingsState extends MusicBeatState
25522633 victorySong = settings .victory_song != null ? settings .victory_song : " Tutorial" ;
25532634
25542635 // Sanity settings with defaults
2636+ enable_sanity_locations = Reflect .hasField (settings , " enable_sanity_locations" ) ? Reflect .field (settings , " enable_sanity_locations" ) : false ;
2637+ sanity_completion_type = Reflect .hasField (settings , " sanity_completion_type" ) ? Reflect .field (settings , " sanity_completion_type" ) : " on_getting" ;
25552638 stagesanity = Reflect .hasField (settings , " stagesanity" ) ? settings .stagesanity : false ;
25562639 charactersanity = Reflect .hasField (settings , " charactersanity" ) ? settings .charactersanity : false ;
25572640 }
@@ -2602,6 +2685,8 @@ class APAdvancedSettingsState extends MusicBeatState
26022685 settings .exLifeWeight = exLifeWeight ;
26032686
26042687 // Save sanity settings
2688+ Reflect .setField (settings , " enable_sanity_locations" , enable_sanity_locations );
2689+ Reflect .setField (settings , " sanity_completion_type" , sanity_completion_type );
26052690 settings .stagesanity = stagesanity ;
26062691 settings .charactersanity = charactersanity ;
26072692 }
@@ -3150,6 +3235,8 @@ class APAdvancedSettingsState extends MusicBeatState
31503235 Reflect .setField (yamlThing , " include_pico" , includePico );
31513236 Reflect .setField (yamlThing , " include_erect" , includeErect );
31523237 Reflect .setField (yamlThing , " include_vanilla" , includeVanilla );
3238+ Reflect .setField (yamlThing , " enable_sanity_locations" , enable_sanity_locations );
3239+ Reflect .setField (yamlThing , " sanity_completion_type" , sanity_completion_type );
31533240 Reflect .setField (yamlThing , " stagesanity" , stagesanity );
31543241 Reflect .setField (yamlThing , " charactersanity" , charactersanity );
31553242 if (startingSong != null )
@@ -3299,6 +3386,8 @@ class APAdvancedSettingsState extends MusicBeatState
32993386 Reflect .setField (yamlThing , " include_pico" , includePico );
33003387 Reflect .setField (yamlThing , " include_erect" , includeErect );
33013388 Reflect .setField (yamlThing , " include_vanilla" , includeVanilla );
3389+ Reflect .setField (yamlThing , " enable_sanity_locations" , enable_sanity_locations );
3390+ Reflect .setField (yamlThing , " sanity_completion_type" , sanity_completion_type );
33023391 Reflect .setField (yamlThing , " stagesanity" , stagesanity );
33033392 Reflect .setField (yamlThing , " charactersanity" , charactersanity );
33043393 if (startingSong != null )
@@ -3701,6 +3790,25 @@ class APAdvancedSettingsState extends MusicBeatState
37013790 navigationCooldown - = elapsed ;
37023791 }
37033792
3793+ // Check for completed tweens and manage refresh queue
3794+ tweenCheckTimer + = elapsed ;
3795+ if (tweenCheckTimer >= tweenCheckInterval )
3796+ {
3797+ tweenCheckTimer = 0 ;
3798+
3799+ // Remove completed tweens from tracking
3800+ activeTweens = activeTweens .filter (function (tween : FlxTween ) {
3801+ return ! tween .finished ;
3802+ });
3803+
3804+ // If refresh is queued and no active tweens, execute refresh
3805+ if (refreshQueued && activeTweens .length == 0 )
3806+ {
3807+ trace (' All tweens completed - executing queued refresh' );
3808+ refreshCurrentPage ();
3809+ }
3810+ }
3811+
37043812 // Handle slider updates if one is active
37053813 if (isSliderActive && sliderUpdateFunc != null )
37063814 {
@@ -3963,6 +4071,8 @@ class APAdvancedSettingsState extends MusicBeatState
39634071 MHPDWeight : MHPDWeight ,
39644072 exLifeWeight : exLifeWeight ,
39654073 // Sanity settings
4074+ enable_sanity_locations : enable_sanity_locations ,
4075+ sanity_completion_type : sanity_completion_type ,
39664076 stagesanity : stagesanity ,
39674077 charactersanity : charactersanity
39684078 };
@@ -4034,6 +4144,10 @@ class APAdvancedSettingsState extends MusicBeatState
40344144 exLifeWeight = data .exLifeWeight ;
40354145
40364146 // Load sanity settings
4147+ if (Reflect .hasField (data , " enable_sanity_locations" ))
4148+ enable_sanity_locations = data .enable_sanity_locations ;
4149+ if (Reflect .hasField (data , " sanity_completion_type" ))
4150+ sanity_completion_type = data .sanity_completion_type ;
40374151 if (Reflect .hasField (data , " stagesanity" ))
40384152 stagesanity = data .stagesanity ;
40394153 if (Reflect .hasField (data , " charactersanity" ))
0 commit comments