diff --git a/Heck/Animation/Events/CoroutineEventManager.cs b/Heck/Animation/Events/CoroutineEventManager.cs index 2154f752..59a60188 100644 --- a/Heck/Animation/Events/CoroutineEventManager.cs +++ b/Heck/Animation/Events/CoroutineEventManager.cs @@ -1,5 +1,7 @@ using System; using System.Collections; +using System.Collections.Generic; +using System.Linq; using CustomJSONData.CustomBeatmap; using JetBrains.Annotations; using UnityEngine; @@ -41,6 +43,17 @@ internal void StartEventCoroutine(CustomEventData customEventData, EventType eve return; } + IEnumerable triggers = heckData.Triggers; + if (triggers != null && !triggers.Any(x => x.isTriggered)) + { + foreach (Trigger t in triggers) + { + t.isTriggered = false; + } + + return; + } + float duration = 60f * heckData.Duration / _bpmController.currentBpm; // Convert to real time; Functions easing = heckData.Easing; int repeat = heckData.Repeat; diff --git a/Heck/Animation/Events/EventController.cs b/Heck/Animation/Events/EventController.cs index 98cc9706..546c015d 100644 --- a/Heck/Animation/Events/EventController.cs +++ b/Heck/Animation/Events/EventController.cs @@ -1,7 +1,11 @@ using System; +using System.Collections.Generic; +using System.Linq; using CustomJSONData.CustomBeatmap; using JetBrains.Annotations; +using UnityEngine; using Zenject; +using static AlphabetScrollInfo; using static Heck.HeckController; namespace Heck.Animation.Events @@ -11,20 +15,58 @@ internal class EventController : IDisposable private readonly BeatmapCallbacksController _callbacksController; private readonly LazyInject _coroutineEventManager; private readonly BeatmapDataCallbackWrapper _callbackWrapper; + private readonly BeatmapObjectManager _beatmapObjectManager; [UsedImplicitly] private EventController( BeatmapCallbacksController callbacksController, - LazyInject coroutineEventManager) + LazyInject coroutineEventManager, + BeatmapObjectManager beatmapObjectManager) { _callbacksController = callbacksController; _coroutineEventManager = coroutineEventManager; _callbackWrapper = callbacksController.AddBeatmapCallback(HandleCallback); + _beatmapObjectManager = beatmapObjectManager; + _beatmapObjectManager.noteWasCutEvent += BeatmapObjectManager_noteWasCutEvent; + _beatmapObjectManager.noteWasMissedEvent += BeatmapObjectManager_noteWasMissedEvent; + } + + private void BeatmapObjectManager_noteWasMissedEvent(NoteController noteController) + { + CustomNoteData noteData = (CustomNoteData)noteController._noteData; + IEnumerable triggers = Trigger.GetTriggers(noteData.customData, "triggerOnMiss"); + if (triggers == null) + { + return; + } + + foreach (Trigger trigger in triggers) + { + trigger.isTriggered = true; + } + } + + private void BeatmapObjectManager_noteWasCutEvent(NoteController noteController, in NoteCutInfo _) + { + CustomNoteData noteData = (CustomNoteData)noteController._noteData; + IEnumerable triggers = Trigger.GetTriggers(noteData.customData, "triggerOnCut"); + if (triggers == null) + { + return; + } + + foreach (Trigger trigger in triggers) + { + trigger.isTriggered = true; + } } public void Dispose() { _callbacksController.RemoveBeatmapCallback(_callbackWrapper); + _beatmapObjectManager.noteWasCutEvent -= BeatmapObjectManager_noteWasCutEvent; + _beatmapObjectManager.noteWasMissedEvent -= BeatmapObjectManager_noteWasMissedEvent; + Trigger.triggers.Clear(); } private void HandleCallback(CustomEventData customEventData) diff --git a/Heck/Animation/Trigger.cs b/Heck/Animation/Trigger.cs new file mode 100644 index 00000000..82252ce4 --- /dev/null +++ b/Heck/Animation/Trigger.cs @@ -0,0 +1,58 @@ +using CustomJSONData.CustomBeatmap; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Heck.Animation +{ + internal class Trigger + { + public static Dictionary triggers = new Dictionary(); + + public Trigger(string _name) { + name = _name; + } + + public bool isTriggered = false; + + public string name; + + public static IEnumerable GetTriggers(CustomData data, string field) + { + object? triggerNameRaw = data.Get(field); + if (triggerNameRaw == null) + { + return null; + } + + IEnumerable triggerNames; + if (triggerNameRaw is List listTrack) + { + triggerNames = listTrack.Cast(); + } + else + { + triggerNames = new[] { (string)triggerNameRaw }; + } + + HashSet result = new(); + foreach (string triggerName in triggerNames) + { + if (triggers.ContainsKey(triggerName)) + { + result.Add(triggers[triggerName]); + } + else + { + Trigger trigger = new Trigger(triggerName); + result.Add(trigger); + triggers.Add(triggerName, trigger); + } + } + + return result; + } + } +} diff --git a/Heck/HeckController.cs b/Heck/HeckController.cs index 7be28045..a1a6ccc8 100644 --- a/Heck/HeckController.cs +++ b/Heck/HeckController.cs @@ -20,6 +20,7 @@ public static class HeckController public const string V2_LOCAL_POSITION = "_localPosition"; public const string V2_SCALE = "_scale"; + public const string TRIGGER = "trigger"; public const string REPEAT = "repeat"; public const string DURATION = "duration"; public const string EASING = "easing"; diff --git a/Heck/HeckImplementation/CustomDataTypes.cs b/Heck/HeckImplementation/CustomDataTypes.cs index cbd31777..bd9e49bf 100644 --- a/Heck/HeckImplementation/CustomDataTypes.cs +++ b/Heck/HeckImplementation/CustomDataTypes.cs @@ -21,7 +21,7 @@ internal HeckCoroutineEventData( IEnumerable tracks = data.GetTrackArray(beatmapTracks, v2); - string[] excludedStrings = { V2_TRACK, V2_DURATION, V2_EASING, TRACK, DURATION, EASING, REPEAT }; + string[] excludedStrings = { V2_TRACK, V2_DURATION, V2_EASING, TRACK, DURATION, EASING, REPEAT, TRIGGER }; IEnumerable propertyKeys = data.Keys.Where(n => excludedStrings.All(m => m != n)).ToList(); List coroutineInfos = new(); foreach (Track track in tracks) @@ -97,6 +97,7 @@ void CreateInfo(BaseProperty property, IPropertyBuilder builder, string name, st if (!v2) { Repeat = data.Get(REPEAT) ?? 0; + Triggers = Trigger.GetTriggers(data, TRIGGER); } } @@ -106,6 +107,8 @@ void CreateInfo(BaseProperty property, IPropertyBuilder builder, string name, st internal int Repeat { get; } + internal IEnumerable Triggers { get; } + internal List CoroutineInfos { get; } internal readonly struct CoroutineInfo