@@ -3347,8 +3347,14 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
33473347 menubarItemToggleToolboxEventData .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT , event .value );
33483348 menubarItemToggleToolboxFreeplay .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_FREEPLAY_LAYOUT , event .value );
33493349 menubarItemToggleToolboxPlaytestProperties .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_PLAYTEST_PROPERTIES_LAYOUT , event .value );
3350- menubarItemToggleToolboxPlayerPreview .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT , event .value );
3351- menubarItemToggleToolboxOpponentPreview .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT , event .value );
3350+ menubarItemToggleToolboxPlayerPreview .onChange = event -> {
3351+ this .setToolboxState (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT , event .value );
3352+ playerPreviewDirty = event .value ;
3353+ }
3354+ menubarItemToggleToolboxOpponentPreview .onChange = event -> {
3355+ this .setToolboxState (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT , event .value );
3356+ opponentPreviewDirty = event .value ;
3357+ }
33523358
33533359 // TODO: Pass specific HaxeUI components to add context menus to them.
33543360 // registerContextMenu(null, Paths.ui('chart-editor/context/test'));
@@ -3671,7 +3677,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
36713677 var oldStepTime : Float = Conductor .instance .currentStepTime ;
36723678 var oldSongPosition : Float = Conductor .instance .songPosition + Conductor .instance .instrumentalOffset ;
36733679 updateSongTime ();
3674- handleHitsounds (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
3680+ handleMusicPositionUpdate (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
36753681 // Resync vocals.
36763682 if (Math .abs (audioInstTrack .time - audioVocalTrackGroup .time ) > 100 )
36773683 {
@@ -3689,7 +3695,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
36893695 // Else, move the entire view.
36903696 var oldSongPosition : Float = Conductor .instance .songPosition + Conductor .instance .instrumentalOffset ;
36913697 updateSongTime ();
3692- handleHitsounds (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
3698+ handleMusicPositionUpdate (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
36933699 // Resync vocals.
36943700 if (Math .abs (audioInstTrack .time - audioVocalTrackGroup .time ) > 100 )
36953701 {
@@ -3906,7 +3912,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
39063912 // If a new event is needed, call buildEventSprite.
39073913 var eventSprite : ChartEditorEventSprite = renderedEvents .recycle (() -> new ChartEditorEventSprite (this ), false , true );
39083914 eventSprite .parentState = this ;
3909- trace (' Creating new Event... ( ${renderedEvents .members .length })' );
3915+ // trace('Creating new Event... (${renderedEvents.members.length})');
39103916
39113917 if (eventData ?. value != null && (eventData ?. value ?. ease != null && eventData ?. value ?. easeDir == null ))
39123918 {
@@ -5394,8 +5400,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
53945400 function handleToolboxes (): Void
53955401 {
53965402 handleDifficultyToolbox ();
5397- // handlePlayerPreviewToolbox();
5398- // handleOpponentPreviewToolbox();
5403+ handlePlayerPreviewToolbox ();
5404+ handleOpponentPreviewToolbox ();
53995405 }
54005406
54015407 function handleDifficultyToolbox (): Void
@@ -5418,15 +5424,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
54185424 function handlePlayerPreviewToolbox (): Void
54195425 {
54205426 // Manage the Select Difficulty tree view.
5421- var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolbox_OLD (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT );
5427+ var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolboxUnCast (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT );
54225428 if (charPreviewToolbox == null ) return ;
5423-
54245429 // TODO: Re-enable the player preview once we figure out the performance issues.
5425- var charPlayer : Null <CharacterPlayer > = null ; // charPreviewToolbox.findComponent('charPlayer');
5430+ var charPlayer : Null <CharacterPlayer > = charPreviewToolbox .findComponent (' charPlayer' );
54265431 if (charPlayer == null ) return ;
5427-
5428- currentPlayerCharacterPlayer = charPlayer ;
5429-
54305432 if (playerPreviewDirty )
54315433 {
54325434 playerPreviewDirty = false ;
@@ -5444,28 +5446,28 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
54445446 charPlayer .targetScale = 0.5 ;
54455447
54465448 charPreviewToolbox .title = ' Player Preview - ${charPlayer .charName }' ;
5449+ charPreviewToolbox .invalidateComponentLayout ();
54475450 }
5451+ }
54485452
5449- if (charPreviewToolbox != null && ! charPreviewToolbox .minimized )
5450- {
5451- charPreviewToolbox .width = charPlayer .width + 32 ;
5452- charPreviewToolbox .height = charPlayer .height + 64 ;
5453- }
5453+ if (charPreviewToolbox != null && ! charPreviewToolbox .minimized )
5454+ {
5455+ charPreviewToolbox .width = charPlayer .width + 32 ;
5456+ charPreviewToolbox .height = charPlayer .height + 64 ;
54545457 }
5458+ currentPlayerCharacterPlayer = charPlayer ;
54555459 }
54565460
54575461 function handleOpponentPreviewToolbox (): Void
54585462 {
54595463 // Manage the Select Difficulty tree view.
5460- var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolbox_OLD (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT );
5464+ var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolboxUnCast (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT );
54615465 if (charPreviewToolbox == null ) return ;
54625466
54635467 // TODO: Re-enable the player preview once we figure out the performance issues.
5464- var charPlayer : Null <CharacterPlayer > = null ; // charPreviewToolbox.findComponent('charPlayer ');
5468+ var charPlayer : Null <CharacterPlayer > = charPreviewToolbox .findComponent (' charOpponent ' );
54655469 if (charPlayer == null ) return ;
54665470
5467- currentOpponentCharacterPlayer = charPlayer ;
5468-
54695471 if (opponentPreviewDirty )
54705472 {
54715473 opponentPreviewDirty = false ;
@@ -5483,14 +5485,16 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
54835485 charPlayer .targetScale = 0.5 ;
54845486
54855487 charPreviewToolbox .title = ' Opponent Preview - ${charPlayer .charName }' ;
5488+ charPreviewToolbox .invalidateComponentLayout ();
54865489 }
5490+ }
54875491
5488- if (charPreviewToolbox != null && ! charPreviewToolbox .minimized )
5489- {
5490- charPreviewToolbox .width = charPlayer .width + 32 ;
5491- charPreviewToolbox .height = charPlayer .height + 64 ;
5492- }
5492+ if (charPreviewToolbox != null && ! charPreviewToolbox .minimized )
5493+ {
5494+ charPreviewToolbox .width = charPlayer .width + 32 ;
5495+ charPreviewToolbox .height = charPlayer .height + 64 ;
54935496 }
5497+ currentOpponentCharacterPlayer = charPlayer ;
54945498 }
54955499
54965500 function handleSelectionButtons (): Void
@@ -5747,32 +5751,40 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
57475751 /**
57485752 * Handle aligning the health icons next to the grid.
57495753 */
5754+ var _charIconData = null ;
5755+
5756+ @:access (funkin.play.character. BaseCharacter )
57505757 function handleHealthIcons (): Void
57515758 {
57525759 if (healthIconsDirty )
57535760 {
5754- var charDataBF = CharacterDataParser .fetchCharacterData (currentSongMetadata .playData .characters .player );
5755- var charDataDad = CharacterDataParser . fetchCharacterData ( currentSongMetadata . playData . characters . opponent );
5761+ _charIconData = currentPlayerCharacterPlayer ?. character ?. _data ?? CharacterDataParser .fetchCharacterData (currentSongMetadata .playData .characters .player );
5762+
57565763 if (healthIconBF != null )
57575764 {
5758- healthIconBF .configure (charDataBF ?. healthIcon );
5765+ healthIconBF .configure (_charIconData ?. healthIcon );
57595766 healthIconBF .size * = 0.5 ; // Make the icon smaller in Chart Editor.
57605767 healthIconBF .flipX = ! healthIconBF .flipX ; // BF faces the other way.
57615768 }
5769+
57625770 if (buttonSelectPlayer != null )
57635771 {
5764- buttonSelectPlayer .text = charDataBF ?. name ?? ' Player' ;
5772+ buttonSelectPlayer .text = _charIconData ?. name ?? ' Player' ;
57655773 }
5774+
5775+ _charIconData = currentOpponentCharacterPlayer ?. character ?. _data ?? CharacterDataParser .fetchCharacterData (currentSongMetadata .playData .characters .opponent );
5776+
57665777 if (healthIconDad != null )
57675778 {
5768- healthIconDad .configure (charDataDad ?. healthIcon );
5779+ healthIconDad .configure (_charIconData ?. healthIcon );
57695780 healthIconDad .size * = 0.5 ; // Make the icon smaller in Chart Editor.
57705781 }
57715782 if (buttonSelectOpponent != null )
57725783 {
5773- buttonSelectOpponent .text = charDataDad ?. name ?? ' Opponent' ;
5784+ buttonSelectOpponent .text = _charIconData ?. name ?? ' Opponent' ;
57745785 }
57755786 healthIconsDirty = false ;
5787+ _charIconData = null ;
57765788 }
57775789
57785790 // Right align, and visibly center, the BF health icon.
@@ -6820,9 +6832,20 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
68206832 /**
68216833 * Handle the playback of hitsounds.
68226834 */
6823- function handleHitsounds (oldSongPosition : Float , newSongPosition : Float ): Void
6835+ var _scriptNoteObj : NoteSprite = null ;
6836+
6837+ var _noteScriptEvent : NoteScriptEvent = null ;
6838+
6839+ var _currentEvents = null ;
6840+ var _allowedEvents = null ;
6841+ var _eventTarget : Null <CharacterPlayer > = null ;
6842+
6843+ public static var _allowedEventsNames : Array <String > = [' PlayAnimation' ];
6844+
6845+ function handleMusicPositionUpdate (oldSongPosition : Float , newSongPosition : Float ): Void
68246846 {
6825- if (! hitsoundsEnabled ) return ;
6847+ _currentEvents = SongDataUtils .getEventsInTimeRange (currentSongChartEventData , oldSongPosition , newSongPosition );
6848+ _allowedEvents = SongDataUtils .getEventsWithKind (_currentEvents , _allowedEventsNames );
68266849
68276850 // Assume notes are sorted by time.
68286851 for (noteData in currentSongChartNoteData )
@@ -6832,32 +6855,66 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
68326855 if (noteData .time < oldSongPosition ) // Note is in the past.
68336856 continue ;
68346857
6835- if (noteData .time > newSongPosition ) // Note is in the future.
6836- return ; // Assume all notes are also in the future.
6837-
6838- // Note was just hit.
6858+ if (noteData .time > newSongPosition ) break ;
68396859
6840- // Character preview.
6860+ /**
6861+ * We hit a note.
6862+ * We're gonna create scripted event and dispatch it al over ChartEditor.
6863+ */
6864+ _scriptNoteObj = new NoteSprite (NoteStyleRegistry .instance .fetchDefault ());
6865+ _scriptNoteObj .noteData = noteData ;
6866+ _scriptNoteObj .kill ();
6867+ _scriptNoteObj .direction = _scriptNoteObj .noteData ?. getDirection () ?? 0 ;
6868+ _scriptNoteObj .scrollFactor .set ();
68416869
6842- // NoteScriptEvent takes a sprite, ehe. Need to rework that.
6843- var tempNote : NoteSprite = new NoteSprite (NoteStyleRegistry .instance .fetchDefault ());
6844- tempNote .noteData = noteData ;
6845- tempNote .scrollFactor .set (0 , 0 );
6846- var event : NoteScriptEvent = new HitNoteScriptEvent (tempNote , 0.0 , 0 , ' perfect' , false , 0 );
6847- dispatchEvent (event );
6870+ _noteScriptEvent = new HitNoteScriptEvent (_scriptNoteObj , 0.0 , 0 , (noteData .getStrumlineIndex () == 0 ? ' perfect' : ' sick' ), false , 0 );
6871+ dispatchEvent (_noteScriptEvent );
68486872
68496873 // Calling event.cancelEvent() skips all the other logic! Neat!
6850- if (event .eventCanceled ) continue ;
6874+ if (_noteScriptEvent .eventCanceled )
6875+ {
6876+ _scriptNoteObj .destroy ();
6877+ _scriptNoteObj = null ;
6878+
6879+ _noteScriptEvent = null ;
6880+
6881+ continue ;
6882+ }
68516883
68526884 // Hitsounds.
6853- switch (noteData .getStrumlineIndex ())
6885+ if ( hitsoundsEnabled ) switch (noteData .getStrumlineIndex ())
68546886 {
68556887 case 0 : // Player
68566888 if (hitsoundVolumePlayer > 0 ) this .playSound (Paths .sound (' chartingSounds/hitNotePlayer' ), hitsoundVolumePlayer );
68576889 case 1 : // Opponent
68586890 if (hitsoundVolumeOpponent > 0 ) this .playSound (Paths .sound (' chartingSounds/hitNoteOpponent' ), hitsoundVolumeOpponent );
68596891 }
68606892 }
6893+ // Clearing memory before next event call.
6894+ _scriptNoteObj ?. destroy ();
6895+ _scriptNoteObj = null ;
6896+
6897+ _noteScriptEvent = null ;
6898+ for (data in _allowedEvents )
6899+ {
6900+ switch (data .eventKind )
6901+ {
6902+ case " PlayAnimation" :
6903+ switch (data .getString (' target' ).toLowerCase ().trim ())
6904+ {
6905+ case ' boyfriend' | ' bf' | ' player' :
6906+ _eventTarget = currentPlayerCharacterPlayer ;
6907+ case ' dad' | ' opponent' | ' enemy' :
6908+ _eventTarget = currentOpponentCharacterPlayer ;
6909+ default :
6910+ }
6911+ if (_eventTarget != null ) _eventTarget .playAnimManually (data .getString (' anim' ) ?? ' idle' , data .getBool (' force' ) ?? false );
6912+ }
6913+ }
6914+
6915+ _currentEvents = null ;
6916+ _allowedEvents .resize (0 );
6917+ _eventTarget = null ;
68616918 }
68626919
68636920 function stopAudioPlayback (): Void
@@ -6927,6 +6984,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
69276984
69286985 // Many things get reset when song length changes.
69296986 healthIconsDirty = true ;
6987+ playerPreviewDirty = true ;
6988+ opponentPreviewDirty = true ;
69306989 }
69316990
69326991 public function loadSubtitles (): Void
0 commit comments