2024-02-26 01:44:56 +00:00
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 ;
using Jukebox ;
namespace HeavenStudio.Games.Loaders
{
using static Minigames ;
public static class AgbBonOdoriLoader
{
public static Minigame AddGame ( EventCaller eventCaller )
2024-03-06 22:35:58 +00:00
{
2024-02-26 01:44:56 +00:00
return new Minigame ( "bonOdori" , "The☆Bon Odori \n<color=#adadad>(Za☆Bon Odori)</color>" , "312B9F" , false , false , new List < GameAction > ( )
2024-03-26 12:13:09 +00:00
{
new GameAction ( "bop" , "Bop" )
{
function = delegate { var e = eventCaller . currentEntity ; BonOdori . instance . ToggleBop ( e . beat , e . length , e [ "toggle" ] , e [ "auto" ] ) ; } ,
resizable = true ,
parameters = new List < Param > ( )
{
new Param ( "toggle" , true , "Bop" , "Toggle if the Donpans and Yagura-chan should bop for the duration of this event." ) ,
new Param ( "auto" , false , "Bop (Auto)" , "Toggle if the Donpans and Yagura-chan should automatically bop until another Bop event is reached." ) ,
2024-02-26 01:44:56 +00:00
} ,
2024-03-26 12:13:09 +00:00
} ,
2024-03-06 22:35:58 +00:00
2024-02-26 01:44:56 +00:00
new GameAction ( "pan" , "Pan" )
{
2024-03-26 12:13:09 +00:00
preFunction = delegate
{
var e = eventCaller . currentEntity ;
string variation = "variation" + ( new string [ ] { "Pan" , "Pa" , "Pa_n" } ) [ e [ "type" ] ] ;
BonOdori . instance . PreClap ( e . beat , e [ variation ] , e [ "type" ] , e [ "mute" ] , e [ "clapType" ] , e [ "semitone" ] ) ;
} ,
2024-02-26 01:44:56 +00:00
defaultLength = 1f ,
parameters = new List < Param > ( )
{
new Param ( "mute" , false , "Mute Sound" , "Mute the voice line." ) ,
new Param ( "type" , BonOdori . typePan . Pan , "Type" , "Set the type of voice line." , new ( ) {
2024-03-26 12:13:09 +00:00
new ( ( x , _ ) = > ( int ) x = = 0 , new string [ ] { "variationPan" } ) ,
new ( ( x , _ ) = > ( int ) x = = 1 , new string [ ] { "variationPa" } ) ,
new ( ( x , _ ) = > ( int ) x = = 2 , new string [ ] { "variationPa_n" } ) ,
} ) ,
2024-04-08 02:18:51 +00:00
new Param ( "variationPan" , new EntityTypes . NoteSampleDropdown ( BonOdori . variationPan . PanC , BonOdori . GetSample , "semitone" ) , "Pan Type" , "Set the variation of the voice line." ) ,
new Param ( "variationPa" , new EntityTypes . NoteSampleDropdown ( BonOdori . variationPa . PaG , BonOdori . GetSample , "semitone" ) , "Pa Type" , "Set the variation of the voice line." ) ,
new Param ( "variationPa_n" , new EntityTypes . NoteSampleDropdown ( BonOdori . variationPa_n . Pa_nA , BonOdori . GetSample , "semitone" ) , "Pa-n Type" , "Set the variation of the voice line." ) ,
2024-03-06 22:35:58 +00:00
new Param ( "clapType" , BonOdori . typeClap . SideClap , "Clap Type" , "Set the type of clap." ) ,
2024-04-08 02:18:51 +00:00
new Param ( "semitone" , new EntityTypes . Note ( offsetToC : false ) , "Semitone" , "Set the number of semitones up or down this note should be pitched." ) ,
2024-03-26 12:13:09 +00:00
} ,
2024-02-26 01:44:56 +00:00
} ,
2024-03-06 22:35:58 +00:00
2024-03-26 12:13:09 +00:00
new GameAction ( "don" , "Don" )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
function = delegate {
var e = eventCaller . currentEntity ;
string variation = "variation" + ( new string [ ] { "Don" , "Do" , "Do_n" } ) [ e [ "type" ] ] ;
BonOdori . instance . PlayDon ( e . beat , e [ variation ] , e [ "type" ] , e [ "semitone" ] ) ;
} ,
2024-02-26 01:44:56 +00:00
defaultLength = 1f ,
parameters = new List < Param > ( )
{
new Param ( "type" , BonOdori . typeDon . Don , "Type" , "Set the type of voiceline" , new ( ) {
2024-03-26 12:13:09 +00:00
new ( ( x , _ ) = > ( int ) x = = 0 , new string [ ] { "variationDon" } ) ,
new ( ( x , _ ) = > ( int ) x = = 1 , new string [ ] { "variationDo" } ) ,
new ( ( x , _ ) = > ( int ) x = = 2 , new string [ ] { "variationDo_n" } ) ,
} ) ,
2024-04-08 02:18:51 +00:00
new Param ( "variationDon" , new EntityTypes . NoteSampleDropdown ( BonOdori . variationDon . DonA , BonOdori . GetSample , "semitone" ) , "Don Type" , "Set the variation of the voice line." ) ,
new Param ( "variationDo" , new EntityTypes . NoteSampleDropdown ( BonOdori . variationDo . DoC , BonOdori . GetSample , "semitone" ) , "Do Type" , "Set the variation of the voice line." ) ,
new Param ( "variationDo_n" , new EntityTypes . NoteSampleDropdown ( BonOdori . variationDo_n . Do_nA , BonOdori . GetSample , "semitone" ) , "Do-n Type" , "Set the variation of the voice line." ) ,
new Param ( "semitone" , new EntityTypes . Note ( offsetToC : false ) , "Semitone" , "Set the number of semitones up or down this note should be pitched." ) ,
2024-03-26 12:13:09 +00:00
} ,
2024-02-26 01:44:56 +00:00
} ,
2024-03-06 22:35:58 +00:00
2024-02-26 01:44:56 +00:00
new GameAction ( "show text" , "Show Text" )
{
2024-03-26 12:13:09 +00:00
function = delegate { var e = eventCaller . currentEntity ; BonOdori . instance . ShowText ( e [ "line 1" ] , e [ "line 2" ] , e [ "line 3" ] , e [ "line 4" ] , e [ "line 5" ] ) ; } ,
2024-02-26 01:44:56 +00:00
defaultLength = 1f ,
parameters = new List < Param > ( )
2024-03-26 12:13:09 +00:00
{
new Param ( "whichLine" , new EntityTypes . Integer ( 1 , 5 , 1 ) , "Line" , "Which line to modify." , new ( )
{
new ( ( x , _ ) = > ( int ) x = = 1 , new string [ ] { "line 1" } ) ,
new ( ( x , _ ) = > ( int ) x = = 2 , new string [ ] { "line 2" } ) ,
new ( ( x , _ ) = > ( int ) x = = 3 , new string [ ] { "line 3" } ) ,
new ( ( x , _ ) = > ( int ) x = = 4 , new string [ ] { "line 4" } ) ,
new ( ( x , _ ) = > ( int ) x = = 5 , new string [ ] { "line 5" } ) ,
} ) ,
2024-02-26 01:44:56 +00:00
new Param ( "line 1" , "Type r| for red text, g| for green text and y| for yellow text. These can be used multiple times in a single line." , "Line 1" , "Set the text for line 1." ) ,
new Param ( "line 2" , "" , "Line 2" , "Set the text for line 2." ) ,
2024-03-26 12:13:09 +00:00
new Param ( "line 3" , "" , "Line 3" , "Set the text for line 3." ) ,
2024-02-26 01:44:56 +00:00
new Param ( "line 4" , "" , "Line 4" , "Set the text for line 4." ) ,
new Param ( "line 5" , "" , "Line 5" , "Set the text for line 5." ) ,
} ,
priority = 1
} ,
2024-03-26 12:13:09 +00:00
new GameAction ( "delete text" , "Delete Text" )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
function = delegate { var e = eventCaller . currentEntity ; BonOdori . instance . DeleteText ( e [ "line 1" ] , e [ "line 2" ] , e [ "line 3" ] , e [ "line 4" ] , e [ "line 5" ] ) ; } ,
2024-02-26 01:44:56 +00:00
defaultLength = 1f ,
parameters = new List < Param > ( )
{
new Param ( "line 1" , false , "Line 1" , "Delete the contents of line 1." ) ,
new Param ( "line 2" , false , "Line 2" , "Delete the contents of line 2." ) ,
new Param ( "line 3" , false , "Line 3" , "Delete the contents of line 3." ) ,
new Param ( "line 4" , false , "Line 4" , "Delete the contents of line 4." ) ,
new Param ( "line 5" , false , "Line 5" , "Delete the contents of line 5." ) ,
} ,
} ,
2024-03-26 12:13:09 +00:00
new GameAction ( "scroll text" , "Scroll Text" )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
function = delegate { var e = eventCaller . currentEntity ; BonOdori . instance . ScrollText ( e . beat , e . length , e [ "line 1" ] , e [ "line 2" ] , e [ "line 3" ] , e [ "line 4" ] , e [ "line 5" ] ) ; } ,
2024-02-26 01:44:56 +00:00
defaultLength = 1f ,
resizable = true ,
parameters = new List < Param > ( )
{
new Param ( "line 1" , false , "Line 1" , "Scroll the contents of line 1." ) ,
new Param ( "line 2" , false , "Line 2" , "Scroll the contents of line 2." ) ,
new Param ( "line 3" , false , "Line 3" , "Scroll the contents of line 3." ) ,
new Param ( "line 4" , false , "Line 4" , "Scroll the contents of line 4." ) ,
new Param ( "line 5" , false , "Line 5" , "Scroll the contents of line 5." ) ,
} ,
} ,
2024-03-26 12:13:09 +00:00
new GameAction ( "bow" , "Bow" )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
function = delegate { BonOdori . instance . Bow ( eventCaller . currentEntity . beat , eventCaller . currentEntity . length ) ; } ,
2024-02-26 01:44:56 +00:00
defaultLength = 2f ,
resizable = true ,
} ,
2024-03-26 12:13:09 +00:00
2024-02-26 01:44:56 +00:00
// new GameAction("spin", "Spin")
// {
2024-03-26 12:13:09 +00:00
// function = delegate { BonOdori.instance.Spin(eventCaller.currentEntity.beat, eventCaller.currentEntity.length);},
2024-02-26 01:44:56 +00:00
// defaultLength = 1f,
// },
2024-03-26 12:13:09 +00:00
new GameAction ( "toggle bg" , "Toggle Darker Background" )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
function = delegate { BonOdori . instance . DarkBG ( eventCaller . currentEntity . beat , eventCaller . currentEntity [ "toggle" ] , eventCaller . currentEntity . length ) ; } ,
2024-02-26 01:44:56 +00:00
defaultLength = 1f ,
parameters = new List < Param > ( )
{
2024-04-08 18:44:27 +00:00
new Param ( "toggle" , true , "Darken Background" , "Darkens the background." ) ,
2024-02-26 01:44:56 +00:00
}
} ,
2024-03-26 12:13:09 +00:00
} ,
2024-03-29 02:35:07 +00:00
new List < string > ( ) { "agb" , "normal" } , "agbBonOdori" , "en" , new List < string > ( ) { } ,
chronologicalSortKey : 10
2024-03-26 12:13:09 +00:00
) ;
2024-03-06 22:35:58 +00:00
}
2024-02-26 01:44:56 +00:00
} ;
} ;
namespace HeavenStudio.Games
{
public class BonOdori : Minigame
{
2024-03-06 22:35:58 +00:00
string prefix ;
double beatUniversal ;
2024-03-26 12:13:09 +00:00
bool noBopPlayer = false ;
bool noBopDonpans = false ;
List < double > noBopBeatsPlayer = new ( ) ;
List < double > noBopBeatsDonpans = new ( ) ;
2024-02-26 01:44:56 +00:00
string suffix ;
SpriteRenderer darkPlane ;
2024-03-26 12:13:09 +00:00
string clapTypeString = "ClapFront" ;
string [ ] originalTexts = new string [ 5 ] ;
Coroutine [ ] Scrolls = new Coroutine [ 5 ] ;
2024-02-26 01:44:56 +00:00
Coroutine DarkerBG ;
bool darkBgIsOn = false ;
2024-03-26 12:13:09 +00:00
[SerializeField] TMP_Text [ ] Texts ;
[SerializeField] TMP_Text [ ] TextsBlue ;
[SerializeField] Animator [ ] Donpans ;
[SerializeField] Animator [ ] DonpansFace ;
2024-02-26 01:44:56 +00:00
[SerializeField] Animator Judge ;
2024-03-26 12:13:09 +00:00
[SerializeField] Animator JudgeFace ;
2024-02-26 01:44:56 +00:00
[SerializeField] GameObject DarkPlane ;
public enum typeClap
{
SideClap = 0 ,
FrontClap = 1
2024-03-06 22:35:58 +00:00
}
private static List < QueuedClaps > queuedClaps = new ( ) ;
private struct QueuedClaps
{
public double beat ;
public int variation ;
public int typeSpeak ;
public bool muted ;
public int clapType ;
public int semitone ;
2024-02-26 01:44:56 +00:00
}
2024-03-26 12:13:09 +00:00
2024-02-26 01:44:56 +00:00
public enum typePan
{
Pan = 0 ,
Pa = 1 ,
Pa_n = 2
}
public enum typeDon
{
Don = 0 ,
Do = 1 ,
Do_n = 2
}
public enum variationPan
{
PanC = 0 ,
PanE = 1 ,
PanA = 2
}
public enum variationPa_n
{
Pa_nA = 0 ,
Pa_nC = 1
}
public enum variationPa
2024-03-06 22:35:58 +00:00
{
2024-02-26 01:44:56 +00:00
PaG = 0
}
public enum variationDon
{
DonA = 0 ,
DonD = 1 ,
2024-03-06 22:35:58 +00:00
DonC = 2 ,
2024-02-26 01:44:56 +00:00
DonG = 3
}
public enum variationDo_n
{
Do_nA = 0 ,
Do_nG = 1
}
public enum variationDo
{
DoC = 0 ,
DoG = 1
}
2024-03-26 12:13:09 +00:00
2024-04-08 02:18:51 +00:00
public static readonly Dictionary < object , NoteSample > NoteSamples = new ( )
{
{ variationPan . PanC , new ( "bonOdori/pan1" , 3 , 4 ) } ,
{ variationPan . PanE , new ( "bonOdori/pan2" , 7 , 4 ) } ,
{ variationPan . PanA , new ( "bonOdori/pan3" , 0 , 4 ) } ,
{ variationPa_n . Pa_nA , new ( "bonOdori/pa_n1" , 0 , 4 ) } ,
{ variationPa_n . Pa_nC , new ( "bonOdori/pa_n2" , 3 , 4 ) } ,
{ variationPa . PaG , new ( "bonOdori/pa1" , 7 , 4 ) } ,
{ variationDon . DonA , new ( "bonOdori/don1" , 0 , 4 ) } ,
{ variationDon . DonD , new ( "bonOdori/don2" , 5 , 4 ) } ,
{ variationDon . DonC , new ( "bonOdori/don3" , 3 , 4 ) } ,
{ variationDon . DonG , new ( "bonOdori/don4" , 10 , 4 ) } ,
{ variationDo_n . Do_nA , new ( "bonOdori/do_n1" , 0 , 4 ) } ,
{ variationDo_n . Do_nG , new ( "bonOdori/do_n2" , 7 , 4 ) } ,
{ variationDo . DoC , new ( "bonOdori/do1" , 3 , 4 ) } ,
{ variationDo . DoG , new ( "bonOdori/do2" , 7 , 4 ) }
} ;
public static NoteSample GetSample ( object sampleEnum )
{
return NoteSamples [ sampleEnum ] ;
}
2024-02-26 01:44:56 +00:00
public static BonOdori instance { get ; set ; }
2024-03-26 12:13:09 +00:00
public void Awake ( )
2024-02-26 01:44:56 +00:00
{
instance = this ;
2024-03-26 12:13:09 +00:00
SetupBopRegion ( "bonOdori" , "bop" , "auto" ) ;
2024-02-26 01:44:56 +00:00
2024-03-26 12:13:09 +00:00
darkPlane = DarkPlane . GetComponent < SpriteRenderer > ( ) ;
2024-02-26 01:44:56 +00:00
}
2024-03-26 12:13:09 +00:00
2024-02-26 01:44:56 +00:00
public void OnStop ( )
{
2024-03-06 22:35:58 +00:00
DarkPlane . GetComponent < SpriteRenderer > ( ) . color = new Color ( 1f , 1f , 1f , 0f ) ;
2024-03-26 12:13:09 +00:00
}
2024-03-06 22:35:58 +00:00
2024-03-26 12:13:09 +00:00
public override void OnLateBeatPulse ( double beat )
{
if ( BeatIsInBopRegion ( beat ) ) Bop ( beat ) ;
noBopBeatsPlayer . RemoveAll ( x = > x + 4 < beat ) ;
noBopBeatsDonpans . RemoveAll ( x = > x + 4 < beat ) ;
2024-02-26 01:44:56 +00:00
}
2024-03-26 12:13:09 +00:00
2024-02-26 01:44:56 +00:00
public void Update ( )
{
2024-03-26 12:13:09 +00:00
var cond = Conductor . instance ;
if ( ! cond . isPlaying | | cond . isPaused ) return ;
if ( ! cond . NotStopped ( ) )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
for ( int i = 0 ; i < Scrolls . Length ; i + + )
{
StopCoroutine ( Scrolls [ i ] ) ;
Texts [ i ] . text = "" ;
TextsBlue [ i ] . text = "" ;
TextsBlue [ i ] . GetComponent < TextMeshPro > ( ) . SetMask ( 0 , new Vector4 ( - 10f , - 10f , - 10f , 10 ) ) ;
}
2024-02-26 01:44:56 +00:00
StopCoroutine ( DarkerBG ) ;
}
2024-03-06 22:35:58 +00:00
if ( PlayerInput . GetIsAction ( BonOdori . InputAction_BasicPress ) & & ! IsExpectingInputNow ( InputAction_BasicPress ) )
{
2024-02-26 01:44:56 +00:00
ScoreMiss ( ) ;
SoundByte . PlayOneShotGame ( "bonOdori/clap" ) ;
2024-03-26 12:13:09 +00:00
Donpans [ 0 ] . DoScaledAnimationAsync ( clapTypeString , 0.5f ) ;
2024-03-06 22:35:58 +00:00
2024-03-26 12:13:09 +00:00
if ( clapTypeString is "ClapFront" )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
var currentBeat = Conductor . instance . songPositionInBeatsAsDouble ;
noBopBeatsPlayer . Add ( currentBeat ) ;
BeatAction . New ( instance , new List < BeatAction . Action > ( )
{
new BeatAction . Action ( currentBeat , delegate {
noBopPlayer = true ;
} ) ,
new BeatAction . Action ( currentBeat + 2d , delegate {
if ( noBopBeatsPlayer [ ^ 1 ] = = currentBeat ) noBopPlayer = false ;
} )
} ) ;
}
2024-03-06 22:35:58 +00:00
}
2024-02-26 01:44:56 +00:00
}
2024-03-26 12:13:09 +00:00
2024-03-06 22:35:58 +00:00
public override void OnGameSwitch ( double beat )
{
if ( queuedClaps . Count > 0 )
{
foreach ( var clap in queuedClaps ) Clap ( clap . beat , clap . variation , clap . typeSpeak , clap . muted , clap . clapType , clap . semitone ) ;
queuedClaps . Clear ( ) ;
}
2024-02-26 01:44:56 +00:00
}
2024-03-06 22:35:58 +00:00
public void PreClap ( double beat , int variation , int typeSpeak , bool muted , int clapType , int semitone )
{
if ( GameManager . instance . currentGame = = "bonOdori" )
{
instance . Clap ( beat , variation , typeSpeak , muted , clapType , semitone ) ;
}
else
{
queuedClaps . Add ( new QueuedClaps ( )
{
beat = beat ,
variation = variation ,
typeSpeak = typeSpeak ,
muted = muted ,
clapType = clapType ,
semitone = semitone
} ) ;
}
}
2024-03-26 12:13:09 +00:00
public void Clap ( double beat , int variation , int typeSpeak , bool muted , int clapType , int semitone )
2024-03-06 22:35:58 +00:00
{
2024-03-26 12:13:09 +00:00
if ( ! muted )
2024-02-26 01:44:56 +00:00
{
2024-03-06 22:35:58 +00:00
string clip = typeSpeak switch
{
0 = > "pan" ,
2024-03-10 00:36:44 +00:00
1 = > "pa" ,
2 or _ = > "pa_n" ,
2024-03-06 22:35:58 +00:00
} ;
var pitch = SoundByte . GetPitchFromSemiTones ( semitone , true ) ;
2024-03-26 12:13:09 +00:00
SoundByte . PlayOneShotGame ( $"bonOdori/" + clip + ( variation + 1 ) , beat , pitch ) ;
2024-03-06 22:35:58 +00:00
}
2024-03-26 12:13:09 +00:00
SoundByte . PlayOneShotGame ( "bonOdori/clap2" , beat , volume : 0.5f ) ;
beatUniversal = beat ;
noBopBeatsDonpans . Add ( beatUniversal ) ;
BeatAction . New ( instance , new List < BeatAction . Action > ( )
{
new BeatAction . Action ( beat - 0.1d , delegate {
clapTypeString = clapType switch {
0 = > "ClapSide" ,
1 or _ = > "ClapFront" ,
} ;
} ) ,
new BeatAction . Action ( beat , delegate {
foreach ( var chara in Donpans [ 1. . Donpans . Length ] ) {
chara . DoScaledAnimationAsync ( clapTypeString , 0.5f ) ;
}
} ) ,
new BeatAction . Action ( beat + 0.05d , delegate {
if ( clapTypeString is "ClapFront" ) noBopDonpans = true ;
} ) ,
new BeatAction . Action ( beat + 1.01d , delegate {
if ( clapTypeString is "ClapFront" ) noBopDonpans = false ;
} ) ,
} ) ;
ScheduleInput ( beat , 0f , InputAction_BasicPress , Success , Miss , Empty ) ;
2024-03-06 22:35:58 +00:00
}
2024-03-26 12:13:09 +00:00
public void PlayDon ( double beat , int variation , int typeSpeak , int semitone )
2024-03-06 22:35:58 +00:00
{
string clip = typeSpeak switch
{
0 = > "don" ,
2024-03-10 00:36:44 +00:00
1 = > "do" ,
2 or _ = > "do_n" ,
2024-03-06 22:35:58 +00:00
} ;
var pitch = SoundByte . GetPitchFromSemiTones ( semitone , true ) ;
SoundByte . PlayOneShotGame ( $"bonOdori/" + clip + ( variation + 1 ) , beat , pitch ) ;
2024-03-26 12:13:09 +00:00
var firstPan = EventCaller . GetAllInGameManagerList ( "bonOdori" , new string [ ] { "pan" } ) . Find ( x = > x . beat > = beat ) ;
if ( firstPan is not null )
{
clapTypeString = firstPan [ "clapType" ] switch {
0 = > "ClapSide" ,
1 or _ = > "ClapFront" ,
} ;
}
2024-02-26 01:44:56 +00:00
}
2024-03-06 22:35:58 +00:00
2024-02-26 01:44:56 +00:00
public void Success ( PlayerActionEvent caller , float state )
{
2024-03-26 12:13:09 +00:00
Donpans [ 0 ] . DoScaledAnimationAsync ( clapTypeString , 0.5f ) ;
if ( state < = - 1f | | state > = 1f )
2024-03-06 22:35:58 +00:00
{
2024-03-26 12:13:09 +00:00
SoundByte . PlayOneShot ( "nearMiss" ) ;
return ;
2024-03-06 22:35:58 +00:00
}
2024-03-26 12:13:09 +00:00
SoundByte . PlayOneShotGame ( "bonOdori/clap" ) ;
2024-02-26 01:44:56 +00:00
2024-03-26 12:13:09 +00:00
var currentBeat = Conductor . instance . songPositionInBeatsAsDouble ;
double closest = noBopBeatsDonpans . Aggregate ( ( x , y ) = > Math . Abs ( x - currentBeat ) < Math . Abs ( y - currentBeat ) ? x : y ) ;
noBopBeatsPlayer . Add ( closest ) ;
if ( clapTypeString is "ClapFront" )
2024-03-06 22:35:58 +00:00
{
BeatAction . New ( instance , new List < BeatAction . Action > ( )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
new BeatAction . Action ( closest + 0.05d , delegate {
noBopPlayer = true ;
} ) ,
new BeatAction . Action ( closest + 1.01d , delegate {
if ( noBopBeatsPlayer [ ^ 1 ] = = closest ) noBopPlayer = false ;
} )
} ) ;
2024-03-06 22:35:58 +00:00
}
2024-02-26 01:44:56 +00:00
}
2024-03-06 22:35:58 +00:00
2024-02-26 01:44:56 +00:00
public void Miss ( PlayerActionEvent caller )
{
2024-03-26 12:13:09 +00:00
// SoundByte.PlayOneShot("miss");
2024-03-06 22:35:58 +00:00
BeatAction . New ( instance , new List < BeatAction . Action > ( )
{
2024-03-26 12:13:09 +00:00
new BeatAction . Action ( beatUniversal + 1d , delegate { JudgeFace . Play ( "Sad" ) ; } ) ,
new BeatAction . Action ( beatUniversal + 3d , delegate { JudgeFace . Play ( "Neutral" ) ; } )
} ) ;
2024-02-26 01:44:56 +00:00
2024-03-26 12:13:09 +00:00
}
2024-02-26 01:44:56 +00:00
2024-03-26 12:13:09 +00:00
public void Empty ( PlayerActionEvent caller ) { }
2024-02-26 01:44:56 +00:00
2024-03-26 12:13:09 +00:00
string ConvertText ( string text , bool isScroll = false )
2024-03-06 22:35:58 +00:00
{
2024-03-26 12:13:09 +00:00
if ( text . Contains ( "r|" ) | text . Contains ( "y|" ) | text . Contains ( "g|" ) | text . Contains ( "s|" ) | text . Contains ( "d|" ) )
2024-02-26 01:44:56 +00:00
{
2024-03-06 22:35:58 +00:00
if ( ! isScroll )
{
return text . Replace ( "r|" , "<color=#ff0000>" )
2024-03-26 12:13:09 +00:00
. Replace ( "g|" , "<color=#00ff00>" )
. Replace ( "y|" , "<color=#ffff00>" )
. Replace ( "s|" , "<size=0.9375>" )
. Replace ( "|s" , "</size>" )
. Replace ( "d|" , "" )
+ "</color>" ;
2024-03-06 22:35:58 +00:00
}
else
{
return text . Replace ( "r|" , "<color=#ff00ff>" )
2024-03-26 12:13:09 +00:00
. Replace ( "g|" , "<color=#00ffff>" )
. Replace ( "y|" , "<color=#ffffff>" )
. Replace ( "s|" , "<size=0.9375>" )
. Replace ( "|s" , "</size>" )
. Replace ( "d|" , "" )
+ "</color>" ;
2024-03-06 22:35:58 +00:00
}
}
2024-02-26 01:44:56 +00:00
return text ;
2024-03-06 22:35:58 +00:00
}
2024-02-26 01:44:56 +00:00
2024-03-26 12:13:09 +00:00
int [ ] GetTextPositions ( string text )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
string preSplitedText = text . Replace ( "r|" , "" )
. Replace ( "g|" , "" )
. Replace ( "y|" , "" )
. Replace ( "s|" , "" )
. Replace ( "|s" , "" ) ;
string [ ] parts = preSplitedText . Split ( new string [ ] { "d|" } , StringSplitOptions . None ) ;
2024-03-06 22:35:58 +00:00
2024-03-26 12:13:09 +00:00
List < int > positions = new List < int > ( ) ;
int currentPosition = 0 ;
foreach ( var part in parts )
2024-03-06 22:35:58 +00:00
{
2024-03-26 12:13:09 +00:00
positions . Add ( currentPosition ) ;
currentPosition + = part . Length ;
2024-03-06 22:35:58 +00:00
}
2024-03-26 12:13:09 +00:00
return positions . ToArray ( ) ;
}
2024-03-06 22:35:58 +00:00
2024-03-26 12:13:09 +00:00
public void ShowText ( string text1 , string text2 , string text3 , string text4 , string text5 )
{
var texts = new string [ ] { text1 , text2 , text3 , text4 , text5 } ;
2024-03-06 22:35:58 +00:00
2024-03-26 12:13:09 +00:00
for ( int i = 0 ; i < texts . Length ; i + + )
2024-03-06 22:35:58 +00:00
{
2024-03-26 12:13:09 +00:00
var text = texts [ i ] ;
if ( text is not "" and not "Type r| for red text, g| for green text and y| for yellow text. These can be used multiple times in a single line." )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
var scroll = Scrolls [ i ] ;
var textTMP = Texts [ i ] ;
var textBlueTMP = TextsBlue [ i ] ;
if ( scroll is not null )
{
StopCoroutine ( scroll ) ;
scroll = null ;
}
textBlueTMP . GetComponent < TextMeshPro > ( ) . SetMask ( 0 , new Vector4 ( - 10f , - 10f , - 10f , 10 ) ) ;
2024-02-26 01:44:56 +00:00
2024-03-26 12:13:09 +00:00
originalTexts [ i ] = text ;
text = ConvertText ( originalTexts [ i ] , false ) ;
2024-02-26 01:44:56 +00:00
2024-03-26 12:13:09 +00:00
textTMP . text = text ;
textBlueTMP . text = ConvertText ( originalTexts [ i ] , true ) ;
2024-02-26 01:44:56 +00:00
}
2024-03-06 22:35:58 +00:00
}
2024-02-26 01:44:56 +00:00
}
2024-03-26 12:13:09 +00:00
2024-03-06 22:35:58 +00:00
public void DeleteText ( bool text1 , bool text2 , bool text3 , bool text4 , bool text5 )
{
2024-03-26 12:13:09 +00:00
var texts = new bool [ ] { text1 , text2 , text3 , text4 , text5 } ;
for ( int i = 0 ; i < texts . Length ; i + + )
2024-03-06 22:35:58 +00:00
{
2024-03-26 12:13:09 +00:00
if ( texts [ i ] = = true )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
var scroll = Scrolls [ i ] ;
var textTMP = Texts [ i ] ;
var textBlueTMP = TextsBlue [ i ] ;
if ( scroll is not null )
{
StopCoroutine ( scroll ) ;
scroll = null ;
}
textBlueTMP . GetComponent < TextMeshPro > ( ) . SetMask ( 0 , new Vector4 ( - 10 , - 10 , - 10 , 10 ) ) ;
textTMP . text = "" ;
textBlueTMP . text = "" ;
2024-02-26 01:44:56 +00:00
}
}
}
2024-03-26 12:13:09 +00:00
IEnumerator SmoothText ( double beat , float length , TextMeshPro textTMP , float [ ] maskEdges )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
var cond = Conductor . instance ;
2024-03-06 22:35:58 +00:00
float startTime = Time . time ;
float endTime = startTime + length ;
2024-03-26 12:13:09 +00:00
float duration = ( ( length / cond . GetBpmAtBeat ( beat ) ) * 60 ) ;
int len = maskEdges . Length ;
2024-02-26 01:44:56 +00:00
2024-03-06 22:35:58 +00:00
while ( Time . time < endTime )
{
float t = ( ( Time . time - startTime ) / duration ) ;
2024-03-26 12:13:09 +00:00
int index = Math . Max ( 0 , Math . Min ( ( int ) Math . Floor ( t * ( len - 1 ) ) , len - 2 ) ) ;
t = t * ( len - 1 ) - index ;
float maskValue = Mathf . Lerp ( maskEdges [ index ] , maskEdges [ index + 1 ] , t ) ;
textTMP . SetMask ( 0 , new Vector4 ( - 10 , - 10 , maskValue , 10 ) ) ;
2024-02-26 01:44:56 +00:00
2024-03-06 22:35:58 +00:00
yield return null ;
}
}
2024-03-26 12:13:09 +00:00
public void ScrollText ( double beat , float length , bool text1 , bool text2 , bool text3 , bool text4 , bool text5 )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
var texts = new bool [ ] { text1 , text2 , text3 , text4 , text5 } ;
for ( int i = 0 ; i < texts . Length ; i + + )
2024-03-06 22:35:58 +00:00
{
2024-03-26 12:13:09 +00:00
if ( texts [ i ] )
{
var textTMP = TextsBlue [ i ] . GetComponent < TextMeshPro > ( ) ;
int [ ] positions = GetTextPositions ( originalTexts [ i ] ) ;
var maskEdges = new List < float > ( ) ;
foreach ( var pos in positions )
{
maskEdges . Add ( textTMP . textInfo . characterInfo [ pos ] . topLeft . x ) ;
}
maskEdges [ 0 ] = - textTMP . rectTransform . sizeDelta . x / 2 ;
maskEdges . Add ( maskEdges [ 0 ] + textTMP . preferredWidth ) ;
2024-03-06 22:35:58 +00:00
2024-03-26 12:13:09 +00:00
Scrolls [ i ] = StartCoroutine ( SmoothText ( beat , length , textTMP , maskEdges . ToArray ( ) ) ) ;
}
}
2024-03-06 22:35:58 +00:00
}
2024-03-26 12:13:09 +00:00
public void ToggleBop ( double beat , float length , bool bopOrNah , bool autoBop )
2024-03-06 22:35:58 +00:00
{
2024-03-26 12:13:09 +00:00
if ( autoBop ) return ;
if ( bopOrNah )
2024-02-26 01:44:56 +00:00
{
for ( int i = 0 ; i < length ; i + + )
{
2024-03-26 12:13:09 +00:00
double bopBeat = beat + i ;
BeatAction . New ( instance , new ( ) { new BeatAction . Action ( bopBeat , delegate { Bop ( bopBeat ) ; } ) } ) ;
}
BeatAction . New ( instance , new List < BeatAction . Action > ( )
{
new BeatAction . Action ( beat + length , delegate
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
if ( ! noBopBeatsDonpans . Any ( x = > Math . Abs ( x - ( beat + length ) ) < = double . Epsilon ) ) {
foreach ( var chara in Donpans ) {
chara . Play ( "NeutralBopped" ) ;
}
}
} )
} ) ;
}
}
2024-02-26 01:44:56 +00:00
2024-03-26 12:13:09 +00:00
private void Bop ( double beat )
{
if ( ! noBopPlayer & ! noBopBeatsPlayer . Any ( x = > Math . Abs ( x - beat ) < = double . Epsilon ) )
{
if ( ! Donpans [ 0 ] . IsPlayingAnimationNames ( "ClapSide" , "ClapFront" ) ) {
Donpans [ 0 ] . DoScaledAnimationAsync ( "Bop" , 0.5f ) ;
2024-02-26 01:44:56 +00:00
}
2024-03-06 22:35:58 +00:00
}
2024-03-26 12:13:09 +00:00
if ( ! noBopDonpans & ! noBopBeatsDonpans . Any ( x = > Math . Abs ( x - beat ) < = double . Epsilon ) )
2024-03-06 22:35:58 +00:00
{
2024-03-26 12:13:09 +00:00
foreach ( var chara in Donpans [ 1. . Donpans . Length ] ) {
if ( ! chara . IsPlayingAnimationNames ( "ClapSide" , "ClapFront" ) ) {
chara . DoScaledAnimationAsync ( "Bop" , 0.5f ) ;
}
}
2024-03-06 22:35:58 +00:00
}
2024-03-26 12:13:09 +00:00
Judge . DoScaledAnimationAsync ( "Bop" , 0.5f ) ;
2024-02-26 01:44:56 +00:00
}
2024-03-26 12:13:09 +00:00
2024-03-06 22:35:58 +00:00
public void Bow ( double beat , float length )
2024-02-26 01:44:56 +00:00
{
2024-03-26 12:13:09 +00:00
noBopPlayer = true ;
noBopDonpans = true ;
foreach ( var chara in Donpans ) {
chara . Play ( "Bow" ) ;
2024-03-06 22:35:58 +00:00
}
BeatAction . New ( instance , new List < BeatAction . Action > ( )
2024-03-26 12:13:09 +00:00
{
new BeatAction . Action ( beat + length , delegate {
noBopPlayer = false ;
noBopDonpans = false ;
if ( ! noBopBeatsPlayer . Any ( x = > Math . Abs ( x - ( beat + length ) ) < = double . Epsilon ) ) {
Donpans [ 0 ] . Play ( "NeutralBopped" ) ;
if ( BeatIsInBopRegion ( beat + length ) ) Bop ( beat + length ) ;
}
if ( ! noBopBeatsDonpans . Any ( x = > Math . Abs ( x - ( beat + length ) ) < = double . Epsilon ) ) {
foreach ( var chara in Donpans [ 1. . Donpans . Length ] ) {
chara . Play ( "NeutralBopped" ) ;
}
if ( BeatIsInBopRegion ( beat + length ) ) Bop ( beat + length ) ;
}
} )
} ) ;
2024-03-06 22:35:58 +00:00
}
2024-03-26 12:13:09 +00:00
2024-03-06 22:35:58 +00:00
// public void Spin(double beat, float length)
// {
// }
2024-03-26 12:13:09 +00:00
2024-03-06 22:35:58 +00:00
public void DarkBG ( double beat , bool toggle , float length )
2024-02-26 01:44:56 +00:00
{
2024-03-06 22:35:58 +00:00
DarkerBG = StartCoroutine ( DarkBGCoroutine ( beat , toggle , length ) ) ;
2024-02-26 01:44:56 +00:00
}
2024-03-26 12:13:09 +00:00
2024-03-06 22:35:58 +00:00
IEnumerator DarkBGCoroutine ( double beat , bool toggle , float length )
2024-02-26 01:44:56 +00:00
{
2024-03-06 22:35:58 +00:00
if ( toggle )
{
if ( darkBgIsOn )
{
yield return null ;
}
else
{
float startTime = Time . time ;
2024-03-26 12:13:09 +00:00
var cond = Conductor . instance ;
float realLength = length / cond . GetBpmAtBeat ( beat ) * 60 ;
2024-03-06 22:35:58 +00:00
while ( Time . time < realLength + startTime )
{
darkPlane . color = new Color ( 1f , 1f , 1f , Mathf . Lerp ( 0f , 0.4666f , ( Time . time - startTime ) / realLength ) ) ;
darkBgIsOn = true ;
yield return null ;
}
}
}
else
{
if ( ! darkBgIsOn )
{
yield return null ;
}
else
{
float startTime = Time . time ;
2024-03-26 12:13:09 +00:00
var cond = Conductor . instance ;
float realLength = length / cond . GetBpmAtBeat ( beat ) * 60 ;
2024-03-06 22:35:58 +00:00
while ( Time . time < realLength + startTime )
{
darkPlane . color = new Color ( 1f , 1f , 1f , Mathf . Lerp ( 0.4666f , 0f , ( Time . time - startTime ) / realLength ) ) ;
darkBgIsOn = true ;
yield return null ;
}
}
}
}
2024-02-26 01:44:56 +00:00
}
2024-03-06 22:35:58 +00:00
}