Jamie Greunbaum 1e8b000b41 - Finished the basic framework for the ACME Crimenet Computer.
- Added a skateboard and VHS cassette for the video music clues.
- Reworked more materials to have a common parent.
2025-08-12 04:55:21 -04:00

1478 lines
44 KiB
C#

using UdonSharp;
using UnityEngine;
using VRC.SDK3.Data;
using VRC.SDK3.UdonNetworkCalling;
using VRC.Udon.Common.Interfaces;
using VRC.SDKBase;
using VRC.SDK3.StringLoading;
public enum PresentationMedium
{
VideoClue,
VideoMusicClue,
ACMECrimenetComputer
}
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class GameManagerRound1 : GameManagerBase
{
[SerializeField] private CaseManager _CaseManager;
[SerializeField] private CaseVideoSyncPlayer _VideoPlayer;
[SerializeField] private VRCUrl _TiebreakerData;
[UdonSynced] protected bool _GameHasBegun = false;
[UdonSynced] private int _QuestionIndex = 0;
[UdonSynced] private int _QuestionStage = 0;
[UdonSynced] private int _QuestionSubstage = 0;
[UdonSynced] private int _QuestionCorrectResponse = 0;
[UdonSynced] private RoundSegmentType _CurrentQuestionType = RoundSegmentType.BetweenSegments;
private DataList _QuestionsList = new DataList();
private DataDictionary _CurrentQuestion;
[UdonSynced] private bool _BuzzInAllowed = false;
[UdonSynced] private bool[] _PlayerBuzzInAllowed;
[UdonSynced] private int _BuzzedInPlayer = 0;
[UdonSynced] private int[] _FinalRoundPlayersSortedByScore;
[UdonSynced] private int[] _TiebreakerPlayerNumbers;
[SerializeField] private PlayerPodium[] _PlayerPodiums;
[Space, Header("Video Music Clue")]
[SerializeField] private VideoMusicClueNoteCard _VideoMusicClueNoteCard;
[Space, Header("ACME Crimenet Computer")]
[SerializeField] private ACMECrimenetComputer _ACMECrimenetComputer;
public override void InitialiseGameMode()
{
_GameHasBegun = false;
_QuestionIndex = 0;
_QuestionStage = 0;
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "ResetPodium");
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "ShowAuxiliaryVideoScreen", false);
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "ShowAuxiliaryMapScreen", false);
}
_PlayerBuzzInAllowed = new bool[_PlayerPodiums.Length];
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All, "PlayMusic", MusicEventType.WhereInTheWorld);
SendCustomEventDelayedSeconds(nameof(PlaySecondPartOfThemeMusic), 3.6666666666f);
RequestSerialization();
base.InitialiseGameMode();
}
public void PlaySecondPartOfThemeMusic()
{
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All, "PlayMusicLoop", MusicEventType.OpeningLoop);
}
public override void LoadQuestionData(DataToken Data)
{
_QuestionsList.Clear();
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
DataList DataDict = Data.DataList;
for (int i = 0; i < DataDict.Count; i++)
{
if (DataDict[i].TokenType == TokenType.DataDictionary)
{
_QuestionsList.Add(DataDict[i]);
}
}
if (_QuestionsList.Count == 0)
{
Interface.HeaderUI.text =
"Unable to find any questions. Ensure the root array elements are all objects.";
return;
}
Interface.HeaderUI.text = "Case has been loaded.";
_GameHasBegun = false;
EnableInteraction("Start Game");
}
private void PlayIntroVideo()
{
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All, "FadeOutMusic");
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
Interface.HeaderUI.text = "Playing intro video...";
_VideoPlayer.VideoURL = _CaseManager.GetIntroVideo();
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.Owner, "ShowAuxiliaryVideoScreen", true);
}
EnableInteraction("Assign Points");
}
private void InitialiseQuestion()
{
_CurrentQuestion = _QuestionsList[_QuestionIndex].DataDictionary;
// Again, why does this work, but not just casting to an enum?
_CurrentQuestionType = (RoundSegmentType)(int)_CurrentQuestion["Type"].Number;
_QuestionStage = 0;
LoadMapsIntoQueue();
}
private void LoadMapsIntoQueue()
{
if (_CurrentQuestion.ContainsKey("Maps") && _CurrentQuestion["Maps"].TokenType == TokenType.DataList)
{
DataList Maps = _CurrentQuestion["Maps"].DataList;
int[] MapIndices = new int[Maps.Count];
for (int i = 0; i < MapIndices.Length; i++)
{
MapIndices[i] = (int)Maps[i].Number;
}
_VideoPlayer.SendCustomNetworkEvent(NetworkEventTarget.All,
"QueueMapDownloads", MapIndices);
}
}
private void AssignStarterPoints()
{
InitialiseQuestion();
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "DisplayScore");
}
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFXAtPitch", SFXEventType.Ding, AudioManager.D6);
ShowBetweenQuestionsInterface();
DisableChoiceCards();
DisableRiskCards();
DisableBuzzers();
EnableInteraction("Show First Question");
_GameHasBegun = true;
}
private void InitialiseCluePresentation()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.Owner, "ShowAuxiliaryVideoScreen", true);
}
HostCardBetweenRoundsInterface Interface;
if (!_CurrentQuestion.ContainsKey("Presentation") ||
_CurrentQuestion["Presentation"].TokenType != TokenType.DataDictionary ||
!_CurrentQuestion["Presentation"].DataDictionary.ContainsKey("Medium"))
{
Interface = (HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
Interface.HeaderUI.text = "No special presentation available. Continuing on...";
EnableInteraction("Reveal Question");
return;
}
DataDictionary Presentation = _CurrentQuestion["Presentation"].DataDictionary;
switch ((PresentationMedium)(int)Presentation["Medium"].Number)
{
case PresentationMedium.VideoClue: InitialiseVideoClue(Presentation); break;
case PresentationMedium.VideoMusicClue: InitialiseVideoMusicClue(Presentation); break;
case PresentationMedium.ACMECrimenetComputer: InitialiseACMECrimenetComputer(Presentation); break;
}
}
private void InitialiseVideoClue(DataDictionary Presentation)
{
DataList Videos = Presentation["Videos"].DataList;
if (_QuestionSubstage < Videos.Count)
{
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
Interface.HeaderUI.text = "Playing video...";
_VideoPlayer.VideoURL = _CaseManager.GetVideo((int)Videos[_QuestionSubstage].Number);
_QuestionSubstage++;
if (_QuestionSubstage < Videos.Count)
{
EnableInteraction("Play Video");
}
else
{
EnableInteraction("Reveal Question");
}
}
else
{
_VideoMusicClueNoteCard.gameObject.SetActive(false);
MultipleChoiceRevealQuestion();
}
}
private void InitialiseVideoMusicClue(DataDictionary Presentation)
{
// The full presentation is not ready yet, so temporarily treat it as
// a regular video clue with some additions.
if (Presentation.ContainsKey("Video Artist") && Presentation.ContainsKey("Clue Description"))
{
_VideoMusicClueNoteCard.Header.text = Presentation["Video Artist"].String;
_VideoMusicClueNoteCard.Comment.text = Presentation["Clue Description"].String;
}
else
{
_VideoMusicClueNoteCard.Header.text = "Error Reading Data";
_VideoMusicClueNoteCard.Comment.text = "just wing it i guess idk";
}
_VideoMusicClueNoteCard.transform.localPosition = Vector3.zero;
_VideoMusicClueNoteCard.transform.localRotation = Quaternion.identity;
_VideoMusicClueNoteCard.gameObject.SetActive(true);
InitialiseVideoClue(Presentation);
}
private void InitialiseACMECrimenetComputer(DataDictionary Presentation)
{
if (_QuestionSubstage < 1)
{
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
Interface.HeaderUI.text = "This part isn't done yet. This will eventually have a really cool computer give you the clue.";
string UntranslatedText = "";
string TranslatedText = "";
if (Presentation.ContainsKey("Clue Description") && Presentation.ContainsKey("Original Text Placeholder"))
{
UntranslatedText = Presentation["Original Text Placeholder"].String;
TranslatedText = Presentation["Clue Description"].String;
}
_ACMECrimenetComputer.SendCustomNetworkEvent(NetworkEventTarget.All,
"SetCardTexts", UntranslatedText, TranslatedText);
_ACMECrimenetComputer.SendCustomNetworkEvent(NetworkEventTarget.All, "SwooceRightIn");
_QuestionSubstage++;
EnableInteraction("Reveal Question");
}
else
{
_ACMECrimenetComputer.SendCustomNetworkEvent(NetworkEventTarget.All, "ResetComputer");
MultipleChoiceRevealQuestion();
}
}
private void MultipleChoiceRevealQuestion()
{
_QuestionSubstage = 0;
_VideoPlayer.SubMapIndex = 0;
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "ShowAuxiliaryVideoScreen", false);
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.Owner, "ShowAuxiliaryMapScreen", true);
}
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.MultipleChoice);
ResetMultipleChoiceInterface(Interface);
Interface.HeaderUI.text = RoundSegmentTypeToString(_CurrentQuestionType);
DataList ClueStrings = _CurrentQuestion["Clues"].DataList;
for (int i = 0; i < Interface.CluesUI.Length && i < ClueStrings.Count; i++)
{
Interface.CluesUI[i].text = ClueStrings[i].ToString();
}
DataList Choices = _CurrentQuestion["Choices"].DataList;
for (int i = 0; i < Choices.Count && i < Interface.ChoiceUI.Length; i++)
{
Interface.ChoiceUI[i].text = Choices[i].ToString();
}
_QuestionCorrectResponse = (int)_CurrentQuestion["Correct Response"].Number;
EnableInteraction("Reveal Choice 1");
}
private void MultipleChoiceRevealChoices()
{
SendCustomEvent(nameof(MultipleChoiceRevealChoice1));
SendCustomEventDelayedSeconds(nameof(MultipleChoiceRevealChoice2), 1.25f);
SendCustomEventDelayedSeconds(nameof(MultipleChoiceRevealChoice3), 2.5f);
}
private void MultipleChoiceRevealChoice1()
{
_VideoPlayer.SubMapIndex = 1;
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.MultipleChoice);
Interface.ChoiceButtonImages[0].color = (_QuestionCorrectResponse == 1) ? Color.green : Color.red;
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFXAtPitch", SFXEventType.Ding, AudioManager.As5);
EnableInteraction("Reveal Choice 2");
}
private void MultipleChoiceRevealChoice2()
{
_VideoPlayer.SubMapIndex = 2;
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.MultipleChoice);
Interface.ChoiceButtonImages[1].color = (_QuestionCorrectResponse == 2) ? Color.green : Color.red;
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFXAtPitch", SFXEventType.Ding, AudioManager.C6);
EnableInteraction("Reveal Choice 3");
}
private void MultipleChoiceRevealChoice3()
{
_VideoPlayer.SubMapIndex = 3;
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.MultipleChoice);
Interface.ChoiceButtonImages[2].color = (_QuestionCorrectResponse == 3) ? Color.green : Color.red;
DataList Choices = _CurrentQuestion["Choices"].DataList;
EnableChoiceCards();
// Complex per-podium randomiser, to prevent peeking
Random.InitState(Networking.GetServerTimeInMilliseconds());
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
int[] Indices = { 0, 1, 2 };
int[] ChoiceOrder = { -1, -1, -1 };
int Choice1Index = Indices[Random.Range(0, 3)];
ChoiceOrder[0] = Choice1Index;
Indices[Choice1Index] = -1;
int Choice2Index = -1;
while (Choice2Index == -1) { Choice2Index = Indices[Random.Range(0, 3)]; }
ChoiceOrder[1] = Choice2Index;
Indices[Choice2Index] = -1;
int Choice3Index = -1;
while (Choice3Index == -1) { Choice3Index = Indices[Random.Range(0, 3)]; }
ChoiceOrder[2] = Choice3Index;
Indices[Choice3Index] = -1;
string[] ChoiceStrings = { Choices[0].ToString(), Choices[1].ToString(), Choices[2].ToString() };
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All,
"SetCardChoices", ChoiceStrings, ChoiceOrder);
}
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFXAtPitch", SFXEventType.Ding, AudioManager.D6);
EnableInteraction("Lock Answers");
}
private void MultipleChoiceLockAnswers()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "LockInChoice");
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.Owner, "ShowAuxiliaryMapScreen", false);
}
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.MultipleChoice);
Interface.HeaderUI.text = "LOCKED IN";
for (int i = 0; i < Interface.CluesUI.Length; i++)
{
Interface.CluesUI[i].text = "";
}
for (int i = 0; i < Interface.ChoiceUI.Length; i++)
{
if (i != (_QuestionCorrectResponse - 1))
{
Interface.ChoiceUI[i].text = "";
}
}
EnableInteraction("Reveal Answers And Assign Points");
}
private void MultipleChoiceRevealAnswersAndAssignPoints()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.Owner, "ShowAuxiliaryMapScreen", true);
}
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.MultipleChoice);
Interface.HeaderUI.text = "ANSWER REVEALED";
bool IsSomeoneCorrect = false;
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
bool Correct = _PlayerPodiums[i].VerifyMultipleChoiceResponse(_QuestionCorrectResponse);
IsSomeoneCorrect = IsSomeoneCorrect ? true : Correct;
}
if (IsSomeoneCorrect)
{
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFX", SFXEventType.Round1Correct);
}
else
{
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFX", SFXEventType.Round1Incorrect);
}
_VideoPlayer.FlashCorrectAnswer = true;
EnableInteraction("Next Question");
}
private void BeginLightningRound()
{
HostCardLightningRoundInterface Interface =
(HostCardLightningRoundInterface)GetHostCardInterface(RoundSegmentType.LightningRound);
Interface.HeaderUI.text = RoundSegmentTypeToString(_CurrentQuestionType) + " | " + _CurrentQuestion["Location"].ToString();
for (int i = 0; i < Interface.ChoiceUI.Length && i < Interface.ChoiceButtons.Length; i++)
{
Interface.ChoiceUI[i].text = "";
}
Interface.QuestionUI.text = "All of these questions are worth 5 Acme Crimebucks. These questions are all about [[CROOK]]'s most recent whereabouts, which is " + _CurrentQuestion["Location"].ToString() + ". Hands on your buzzers. Here's the first question...";
EnableBuzzers();
EnableInteraction("First Question");
}
private void LightningRoundCluesLoop()
{
DataList QuestionsList = _CurrentQuestion["Questions"].DataList;
if (_QuestionSubstage >= QuestionsList.Count)
{
_QuestionSubstage = 0;
EnableInteraction("End Lightning Round");
return;
}
DataDictionary CurrentQuestion = _CurrentQuestion["Questions"].DataList[_QuestionSubstage].DataDictionary;
HostCardLightningRoundInterface Interface =
(HostCardLightningRoundInterface)GetHostCardInterface(RoundSegmentType.LightningRound);
Interface.QuestionUI.text = CurrentQuestion["Question"].ToString();
DataList Choices = CurrentQuestion["Choices"].DataList;
for (int i = 0; i < Choices.Count && i < Interface.ChoiceUI.Length; i++)
{
Interface.ChoiceUI[i].text = Choices[i].ToString();
}
_QuestionCorrectResponse = (int)CurrentQuestion["Correct Response"].Number;
for (int i = 0; i < Interface.ChoiceButtons.Length && i < Interface.ChoiceButtonImages.Length; i++)
{
Interface.ChoiceButtonImages[i].color = (_QuestionCorrectResponse == (i + 1)) ? Color.green : Color.red;
Interface.ChoiceButtons[i].interactable = true;
}
Interface.OtherButton.interactable = true;
EnableBuzzInPeriodForAllPlayers();
}
private void LightningRoundCheckAnswer(int Answer)
{
if (_QuestionCorrectResponse == Answer)
{
HostCardLightningRoundInterface Interface =
(HostCardLightningRoundInterface)GetHostCardInterface(RoundSegmentType.LightningRound);
for (int i = 0; i < Interface.ChoiceButtons.Length; i++)
{
Interface.ChoiceButtons[i].interactable = false;
}
Interface.OtherButton.interactable = false;
int PodiumIndex = _BuzzedInPlayer - 1;
if (PodiumIndex >= 0 && PodiumIndex < _PlayerPodiums.Length)
{
_PlayerPodiums[PodiumIndex].SendCustomNetworkEvent(NetworkEventTarget.Owner,
"AdjustScore", 5);
}
EndBuzzInPeriod();
_QuestionSubstage++;
AdvanceQuestion();
}
else
{
WaitForBuzzInsWithoutLastPlayer();
}
}
public void LightningRoundCheckAnswer1()
{
LightningRoundCheckAnswer(1);
}
public void LightningRoundCheckAnswer2()
{
LightningRoundCheckAnswer(2);
}
public void LightningRoundCheckAnswer3()
{
LightningRoundCheckAnswer(3);
}
public void LightningRoundOtherOptionChosen()
{
WaitForBuzzInsWithoutLastPlayer();
}
private void BeginTheChase()
{
HostCardTheChaseInterface Interface =
(HostCardTheChaseInterface)GetHostCardInterface(RoundSegmentType.TheChase);
Interface.HeaderUI.text = RoundSegmentTypeToString(_CurrentQuestionType);
Interface.ClueUI.text = "";
for (int i = 0; i < Interface.ChoiceUI.Length && i < Interface.ChoiceButtons.Length; i++)
{
Interface.ChoiceUI[i].text = "";
}
EnableBuzzers();
EnableInteraction("Play The Music");
}
private void PlayTheChaseMusic()
{
HostCardTheChaseInterface Interface =
(HostCardTheChaseInterface)GetHostCardInterface(RoundSegmentType.TheChase);
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlayMusic", MusicEventType.TheChase);
Interface.HeaderUI.text = RoundSegmentTypeToString(RoundSegmentType.TheChase);
Interface.ClueUI.text = "All of these questions are worth 5 Acme Crimebucks. Hands on your buzzers. Listen carefully. Here we go.";
EnableBuzzers();
EnableInteraction("Here We Go");
}
private void TheChaseCluesLoop()
{
DataList CluesList = _CurrentQuestion["Clues"].DataList;
if (_QuestionSubstage >= CluesList.Count)
{
_QuestionSubstage = 0;
EnableInteraction("End The Chase");
return;
}
DataDictionary CurrentClue = _CurrentQuestion["Clues"].DataList[_QuestionSubstage].DataDictionary;
HostCardTheChaseInterface Interface =
(HostCardTheChaseInterface)GetHostCardInterface(RoundSegmentType.TheChase);
Interface.ClueUI.text = CurrentClue["Clue"].ToString();
DataList Choices = CurrentClue["Choices"].DataList;
for (int i = 0; i < Choices.Count && i < Interface.ChoiceUI.Length; i++)
{
Interface.ChoiceUI[i].text = Choices[i].ToString();
}
Interface.OtherButton.interactable = true;
_QuestionCorrectResponse = (int)CurrentClue["Correct Response"].Number;
for (int i = 0; i < Interface.ChoiceButtons.Length && i < Interface.ChoiceButtonImages.Length; i++)
{
Interface.ChoiceButtonImages[i].color = (_QuestionCorrectResponse == (i + 1)) ? Color.green : Color.red;
Interface.ChoiceButtons[i].interactable = true;
}
SendCustomEventDelayedSeconds(nameof(DisplayNextChaseMap), 1.25f);
EnableBuzzInPeriodForAllPlayers();
}
public void DisplayNextChaseMap()
{
_VideoPlayer.SubMapIndex = _QuestionSubstage * 2;
}
private void TheChaseCheckAnswer(int Answer)
{
if (_QuestionCorrectResponse == Answer)
{
int PodiumIndex = _BuzzedInPlayer - 1;
if (PodiumIndex >= 0 && PodiumIndex < _PlayerPodiums.Length)
{
_PlayerPodiums[PodiumIndex].SendCustomNetworkEvent(NetworkEventTarget.Owner,
"AdjustScore", 5);
}
}
TheChaseEndClue();
}
public void TheChaseCheckAnswer1()
{
TheChaseCheckAnswer(1);
}
public void TheChaseCheckAnswer2()
{
TheChaseCheckAnswer(2);
}
public void TheChaseCheckAnswer3()
{
TheChaseCheckAnswer(3);
}
public void TheChaseEndClue()
{
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFXAtPitch", SFXEventType.Ding, AudioManager.D6);
HostCardTheChaseInterface Interface =
(HostCardTheChaseInterface)GetHostCardInterface(RoundSegmentType.TheChase);
for (int i = 0; i < Interface.ChoiceButtons.Length; i++)
{
Interface.ChoiceButtons[i].interactable = false;
}
Interface.OtherButton.interactable = false;
EndBuzzInPeriod();
_VideoPlayer.SubMapIndex++;
_QuestionSubstage++;
AdvanceQuestion();
}
private void BeginFinalRound()
{
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
Interface.HeaderUI.text = "Introduce the round here.";
LoadMapsIntoQueue();
EnableInteraction("Show Map Preview");
}
private void FinalRoundShowMapPreview()
{
_VideoPlayer.SubMapIndex = 3;
EnableRiskCards();
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
Interface.HeaderUI.text = "Introduce the round here.";
EnableInteraction("Think About It");
}
private void FinalRoundPlayThinkingMusic()
{
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
Interface.HeaderUI.text = "Think about it...";
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlayMusic", MusicEventType.ThinkAboutIt);
SendCustomEventDelayedSeconds(nameof(ThinkAboutItCountdownFinished), 15.0f);
}
public void ThinkAboutItCountdownFinished()
{
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.FinalRound);
Interface.HeaderUI.text = RoundSegmentTypeToString(_CurrentQuestionType);
DataList ClueStrings = _CurrentQuestion["Clues"].DataList;
for (int i = 0; i < Interface.CluesUI.Length && i < ClueStrings.Count; i++)
{
Interface.CluesUI[i].text = ClueStrings[i].ToString();
}
DataList Choices = _CurrentQuestion["Choices"].DataList;
for (int i = 0; i < Choices.Count && i < Interface.ChoiceUI.Length; i++)
{
Interface.ChoiceUI[i].text = Choices[i].ToString();
}
_QuestionCorrectResponse = (int)_CurrentQuestion["Correct Response"].Number;
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "LockInRisk");
}
EnableInteraction("Present Clues");
}
private void FinalRoundRevealChoices()
{
SendCustomEvent(nameof(FinalRoundRevealChoice1));
SendCustomEventDelayedSeconds(nameof(FinalRoundRevealChoice2), 1.25f);
SendCustomEventDelayedSeconds(nameof(FinalRoundRevealChoice3), 2.5f);
}
private void FinalRoundRevealChoice1()
{
_VideoPlayer.SubMapIndex = 1;
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.FinalRound);
Interface.ChoiceButtonImages[0].color = (_QuestionCorrectResponse == 1) ? Color.green : Color.red;
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFXAtPitch", SFXEventType.Ding, AudioManager.As5);
EnableInteraction("Reveal Choice 2");
}
private void FinalRoundRevealChoice2()
{
_VideoPlayer.SubMapIndex = 2;
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.FinalRound);
Interface.ChoiceButtonImages[1].color = (_QuestionCorrectResponse == 2) ? Color.green : Color.red;
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFXAtPitch", SFXEventType.Ding, AudioManager.C6);
EnableInteraction("Reveal Choice 3");
}
private void FinalRoundRevealChoice3()
{
_VideoPlayer.SubMapIndex = 3;
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.FinalRound);
Interface.ChoiceButtonImages[2].color = (_QuestionCorrectResponse == 3) ? Color.green : Color.red;
DataList Choices = _CurrentQuestion["Choices"].DataList;
EnableChoiceCards();
// Complex per-podium randomiser, to prevent peeking
Random.InitState(Networking.GetServerTimeInMilliseconds());
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
int[] Indices = { 0, 1, 2 };
int[] ChoiceOrder = { -1, -1, -1 };
int Choice1Index = Indices[Random.Range(0, 3)];
ChoiceOrder[0] = Choice1Index;
Indices[Choice1Index] = -1;
int Choice2Index = -1;
while (Choice2Index == -1) { Choice2Index = Indices[Random.Range(0, 3)]; }
ChoiceOrder[1] = Choice2Index;
Indices[Choice2Index] = -1;
int Choice3Index = -1;
while (Choice3Index == -1) { Choice3Index = Indices[Random.Range(0, 3)]; }
ChoiceOrder[2] = Choice3Index;
Indices[Choice3Index] = -1;
string[] ChoiceStrings = { Choices[0].ToString(), Choices[1].ToString(), Choices[2].ToString() };
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All,
"SetCardChoices", ChoiceStrings, ChoiceOrder);
}
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFXAtPitch", SFXEventType.Ding, AudioManager.D6);
EnableInteraction("Lock Answers");
}
private void FinalRoundLockAnswers()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "LockInChoice");
}
HostCardMultipleChoiceInterface Interface =
(HostCardMultipleChoiceInterface)GetHostCardInterface(RoundSegmentType.FinalRound);
Interface.HeaderUI.text = "LOCKED IN";
for (int i = 0; i < Interface.CluesUI.Length; i++)
{
Interface.CluesUI[i].text = "";
}
for (int i = 0; i < Interface.ChoiceUI.Length; i++)
{
if (i != (_QuestionCorrectResponse - 1))
{
Interface.ChoiceUI[i].text = "";
}
}
SortPlayersHighToLowScore();
EnableInteraction("Reveal Third Place");
}
private void SortPlayersHighToLowScore()
{
int PlayerPodiumsCount = _PlayerPodiums.Length;
// We're gonna pull a trick here that lets us sort the scores and
// players properly. By multiplying the score by 1000 and then adding
// the player number to it, we can easily sort by score, followed by
// player number, and then convert that back to the needed information
// later. We also store the inverse player number (1000 - player no.)
// so that they are sorted in the opposite order they normally would
// when scores are equal, ensuring that if there is a 3-way tie, the
// order will still be Player 1 -> Player 2 -> Player 3.
DataList ScoresList = new DataList();
for (int i = 0; i < PlayerPodiumsCount; i++)
{
ScoresList.Add(((_PlayerPodiums[i].PlayerScore) * 1000) + (1000 - _PlayerPodiums[i].PlayerNumber));
}
ScoresList.Sort();
_FinalRoundPlayersSortedByScore = new int[ScoresList.Count];
for (int i = 0; i < _FinalRoundPlayersSortedByScore.Length; i++)
{
int DecodedPlayerNumber = 1000 - (ScoresList[i].Int % 1000);
_FinalRoundPlayersSortedByScore[_FinalRoundPlayersSortedByScore.Length - i - 1] = DecodedPlayerNumber;
}
}
private void FinalRoundRevealPlayerPlace(int PlayerPlace)
{
int PlayerNumber = _FinalRoundPlayersSortedByScore[PlayerPlace - 1];
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
Interface.HeaderUI.text = "Player: " + _PlayerPodiums[PlayerNumber - 1].PlayerName;
_PlayerPodiums[PlayerNumber - 1].EnableBuzzInEffect(true);
EnableInteraction("Assign Points");
}
private void FinalRoundAssignPointsToPlayerPlace(int PlayerPlace)
{
int PlayerNumber = _FinalRoundPlayersSortedByScore[PlayerPlace - 1];
_PlayerPodiums[PlayerNumber - 1].EnableBuzzInEffect(false);
_PlayerPodiums[PlayerNumber - 1].VerifyFinalRoundResponse(_QuestionCorrectResponse);
// If we're assigning points to the first-place player, then we're
// about to finish up, so just move on to determining winners.
if (PlayerPlace == 1)
{
EnableInteraction("End Of Round");
}
else
{
EnableInteraction("Reveal Next Player Answer");
}
}
private bool FinalRoundCheckNeedForTiebreaker()
{
DisableChoiceCards();
DisableRiskCards();
DisableBuzzers();
SortPlayersHighToLowScore();
int[] SortedPlayerScores = new int[_PlayerPodiums.Length];
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
SortedPlayerScores[i] = _PlayerPodiums[_FinalRoundPlayersSortedByScore[i] - 1].PlayerScore;
}
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
PlayerPodium Number1Podium = _PlayerPodiums[_FinalRoundPlayersSortedByScore[0] - 1];
PlayerPodium Number2Podium = _PlayerPodiums[_FinalRoundPlayersSortedByScore[1] - 1];
PlayerPodium Number3Podium = _PlayerPodiums[_FinalRoundPlayersSortedByScore[2] - 1];
VRCPlayerApi Number1 = Networking.GetOwner(Number1Podium.gameObject);
VRCPlayerApi Number2 = Networking.GetOwner(Number2Podium.gameObject);
VRCPlayerApi Number3 = Networking.GetOwner(Number3Podium.gameObject);
bool TiebreakerNeeded = false;
if (SortedPlayerScores[1] == SortedPlayerScores[2])
{
if (SortedPlayerScores[0] == SortedPlayerScores[1])
{
Interface.HeaderUI.text = "We have a three-way tie. We'll start with a tiebreaker between " + Number2.displayName + " and " + Number3.displayName + ".";
}
else
{
Interface.HeaderUI.text = Number1.displayName + " is in first place and will be moving on to the next round. There is a tie for second place between " + Number2.displayName + " and " + Number3.displayName + ", so we will move on to a tiebreaker.";
}
TiebreakerNeeded = true;
PrepareTiebreakerRound(Number2Podium.PlayerNumber, Number3Podium.PlayerNumber);
}
else
{
string[] WinningPlayers = new string[2];
if (SortedPlayerScores[0] == SortedPlayerScores[1])
{
Random.InitState(Networking.GetServerTimeInMilliseconds());
VRCPlayerApi[] Randomiser = new VRCPlayerApi[2];
Randomiser[0] = Number1;
Randomiser[1] = Number2;
int RandomIndex = Random.Range(0, 2);
WinningPlayers[0] = Randomiser[RandomIndex].displayName;
WinningPlayers[1] = Randomiser[(RandomIndex + 1) % 2].displayName;
Interface.HeaderUI.text = Number1.displayName + " and " + Number2.displayName + " are tied for first place; both will move on to the next round.";
}
else
{
WinningPlayers[0] = Number1.displayName;
WinningPlayers[1] = Number2.displayName;
Interface.HeaderUI.text = Number1.displayName + " and " + Number2.displayName + " will move on to the next round.";
}
_CaseManager.SetCurrentWinningPlayers(WinningPlayers);
}
return TiebreakerNeeded;
}
private void PrepareTiebreakerRound(int FirstPlayer, int SecondPlayer)
{
_QuestionStage = 0;
_TiebreakerPlayerNumbers = new int[2];
_TiebreakerPlayerNumbers[0] = FirstPlayer;
_TiebreakerPlayerNumbers[1] = SecondPlayer;
}
private void AdvanceToNextQuestion()
{
DisableChoiceCards();
DisableRiskCards();
DisableBuzzers();
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.Owner, "ShowAuxiliaryMapScreen", false);
}
_VideoPlayer.SendCustomNetworkEvent(NetworkEventTarget.All, "ClearScreen");
_QuestionIndex++;
if (_QuestionIndex >= _QuestionsList.Count)
{
PrepareEndGame();
}
else
{
PrepareNextQuestion();
}
}
private void PrepareNextQuestion()
{
InitialiseQuestion();
ShowBetweenQuestionsInterface();
EnableInteraction("Show Next Question");
}
private void PrepareEndGame()
{
bool TiebreakerNeeded = FinalRoundCheckNeedForTiebreaker();
if (TiebreakerNeeded)
{
_CurrentQuestionType = RoundSegmentType.Tiebreaker;
EnableInteraction("Advance To Tiebreaker");
}
else
{
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
Interface.HeaderUI.text = "Round is over. Move to the loot recovery area.";
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlayMusicLoop", MusicEventType.CapitalLoop);
_CaseManager.ContinueToRound2();
EnableInteraction("End Game");
}
}
private void BeginTiebreakerRound()
{
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
Interface.HeaderUI.text = "Preparing tiebreaker...";
VRCStringDownloader.LoadUrl(_TiebreakerData, (IUdonEventReceiver)this);
}
public override void OnStringLoadSuccess(IVRCStringDownload TiebreakerString)
{
HostCardTiebreakerInterface Interface =
(HostCardTiebreakerInterface)GetHostCardInterface(RoundSegmentType.Tiebreaker);
string ErrorString = "";
string JSONString = TiebreakerString.Result;
if (VRCJson.TryDeserializeFromJson(JSONString, out DataToken JSONResult))
{
if (JSONResult.TokenType == TokenType.DataDictionary)
{
DataDictionary TiebreakerDictionary = JSONResult.DataDictionary;
DataList TiebreakerRegions = TiebreakerDictionary.GetKeys();
Random.InitState(Networking.GetServerTimeInMilliseconds());
int TiebreakerIndex = Random.Range(0, TiebreakerRegions.Count);
string TiebreakerRegion = TiebreakerRegions[TiebreakerIndex].String;
Interface.ChoiceUI[1].text = TiebreakerRegion;
if (TiebreakerDictionary[TiebreakerRegion].TokenType == TokenType.DataDictionary)
{
DataDictionary RegionDictionary = TiebreakerDictionary[TiebreakerRegion].DataDictionary;
if (RegionDictionary.ContainsKey("Type") && RegionDictionary.ContainsKey("Key Locations"))
{
Interface.HeaderUI.text = "Tiebreaker | " + RegionDictionary["Type"].String;
if (RegionDictionary["Key Locations"].TokenType == TokenType.DataList)
{
for (int i = 0; i < Interface.CluesUI.Length; i++)
{
Interface.CluesUI[i].text = "";
}
DataList KeyLocations = RegionDictionary["Key Locations"].DataList;
for (int i = 0; i < KeyLocations.Count && i < Interface.CluesUI.Length; i++)
{
Interface.CluesUI[i].text = KeyLocations[i].String;
}
EnableBuzzInPeriodForPlayer(_TiebreakerPlayerNumbers[0]);
EnableBuzzInPeriodForPlayer(_TiebreakerPlayerNumbers[1]);
}
else
{
ErrorString = "The Key Locations key should be a list of locations.";
}
}
else
{
ErrorString = "Each region entry should have a region type and a list of key locations.";
}
}
else
{
ErrorString = "Ensure the elements of the root dictionary are all dictionaries.";
}
}
else
{
ErrorString = "Ensure the first element is a dictionary.";
}
}
else
{
ErrorString = "Could not parse JSON document.";
}
if (ErrorString != "")
{
Debug.LogError("Malformed tiebreaker data file. " + ErrorString);
}
}
public void TiebreakerIncorrectResponse()
{
int PodiumIndex = _BuzzedInPlayer - 1;
if (PodiumIndex >= 0 && PodiumIndex < _PlayerPodiums.Length)
{
_PlayerPodiums[PodiumIndex].SendCustomNetworkEvent(NetworkEventTarget.All,
"EnableBuzzInEffect", false);
}
_BuzzedInPlayer = -1;
_BuzzInAllowed = true;
RequestSerialization();
}
public void TiebreakerCorrectResponse()
{
int PodiumIndex = _BuzzedInPlayer - 1;
if (PodiumIndex >= 0 && PodiumIndex < _PlayerPodiums.Length)
{
_PlayerPodiums[PodiumIndex].SendCustomNetworkEvent(NetworkEventTarget.Owner,
"AdjustScore", 5);
}
_BuzzedInPlayer = -1;
DisableBuzzers();
EndBuzzInPeriod();
EnableInteraction("End Tiebreaker");
}
private void ResetMultipleChoiceInterface(HostCardMultipleChoiceInterface Interface)
{
Interface.HeaderUI.text = "";
for (int i = 0; i < Interface.CluesUI.Length; i++)
{
Interface.CluesUI[i].text = "";
}
for (int i = 0; i < Interface.ChoiceButtonImages.Length; i++)
{
Interface.ChoiceButtonImages[i].color = Color.white;
}
for (int i = 0; i < Interface.ChoiceUI.Length; i++)
{
Interface.ChoiceUI[i].text = "";
}
}
private void EnableChoiceCards()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "EnableChoiceCards", true);
}
}
private void DisableChoiceCards()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "EnableChoiceCards", false);
}
}
private void EnableRiskCards()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "EnableRiskCards", true);
}
}
private void DisableRiskCards()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "EnableRiskCards", false);
}
}
private void EnableBuzzers()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "EnableBuzzer", true);
}
}
private void DisableBuzzers()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "EnableBuzzer", false);
}
}
private void EnableBuzzInPeriodForAllPlayers()
{
_BuzzInAllowed = true;
ResetBuzzers();
}
private void EnableBuzzInPeriodForPlayer(int PlayerNumber)
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
if (_PlayerPodiums[i].PlayerNumber == PlayerNumber)
{
_PlayerBuzzInAllowed[i] = true;
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "EnableBuzzer", true);
_BuzzedInPlayer = -1;
break;
}
}
_BuzzInAllowed = true;
}
private void WaitForBuzzInsWithoutLastPlayer()
{
_BuzzInAllowed = true;
int PodiumIndex = _BuzzedInPlayer - 1;
if (PodiumIndex >= 0 && PodiumIndex < _PlayerPodiums.Length)
{
_PlayerPodiums[PodiumIndex].SendCustomNetworkEvent(NetworkEventTarget.All,
"EnableBuzzInEffect", false);
_BuzzedInPlayer = -1;
}
RequestSerialization();
}
[NetworkCallable]
public void PlayerBuzzedIn(int PlayerNumber)
{
int PlayerIndex = PlayerNumber - 1;
if (!_BuzzInAllowed || !_PlayerBuzzInAllowed[PlayerIndex]) { return; }
// Prevent new buzz-ins and store which player is currently buzzed in.
_BuzzInAllowed = false;
_PlayerBuzzInAllowed[PlayerIndex] = false;
_BuzzedInPlayer = PlayerNumber;
RequestSerialization();
_PlayerPodiums[PlayerIndex].SendCustomNetworkEvent(NetworkEventTarget.All,
"EnableBuzzInEffect", true);
// Play the buzzer sound globally.
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFX", SFXEventType.Buzzer);
}
private void EndBuzzInPeriod()
{
_BuzzInAllowed = false;
ResetBuzzers();
}
private void ResetBuzzers()
{
for (int i = 0; i < _PlayerPodiums.Length; i++)
{
_PlayerBuzzInAllowed[i] = true;
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "EnableBuzzInEffect", false);
}
_BuzzedInPlayer = -1;
}
private void AdvanceQuestion()
{
// Disable interaction until we unlock it again later.
DisableInteraction();
// Only advance to the next stage if we aren't in the middle of a substage
if (_QuestionSubstage <= 0)
{
_QuestionStage++;
}
// Handle the intro until the game properly begins.
if (!_GameHasBegun)
{
AdvanceIntro();
return;
}
// TO-DO: Ask someone at either Microsoft or VRChat why the VM crashes if you
// cast an int to an enum in a switch parameter, but not if you cast an enum
// to an int in a case statement. I'm starting to wonder if either C# or U#
// are just fucking terrible languages. C++ figured this problem out in at
// least 1985, and it turns out the proper solution was "it's not a problem,
// it's two numbers, they're the same fucking thing".
switch (_CurrentQuestionType)
{
case RoundSegmentType.MultipleChoice: AdvanceMultipleChoiceStage(); break;
case RoundSegmentType.LightningRound: AdvanceLightningRoundQuestion(); break;
case RoundSegmentType.TheChase: AdvanceTheChase(); break;
case RoundSegmentType.FinalRound: AdvanceFinalRound(); break;
case RoundSegmentType.Tiebreaker: AdvanceTiebreaker(); break;
}
RequestSerialization();
}
private void AdvanceIntro()
{
switch (_QuestionStage)
{
case 1: PlayIntroVideo(); break;
case 2: AssignStarterPoints(); break;
default: break;
}
}
private void AdvanceMultipleChoiceStage()
{
switch (_QuestionStage)
{
case 1: InitialiseCluePresentation(); break;
case 2: MultipleChoiceRevealChoice1(); break;
case 3: MultipleChoiceRevealChoice2(); break;
case 4: MultipleChoiceRevealChoice3(); break;
case 5: MultipleChoiceLockAnswers(); break;
case 6: MultipleChoiceRevealAnswersAndAssignPoints(); break;
case 7: AdvanceToNextQuestion(); break;
default: break;
}
}
private void AdvanceLightningRoundQuestion()
{
switch (_QuestionStage)
{
case 1: BeginLightningRound(); break;
case 2: LightningRoundCluesLoop(); break;
case 3: AdvanceToNextQuestion(); break;
default: break;
}
}
private void AdvanceTheChase()
{
Debug.Log("The Chase is now advancing to stage " + _QuestionStage);
switch (_QuestionStage)
{
case 1: BeginTheChase(); break;
case 2: PlayTheChaseMusic(); break;
case 3: TheChaseCluesLoop(); break;
case 4: AdvanceToNextQuestion(); break;
default: break;
}
}
private void AdvanceFinalRound()
{
switch (_QuestionStage)
{
case 1: BeginFinalRound(); break;
case 2: FinalRoundShowMapPreview(); break;
case 3: FinalRoundPlayThinkingMusic(); break;
case 4: InitialiseCluePresentation(); break;
case 5: FinalRoundRevealChoice1(); break;
case 6: FinalRoundRevealChoice2(); break;
case 7: FinalRoundRevealChoice3(); break;
case 8: FinalRoundLockAnswers(); break;
case 9: FinalRoundRevealPlayerPlace(3); break;
case 10: FinalRoundAssignPointsToPlayerPlace(3); break;
case 11: FinalRoundRevealPlayerPlace(2); break;
case 12: FinalRoundAssignPointsToPlayerPlace(2); break;
case 13: FinalRoundRevealPlayerPlace(1); break;
case 14: FinalRoundAssignPointsToPlayerPlace(1); break;
case 15: AdvanceToNextQuestion(); break;
default: break;
}
}
private void AdvanceTiebreaker()
{
switch(_QuestionStage)
{
case 1: BeginTiebreakerRound(); break;
case 2: AdvanceToNextQuestion(); break;
default: break;
}
}
public VRCUrl GetMapURL(int MapIndex)
{
return _CaseManager.GetMap(MapIndex);
}
public int GetMapCount()
{
return _CaseManager.GetMapCount();
}
protected override void _HostCardUseButtonDown_Internal()
{
AdvanceQuestion();
}
protected override HostCardInterfaceBase GetHostCardInterface(RoundSegmentType Question)
{
return _HostCard.EnableHostCardDisplay(RoundType.LocateTheCrook, Question);
}
private HostCardBetweenRoundsInterface ShowBetweenQuestionsInterface()
{
HostCardBetweenRoundsInterface Interface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
string PresentationMediumString = "";
if (_CurrentQuestion.ContainsKey("Presentation") && _CurrentQuestion["Presentation"].DataDictionary.ContainsKey("Medium"))
{
DataDictionary Presentation = _CurrentQuestion["Presentation"].DataDictionary;
PresentationMediumString = PresentationMediumToString((PresentationMedium)(int)Presentation["Medium"].Number);
}
Interface.HeaderUI.text = "Upcoming Question: " + ((PresentationMediumString == "") ? RoundSegmentTypeToString(_CurrentQuestionType) : PresentationMediumString);
return Interface;
}
protected string PresentationMediumToString(PresentationMedium Type)
{
switch (Type)
{
case PresentationMedium.VideoClue: return "Standard Video Clue";
case PresentationMedium.VideoMusicClue: return "Video Music Clue";
case PresentationMedium.ACMECrimenetComputer: return "ACME Crimenet Computer";
default: return "[[ERROR]]";
}
}
}