HeavenStudio/Assets/Scripts/Games/Flockstep/Flockstep.cs
2024-03-29 21:20:41 +09:00

272 lines
9.7 KiB
C#

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HeavenStudio.Util;
using HeavenStudio.InputSystem;
using Jukebox;
namespace HeavenStudio.Games.Loaders
{
using static Minigames;
/// Minigame loaders handle the setup of your minigame.
/// Here, you designate the game prefab, define entities, and mark what AssetBundle to load
/// Names of minigame loaders follow a specific naming convention of `PlatformcodeNameLoader`, where:
/// `Platformcode` is a three-leter platform code with the minigame's origin
/// `Name` is a short internal name
/// `Loader` is the string "Loader"
/// Platform codes are as follows:
/// Agb: Gameboy Advance ("Advance Gameboy")
/// Ntr: Nintendo DS ("Nitro")
/// Rvl: Nintendo Wii ("Revolution")
/// Ctr: Nintendo 3DS ("Centrair")
/// Mob: Mobile
/// Pco: PC / Other
/// Fill in the loader class label, "*prefab name*", and "*Display Name*" with the relevant information
/// For help, feel free to reach out to us on our discord, in the #development channel.
public static class RvlFlockStepLoader
{
public static Minigame AddGame(EventCaller eventCaller)
{
return new Minigame("flockStep", "Flock Step", "ffffff", false, false, new List<GameAction>()
{
new GameAction("bop", "Bop")
{
function = delegate { var e = eventCaller.currentEntity; FlockStep.instance.ToggleBop(e.beat, e.length, e["toggle2"], e["toggle"]); },
resizable = true,
parameters = new List<Param>()
{
new Param("toggle2", true, "Bop", "Toggle if the the Hue Birds should bop for the duration of this event."),
new Param("toggle", false, "Bop (Auto)", "Toggle if the Hue Birds should automatically bop until another Bop event is reached.")
}
},
new GameAction("march", "Stepping")
{
function = delegate {var e = eventCaller.currentEntity; FlockStep.instance.StartStep(e.beat, e.length); },
defaultLength = 1,
},
new GameAction("jump", "Jump")
{
defaultLength = 4f,
},
new GameAction("color", "Birds Color")
{
defaultLength = 0.5f,
},
new GameAction("force", "Force Stepping")
{
resizable = true,
},
}
);
}
}
}
namespace HeavenStudio.Games
{
using Scripts_FlockStep;
public class FlockStep : Minigame
{
bool noBop;
public GameEvent bop = new GameEvent();
[SerializeField] Huebird[] Huebirds;
[SerializeField] Huebird HuebirdPlayer;
[SerializeField] Transform Root;
[SerializeField] Transform birdHolder;
[SerializeField] float stepDistance;
[SerializeField] float stepTime;
int marchIteratorGlobal;
public static FlockStep instance;
// Start is called before the first frame update
void Awake()
{
instance = this;
SetupBopRegion("flockStep", "bop", "toggle");
}
public override void OnBeatPulse(double beat)
{
if (BeatIsInBopRegion(beat)) Bop();
}
void Update()
{
if (PlayerInput.GetIsAction(InputAction_BasicPress) && !IsExpectingInputNow(InputAction_BasicPress))
{
ScoreMiss();
}
if (PlayerInput.GetIsAction(InputAction_BasicRelease))
{
Steppers(HuebirdPlayer, true, marchIteratorGlobal + 1);
}
}
void PlayBirdAnim(string animName, bool player, float timescale = 0.5f, float startpos = 0f, int layer = -1)
{
if (player) HuebirdPlayer.PlayAnim(animName, timescale, startpos, layer);
foreach(Huebird bird in Huebirds)
{
bird.PlayAnim(animName, timescale, startpos, layer);
}
}
void PlayBirdAnimDesync(Huebird birdSelected, string animName, bool player, float timescale = 0.5f, float startpos = 0f, int layer = -1)
{
if (player)
{
HuebirdPlayer.PlayAnim(animName, timescale, startpos, layer);
}
if (!player)
{
birdSelected.PlayAnim(animName, timescale, startpos, layer);
}
}
public void ToggleBop(double beat, float length, bool shouldBop, bool autoBop)
{
if (shouldBop)
{
for (int i = 0; i < length; i++)
{
BeatAction.New(instance, new List<BeatAction.Action>()
{
new BeatAction.Action(beat + i, delegate { Bop();})
});
}
}
}
private void Bop()
{
if (!noBop) PlayBirdAnim("bop", true);
}
public void StartStep(double beat, double length)
{
noBop = true;
PlayBirdAnim("startStep", true);
SoundByte.PlayOneShotGame("flockStep/start", beat);
RecursiveMarching(beat + length, 0);
// RecursiveSteppers(beat + length, HuebirdPlayer, true, 0);
foreach(Huebird bird in Huebirds)
{
RecursiveSteppers(beat + length + UnityEngine.Random.Range(-0.05f, 0.05f), bird, false, 0);
}
}
private void RecursiveSteppers(double beat, Huebird birdSelected, bool player, int marchIterator)
{
marchIterator %= 4;
BeatAction.New(instance, new List<BeatAction.Action>()
{
new BeatAction.Action(beat, delegate
{
Steppers(birdSelected, player, marchIterator);
RecursiveSteppers(beat + 0.5f, birdSelected, player, marchIterator + 1);
}),
});
}
private void RecursiveMarching(double beat, int marchIterator)
{
marchIterator %= 4;
marchIteratorGlobal = marchIterator;
ScheduleStep(beat);
BeatAction.New(instance, new List<BeatAction.Action>() {
new BeatAction.Action(beat, delegate
{
UpdatePos();
StartCoroutine(StepCo(Root, beat, stepTime, stepDistance));
StartCoroutine(StepCo(birdHolder, beat, 0, -stepDistance));
RecursiveMarching(beat + 1f, marchIterator + 2);
}),
});
}
private void Steppers(Huebird birdSelected, bool player, int marchIterator)
{
switch(marchIterator)
{
case 0:
PlayBirdAnimDesync(birdSelected, "walkRight_00", player);
if (player) SoundByte.PlayOneShotGame("flockStep/step1");
break;
case 1:
PlayBirdAnimDesync(birdSelected, "walkRight_01", player);
if (player) SoundByte.PlayOneShotGame("flockStep/step2");
break;
case 2:
PlayBirdAnimDesync(birdSelected, "walkLeft_00", player);
if (player) SoundByte.PlayOneShotGame("flockStep/step3");
break;
case 3:
PlayBirdAnimDesync(birdSelected, "walkLeft_01", player);
if (player) SoundByte.PlayOneShotGame("flockStep/step4");
break;
}
}
IEnumerator StepCo(Transform thing, double beat, float length, float xValue)
{
float xPos = thing.localPosition.x;
if (length > 0)
{
float normalized = Conductor.instance.GetPositionFromBeat(beat, length, false);
while (normalized <= 1f)
{
normalized = Conductor.instance.GetPositionFromBeat(beat, length);
thing.localPosition = new Vector2(Mathf.SmoothStep(xPos, xPos + xValue, normalized), thing.localPosition.y);
yield return null;
}
}
thing.localPosition = new Vector2(xPos + xValue, thing.localPosition.y);
yield break;
}
void UpdatePos()
{
var rootPos = Root.localPosition;
var newPosX = rootPos.x % 18.32f;
Root.localPosition = new Vector2(newPosX, rootPos.y);
var birdPos = birdHolder.localPosition;
birdHolder.localPosition = new Vector2(-newPosX, birdPos.y);
}
private void ScheduleStep(double beat)
{
ScheduleInput(beat, 0, InputAction_BasicPress, StepJust, StepMiss, Empty);
ScheduleAutoplayInput(beat, 0.5, InputAction_BasicRelease, StepReleaseAutoplay, Empty, Empty).countsForAccuracy = false;
}
public void StepJust(PlayerActionEvent caller, float state)
{
Steppers(HuebirdPlayer, true, marchIteratorGlobal);
// man.Step();
// if (state is >= 1f or <= -1f) SoundByte.PlayOneShot("nearMiss");
}
void StepReleaseAutoplay(PlayerActionEvent caller, float state)
{
Steppers(HuebirdPlayer, true, marchIteratorGlobal + 1);
}
public void StepMiss(PlayerActionEvent caller)
{
// man.Fall();
}
public void Empty(PlayerActionEvent caller) { }
}
}