@@ -3345,8 +3345,14 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
33453345 menubarItemToggleToolboxEventData .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT , event .value );
33463346 menubarItemToggleToolboxFreeplay .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_FREEPLAY_LAYOUT , event .value );
33473347 menubarItemToggleToolboxPlaytestProperties .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_PLAYTEST_PROPERTIES_LAYOUT , event .value );
3348- menubarItemToggleToolboxPlayerPreview .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT , event .value );
3349- menubarItemToggleToolboxOpponentPreview .onChange = event -> this .setToolboxState (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT , event .value );
3348+ menubarItemToggleToolboxPlayerPreview .onChange = event -> {
3349+ this .setToolboxState (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT , event .value );
3350+ playerPreviewDirty = event .value ;
3351+ }
3352+ menubarItemToggleToolboxOpponentPreview .onChange = event -> {
3353+ this .setToolboxState (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT , event .value );
3354+ opponentPreviewDirty = event .value ;
3355+ }
33503356
33513357 // TODO: Pass specific HaxeUI components to add context menus to them.
33523358 // registerContextMenu(null, Paths.ui('chart-editor/context/test'));
@@ -3669,7 +3675,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
36693675 var oldStepTime : Float = Conductor .instance .currentStepTime ;
36703676 var oldSongPosition : Float = Conductor .instance .songPosition + Conductor .instance .instrumentalOffset ;
36713677 updateSongTime ();
3672- handleHitsounds (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
3678+ handleMusicPositionUpdate (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
36733679 // Resync vocals.
36743680 if (Math .abs (audioInstTrack .time - audioVocalTrackGroup .time ) > 100 )
36753681 {
@@ -3687,7 +3693,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
36873693 // Else, move the entire view.
36883694 var oldSongPosition : Float = Conductor .instance .songPosition + Conductor .instance .instrumentalOffset ;
36893695 updateSongTime ();
3690- handleHitsounds (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
3696+ handleMusicPositionUpdate (oldSongPosition , Conductor .instance .songPosition + Conductor .instance .instrumentalOffset );
36913697 // Resync vocals.
36923698 if (Math .abs (audioInstTrack .time - audioVocalTrackGroup .time ) > 100 )
36933699 {
@@ -3904,7 +3910,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
39043910 // If a new event is needed, call buildEventSprite.
39053911 var eventSprite : ChartEditorEventSprite = renderedEvents .recycle (() -> new ChartEditorEventSprite (this ), false , true );
39063912 eventSprite .parentState = this ;
3907- trace (' Creating new Event... ( ${renderedEvents .members .length })' );
3913+ // trace('Creating new Event... (${renderedEvents.members.length})');
39083914
39093915 if (eventData ?. value != null && (eventData ?. value ?. ease != null && eventData ?. value ?. easeDir == null ))
39103916 {
@@ -5392,8 +5398,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
53925398 function handleToolboxes (): Void
53935399 {
53945400 handleDifficultyToolbox ();
5395- // handlePlayerPreviewToolbox();
5396- // handleOpponentPreviewToolbox();
5401+ handlePlayerPreviewToolbox ();
5402+ handleOpponentPreviewToolbox ();
53975403 }
53985404
53995405 function handleDifficultyToolbox (): Void
@@ -5416,15 +5422,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
54165422 function handlePlayerPreviewToolbox (): Void
54175423 {
54185424 // Manage the Select Difficulty tree view.
5419- var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolbox_OLD (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT );
5425+ var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolboxUnCast (CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT );
54205426 if (charPreviewToolbox == null ) return ;
5421-
54225427 // TODO: Re-enable the player preview once we figure out the performance issues.
5423- var charPlayer : Null <CharacterPlayer > = null ; // charPreviewToolbox.findComponent('charPlayer');
5428+ var charPlayer : Null <CharacterPlayer > = charPreviewToolbox .findComponent (' charPlayer' );
54245429 if (charPlayer == null ) return ;
5425-
5426- currentPlayerCharacterPlayer = charPlayer ;
5427-
54285430 if (playerPreviewDirty )
54295431 {
54305432 playerPreviewDirty = false ;
@@ -5442,28 +5444,28 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
54425444 charPlayer .targetScale = 0.5 ;
54435445
54445446 charPreviewToolbox .title = ' Player Preview - ${charPlayer .charName }' ;
5447+ charPreviewToolbox .invalidateComponentLayout ();
54455448 }
54465449
54475450 if (charPreviewToolbox != null && ! charPreviewToolbox .minimized )
54485451 {
54495452 charPreviewToolbox .width = charPlayer .width + 32 ;
54505453 charPreviewToolbox .height = charPlayer .height + 64 ;
54515454 }
5455+ currentPlayerCharacterPlayer = charPlayer ;
54525456 }
54535457 }
54545458
54555459 function handleOpponentPreviewToolbox (): Void
54565460 {
54575461 // Manage the Select Difficulty tree view.
5458- var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolbox_OLD (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT );
5462+ var charPreviewToolbox : Null <CollapsibleDialog > = this .getToolboxUnCast (CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT );
54595463 if (charPreviewToolbox == null ) return ;
54605464
54615465 // TODO: Re-enable the player preview once we figure out the performance issues.
5462- var charPlayer : Null <CharacterPlayer > = null ; // charPreviewToolbox.findComponent('charPlayer ');
5466+ var charPlayer : Null <CharacterPlayer > = charPreviewToolbox .findComponent (' charOpponent ' );
54635467 if (charPlayer == null ) return ;
54645468
5465- currentOpponentCharacterPlayer = charPlayer ;
5466-
54675469 if (opponentPreviewDirty )
54685470 {
54695471 opponentPreviewDirty = false ;
@@ -5481,13 +5483,15 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
54815483 charPlayer .targetScale = 0.5 ;
54825484
54835485 charPreviewToolbox .title = ' Opponent Preview - ${charPlayer .charName }' ;
5486+ charPreviewToolbox .invalidateComponentLayout ();
54845487 }
54855488
54865489 if (charPreviewToolbox != null && ! charPreviewToolbox .minimized )
54875490 {
54885491 charPreviewToolbox .width = charPlayer .width + 32 ;
54895492 charPreviewToolbox .height = charPlayer .height + 64 ;
54905493 }
5494+ currentOpponentCharacterPlayer = charPlayer ;
54915495 }
54925496 }
54935497
@@ -5745,32 +5749,40 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
57455749 /**
57465750 * Handle aligning the health icons next to the grid.
57475751 */
5752+ var _charIconData = null ;
5753+
5754+ @:access (funkin.play.character. BaseCharacter )
57485755 function handleHealthIcons (): Void
57495756 {
57505757 if (healthIconsDirty )
57515758 {
5752- var charDataBF = CharacterDataParser .fetchCharacterData (currentSongMetadata .playData .characters .player );
5753- var charDataDad = CharacterDataParser . fetchCharacterData ( currentSongMetadata . playData . characters . opponent );
5759+ _charIconData = currentPlayerCharacterPlayer ?. character ?. _data ?? CharacterDataParser .fetchCharacterData (currentSongMetadata .playData .characters .player );
5760+
57545761 if (healthIconBF != null )
57555762 {
5756- healthIconBF .configure (charDataBF ?. healthIcon );
5763+ healthIconBF .configure (_charIconData ?. healthIcon );
57575764 healthIconBF .size * = 0.5 ; // Make the icon smaller in Chart Editor.
57585765 healthIconBF .flipX = ! healthIconBF .flipX ; // BF faces the other way.
57595766 }
5767+
57605768 if (buttonSelectPlayer != null )
57615769 {
5762- buttonSelectPlayer .text = charDataBF ?. name ?? ' Player' ;
5770+ buttonSelectPlayer .text = _charIconData ?. name ?? ' Player' ;
57635771 }
5772+
5773+ _charIconData = currentOpponentCharacterPlayer ?. character ?. _data ?? CharacterDataParser .fetchCharacterData (currentSongMetadata .playData .characters .opponent );
5774+
57645775 if (healthIconDad != null )
57655776 {
5766- healthIconDad .configure (charDataDad ?. healthIcon );
5777+ healthIconDad .configure (_charIconData ?. healthIcon );
57675778 healthIconDad .size * = 0.5 ; // Make the icon smaller in Chart Editor.
57685779 }
57695780 if (buttonSelectOpponent != null )
57705781 {
5771- buttonSelectOpponent .text = charDataDad ?. name ?? ' Opponent' ;
5782+ buttonSelectOpponent .text = _charIconData ?. name ?? ' Opponent' ;
57725783 }
57735784 healthIconsDirty = false ;
5785+ _charIconData = null ;
57745786 }
57755787
57765788 // Right align, and visibly center, the BF health icon.
@@ -6818,9 +6830,20 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
68186830 /**
68196831 * Handle the playback of hitsounds.
68206832 */
6821- function handleHitsounds (oldSongPosition : Float , newSongPosition : Float ): Void
6833+ var _scriptNoteObj : NoteSprite = null ;
6834+
6835+ var _noteScriptEvent : NoteScriptEvent = null ;
6836+
6837+ var _currentEvents = null ;
6838+ var _allowedEvents = null ;
6839+ var _eventTarget : Null <CharacterPlayer > = null ;
6840+
6841+ public static var _allowedEventsNames : Array <String > = [' PlayAnimation' ];
6842+
6843+ function handleMusicPositionUpdate (oldSongPosition : Float , newSongPosition : Float ): Void
68226844 {
6823- if (! hitsoundsEnabled ) return ;
6845+ _currentEvents = SongDataUtils .getEventsInTimeRange (currentSongChartEventData , oldSongPosition , newSongPosition );
6846+ _allowedEvents = SongDataUtils .getEventsWithKind (_currentEvents , _allowedEventsNames );
68246847
68256848 // Assume notes are sorted by time.
68266849 for (noteData in currentSongChartNoteData )
@@ -6830,32 +6853,66 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
68306853 if (noteData .time < oldSongPosition ) // Note is in the past.
68316854 continue ;
68326855
6833- if (noteData .time > newSongPosition ) // Note is in the future.
6834- return ; // Assume all notes are also in the future.
6856+ if (noteData .time > newSongPosition ) break ;
68356857
6836- // Note was just hit.
6858+ /**
6859+ * We hit a note.
6860+ * We're gonna create scripted event and dispatch it al over ChartEditor.
6861+ */
6862+ _scriptNoteObj = new NoteSprite (NoteStyleRegistry .instance .fetchDefault ());
6863+ _scriptNoteObj .noteData = noteData ;
6864+ _scriptNoteObj .kill ();
6865+ _scriptNoteObj .direction = _scriptNoteObj .noteData ?. getDirection () ?? 0 ;
6866+ _scriptNoteObj .scrollFactor .set ();
68376867
6838- // Character preview.
6839-
6840- // NoteScriptEvent takes a sprite, ehe. Need to rework that.
6841- var tempNote : NoteSprite = new NoteSprite (NoteStyleRegistry .instance .fetchDefault ());
6842- tempNote .noteData = noteData ;
6843- tempNote .scrollFactor .set (0 , 0 );
6844- var event : NoteScriptEvent = new HitNoteScriptEvent (tempNote , 0.0 , 0 , ' perfect' , false , 0 );
6845- dispatchEvent (event );
6868+ _noteScriptEvent = new HitNoteScriptEvent (_scriptNoteObj , 0.0 , 0 , (noteData .getStrumlineIndex () == 0 ? ' perfect' : ' sick' ), false , 0 );
6869+ dispatchEvent (_noteScriptEvent );
68466870
68476871 // Calling event.cancelEvent() skips all the other logic! Neat!
6848- if (event .eventCanceled ) continue ;
6872+ if (_noteScriptEvent .eventCanceled )
6873+ {
6874+ _scriptNoteObj .destroy ();
6875+ _scriptNoteObj = null ;
6876+
6877+ _noteScriptEvent = null ;
6878+
6879+ continue ;
6880+ }
68496881
68506882 // Hitsounds.
6851- switch (noteData .getStrumlineIndex ())
6883+ if ( hitsoundsEnabled ) switch (noteData .getStrumlineIndex ())
68526884 {
68536885 case 0 : // Player
68546886 if (hitsoundVolumePlayer > 0 ) this .playSound (Paths .sound (' chartingSounds/hitNotePlayer' ), hitsoundVolumePlayer );
68556887 case 1 : // Opponent
68566888 if (hitsoundVolumeOpponent > 0 ) this .playSound (Paths .sound (' chartingSounds/hitNoteOpponent' ), hitsoundVolumeOpponent );
68576889 }
68586890 }
6891+ // Clearing memory before next event call.
6892+ _scriptNoteObj ?. destroy ();
6893+ _scriptNoteObj = null ;
6894+
6895+ _noteScriptEvent = null ;
6896+ for (data in _allowedEvents )
6897+ {
6898+ switch (data .eventKind )
6899+ {
6900+ case " PlayAnimation" :
6901+ switch (data .getString (' target' ).toLowerCase ().trim ())
6902+ {
6903+ case ' boyfriend' | ' bf' | ' player' :
6904+ _eventTarget = currentPlayerCharacterPlayer ;
6905+ case ' dad' | ' opponent' | ' enemy' :
6906+ _eventTarget = currentOpponentCharacterPlayer ;
6907+ default :
6908+ }
6909+ if (_eventTarget != null ) _eventTarget .playAnimManually (data .getString (' anim' ) ?? ' idle' , data .getBool (' force' ) ?? false );
6910+ }
6911+ }
6912+
6913+ _currentEvents = null ;
6914+ _allowedEvents .resize (0 );
6915+ _eventTarget = null ;
68596916 }
68606917
68616918 function stopAudioPlayback (): Void
@@ -6925,6 +6982,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
69256982
69266983 // Many things get reset when song length changes.
69276984 healthIconsDirty = true ;
6985+ playerPreviewDirty = true ;
6986+ opponentPreviewDirty = true ;
69286987 }
69296988
69306989 public function loadSubtitles (): Void
0 commit comments