- Reduced polygon count of drywall meshes. - Improved triangulation of the TV screen. - Improved lightmaps, and reduce their size. - Added video player to show Patty Larceny going to jail. - Added temporary Patty In Jail tune. - Added a new interface to the host card for these experimental features.
1714 lines
50 KiB
C#
1714 lines
50 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
|
|
{
|
|
[Space]
|
|
|
|
[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;
|
|
|
|
[Space]
|
|
|
|
[SerializeField] private PlayerPodium[] _PlayerPodiums;
|
|
|
|
[Space, Header("Props")]
|
|
[SerializeField] private VideoMusicClueSkateboard _VideoMusicClueSkateboard;
|
|
[SerializeField] private ACMECrimenetComputer _ACMECrimenetComputer;
|
|
[SerializeField] private Modem _Modem;
|
|
[SerializeField] private ArrivalDisplay _ArrivalDisplay;
|
|
|
|
[Space, Header("Effects")]
|
|
[SerializeField] private Animator _LightningRoundAnimator;
|
|
|
|
|
|
public override void InitialiseGameMode()
|
|
{
|
|
_GameHasBegun = false;
|
|
_QuestionIndex = 0;
|
|
_QuestionStage = 0;
|
|
|
|
_PlayerBuzzInAllowed = new bool[_PlayerPodiums.Length];
|
|
|
|
VRCPlayerApi Owner = Networking.GetOwner(gameObject);
|
|
SetOwnershipOfObjects(Owner);
|
|
|
|
_Modem.Activate(false);
|
|
_ArrivalDisplay.Activate(false);
|
|
|
|
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All, "PlayMusic", MusicEventType.WhereInTheWorld);
|
|
SendCustomEventDelayedSeconds(nameof(PlaySecondPartOfThemeMusic), 3.6666666666f);
|
|
|
|
DisableInteraction();
|
|
|
|
RequestSerialization();
|
|
base.InitialiseGameMode();
|
|
}
|
|
|
|
public override void SetOwnershipOfObjects(VRCPlayerApi NewOwner)
|
|
{
|
|
Networking.SetOwner(NewOwner, _VideoPlayer.gameObject);
|
|
Networking.SetOwner(NewOwner, _Modem.gameObject);
|
|
Networking.SetOwner(NewOwner, _ArrivalDisplay.gameObject);
|
|
Networking.SetOwner(NewOwner, _VideoMusicClueSkateboard.gameObject);
|
|
|
|
base.SetOwnershipOfObjects(NewOwner);
|
|
}
|
|
|
|
public void PlaySecondPartOfThemeMusic()
|
|
{
|
|
EnableInteraction("Start Game");
|
|
_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 = "Error loading case file";
|
|
Interface.CommentUI.text =
|
|
"Unable to find any questions. Ensure the root array elements are all objects.";
|
|
return;
|
|
}
|
|
|
|
Interface.HeaderUI.text = _CaseManager.GetCaseTitle() + " has been loaded.";
|
|
Interface.CommentUI.text = _CaseManager.GetCaseDescription();
|
|
|
|
TryIntroVideoLoad();
|
|
|
|
_GameHasBegun = false;
|
|
}
|
|
public void TryIntroVideoLoad()
|
|
{
|
|
int IntroVideoIndex = _CaseManager.GetIntroVideo();
|
|
if (IntroVideoIndex >= 0)
|
|
{
|
|
_VideoPlayer.VideoIndex = IntroVideoIndex;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("[GameManagerRound1] Intro video index is currently invalid. Retrying...");
|
|
SendCustomEventDelayedSeconds(nameof(TryIntroVideoLoad), 1.0f);
|
|
}
|
|
}
|
|
|
|
|
|
private void PlayIntroVideo()
|
|
{
|
|
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All, "FadeOutMusic");
|
|
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
Interface.HeaderUI.text = "Playing intro video...";
|
|
Interface.CommentUI.text = _CaseManager.GetIntroVideoTranscript();
|
|
|
|
for (int i = 0; i < _PlayerPodiums.Length; i++)
|
|
{
|
|
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.Owner, "ShowAuxiliaryVideoScreen", true);
|
|
}
|
|
|
|
_VideoPlayer.PlayVideo = 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);
|
|
|
|
DisableChoiceCards();
|
|
DisableRiskCards();
|
|
DisableBuzzers();
|
|
|
|
ShowBetweenQuestionsInterface();
|
|
|
|
_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...";
|
|
Interface.CommentUI.text = "";
|
|
|
|
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...";
|
|
if (Presentation.ContainsKey("Video Transcripts"))
|
|
{
|
|
Interface.CommentUI.text = Presentation["Video Transcripts"].DataList[_QuestionSubstage].String;
|
|
}
|
|
else
|
|
{
|
|
Interface.CommentUI.text = "";
|
|
}
|
|
_VideoPlayer.PlayVideo = true;
|
|
|
|
_QuestionSubstage++;
|
|
if (_QuestionSubstage < Videos.Count)
|
|
{
|
|
EnableInteraction("Play Video");
|
|
}
|
|
else
|
|
{
|
|
EnableInteraction("Reveal Question");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MultipleChoiceRevealQuestion();
|
|
}
|
|
|
|
RequestSerialization();
|
|
}
|
|
|
|
private void InitialiseVideoMusicClue(DataDictionary Presentation)
|
|
{
|
|
switch (_QuestionSubstage)
|
|
{
|
|
case 0:
|
|
{
|
|
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All, "PlaySFX", SFXEventType.VideoMusicClue);
|
|
_VideoMusicClueSkateboard.SendCustomNetworkEvent(NetworkEventTarget.All, "SwooceRightIn");
|
|
|
|
string Header = "Error Reading Data";
|
|
string Clue = "just wing it i guess idk";
|
|
if (Presentation.ContainsKey("Video Artist") && Presentation.ContainsKey("Note"))
|
|
{
|
|
Header = Presentation["Video Artist"].String;
|
|
Clue = Presentation["Note"].String;
|
|
}
|
|
_VideoMusicClueSkateboard.SendCustomNetworkEvent(NetworkEventTarget.All,
|
|
"SetCardTexts", Header, Clue);
|
|
|
|
_QuestionSubstage++;
|
|
|
|
EnableInteraction("Play Video");
|
|
} break;
|
|
case 1:
|
|
{
|
|
if (Presentation.ContainsKey("Videos"))
|
|
{
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
Interface.HeaderUI.text = "Playing video...";
|
|
if (Presentation.ContainsKey("Video Artist"))
|
|
{
|
|
Interface.CommentUI.text = "Artist: " + Presentation["Video Artist"].String;
|
|
}
|
|
else
|
|
{
|
|
Interface.CommentUI.text = "";
|
|
}
|
|
|
|
DataList Videos = Presentation["Videos"].DataList;
|
|
_VideoPlayer.PlayVideo = true;
|
|
}
|
|
|
|
_QuestionSubstage++;
|
|
|
|
EnableInteraction("Reveal Question");
|
|
} break;
|
|
default:
|
|
{
|
|
_VideoMusicClueSkateboard.SendCustomNetworkEvent(NetworkEventTarget.All, "ResetSkateboard");
|
|
MultipleChoiceRevealQuestion();
|
|
} break;
|
|
}
|
|
|
|
RequestSerialization();
|
|
}
|
|
|
|
private void InitialiseACMECrimenetComputer(DataDictionary Presentation)
|
|
{
|
|
if (_QuestionSubstage < 1)
|
|
{
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
Interface.HeaderUI.text = "Check the computer for clues that need translating.";
|
|
Interface.CommentUI.text = "";
|
|
|
|
string UntranslatedText = "";
|
|
string TranslatedText = "";
|
|
if (Presentation.ContainsKey("Untranslated Text Placeholder") && Presentation.ContainsKey("Translated Text"))
|
|
{
|
|
UntranslatedText = Presentation["Untranslated Text Placeholder"].String;
|
|
TranslatedText = Presentation["Translated Text"].String;
|
|
}
|
|
|
|
_ACMECrimenetComputer.SendCustomNetworkEvent(NetworkEventTarget.All,
|
|
"SetCardTexts", UntranslatedText, TranslatedText);
|
|
_ACMECrimenetComputer.SendCustomNetworkEvent(NetworkEventTarget.All, "SwooceRightIn");
|
|
|
|
_QuestionSubstage++;
|
|
EnableInteraction("Reveal Question");
|
|
}
|
|
else
|
|
{
|
|
_ACMECrimenetComputer.SendCustomNetworkEvent(NetworkEventTarget.All, "ResetComputer");
|
|
MultipleChoiceRevealQuestion();
|
|
}
|
|
|
|
RequestSerialization();
|
|
}
|
|
|
|
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()
|
|
{
|
|
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(PlayLightningRoundAnimation));
|
|
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All, "PlaySFX", SFXEventType.Thunder);
|
|
|
|
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 " + _CaseManager.GetCrookName() + "'s most recent whereabouts, which is " + _CurrentQuestion["Location"].ToString() + ". Hands on your buzzers. Here's the first question...";
|
|
|
|
EnableBuzzers();
|
|
|
|
EnableInteraction("First Question");
|
|
}
|
|
[NetworkCallable]
|
|
public void PlayLightningRoundAnimation()
|
|
{
|
|
_LightningRoundAnimator.SetBool("Lightning", true);
|
|
SendCustomEventDelayedSeconds(nameof(ResetLightningRoundAnimation), 5.0f);
|
|
}
|
|
public void ResetLightningRoundAnimation()
|
|
{
|
|
_LightningRoundAnimator.SetBool("Lightning", false);
|
|
}
|
|
|
|
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()
|
|
{
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
|
|
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
|
|
"PlayMusic", MusicEventType.TheChase);
|
|
|
|
Interface.HeaderUI.text = RoundSegmentTypeToString(RoundSegmentType.TheChase);
|
|
Interface.CommentUI.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()
|
|
{
|
|
for (int i = 0; i < _PlayerPodiums.Length; i++)
|
|
{
|
|
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.Owner, "ShowAuxiliaryMapScreen", true);
|
|
}
|
|
|
|
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.HeaderUI.text = "The Chase" + (_CurrentQuestion.ContainsKey("Location") ? (" | " + _CurrentQuestion["Location"].String) : "");
|
|
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 IntroduceFinalRound()
|
|
{
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
|
|
Interface.HeaderUI.text = "The Final Round";
|
|
Interface.CommentUI.text =
|
|
"- Now it's time for the final clue of this round, which means you have to decide how many of your ACME Crimebucks you want to risk.\n" +
|
|
"- If you're right, we'll add that amount to your score.\n" +
|
|
"- If you're not right, we'll subtract that amount from your score.\n" +
|
|
"- You can risk 0, 10, 20, 30, 40, or 50 ACME Crimebucks.\n\n" +
|
|
"- Choose how much to risk by placing your wager to the other side of your podium.";
|
|
|
|
LoadMapsIntoQueue();
|
|
|
|
EnableInteraction("Show Map Preview");
|
|
}
|
|
|
|
private void FinalRoundShowMapPreview()
|
|
{
|
|
_VideoPlayer.SubMapIndex = 3;
|
|
|
|
EnableRiskCards();
|
|
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
|
|
Interface.HeaderUI.text = "Show The Map Preview";
|
|
Interface.CommentUI.text =
|
|
"- Here's a portion of the world where we think " + _CaseManager.GetCrookName() + " is headed with " + _CaseManager.GetLoot() + ".\n" +
|
|
"- If you think you know a lot about this part of the world, you may want to risk a lot.\n" +
|
|
"- If you don't know very much about it, though, you may not want to risk quite so much.\n\n" +
|
|
"So, take a look at the map, and think about it.";
|
|
|
|
EnableInteraction("Think About It");
|
|
}
|
|
|
|
private void FinalRoundPlayThinkingMusic()
|
|
{
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
Interface.HeaderUI.text = "Think about it...";
|
|
Interface.CommentUI.text = "";
|
|
|
|
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
|
|
"PlayMusic", MusicEventType.ThinkAboutIt);
|
|
SendCustomEventDelayedSeconds(nameof(ThinkAboutItCountdownFinished), 15.0f);
|
|
}
|
|
public void ThinkAboutItCountdownFinished()
|
|
{
|
|
for (int i = 0; i < _PlayerPodiums.Length; i++)
|
|
{
|
|
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.Owner, "ShowAuxiliaryMapScreen", false);
|
|
}
|
|
|
|
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");
|
|
}
|
|
|
|
ShowBetweenQuestionsInterface();
|
|
|
|
CreateClueSpecificHostInteractionText(_CurrentQuestion["Presentation"].DataDictionary);
|
|
}
|
|
|
|
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;
|
|
Interface.CommentUI.text =
|
|
"- Before you show us your answer, how much did you risk?\n" +
|
|
"- What is your answer?";
|
|
_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 = "Three-Way Tie.";
|
|
Interface.CommentUI.text = "We'll start with a tiebreaker between " + Number2.displayName + " and " + Number3.displayName + ".";
|
|
}
|
|
else
|
|
{
|
|
Interface.HeaderUI.text = Number1.displayName + " Wins";
|
|
Interface.CommentUI.text =
|
|
"- " + Number1.displayName + " will be moving on to the next round.\n" +
|
|
"- 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 = "Tie For First";
|
|
Interface.CommentUI.text =
|
|
"- " + Number1.displayName + " and " + Number2.displayName + " are tied for first place.\n" +
|
|
"- Both will move on to the next round.";
|
|
}
|
|
else
|
|
{
|
|
WinningPlayers[0] = Number1.displayName;
|
|
WinningPlayers[1] = Number2.displayName;
|
|
|
|
Interface.HeaderUI.text = "Winners";
|
|
Interface.CommentUI.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();
|
|
|
|
_VideoPlayer.SendCustomNetworkEvent(NetworkEventTarget.All, "ClearScreen");
|
|
|
|
_QuestionIndex++;
|
|
if (_QuestionIndex >= _QuestionsList.Count)
|
|
{
|
|
PrepareEndGame();
|
|
}
|
|
else
|
|
{
|
|
PrepareNextQuestion();
|
|
}
|
|
}
|
|
private void PrepareNextQuestion()
|
|
{
|
|
InitialiseQuestion();
|
|
if (_CurrentQuestionType == RoundSegmentType.FinalRound)
|
|
{
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
Interface.HeaderUI.text = "The Final Round";
|
|
Interface.CommentUI.text = "";
|
|
AdvanceQuestion();
|
|
}
|
|
else
|
|
{
|
|
ShowBetweenQuestionsInterface();
|
|
}
|
|
}
|
|
private void PrepareEndGame()
|
|
{
|
|
bool TiebreakerNeeded = FinalRoundCheckNeedForTiebreaker();
|
|
|
|
if (TiebreakerNeeded)
|
|
{
|
|
_CurrentQuestionType = RoundSegmentType.Tiebreaker;
|
|
EnableInteraction("Advance To Tiebreaker");
|
|
}
|
|
else
|
|
{
|
|
_QuestionStage = 0;
|
|
_CurrentQuestionType = RoundSegmentType.EndGame;
|
|
|
|
EnableInteraction("Play Round End Music");
|
|
}
|
|
}
|
|
|
|
private void PrepareModem()
|
|
{
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
Interface.HeaderUI.text = "Round is over.";
|
|
Interface.CommentUI.text = "Everybody enter the Modem";
|
|
|
|
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
|
|
"PlayMusicLoop", MusicEventType.CapitalLoop);
|
|
|
|
_Modem.Activate(true);
|
|
_ArrivalDisplay.Activate(true);
|
|
|
|
EnableInteraction("Activate Modem");
|
|
}
|
|
|
|
private void ActivateModem()
|
|
{
|
|
_Modem.Teleport();
|
|
SendCustomEventDelayedSeconds(nameof(_ContinueToRound2_Private), 5.0f);
|
|
}
|
|
public void _ContinueToRound2_Private()
|
|
{
|
|
for (int i = 0; i < _PlayerPodiums.Length; i++)
|
|
{
|
|
_PlayerPodiums[i].SendCustomNetworkEvent(NetworkEventTarget.All, "ResetPodium");
|
|
}
|
|
|
|
_CaseManager.ContinueToRound2();
|
|
EnableInteraction("Continue To Round 2");
|
|
}
|
|
|
|
|
|
private void BeginTiebreakerRound()
|
|
{
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
Interface.HeaderUI.text = "Preparing tiebreaker...";
|
|
Interface.CommentUI.text = "";
|
|
|
|
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;
|
|
case RoundSegmentType.EndGame: AdvanceEndGame(); 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()
|
|
{
|
|
switch (_QuestionStage)
|
|
{
|
|
case 1: PlayTheChaseMusic(); break;
|
|
case 2: TheChaseCluesLoop(); break;
|
|
case 3: AdvanceToNextQuestion(); break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
private void AdvanceFinalRound()
|
|
{
|
|
switch (_QuestionStage)
|
|
{
|
|
case 1: IntroduceFinalRound(); 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;
|
|
}
|
|
}
|
|
|
|
private void AdvanceEndGame()
|
|
{
|
|
switch (_QuestionStage)
|
|
{
|
|
case 1: PrepareModem(); break;
|
|
case 2: ActivateModem(); break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
|
|
public VRCUrl GetMapURL(int MapIndex)
|
|
{
|
|
return _CaseManager.GetMap(MapIndex);
|
|
}
|
|
public int GetMapCount()
|
|
{
|
|
return _CaseManager.GetMapCount();
|
|
}
|
|
|
|
public VRCUrl GetClueImageURL(int ImageIndex)
|
|
{
|
|
return _CaseManager.GetClueImage(ImageIndex);
|
|
}
|
|
|
|
|
|
protected override void _HostCardUseButtonDown_Internal()
|
|
{
|
|
AdvanceQuestion();
|
|
}
|
|
|
|
protected override HostCardInterfaceBase GetHostCardInterface(RoundSegmentType Question)
|
|
{
|
|
return _HostCard.EnableHostCardDisplay(RoundType.LocateTheCrook, Question);
|
|
}
|
|
|
|
private void CreateClueSpecificHostInteractionText(DataDictionary Presentation)
|
|
{
|
|
switch ((PresentationMedium)(int)Presentation["Medium"].Number)
|
|
{
|
|
case PresentationMedium.VideoClue:
|
|
case PresentationMedium.VideoMusicClue:
|
|
EnableInteraction("Play Video"); break;
|
|
case PresentationMedium.ACMECrimenetComputer:
|
|
EnableInteraction("ACME Crimenet Computer"); break;
|
|
default:
|
|
EnableInteraction("Present Next Clue"); break;
|
|
}
|
|
}
|
|
|
|
private HostCardBetweenRoundsInterface ShowBetweenQuestionsInterface()
|
|
{
|
|
HostCardBetweenRoundsInterface Interface =
|
|
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
|
|
|
|
Interface.CommentUI.text = "";
|
|
|
|
bool VideosAvailable = false;
|
|
|
|
string PresentationMediumString = "";
|
|
if (_CurrentQuestion.ContainsKey("Presentation"))
|
|
{
|
|
DataDictionary Presentation = _CurrentQuestion["Presentation"].DataDictionary;
|
|
|
|
if (_CurrentQuestion["Presentation"].DataDictionary.ContainsKey("Clue Title"))
|
|
{
|
|
PresentationMediumString = Presentation["Clue Title"].String;
|
|
}
|
|
else if (_CurrentQuestion["Presentation"].DataDictionary.ContainsKey("Medium"))
|
|
{
|
|
PresentationMediumString = PresentationMediumToString((PresentationMedium)(int)Presentation["Medium"].Number);
|
|
}
|
|
|
|
if (_CurrentQuestionType == RoundSegmentType.FinalRound)
|
|
{
|
|
EnableInteraction("Introduce Final Round");
|
|
}
|
|
else
|
|
{
|
|
CreateClueSpecificHostInteractionText(Presentation);
|
|
}
|
|
|
|
if (Presentation.ContainsKey("Clue Description"))
|
|
{
|
|
Interface.CommentUI.text = Presentation["Clue Description"].String;
|
|
}
|
|
|
|
if (Presentation.ContainsKey("Videos"))
|
|
{
|
|
DataList Videos = Presentation["Videos"].DataList;
|
|
_VideoPlayer.VideoIndex = (int)Videos[_QuestionSubstage].Number;
|
|
|
|
VideosAvailable = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PresentationMediumString = RoundSegmentTypeToString(_CurrentQuestionType);
|
|
if (_CurrentQuestion.ContainsKey("Clue Description"))
|
|
{
|
|
Interface.CommentUI.text = _CurrentQuestion["Clue Description"].String;
|
|
}
|
|
|
|
if (VideosAvailable)
|
|
{
|
|
EnableInteraction("Play Videos");
|
|
}
|
|
else
|
|
{
|
|
EnableInteraction("Begin " + PresentationMediumString);
|
|
}
|
|
}
|
|
|
|
Interface.HeaderUI.text = "Upcoming Question: " + 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]]";
|
|
}
|
|
}
|
|
}
|