mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-13 12:47:38 +02:00
Rhythm Test Text Update!!! (#898)
Rhythm Test GBA now has customizable text! This can only go well! (Also it's fuckin audible now)
This commit is contained in:
@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
|
||||
using HeavenStudio.Util;
|
||||
using HeavenStudio.InputSystem;
|
||||
@ -37,21 +39,31 @@ namespace HeavenStudio.Games.Loaders
|
||||
return new Minigame("rhythmTestGBA", "Rhythm Test (GBA) \n<color=#adadad>(Rhythm-kan Check)</color>", "2DD816", false, false, new List<GameAction>()
|
||||
{
|
||||
|
||||
new GameAction("countin", "Start Beeping")
|
||||
new GameAction("countin", "Change Screen Beeping Properties")
|
||||
{
|
||||
function = delegate { RhythmTestGBA.instance.KeepTheBeep(eventCaller.currentEntity.beat, eventCaller.currentEntity.length, eventCaller.currentEntity["toggle"], eventCaller.currentEntity["auto"]); },
|
||||
function = delegate { RhythmTestGBA.instance.KTBPrep(eventCaller.currentEntity.beat, eventCaller.currentEntity.length, eventCaller.currentEntity["toggle"], eventCaller.currentEntity["auto"],
|
||||
eventCaller.currentEntity["image"],
|
||||
eventCaller.currentEntity["textFlash"], eventCaller.currentEntity["textDisplay"], eventCaller.currentEntity["hasSound"]); },
|
||||
defaultLength = 1f,
|
||||
resizable = true,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("toggle", true, "Toggle", "Toggle the automatic beeping on or off."),
|
||||
new Param("toggle", true, "Toggle", "Toggle the beeping on or off."),
|
||||
new Param("auto", false, "Auto", "Toggle if the machine should beep automatically."),
|
||||
new Param("image", RhythmTestGBA.PulseOption.Note, "Screen Image", "Set what appears on the machine's screen.", new List<Param.CollapseParam>()
|
||||
{
|
||||
new Param.CollapseParam((x, _) => (int)x == (int)RhythmTestGBA.PulseOption.Text, new string[] { "textFlash", "textDisplay" }),
|
||||
}),
|
||||
new Param("textDisplay", "Get ready...", "Text to Display", "Changes the text displayed on the screen."),
|
||||
new Param("textFlash", true, "Text Flash", "Toggle if the text on the screen pulses to the beat."),
|
||||
new Param("hasSound", true, "Has Sound", "Toggle if the beeping plays sound or not.")
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
new GameAction("button", "Start Keep-the-Beat")
|
||||
{
|
||||
function = delegate { var e = eventCaller.currentEntity; RhythmTestGBA.StartKeepbeat(e.beat); },
|
||||
preFunction = delegate { var e = eventCaller.currentEntity; RhythmTestGBA.PreStartKeepbeat(e.beat, e.length); },
|
||||
defaultLength = 1f,
|
||||
resizable = false,
|
||||
|
||||
@ -59,12 +71,17 @@ namespace HeavenStudio.Games.Loaders
|
||||
|
||||
new GameAction("stopktb", "Stop Keep-the-Beat")
|
||||
{
|
||||
preFunction = delegate { RhythmTestGBA.instance.PreStopKeepbeat(eventCaller.currentEntity.beat, eventCaller.currentEntity.length, eventCaller.currentEntity["mutecue"]); },
|
||||
preFunction = delegate { RhythmTestGBA.instance.PreStopKeepbeat(eventCaller.currentEntity.beat, eventCaller.currentEntity.length, eventCaller.currentEntity["mutecue"], eventCaller.currentEntity["finishText"], eventCaller.currentEntity["textDisplay"]); },
|
||||
defaultLength = 4f,
|
||||
resizable = false,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("mutecue", false, "Mute Cue", "Mute the sound cue signifying the end of the keep-the-beat section."),
|
||||
new Param("finishText", true, "Finish Text", "Set if text appears once the keep-the-bet section is finished.", new List<Param.CollapseParam>()
|
||||
{
|
||||
new Param.CollapseParam((x, _) => (bool)x, new string[] { "textDisplay" }),
|
||||
}),
|
||||
new Param("textDisplay", "Test complete!", "Text to Display", "Changes the text displayed on the screen."),
|
||||
}
|
||||
},
|
||||
|
||||
@ -105,25 +122,40 @@ namespace HeavenStudio.Games
|
||||
{
|
||||
/// This class handles the minigame logic.
|
||||
/// Minigame inherits directly from MonoBehaviour, and adds Heaven Studio specific methods to override.
|
||||
using Scripts_RhythmTestGBA;
|
||||
public class RhythmTestGBA : Minigame
|
||||
{
|
||||
public static RhythmTestGBA instance;
|
||||
static List<double> queuedButton = new();
|
||||
|
||||
bool goBeep;
|
||||
//bool stopBeep; Unused value - Marc
|
||||
bool stopAutoBeep;
|
||||
bool keepPressing;
|
||||
bool shouldmute;
|
||||
bool disableCount;
|
||||
bool beatPulseTextFlash = false;
|
||||
bool beepHasSound;
|
||||
bool canBeep = false;
|
||||
//bool isBeeping = false;
|
||||
|
||||
int screenFXType;
|
||||
|
||||
private double numberSelect;
|
||||
private float countLength;
|
||||
|
||||
[NonSerialized] public List<Interval> noBopIntervals = new(),
|
||||
noBeepIntervals = new();
|
||||
|
||||
[Header("Objects")]
|
||||
[SerializeField] GameObject noteFlash;
|
||||
[SerializeField] TMP_Text screenText;
|
||||
|
||||
[Header("Animators")]
|
||||
[SerializeField] Animator buttonAnimator;
|
||||
[SerializeField] Animator flashAnimator;
|
||||
[SerializeField] Animator numberBGAnimator;
|
||||
[SerializeField] Animator numberAnimator;
|
||||
[SerializeField] Animator textAnimator;
|
||||
|
||||
[Header("Properties")]
|
||||
//private static double startBlippingBeat = double.MaxValue; Unused value - Marc
|
||||
@ -136,18 +168,36 @@ namespace HeavenStudio.Games
|
||||
GameEvent button = new GameEvent();
|
||||
|
||||
double lastButton = double.MaxValue;
|
||||
|
||||
// public struct QueuedButton
|
||||
// {
|
||||
// public double beat;
|
||||
// public float length;
|
||||
// }
|
||||
// static List<QueuedButton> queuedButton = new List<QueuedButton>();
|
||||
|
||||
public enum PulseOption
|
||||
{
|
||||
Note,
|
||||
Text
|
||||
}
|
||||
|
||||
public enum BeepNoise: int
|
||||
{
|
||||
defaultBeep = 0,
|
||||
highBeep = 1,
|
||||
dingBeep = 2
|
||||
}
|
||||
|
||||
public int beepType = 0;
|
||||
//public struct QueuedButton
|
||||
//{
|
||||
// public double beat;
|
||||
// public float length;
|
||||
//}
|
||||
//static List<QueuedButton> queuedButton = new List<QueuedButton>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
instance = this;
|
||||
|
||||
screenText.text = "";
|
||||
SetupBopRegion("rhythmTestGBA", "countin", "auto");
|
||||
var currentBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
|
||||
KeepTheBeep(currentBeat, 1f, false, false, 0, true);
|
||||
HandleBeeps();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
@ -208,36 +258,202 @@ namespace HeavenStudio.Games
|
||||
}
|
||||
}
|
||||
|
||||
public void KeepTheBeep(double beat, float length, bool shouldBeep, bool autoBeep)
|
||||
//public override void OnGameSwitch (double beat)
|
||||
//{
|
||||
|
||||
// var actions = GameManager.instance.Beatmap.Entities.FindAll(e => e.datamodel.Split('/')[0] == "rhythmTestGBA");
|
||||
// var tempStops = actions.FindAll(e => e.datamodel == "rhythmTestGBA/stopktb");
|
||||
|
||||
// foreach (var e in tempStops.FindAll(e => e.beat < beat && e.beat + 2 > beat)) {
|
||||
// PreStopKeepbeat(e.beat, e.length, e["mutecue"], e["textFlash"]);
|
||||
// }
|
||||
//}
|
||||
|
||||
private void HandleBeeps()
|
||||
{
|
||||
//stopBeep = false; Unused value - Marc
|
||||
if (!shouldBeep) { goBeep = false; return;}
|
||||
goBeep = autoBeep;
|
||||
if (shouldBeep)
|
||||
List<RiqEntity> events = EventCaller.GetAllInGameManagerList("rhythmTestGBA", new string[] { "countin" });
|
||||
|
||||
foreach (var e in events)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
BeatAction.New(instance, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat + i, delegate
|
||||
{
|
||||
PlayFlashFX();
|
||||
SoundByte.PlayOneShotGame("rhythmTestGBA/blip");
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
}
|
||||
noBopIntervals.Add(new Interval(e.beat, e.beat + 1));
|
||||
}
|
||||
|
||||
foreach (var v in events)
|
||||
{
|
||||
noBeepIntervals.Add(new Interval(v.beat, v.beat + v.length));
|
||||
}
|
||||
}
|
||||
|
||||
public void KTBPrep(double beat, float length, bool shouldBeep, bool autoBeep, int type, bool textFlash, string textDisplay, bool hasSound)
|
||||
{
|
||||
canBeep = true;
|
||||
if (type == 1)
|
||||
{
|
||||
screenText.text = textDisplay;
|
||||
}
|
||||
beepType = 0;
|
||||
screenFXType = type;
|
||||
beepHasSound = hasSound;
|
||||
KeepTheBeep(beat, length, shouldBeep, autoBeep, type, textFlash);
|
||||
}
|
||||
|
||||
public void KeepTheBeep(double beat, float length, bool shouldBeep, bool autoBeep, int type, bool textFlash)
|
||||
{
|
||||
|
||||
beatPulseTextFlash = textFlash;
|
||||
if (beepHasSound)
|
||||
{
|
||||
switch (beepType)
|
||||
{
|
||||
case (int)BeepNoise.defaultBeep:
|
||||
SoundByte.PlayOneShotGame("rhythmTestGBA/blip");
|
||||
break;
|
||||
case (int)BeepNoise.highBeep:
|
||||
SoundByte.PlayOneShotGame("rhythmTestGBA/blip2");
|
||||
break;
|
||||
case (int)BeepNoise.dingBeep:
|
||||
SoundByte.PlayOneShotGame("rhythmTestGBA/end_ding");
|
||||
break;
|
||||
}}
|
||||
|
||||
if (shouldBeep)
|
||||
{
|
||||
PlayFakeFlashFX(type, textFlash);
|
||||
List<BeatAction.Action> beeps = new List<BeatAction.Action>();
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
beeps.Add(new BeatAction.Action(beat + i, delegate {
|
||||
PlayFlashFX();}
|
||||
|
||||
));
|
||||
}
|
||||
BeatAction.New(instance, beeps);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//goBeep = autoBeep;
|
||||
//if (autoBeep)
|
||||
//{
|
||||
// PlayFlashFX(beatPulseTextFlash, type);
|
||||
// SoundByte.PlayOneShotGame("rhythmTestGBA/blip");
|
||||
//}
|
||||
|
||||
// if (shouldBeep && !autoBeep)
|
||||
// {
|
||||
|
||||
//if (!isBeeping)
|
||||
// {
|
||||
// PlayFlashFX(beatPulseTextFlash, type);
|
||||
// SoundByte.PlayOneShotGame("rhythmTestGBA/blip");
|
||||
// isBeeping = true;
|
||||
// }
|
||||
// for (int i = 0; i < length; i++)
|
||||
// {
|
||||
// BeatAction.New(instance, new List<BeatAction.Action>()
|
||||
// {
|
||||
// new BeatAction.Action(beat + i, delegate
|
||||
// {
|
||||
// PlayFlashFX(beatPulseTextFlash, type);
|
||||
|
||||
// SoundByte.PlayOneShotGame("rhythmTestGBA/blip");
|
||||
// })
|
||||
// });
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public void PlayFlashFX()
|
||||
{
|
||||
numberAnimator.Play("Idle");
|
||||
numberBGAnimator.Play("Idle");
|
||||
flashAnimator.Play("KTBPulse", 0 ,0);
|
||||
var currentBeat = Conductor.instance.songPositionInBeatsAsDouble;
|
||||
if (!noBopIntervals.Any(x => x.Contains(currentBeat)))
|
||||
|
||||
if (beepHasSound){
|
||||
if(!noBeepIntervals.Any(x => x.Contains(currentBeat)))
|
||||
{
|
||||
{
|
||||
switch (beepType)
|
||||
{
|
||||
case (int)BeepNoise.defaultBeep:
|
||||
SoundByte.PlayOneShotGame("rhythmTestGBA/blip");
|
||||
break;
|
||||
case (int)BeepNoise.highBeep:
|
||||
SoundByte.PlayOneShotGame("rhythmTestGBA/blip2");
|
||||
break;
|
||||
case (int)BeepNoise.dingBeep:
|
||||
SoundByte.PlayOneShotGame("rhythmTestGBA/end_ding");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}}
|
||||
if (screenFXType == 0)
|
||||
{
|
||||
|
||||
noteFlash.SetActive(true);
|
||||
flashAnimator.DoScaledAnimationAsync("KTBPulse", 0.5f);
|
||||
screenText.text = "";
|
||||
}
|
||||
else if (beatPulseTextFlash){
|
||||
|
||||
noteFlash.SetActive(false);
|
||||
textAnimator.DoScaledAnimationAsync("TextFlash", 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
noteFlash.SetActive(false);
|
||||
textAnimator.DoScaledAnimationAsync("TextIdle", 0.5f);
|
||||
}
|
||||
|
||||
BeatAction.New(instance, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(currentBeat+0.9f, delegate {noteFlash.SetActive(false);})
|
||||
});
|
||||
}
|
||||
|
||||
public void PlayFakeFlashFX(int fakeFXType, bool textFlash)
|
||||
{
|
||||
numberAnimator.Play("Idle");
|
||||
numberBGAnimator.Play("Idle");
|
||||
|
||||
var currentBeat = Conductor.instance.songPositionInBeatsAsDouble;
|
||||
if (fakeFXType == 0)
|
||||
{
|
||||
|
||||
noteFlash.SetActive(true);
|
||||
flashAnimator.DoScaledAnimationAsync("KTBPulse", 0.5f);
|
||||
screenText.text = "";
|
||||
|
||||
|
||||
}
|
||||
else if (textFlash){
|
||||
|
||||
noteFlash.SetActive(false);
|
||||
textAnimator.DoScaledAnimationAsync("TextFlash", 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
noteFlash.SetActive(false);
|
||||
textAnimator.DoScaledAnimationAsync("TextIdle", 0.5f);
|
||||
}
|
||||
|
||||
BeatAction.New(instance, new List<BeatAction.Action>()
|
||||
{
|
||||
//new BeatAction.Action(beat-1, delegate {KillBeeps(beat);}),
|
||||
new BeatAction.Action(currentBeat+0.9f, delegate {noteFlash.SetActive(false);})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void ChangeText(double beat, string newText, bool newTextFlash)
|
||||
{
|
||||
screenText.text = newText;
|
||||
beatPulseTextFlash = newTextFlash;
|
||||
}
|
||||
|
||||
|
||||
public void PressButton()
|
||||
@ -248,79 +464,112 @@ namespace HeavenStudio.Games
|
||||
|
||||
}
|
||||
|
||||
public void PreStopKeepbeat(double beat, float length, bool muted)
|
||||
public void PreStopKeepbeat(double beat, float length, bool muted, bool hasFinish, string finishText)
|
||||
{
|
||||
noBeepIntervals.Add(new Interval(beat, beat + length));
|
||||
|
||||
|
||||
shouldmute = muted;
|
||||
noBeepIntervals.Add(new Interval(beat, beat + length));
|
||||
|
||||
noBeepIntervals.Add(new Interval(beat, beat + length));
|
||||
BeatAction.New(instance, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat-1, delegate {killBeeps(beat);}),
|
||||
new BeatAction.Action(beat, delegate {StopKeepbeat(beat, shouldmute);})
|
||||
|
||||
new BeatAction.Action(beat, delegate {StopKeepbeat(beat, length, shouldmute, hasFinish, finishText);
|
||||
canBeep = false;
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void StopKeepbeat(double beat, bool shouldmute)
|
||||
public void StopKeepbeat(double beat, float length, bool shouldmute, bool hasFinish, string finishText)
|
||||
{
|
||||
|
||||
|
||||
keepPressing = false;
|
||||
|
||||
ScheduleInput(beat, 1f, InputAction_BasicPress, ButtonSuccess, ButtonFailure, ButtonEmpty);
|
||||
ScheduleInput(beat, 2f, InputAction_BasicPress, ButtonSuccess, ButtonFailure, ButtonEmpty);
|
||||
ScheduleInput(beat, 3f, InputAction_BasicPress, ButtonSuccess, ButtonFailure, ButtonEmpty);
|
||||
|
||||
|
||||
|
||||
|
||||
BeatAction.New(instance, new List<BeatAction.Action>()
|
||||
{
|
||||
|
||||
new BeatAction.Action(beat, delegate {PlayFlashFX();}),
|
||||
|
||||
new BeatAction.Action(beat+1, delegate {PlayFlashFX();}),
|
||||
new BeatAction.Action(beat+1, delegate {PlayFlashFX();}),
|
||||
|
||||
new BeatAction.Action(beat+2, delegate {PlayFlashFX();}),
|
||||
new BeatAction.Action(beat+2, delegate {PlayFlashFX();}),
|
||||
|
||||
new BeatAction.Action(beat+3, delegate { SoundByte.PlayOneShotGame("rhythmTestGBA/end_ding", beat: beat, forcePlay: true);})
|
||||
|
||||
|
||||
new BeatAction.Action(beat+3, delegate { SoundByte.PlayOneShotGame("rhythmTestGBA/end_ding", beat: beat, forcePlay: true);
|
||||
|
||||
if (hasFinish)
|
||||
{
|
||||
screenText.text = finishText;
|
||||
textAnimator.DoScaledAnimationAsync("TextIdle", 0.5f);
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
if (!shouldmute)
|
||||
{
|
||||
SoundByte.PlayOneShotGame("rhythmTestGBA/blip2");
|
||||
BeatAction.New(instance, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat+1, delegate { SoundByte.PlayOneShotGame("rhythmTestGBA/blip2", beat: beat);}),
|
||||
new BeatAction.Action(beat+2, delegate { SoundByte.PlayOneShotGame("rhythmTestGBA/blip2", beat: beat);})
|
||||
});
|
||||
|
||||
MultiSound.Play(new MultiSound.Sound[] {
|
||||
new MultiSound.Sound("rhythmTestGBA/blip2", beat),
|
||||
new MultiSound.Sound("rhythmTestGBA/blip2", beat+1),
|
||||
new MultiSound.Sound("rhythmTestGBA/blip2", beat+2),
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void StopKeepbeatInput(double beat)
|
||||
{
|
||||
ScheduleInput(beat, 0f, InputAction_BasicPress, ButtonSuccess, ButtonFailure, ButtonEmpty);
|
||||
PlayFlashFX();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void OnBeatPulse(double beat)
|
||||
{
|
||||
if (goBeep)
|
||||
if (BeatIsInBopRegion(beat) && canBeep)
|
||||
{
|
||||
PlayFlashFX();
|
||||
SoundByte.PlayOneShotGame("rhythmTestGBA/blip");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void killBeeps(double beat)
|
||||
//public void KillBeeps(double beat)
|
||||
//{
|
||||
// goBeep = false;
|
||||
//isBeeping = false;
|
||||
//}
|
||||
|
||||
public static void PreStartKeepbeat(double beat, float length)
|
||||
{
|
||||
goBeep = false;
|
||||
if (GameManager.instance.currentGame == "rhythmTestGBA")
|
||||
{
|
||||
StartKeepbeat(beat, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
BeatAction.New(instance, new List<BeatAction.Action>()
|
||||
{
|
||||
|
||||
new BeatAction.Action(beat, delegate {queuedButton.Add(wantButton);}),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void StartKeepbeat(double beat)
|
||||
public static void StartKeepbeat(double beat, float length)
|
||||
{
|
||||
RhythmTestGBA.wantButton = beat-1;
|
||||
|
||||
@ -328,6 +577,7 @@ namespace HeavenStudio.Games
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void PreCountDown(double startBeat, float length, int countdownNumber)
|
||||
{
|
||||
if (keepPressing) return;
|
||||
@ -667,3 +917,29 @@ namespace HeavenStudio.Games
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_RhythmTestGBA
|
||||
{
|
||||
public class Interval
|
||||
{
|
||||
private readonly double _start;
|
||||
private readonly double _end;
|
||||
private readonly Func<double, double, bool> _leftComparer;
|
||||
private readonly Func<double, double, bool> _rightComparer;
|
||||
|
||||
public double Start => _start;
|
||||
public double End => _end;
|
||||
|
||||
public Interval(double start, double end, bool isLeftClosed = true, bool isRightClosed = false)
|
||||
{
|
||||
_start = start;
|
||||
_end = end;
|
||||
|
||||
_leftComparer = isLeftClosed ? (value, boundary) => value >= boundary : (value, boundary) => value > boundary;
|
||||
_rightComparer = isRightClosed ? (value, boundary) => value <= boundary : (value, boundary) => value < boundary;
|
||||
}
|
||||
|
||||
public bool Contains(double value) => _leftComparer(value, _start) && _rightComparer(value, _end);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user