using System.Collections; using System.Collections.Generic; using UnityEngine; using HeavenStudio.Util; namespace HeavenStudio.Games.Loaders { using static Minigames; public static class NtrFillbotsLoader { public static Minigame AddGame(EventCaller eventCaller) { return new Minigame("fillbots", "Fillbots", "FFFFFF", false, false, new List() { new("bop", "Bop") { function = delegate { var e = eventCaller.currentEntity; Fillbots.instance.ToggleBop(e.beat, e.length, e["toggle"], e["auto"]); }, resizable = true, parameters = new() { new("toggle", false, "Bop"), new("auto", false, "Bop (Auto)") } }, new GameAction("medium", "Medium Bot") { preFunction = delegate { Fillbots.PreSpawnFillbot(eventCaller.currentEntity.beat, 3, Scripts_Fillbots.BotSize.Medium); }, defaultLength = 8f }, new GameAction("large", "Large Bot") { preFunction = delegate { Fillbots.PreSpawnFillbot(eventCaller.currentEntity.beat, 7, Scripts_Fillbots.BotSize.Large); }, defaultLength = 12f }, new GameAction("small", "Small Bot") { preFunction = delegate { Fillbots.PreSpawnFillbot(eventCaller.currentEntity.beat, 1, Scripts_Fillbots.BotSize.Small); }, defaultLength = 6f }, }, new List() {"ntr", "normal"}, "ntrfillbots", "en", new List() {}, chronologicalSortKey: 3 ); } } } namespace HeavenStudio.Games { using Scripts_Fillbots; using System; public class Fillbots : Minigame { private struct QueuedFillbot { public double beat; public double holdLength; public BotSize size; } private static List queuedBots = new List(); [Header("Components")] [SerializeField] private NtrFillbot smallBot; [SerializeField] private NtrFillbot mediumBot; [SerializeField] private NtrFillbot largeBot; public Animator filler; [SerializeField] private Transform[] gears; [SerializeField] private Animator[] meters; [SerializeField] private Animator conveyerBelt; public static Fillbots instance; [NonSerialized] public List currentBots = new List(); [NonSerialized] public double conveyerStartBeat = -1; [NonSerialized] public float conveyerNormalizedOffset; private void Awake() { instance = this; SetupBopRegion("fillbots", "bop", "auto"); } public override void OnBeatPulse(double beat) { int toggle = (int)(beat % 2); if (BeatIsInBopRegion(beat)) Bop(toggle); } private void OnDestroy() { if (queuedBots.Count > 0) queuedBots.Clear(); foreach (var evt in scheduledInputs) { evt.Disable(); } } private void Update() { var cond = Conductor.instance; if (cond.isPlaying && !cond.isPaused) { if (queuedBots.Count > 0) { foreach (var queuedBot in queuedBots) { SpawnFillbot(queuedBot.beat, queuedBot.holdLength, queuedBot.size); } queuedBots.Clear(); } if (PlayerInput.GetIsAction(InputAction_BasicPress) && !IsExpectingInputNow(InputAction_BasicPress)) { filler.DoScaledAnimationAsync("Hold", 0.5f); SoundByte.PlayOneShotGame("fillbots/armExtension"); } if (PlayerInput.GetIsAction(InputAction_BasicRelease) && !IsExpectingInputNow(InputAction_BasicRelease)) { filler.DoScaledAnimationAsync("ReleaseWhiff", 0.5f); // SoundByte.PlayOneShotGame("fillbots/armRetractionWhiff"); } if (conveyerStartBeat >= 0) { float normalizedBeat = cond.GetPositionFromBeat(conveyerStartBeat, 1); if (normalizedBeat >= 0) { for (int i = 0; i < currentBots.Count; i++) { var bot = currentBots[i]; bot.MoveConveyer(normalizedBeat); } conveyerBelt.Play("Move", -1, ((normalizedBeat + conveyerNormalizedOffset) % 1) / 4); foreach (var gear in gears) { gear.localEulerAngles = new Vector3(0, 0, Mathf.LerpUnclamped(0, 90, normalizedBeat + conveyerNormalizedOffset)); } } else { foreach (var bot in currentBots) { bot.StopConveyer(); } conveyerBelt.Play("Move", -1, (conveyerNormalizedOffset % 1) / 4); foreach (var gear in gears) { gear.localEulerAngles = new Vector3(0, 0, Mathf.LerpUnclamped(0, 90, conveyerNormalizedOffset)); } } } else { foreach (var bot in currentBots) { bot.StopConveyer(); } conveyerBelt.Play("Move", -1, (conveyerNormalizedOffset % 1) / 4); foreach (var gear in gears) { gear.localEulerAngles = new Vector3(0, 0, Mathf.LerpUnclamped(0, 90, conveyerNormalizedOffset)); } } } } public static void PreSpawnFillbot(double beat, double holdLength, BotSize size) { if (GameManager.instance.currentGame == "fillbots") { instance.SpawnFillbot(beat, holdLength, size); } else { queuedBots.Add(new QueuedFillbot { beat = beat, holdLength = holdLength, size = size, }); } } private void SpawnFillbot(double beat, double holdLength, BotSize size) { NtrFillbot Bot = size switch { BotSize.Small => smallBot, BotSize.Medium => mediumBot, BotSize.Large => largeBot, _ => throw new System.NotImplementedException() }; NtrFillbot spawnedBot = Instantiate(Bot, transform); if (holdLength > 0) { spawnedBot.holdLength = holdLength; } spawnedBot.Init(beat); BeatAction.New(instance, new List() { new BeatAction.Action(beat, delegate { if (conveyerStartBeat != -1) conveyerNormalizedOffset = Conductor.instance.GetPositionFromBeat(conveyerStartBeat, 1); conveyerStartBeat = -2; }), new BeatAction.Action(beat + 3, delegate { if (!PlayerInput.GetIsAction(InputAction_BasicPress)) filler.DoScaledAnimationAsync("FillerPrepare", 0.5f); conveyerStartBeat = beat + 3; }) }); } public void ToggleBop(double beat, float length, bool bopOrNah, bool autoBop) { if (bopOrNah) { for (int i = 0; i < length; i++) { BeatAction.New(instance, new List() { new BeatAction.Action(beat + i, delegate { int toggle = (int)((beat + i) % 2); Bop(toggle); }) }); } } } private void Bop(int toggle) { toggle = (toggle != 0) ? 1 : 0; foreach (var meter in meters) { meter.DoScaledAnimationAsync(toggle switch { 0 => "Up", 1 or _ => "Down" }, 0.5f); toggle ^= 1; } } } }