cda15b8cf0
try to fix weird performance regression in board meeting
488 lines
18 KiB
C#
488 lines
18 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using HeavenStudio.Util;
|
|
using DG.Tweening;
|
|
|
|
namespace HeavenStudio.Games.Loaders
|
|
{
|
|
using static Minigames;
|
|
|
|
public static class RvlBoardMeetingLoader
|
|
{
|
|
public static Minigame AddGame(EventCaller eventCaller)
|
|
{
|
|
return new Minigame("boardMeeting", "Board Meeting", "d37912", false, false, new List<GameAction>()
|
|
{
|
|
new GameAction("bop", "Bop")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; BoardMeeting.instance.Bop(e.beat, e.length, e["bop"], e["auto"]); },
|
|
resizable = true,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("bop", true, "Bop", "Toggle if the pigs & assistant should bop for the duration of this event."),
|
|
new Param("auto", false, "Bop (Auto)", "Toggle if the pigs & assistant should automatically bop until another Bop event is reached.")
|
|
}
|
|
},
|
|
new GameAction("prepare", "Prepare")
|
|
{
|
|
function = delegate { BoardMeeting.instance.Prepare(); }
|
|
},
|
|
new GameAction("spinEqui", "Spin")
|
|
{
|
|
function = delegate {var e = eventCaller.currentEntity; BoardMeeting.instance.SpinEqui(e.beat, e.length); },
|
|
resizable = true,
|
|
priority = 2
|
|
},
|
|
new GameAction("spin", "Spin (Range)")
|
|
{
|
|
function = delegate {var e = eventCaller.currentEntity; BoardMeeting.instance.Spin(e["start"], e["end"]); },
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("start", new EntityTypes.Integer(1, 6, 1), "Starting Pig", "Choose the leftmost pig in the range to start spinning."),
|
|
new Param("end", new EntityTypes.Integer(1, 6, 4), "Ending Pig", "Choose the rightmost pig in the range to start spinning.")
|
|
},
|
|
priority = 2
|
|
},
|
|
new GameAction("stop", "Stop")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; BoardMeeting.instance.Stop(e.beat, e.length); },
|
|
resizable = true,
|
|
priority = 1
|
|
},
|
|
new GameAction("assStop", "Assistant Stop")
|
|
{
|
|
function = delegate { var e = eventCaller.currentEntity; BoardMeeting.instance.AssistantStop(e.beat); },
|
|
defaultLength = 3f
|
|
},
|
|
new GameAction("changeCount", "Change Pig Number")
|
|
{
|
|
function = delegate { BoardMeeting.instance.ChangeExecutiveCount(eventCaller.currentEntity["amount"]); },
|
|
defaultLength = 0.5f,
|
|
parameters = new List<Param>()
|
|
{
|
|
new Param("amount", new EntityTypes.Integer(3, 5, 4), "Pigs", "Set how many pigs there will be. The player is always the rightmost pig.")
|
|
}
|
|
}
|
|
},
|
|
new List<string>() { "rvl", "normal" },
|
|
"rvlrotation", "en",
|
|
new List<string>() { "en" }
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace HeavenStudio.Games
|
|
{
|
|
using Scripts_BoardMeeting;
|
|
using System;
|
|
|
|
public class BoardMeeting : Minigame
|
|
{
|
|
[Header("Components")]
|
|
[SerializeField] Transform farLeft;
|
|
[SerializeField] Transform farRight;
|
|
[SerializeField] Animator assistantAnim;
|
|
|
|
[Header("Properties")]
|
|
[SerializeField] int executiveCount = 4;
|
|
[SerializeField] List<BMExecutive> executives = new List<BMExecutive>();
|
|
public BMExecutive firstSpinner;
|
|
[SerializeField] float shakeIntensity = 0.5f;
|
|
private bool assistantCanBop = true;
|
|
private bool executivesCanBop = true;
|
|
[NonSerialized] public Sound chairLoopSound = null;
|
|
int missCounter = 0;
|
|
private Tween shakeTween;
|
|
|
|
public static BoardMeeting instance;
|
|
|
|
private void Awake()
|
|
{
|
|
instance = this;
|
|
SetupBopRegion("boardMeeting", "bop", "auto");
|
|
InitExecutives();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
foreach (var evt in scheduledInputs)
|
|
{
|
|
evt.Disable();
|
|
}
|
|
if (chairLoopSound != null)
|
|
{
|
|
chairLoopSound.KillLoop(0);
|
|
chairLoopSound = null;
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
var cond = Conductor.instance;
|
|
|
|
if (cond.isPlaying && !cond.isPaused)
|
|
{
|
|
if (PlayerInput.GetIsAction(InputAction_BasicPressing) && !IsExpectingInputNow(InputAction_BasicPress))
|
|
{
|
|
if (executives[executiveCount - 1].spinning)
|
|
{
|
|
executives[executiveCount - 1].Stop(false);
|
|
SoundByte.PlayOneShotGame("boardMeeting/miss");
|
|
SoundByte.PlayOneShot("miss");
|
|
ScoreMiss();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void OnBeatPulse(double beat)
|
|
{
|
|
if (!BeatIsInBopRegion(beat)) return;
|
|
SingleBop();
|
|
}
|
|
|
|
void SingleBop()
|
|
{
|
|
if (assistantCanBop)
|
|
{
|
|
if (missCounter > 0) assistantAnim.DoScaledAnimationAsync("MissBop", 0.5f);
|
|
else assistantAnim.DoScaledAnimationAsync("Bop", 0.5f);
|
|
}
|
|
if (missCounter > 0) missCounter--;
|
|
if (!executivesCanBop) return;
|
|
foreach (var executive in executives)
|
|
{
|
|
executive.Bop();
|
|
}
|
|
}
|
|
|
|
public void Bop(double beat, float length, bool goBop, bool autoBop)
|
|
{
|
|
if (goBop)
|
|
{
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
BeatAction.New(instance, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat + i, delegate
|
|
{
|
|
SingleBop();
|
|
})
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
public void AssistantStop(double beat)
|
|
{
|
|
assistantCanBop = false;
|
|
string twoSound = "boardMeeting/two";
|
|
if (beat % 1 != 0) twoSound = "boardMeeting/twoUra";
|
|
MultiSound.Play(new MultiSound.Sound[]
|
|
{
|
|
new MultiSound.Sound("boardMeeting/one", beat),
|
|
new MultiSound.Sound(twoSound, beat + 0.5f),
|
|
new MultiSound.Sound("boardMeeting/three", beat + 1),
|
|
new MultiSound.Sound("boardMeeting/stopAll", beat + 2)
|
|
});
|
|
BeatAction.New(instance, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat, delegate { assistantAnim.DoScaledAnimationAsync("One", 0.5f); }),
|
|
new BeatAction.Action(beat + 1, delegate { assistantAnim.DoScaledAnimationAsync("Three", 0.5f); }),
|
|
new BeatAction.Action(beat + 2, delegate
|
|
{
|
|
foreach (var executive in executives)
|
|
{
|
|
if (executive.player) continue;
|
|
executive.Stop();
|
|
}
|
|
if (!executives[executiveCount - 1].spinning)
|
|
{
|
|
if (chairLoopSound != null)
|
|
{
|
|
chairLoopSound.KillLoop(0);
|
|
chairLoopSound = null;
|
|
}
|
|
}
|
|
}),
|
|
new BeatAction.Action(beat + 2.5f, delegate { assistantCanBop = true; })
|
|
});
|
|
ScheduleInput(beat, 2f, InputAction_BasicPress, JustAssistant, MissAssistant, Empty, CanJust);
|
|
}
|
|
|
|
public void Stop(double beat, float length)
|
|
{
|
|
executivesCanBop = false;
|
|
List<BeatAction.Action> stops = new List<BeatAction.Action>();
|
|
for (int i = 0; i < executiveCount; i++)
|
|
{
|
|
if (executives[i].player) break;
|
|
int index = i;
|
|
int ex = executiveCount;
|
|
if (executiveCount < 4) ex = 4;
|
|
if (index < ex - 3)
|
|
{
|
|
SoundByte.PlayOneShotGame("boardMeeting/stopA", beat + length * i);
|
|
}
|
|
else if (index == ex - 3)
|
|
{
|
|
SoundByte.PlayOneShotGame("boardMeeting/stopB", beat + length * i);
|
|
}
|
|
else if (index == ex - 2)
|
|
{
|
|
SoundByte.PlayOneShotGame("boardMeeting/stopC", beat + length * i);
|
|
}
|
|
stops.Add(new BeatAction.Action(beat + length * i, delegate
|
|
{
|
|
if (index == executiveCount - 2 && !executives[executiveCount - 1].spinning)
|
|
{
|
|
if (chairLoopSound != null)
|
|
{
|
|
chairLoopSound.KillLoop(0);
|
|
chairLoopSound = null;
|
|
}
|
|
}
|
|
executives[index].Stop();
|
|
}));
|
|
}
|
|
stops.Add(new BeatAction.Action(beat + length * executiveCount + 0.5f, delegate { executivesCanBop = true; }));
|
|
BeatAction.New(instance, stops);
|
|
ScheduleInput(beat, length * (executiveCount - 1), InputAction_BasicPress, Just, Miss, Empty, CanJust);
|
|
}
|
|
|
|
public void Prepare()
|
|
{
|
|
SoundByte.PlayOneShotGame("boardMeeting/prepare");
|
|
foreach (var executive in executives)
|
|
{
|
|
executive.Prepare();
|
|
}
|
|
}
|
|
|
|
public void SpinEqui(double beat, float length)
|
|
{
|
|
if (chairLoopSound == null) chairLoopSound = SoundByte.PlayOneShotGame("boardMeeting/chairLoop", -1, 1, 1, true);
|
|
firstSpinner = executives[0];
|
|
List<BeatAction.Action> rolls = new List<BeatAction.Action>();
|
|
for (int i = 0; i < executiveCount; i++)
|
|
{
|
|
int index = i;
|
|
rolls.Add(new BeatAction.Action(beat + length * i, delegate
|
|
{
|
|
int ex = executiveCount;
|
|
string soundToPlay = "A";
|
|
if (executiveCount < 4) ex = 4;
|
|
if (index == ex - 3)
|
|
{
|
|
soundToPlay = "B";
|
|
}
|
|
else if (index == ex - 2)
|
|
{
|
|
soundToPlay = "C";
|
|
}
|
|
else if (index == ex - 1)
|
|
{
|
|
soundToPlay = "Player";
|
|
}
|
|
executives[index].Spin(soundToPlay);
|
|
}));
|
|
}
|
|
BeatAction.New(instance, rolls);
|
|
|
|
}
|
|
|
|
public void Spin(int start, int end)
|
|
{
|
|
if (start > executiveCount || end > executiveCount) return;
|
|
bool forceStart = false;
|
|
chairLoopSound?.KillLoop(0);
|
|
if (chairLoopSound == null)
|
|
{
|
|
chairLoopSound = SoundByte.PlayOneShotGame("boardMeeting/chairLoop", -1, 1, 1, true);
|
|
firstSpinner = executives[start - 1];
|
|
forceStart = true;
|
|
}
|
|
for (int i = start - 1; i < end; i++)
|
|
{
|
|
int ex = executiveCount;
|
|
string soundToPlay = "A";
|
|
if (executiveCount < 4) ex = 4;
|
|
if (i == ex - 3)
|
|
{
|
|
soundToPlay = "B";
|
|
}
|
|
else if (i == ex - 2)
|
|
{
|
|
soundToPlay = "C";
|
|
}
|
|
else if (i == ex - 1)
|
|
{
|
|
soundToPlay = "Player";
|
|
}
|
|
executives[i].Spin(soundToPlay, forceStart);
|
|
}
|
|
}
|
|
|
|
public void StopChairLoopSoundIfLastToStop()
|
|
{
|
|
if (executives.FindAll(x => x.spinning).Count > 1) return;
|
|
if (chairLoopSound != null)
|
|
{
|
|
chairLoopSound.KillLoop(0);
|
|
chairLoopSound = null;
|
|
}
|
|
}
|
|
|
|
public void InitExecutives()
|
|
{
|
|
float startPos = farLeft.position.x;
|
|
float maxWidth = Mathf.Abs(farLeft.position.x - farRight.position.x);
|
|
|
|
float betweenDistance = maxWidth / 3;
|
|
|
|
maxWidth = betweenDistance * executiveCount;
|
|
|
|
startPos = -(maxWidth / 2);
|
|
|
|
for (int i = -1; i < executiveCount; i++)
|
|
{
|
|
if (i == -1)
|
|
{
|
|
assistantAnim.transform.localPosition = new Vector3(startPos + 5.359f, 0);
|
|
}
|
|
else
|
|
{
|
|
BMExecutive executive;
|
|
if (i == 0) executive = executives[0];
|
|
else executive = Instantiate(executives[0], transform);
|
|
|
|
executive.transform.localPosition = new Vector3(startPos + betweenDistance * (i + 1), 0);
|
|
executive.GetComponent<SortingGroup>().sortingOrder = i;
|
|
|
|
if (i > 0)
|
|
executives.Add(executive);
|
|
|
|
if (i == executiveCount - 1)
|
|
executive.player = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ChangeExecutiveCount(int count)
|
|
{
|
|
for (int i = 1; i < executiveCount; i++)
|
|
{
|
|
Destroy(executives[i].gameObject);
|
|
}
|
|
executives.RemoveRange(1, executiveCount - 1);
|
|
executiveCount = count;
|
|
InitExecutives();
|
|
}
|
|
|
|
bool CanJust()
|
|
{
|
|
return executives[executiveCount - 1].spinning;
|
|
}
|
|
|
|
void Just(PlayerActionEvent caller, float state)
|
|
{
|
|
if (chairLoopSound != null)
|
|
{
|
|
chairLoopSound.KillLoop(0);
|
|
chairLoopSound = null;
|
|
}
|
|
if (state >= 1f || state <= -1f)
|
|
{
|
|
SoundByte.PlayOneShotGame("boardMeeting/missThrough");
|
|
SoundByte.PlayOneShot("miss");
|
|
executives[executiveCount - 1].Stop(false);
|
|
return;
|
|
}
|
|
SoundByte.PlayOneShotGame("boardMeeting/stopPlayer");
|
|
executives[executiveCount - 1].Stop();
|
|
BeatAction.New(instance, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(caller.timer + caller.startBeat + 1f, delegate
|
|
{
|
|
foreach (var executive in executives)
|
|
{
|
|
executive.Smile();
|
|
}
|
|
})
|
|
});
|
|
}
|
|
|
|
void JustAssistant(PlayerActionEvent caller, float state)
|
|
{
|
|
if (chairLoopSound != null)
|
|
{
|
|
chairLoopSound.KillLoop(0);
|
|
chairLoopSound = null;
|
|
}
|
|
if (state >= 1f || state <= -1f)
|
|
{
|
|
SoundByte.PlayOneShotGame("boardMeeting/missThrough");
|
|
SoundByte.PlayOneShot("miss");
|
|
executives[executiveCount - 1].Stop(false);
|
|
return;
|
|
}
|
|
if (shakeTween != null)
|
|
shakeTween.Kill(true);
|
|
|
|
DOTween.Punch(() => GameCamera.AdditionalPosition, x => GameCamera.AdditionalPosition = x, new Vector3(shakeIntensity, 0, 0),
|
|
Conductor.instance.pitchedSecPerBeat * 0.5f, 18, 1f);
|
|
executives[executiveCount - 1].Stop();
|
|
assistantAnim.DoScaledAnimationAsync("Stop", 0.5f);
|
|
SoundByte.PlayOneShotGame("boardMeeting/stopAllPlayer");
|
|
BeatAction.New(instance, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(caller.timer + caller.startBeat + 1f, delegate
|
|
{
|
|
foreach (var executive in executives)
|
|
{
|
|
executive.Smile();
|
|
}
|
|
})
|
|
});
|
|
}
|
|
|
|
void Miss(PlayerActionEvent caller)
|
|
{
|
|
if (executives[executiveCount - 1].spinning)
|
|
{
|
|
executives[executiveCount - 1].Stop(false);
|
|
SoundByte.PlayOneShotGame("boardMeeting/missThrough");
|
|
SoundByte.PlayOneShot("miss");
|
|
if (chairLoopSound != null)
|
|
{
|
|
chairLoopSound.KillLoop(0);
|
|
chairLoopSound = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
void MissAssistant(PlayerActionEvent caller)
|
|
{
|
|
if (executives[executiveCount - 1].spinning)
|
|
{
|
|
executives[executiveCount - 1].Stop(false);
|
|
SoundByte.PlayOneShotGame("boardMeeting/missThrough");
|
|
SoundByte.PlayOneShot("miss");
|
|
if (chairLoopSound != null)
|
|
{
|
|
chairLoopSound.KillLoop(0);
|
|
chairLoopSound = null;
|
|
}
|
|
}
|
|
assistantAnim.Play("MissIdle", 0, 0);
|
|
missCounter = 2;
|
|
}
|
|
|
|
void Empty(PlayerActionEvent caller) { }
|
|
}
|
|
}
|
|
|