HeavenStudio/Assets/Scripts/Games/Fillbots/Fillbots.cs
2024-03-30 19:27:41 +09:00

255 lines
8.9 KiB
C#

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<GameAction>()
{
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<string>() {"ntr", "normal"},
"ntrfillbots", "en",
new List<string>() {},
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<QueuedFillbot> queuedBots = new List<QueuedFillbot>();
[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<NtrFillbot> currentBots = new List<NtrFillbot>();
[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<BeatAction.Action>()
{
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<BeatAction.Action>()
{
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;
}
}
}
}