@@ -3282,8 +3282,14 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
32823282 menubarItemToggleToolboxEventData .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT , event .value );
32833283 menubarItemToggleToolboxFreeplay .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_FREEPLAY_LAYOUT , event .value );
32843284 menubarItemToggleToolboxPlaytestProperties .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_PLAYTEST_PROPERTIES_LAYOUT , event .value );
3285- menubarItemToggleToolboxPlayerPreview .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT , event .value );
3286- menubarItemToggleToolboxOpponentPreview .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT , event .value );
3285+ menubarItemToggleToolboxPlayerPreview .onChange = event -> {
3286+ this .setToolboxState (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT , event .value );
3287+ playerPreviewDirty = event .value ;
3288+ }
3289+ menubarItemToggleToolboxOpponentPreview .onChange = event -> {
3290+ this .setToolboxState (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT , event .value );
3291+ opponentPreviewDirty = event .value ;
3292+ }
32873293
32883294 // TODO: Pass specific HaxeUI components to add context menus to them.
32893295 // registerContextMenu(null, Paths.ui('chart-editor/context/test'));
@@ -3506,6 +3512,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
35063512 handleToolboxes ();
35073513 handlePlaybar ();
35083514 handleNotePreview ();
3515+ // handleCharacters();
35093516 handleHealthIcons ();
35103517
35113518 handleFileKeybinds ();
@@ -3606,7 +3613,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
36063613 var oldStepTime : Float = Conductor .instance .currentStepTime ;
36073614 var oldSongPosition : Float = Conductor .instance .songPosition + Conductor .instance .instrumentalOffset ;
36083615 updateSongTime ();
3609- handleHitsounds (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
3616+ handleMusicPositionUpdate (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
36103617 // Resync vocals.
36113618 if (Math .abs (audioInstTrack .time - audioVocalTrackGroup .time ) > 100 )
36123619 {
@@ -3624,7 +3631,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
36243631 // Else, move the entire view.
36253632 var oldSongPosition : Float = Conductor .instance .songPosition + Conductor .instance .instrumentalOffset ;
36263633 updateSongTime ();
3627- handleHitsounds (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
3634+ handleMusicPositionUpdate (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
36283635 // Resync vocals.
36293636 if (Math .abs (audioInstTrack .time - audioVocalTrackGroup .time ) > 100 )
36303637 {
@@ -3844,7 +3851,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
38443851 // If a new event is needed, call buildEventSprite.
38453852 var eventSprite : ChartEditorEventSprite = renderedEvents .recycle (() -> new ChartEditorEventSprite (this ), false , true );
38463853 eventSprite .parentState = this ;
3847- trace (' Creating new Event... ( ${renderedEvents .members .length })' );
3854+ // trace('Creating new Event... (${renderedEvents.members.length})');
38483855
38493856 // The event sprite handles animation playback and positioning.
38503857 eventSprite .eventData = eventData ;
@@ -5314,8 +5321,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
53145321 function handleToolboxes (): Void
53155322 {
53165323 handleDifficultyToolbox ();
5317- // handlePlayerPreviewToolbox();
5318- // handleOpponentPreviewToolbox();
5324+ handlePlayerPreviewToolbox ();
5325+ handleOpponentPreviewToolbox ();
53195326 }
53205327
53215328 function handleDifficultyToolbox (): Void
@@ -5338,15 +5345,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
53385345 function handlePlayerPreviewToolbox (): Void
53395346 {
53405347 // Manage the Select Difficulty tree view.
5341- var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolbox_OLD (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT );
5348+ var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolboxUnCast (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT );
53425349 if (charPreviewToolbox == null ) return ;
5343-
53445350 // TODO: Re-enable the player preview once we figure out the performance issues.
5345- var charPlayer : Null <CharacterPlayer > = null ; // charPreviewToolbox.findComponent('charPlayer');
5351+ var charPlayer : Null <CharacterPlayer > = charPreviewToolbox .findComponent (' charPlayer' );
53465352 if (charPlayer == null ) return ;
5347-
5348- currentPlayerCharacterPlayer = charPlayer ;
5349-
53505353 if (playerPreviewDirty )
53515354 {
53525355 playerPreviewDirty = false ;
@@ -5364,28 +5367,28 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
53645367 charPlayer .targetScale = 0.5 ;
53655368
53665369 charPreviewToolbox .title = ' Player Preview - ${charPlayer .charName }' ;
5370+ charPreviewToolbox .invalidateComponentLayout ();
53675371 }
53685372
53695373 if (charPreviewToolbox != null && ! charPreviewToolbox .minimized )
53705374 {
53715375 charPreviewToolbox .width = charPlayer .width + 32 ;
53725376 charPreviewToolbox .height = charPlayer .height + 64 ;
53735377 }
5378+ currentPlayerCharacterPlayer = charPlayer ;
53745379 }
53755380 }
53765381
53775382 function handleOpponentPreviewToolbox (): Void
53785383 {
53795384 // Manage the Select Difficulty tree view.
5380- var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolbox_OLD (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT );
5385+ var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolboxUnCast (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT );
53815386 if (charPreviewToolbox == null ) return ;
53825387
53835388 // TODO: Re-enable the player preview once we figure out the performance issues.
5384- var charPlayer : Null <CharacterPlayer > = null ; // charPreviewToolbox.findComponent('charPlayer ');
5389+ var charPlayer : Null <CharacterPlayer > = charPreviewToolbox .findComponent (' charOpponent ' );
53855390 if (charPlayer == null ) return ;
53865391
5387- currentOpponentCharacterPlayer = charPlayer ;
5388-
53895392 if (opponentPreviewDirty )
53905393 {
53915394 opponentPreviewDirty = false ;
@@ -5403,13 +5406,15 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
54035406 charPlayer .targetScale = 0.5 ;
54045407
54055408 charPreviewToolbox .title = ' Opponent Preview - ${charPlayer .charName }' ;
5409+ charPreviewToolbox .invalidateComponentLayout ();
54065410 }
54075411
54085412 if (charPreviewToolbox != null && ! charPreviewToolbox .minimized )
54095413 {
54105414 charPreviewToolbox .width = charPlayer .width + 32 ;
54115415 charPreviewToolbox .height = charPlayer .height + 64 ;
54125416 }
5417+ currentOpponentCharacterPlayer = charPlayer ;
54135418 }
54145419 }
54155420
@@ -5667,32 +5672,40 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
56675672 /**
56685673 * Handle aligning the health icons next to the grid.
56695674 */
5675+ var _charIconData = null ;
5676+
5677+ @:access (funkin.play.character. BaseCharacter )
56705678 function handleHealthIcons (): Void
56715679 {
56725680 if (healthIconsDirty )
56735681 {
5674- var charDataBF = CharacterDataParser .fetchCharacterData (currentSongMetadata .playData .characters .player );
5675- var charDataDad = CharacterDataParser . fetchCharacterData ( currentSongMetadata . playData . characters . opponent );
5682+ _charIconData = currentPlayerCharacterPlayer ?. character ?. _data ?? CharacterDataParser .fetchCharacterData (currentSongMetadata .playData .characters .player );
5683+
56765684 if (healthIconBF != null )
56775685 {
5678- healthIconBF .configure (charDataBF ?. healthIcon );
5686+ healthIconBF .configure (_charIconData ?. healthIcon );
56795687 healthIconBF .size * = 0.5 ; // Make the icon smaller in Chart Editor.
56805688 healthIconBF .flipX = ! healthIconBF .flipX ; // BF faces the other way.
56815689 }
5690+
56825691 if (buttonSelectPlayer != null )
56835692 {
5684- buttonSelectPlayer .text = charDataBF ?. name ?? ' Player' ;
5693+ buttonSelectPlayer .text = _charIconData ?. name ?? ' Player' ;
56855694 }
5695+
5696+ _charIconData = currentOpponentCharacterPlayer ?. character ?. _data ?? CharacterDataParser .fetchCharacterData (currentSongMetadata .playData .characters .opponent );
5697+
56865698 if (healthIconDad != null )
56875699 {
5688- healthIconDad .configure (charDataDad ?. healthIcon );
5700+ healthIconDad .configure (_charIconData ?. healthIcon );
56895701 healthIconDad .size * = 0.5 ; // Make the icon smaller in Chart Editor.
56905702 }
56915703 if (buttonSelectOpponent != null )
56925704 {
5693- buttonSelectOpponent .text = charDataDad ?. name ?? ' Opponent' ;
5705+ buttonSelectOpponent .text = _charIconData ?. name ?? ' Opponent' ;
56945706 }
56955707 healthIconsDirty = false ;
5708+ _charIconData = null ;
56965709 }
56975710
56985711 // Right align, and visibly center, the BF health icon.
@@ -6740,9 +6753,20 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
67406753 /**
67416754 * Handle the playback of hitsounds.
67426755 */
6743- function handleHitsounds (oldSongPosition : Float , newSongPosition : Float ): Void
6756+ var _scriptNoteObj : NoteSprite = null ;
6757+
6758+ var _noteScriptEvent : NoteScriptEvent = null ;
6759+
6760+ var _currentEvents = null ;
6761+ var _allowedEvents = null ;
6762+ var _eventTarget : Null <CharacterPlayer > = null ;
6763+
6764+ public static var _allowedEventsNames : Array <String > = [' PlayAnimation' ];
6765+
6766+ function handleMusicPositionUpdate (oldSongPosition : Float , newSongPosition : Float ): Void
67446767 {
6745- if (! hitsoundsEnabled ) return ;
6768+ _currentEvents = SongDataUtils .getEventsInTimeRange (currentSongChartEventData , oldSongPosition , newSongPosition );
6769+ _allowedEvents = SongDataUtils .getEventsWithKind (_currentEvents , _allowedEventsNames );
67466770
67476771 // Assume notes are sorted by time.
67486772 for (noteData in currentSongChartNoteData )
@@ -6752,32 +6776,66 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
67526776 if (noteData .time < oldSongPosition ) // Note is in the past.
67536777 continue ;
67546778
6755- if (noteData .time > newSongPosition ) // Note is in the future.
6756- return ; // Assume all notes are also in the future.
6779+ if (noteData .time > newSongPosition ) break ;
67576780
6758- // Note was just hit.
6781+ /**
6782+ * We hit a note.
6783+ * We're gonna create scripted event and dispatch it al over ChartEditor.
6784+ */
6785+ _scriptNoteObj = new NoteSprite (NoteStyleRegistry .instance .fetchDefault ());
6786+ _scriptNoteObj .noteData = noteData ;
6787+ _scriptNoteObj .kill ();
6788+ _scriptNoteObj .direction = _scriptNoteObj .noteData ?. getDirection () ?? 0 ;
6789+ _scriptNoteObj .scrollFactor .set ();
67596790
6760- // Character preview.
6761-
6762- // NoteScriptEvent takes a sprite, ehe. Need to rework that.
6763- var tempNote : NoteSprite = new NoteSprite (NoteStyleRegistry .instance .fetchDefault ());
6764- tempNote .noteData = noteData ;
6765- tempNote .scrollFactor .set (0 , 0 );
6766- var event : NoteScriptEvent = new HitNoteScriptEvent (tempNote , 0.0 , 0 , ' perfect' , false , 0 );
6767- dispatchEvent (event );
6791+ _noteScriptEvent = new HitNoteScriptEvent (_scriptNoteObj , 0.0 , 0 , (noteData .getStrumlineIndex () == 0 ? ' perfect' : ' sick' ), false , 0 );
6792+ dispatchEvent (_noteScriptEvent );
67686793
67696794 // Calling event.cancelEvent() skips all the other logic! Neat!
6770- if (event .eventCanceled ) continue ;
6795+ if (_noteScriptEvent .eventCanceled )
6796+ {
6797+ _scriptNoteObj .destroy ();
6798+ _scriptNoteObj = null ;
6799+
6800+ _noteScriptEvent = null ;
6801+
6802+ continue ;
6803+ }
67716804
67726805 // Hitsounds.
6773- switch (noteData .getStrumlineIndex ())
6806+ if ( hitsoundsEnabled ) switch (noteData .getStrumlineIndex ())
67746807 {
67756808 case 0 : // Player
67766809 if (hitsoundVolumePlayer > 0 ) this .playSound (Paths .sound (' chartingSounds/hitNotePlayer' ), hitsoundVolumePlayer );
67776810 case 1 : // Opponent
67786811 if (hitsoundVolumeOpponent > 0 ) this .playSound (Paths .sound (' chartingSounds/hitNoteOpponent' ), hitsoundVolumeOpponent );
67796812 }
67806813 }
6814+ // Clearing memory before next event call.
6815+ _scriptNoteObj ?. destroy ();
6816+ _scriptNoteObj = null ;
6817+
6818+ _noteScriptEvent = null ;
6819+ for (data in _allowedEvents )
6820+ {
6821+ switch (data .eventKind )
6822+ {
6823+ case " PlayAnimation" :
6824+ switch (data .getString (' target' ).toLowerCase ().trim ())
6825+ {
6826+ case ' boyfriend' | ' bf' | ' player' :
6827+ _eventTarget = currentPlayerCharacterPlayer ;
6828+ case ' dad' | ' opponent' | ' enemy' :
6829+ _eventTarget = currentOpponentCharacterPlayer ;
6830+ default :
6831+ }
6832+ if (_eventTarget != null ) _eventTarget .playAnimManually (data .getString (' anim' ) ?? ' idle' , data .getBool (' force' ) ?? false );
6833+ }
6834+ }
6835+
6836+ _currentEvents = null ;
6837+ _allowedEvents .resize (0 );
6838+ _eventTarget = null ;
67816839 }
67826840
67836841 function stopAudioPlayback (): Void
@@ -6847,6 +6905,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
68476905
68486906 // Many things get reset when song length changes.
68496907 healthIconsDirty = true ;
6908+ playerPreviewDirty = true ;
6909+ opponentPreviewDirty = true ;
68506910 }
68516911
68526912 public function postLoadVocals (): Void
0 commit comments