diff --git a/Assets/Resources/Sfx/games/catchyTune/GROUP_STEP_0000000F.wav b/Assets/Resources/Sfx/games/catchyTune/fruitThrough.wav similarity index 100% rename from Assets/Resources/Sfx/games/catchyTune/GROUP_STEP_0000000F.wav rename to Assets/Resources/Sfx/games/catchyTune/fruitThrough.wav diff --git a/Assets/Resources/Sfx/games/catchyTune/GROUP_STEP_0000000F.wav.meta b/Assets/Resources/Sfx/games/catchyTune/fruitThrough.wav.meta similarity index 100% rename from Assets/Resources/Sfx/games/catchyTune/GROUP_STEP_0000000F.wav.meta rename to Assets/Resources/Sfx/games/catchyTune/fruitThrough.wav.meta diff --git a/Assets/Scripts/Games/CatchyTune/CatchyTune.cs b/Assets/Scripts/Games/CatchyTune/CatchyTune.cs index d135497b4..d0354615c 100644 --- a/Assets/Scripts/Games/CatchyTune/CatchyTune.cs +++ b/Assets/Scripts/Games/CatchyTune/CatchyTune.cs @@ -11,34 +11,35 @@ namespace HeavenStudio.Games.Loaders public static class CtrCatchLoader { // minigame menu items - public static Minigame AddGame(EventCaller eventCaller) { + public static Minigame AddGame(EventCaller eventCaller) + { return new Minigame("catchyTune", "Catchy Tune \n[WIP]", "B4E6F6", false, false, new List() { new GameAction("orange", "Orange") { - function = delegate {var e = eventCaller.currentEntity; CatchyTune.instance.DropFruit(e.beat, e["side"], e["smile"], false); }, - defaultLength = 5f, + defaultLength = 4f, parameters = new List() { new Param("side", CatchyTune.Side.Left, "Side", "The side the orange falls down"), new Param("smile", false, "Smile", "If the characters smile with the heart message after catching") }, + preFunction = delegate {var e = eventCaller.currentEntity; CatchyTune.PreDropFruit(e.beat, e["side"], e["smile"], false); }, }, new GameAction("pineapple", "Pineapple") { - function = delegate {var e = eventCaller.currentEntity; CatchyTune.instance.DropFruit(e.beat, e["side"], e["smile"], true); }, - defaultLength = 9f, + defaultLength = 8f, parameters = new List() { new Param("side", CatchyTune.Side.Left, "Side", "The side the pineapple falls down"), new Param("smile", false, "Smile", "If the characters smile with the heart message after catching") }, + preFunction = delegate {var e = eventCaller.currentEntity; CatchyTune.PreDropFruit(e.beat, e["side"], e["smile"], true); }, }, new GameAction("bop", "Bop") { - function = delegate {var e = eventCaller.currentEntity; CatchyTune.instance.Bop(e.beat, e["left"], e["right"]); }, + function = delegate {var e = eventCaller.currentEntity; CatchyTune.instance.Bop(e.beat, e["left"], e["right"]); }, defaultLength = 1f, parameters = new List() { @@ -88,6 +89,14 @@ namespace HeavenStudio.Games public GameEvent bop = new GameEvent(); public static CatchyTune instance; + static List queuedFruits = new List(); + struct QueuedFruit + { + public float beat; + public int side; + public bool smile; + public bool isPineapple; + } private void Awake() { @@ -99,46 +108,19 @@ namespace HeavenStudio.Games private void Update() { - - // doesnt work here since i need the parameter and i dont know how to get it - - // if (!Conductor.instance.isPlaying && !Conductor.instance.isPaused) - // return; - - // var currentBeat = Conductor.instance.songPositionInBeats; - - // var orangeEvents = GameManager.instance.Beatmap.entities.FindAll(c => c.datamodel == "catchyTune/orange"); - // for (int i = 0; i < orangeEvents.Count; i++) - // { - // var ev = orangeEvents[i]; - // if (spawnedOrangeEvents.Contains(ev)) continue; // Don't spawn the same oranges multiple times. - - // var spawnBeat = ev.beat - orangeoffset; - // if (currentBeat > spawnBeat && currentBeat < ev.beat + 4f) - // { - // DropFruit(currentBeat, ev[side], false); - // spawnedOrangeEvents.Add(ev); - // break; - // } - // } - - // if (PlayerInput.GetAnyDirectionDown()) - // { - // plalinAnim.Play("catchOrange", 0, 0); - // } - // else if (PlayerInput.Pressed()) - // { - // alalinAnim.Play("catchOrange", 0, 0); - // } - - - Conductor cond = Conductor.instance; - - if (cond.isPlaying && !cond.isPaused) { + if (queuedFruits.Count > 0) + { + foreach (var fruit in queuedFruits) + { + DropFruit(fruit.beat, fruit.side, fruit.smile, fruit.isPineapple); + } + queuedFruits.Clear(); + } + // print(stopCatchLeft + " " + stopCatchRight); // print("current beat: " + conductor.songPositionInBeats); if (stopCatchLeft > 0 && stopCatchLeft <= cond.songPositionInBeats) @@ -184,12 +166,20 @@ namespace HeavenStudio.Games } } + if (!IsExpectingInputNow()) + { + if (PlayerInput.GetAnyDirectionDown()) + { + catchWhiff(false); + } + if (PlayerInput.Pressed()) + { + catchWhiff(true); + } + } } - - } - public void DropFruit(float beat, int side, bool smile, bool isPineapple) { var objectToSpawn = isPineapple ? pineappleBase : orangeBase; @@ -203,8 +193,39 @@ namespace HeavenStudio.Games { DropFruitSingle(beat, true, smile, objectToSpawn); } - + } + //minenice: experiment to test preFunction + public static void PreDropFruit(float beat, int side, bool smile, bool isPineapple) + { + float spawnBeat = beat - 1f; + beat = beat - (isPineapple ? 2f : 1f); + if (GameManager.instance.currentGame == "catchyTune") + { + BeatAction.New(instance.gameObject, new List() + { + new BeatAction.Action(spawnBeat, delegate { if (instance != null) instance.DropFruit(beat, side, smile, isPineapple); }), + }); + } + else + { + queuedFruits.Add(new QueuedFruit() + { + beat = beat, + side = side, + smile = smile, + isPineapple = isPineapple + }); + } + + if (side == (int)Side.Left || side == (int)Side.Both) + { + Fruit.PlaySound(beat, false, isPineapple); + } + if (side == (int)Side.Right || side == (int)Side.Both) + { + Fruit.PlaySound(beat, true, isPineapple); + } } public void DropFruitSingle(float beat, bool side, bool smile, GameObject objectToSpawn) @@ -224,13 +245,12 @@ namespace HeavenStudio.Games bopRight = right; } - public void catchSuccess(bool side, bool isPineapple, bool smile, float beat) { - string anim = isPineapple ? "catchPineapple" : "catchOrange"; - if (side) { + if (side) + { alalinAnim.Play(anim, 0, 0); stopCatchRight = beat + 0.9f; } @@ -249,10 +269,17 @@ namespace HeavenStudio.Games public void catchMiss(bool side, bool isPineapple) { - return; + // not the right sound at all but need an accurate rip + Jukebox.PlayOneShotGame("catchyTune/fruitThrough"); + + // hurt animation here } - - + public void catchWhiff(bool side) + { + Jukebox.PlayOneShotGame("catchyTune/whiff"); + + // whiff animation here + } } } diff --git a/Assets/Scripts/Games/CatchyTune/Fruit.cs b/Assets/Scripts/Games/CatchyTune/Fruit.cs index 00fbce3d2..7bf4f0148 100644 --- a/Assets/Scripts/Games/CatchyTune/Fruit.cs +++ b/Assets/Scripts/Games/CatchyTune/Fruit.cs @@ -20,8 +20,6 @@ namespace HeavenStudio.Games.Scripts_CatchyTune public bool smile; - public bool eligable = true; - private string soundText; private Minigame.Eligible e = new Minigame.Eligible(); @@ -29,7 +27,7 @@ namespace HeavenStudio.Games.Scripts_CatchyTune private CatchyTune game; private float beatLength = 4f; - + private void Awake() { game = CatchyTune.instance; @@ -42,14 +40,12 @@ namespace HeavenStudio.Games.Scripts_CatchyTune if (isPineapple) beatLength = 8f; - anim.SetFloat("speed", GetAnimSpeed(isPineapple, tempo, playbackSpeed)); - if (side) { transform.localScale = new Vector3(-1f, 1f, 1f); } - anim.Play("fruit bounce", 0, 0f); + anim.DoScaledAnimation("fruit bounce", startBeat, beatLength + (isPineapple ? 1f : 0.5f)); soundText = "catchyTune/"; @@ -57,7 +53,8 @@ namespace HeavenStudio.Games.Scripts_CatchyTune { soundText += "right"; } - else { + else + { soundText += "left"; } @@ -65,7 +62,46 @@ namespace HeavenStudio.Games.Scripts_CatchyTune { soundText += "Pineapple"; } - else { + else + { + soundText += "Orange"; + } + + game.ScheduleInput(startBeat, beatLength, side ? InputType.STANDARD_DOWN : InputType.DIRECTION_DOWN, + CatchFruit, Miss, WayOff); + } + + // minenice: note - needs PlayerActionEvent implementation + private void Update() + { + Conductor cond = Conductor.instance; + float tempo = cond.songBpm; + float playbackSpeed = cond.musicSource.pitch; + + anim.DoScaledAnimation("fruit bounce", startBeat, beatLength + (isPineapple ? 1f : 0.5f)); + + float normalizedBeat = Conductor.instance.GetPositionFromBeat(startBeat, beatLength); + } + + public static void PlaySound(float startBeat, bool side, bool isPineapple) + { + string soundText = "catchyTune/"; + + if (side) + { + soundText += "right"; + } + else + { + soundText += "left"; + } + + if (isPineapple) + { + soundText += "Pineapple"; + } + else + { soundText += "Orange"; } @@ -73,7 +109,8 @@ namespace HeavenStudio.Games.Scripts_CatchyTune MultiSound.Sound[] sound; - if (isPineapple) { + if (isPineapple) + { sound = new MultiSound.Sound[] { new MultiSound.Sound(soundText, startBeat + 2f), @@ -91,86 +128,27 @@ namespace HeavenStudio.Games.Scripts_CatchyTune }; } - MultiSound.Play(sound); + MultiSound.Play(sound, forcePlay: true); } - private void Update() + private void CatchFruit(PlayerActionEvent caller, float state) { - Conductor cond = Conductor.instance; - float tempo = cond.songBpm; - float playbackSpeed = cond.musicSource.pitch; - - if (cond.isPaused) - { - anim.SetFloat("speed", 0f); - } - else { - anim.SetFloat("speed", GetAnimSpeed(isPineapple, tempo, playbackSpeed)); - } - - - - float normalizedBeat = Conductor.instance.GetPositionFromBeat(startBeat, beatLength); - - if (eligable) - { - // check input timing - StateCheck(normalizedBeat); - bool pressed = (PlayerInput.Pressed() && side) || (PlayerInput.GetAnyDirectionDown() && !side); - if (pressed) - { - if (state.perfect) - { - CatchFruit(); - } - else if (state.notPerfect()) - { - Miss(); - } - else { - WayOff(); - } - } - } - - // fell off screen - if (normalizedBeat > 1.5f) { - Destroy(this.gameObject); - } - } - - private float GetAnimSpeed(bool pineapple, float tempo, float playbackSpeed) - { - float speedmult = pineapple ? 0.5f : 1f; - return (speedmult * tempo / 60f) * 0.17f * playbackSpeed; - } - - public override void OnAce() - { - CatchFruit(); - } - - private void CatchFruit() - { - //print("catch fruit"); + //minenice: TODO - near misses (-1 > state > 1) Jukebox.PlayOneShotGame(soundText + "Catch"); - game.catchSuccess(side, isPineapple, smile, startBeat+beatLength); + game.catchSuccess(side, isPineapple, smile, startBeat + beatLength); Destroy(this.gameObject); } - private void Miss() + private void Miss(PlayerActionEvent caller) { - //print("miss fruit"); - eligable = false; game.catchMiss(side, isPineapple); - Jukebox.PlayOneShotGame("catchyTune/whiff"); + + BeatAction.New(gameObject, new List() + { + new BeatAction.Action(startBeat + beatLength + (isPineapple ? 1f : 0.5f), delegate { Destroy(this.gameObject); }), + }); } - private void WayOff() - { - //print("way off"); - //eligable = false; - Jukebox.PlayOneShotGame("catchyTune/whiff"); - } + private void WayOff(PlayerActionEvent caller) {} // whiffing is handled in the main loop } } diff --git a/Assets/Scripts/Games/Minigame.cs b/Assets/Scripts/Games/Minigame.cs index b34e27057..77199a8cb 100644 --- a/Assets/Scripts/Games/Minigame.cs +++ b/Assets/Scripts/Games/Minigame.cs @@ -106,6 +106,7 @@ namespace HeavenStudio.Games //Get the scheduled input that should happen the **Soonest** //Can return null if there's no scheduled inputs + // remark: need a check for specific button(s) public PlayerActionEvent GetClosestScheduledInput() { PlayerActionEvent closest = null; @@ -132,6 +133,7 @@ namespace HeavenStudio.Games //Hasn't been tested yet. *Should* work. //Can be used to detect if the user is expected to input something now or not //Useful for strict call and responses games like Tambourine + // remark: need a check for specific button(s) public bool IsExpectingInputNow() { PlayerActionEvent input = GetClosestScheduledInput();