content/hifi-content/brosche/dev/triviaMasterClientStandard.js
2022-02-13 21:50:01 +01:00

1043 lines
No EOL
46 KiB
JavaScript

// triviaMasterClientStandard.js
//
// Created by Rebecca Stankus on 06/11/18
// Modified by Mark Brosche on 10/16/18
// Updated 3/13/19 by Mark Brosche
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
// This is the standard version of "Last Avatar Standing" Trivia
// that draws from a third-party database of thousands of questions.
/* global EventBridge Users AccountServices */
(function() {
var SECRETS = Script.require(Script.resolvePath('triviaInfo.json')),
TRIVIA_CHANNEL = SECRETS.TRIVIA_CHANNEL,
GOOGLE_URL = SECRETS.GOOGLE_URL,
TABLET_BUTTON_IMAGE = Script.resolvePath('../entities/icons/questionMark-i.png'),
TABLET_BUTTON_PRESSED = Script.resolvePath('../entities/icons/questionMark-a.png'),
SEARCH_RADIUS = 1000,
ONE_SECOND_MS = 1000;
var FIVE_SECONDS = 5 * ONE_SECOND_MS,
TEN_SECONDS_MS = 10 * ONE_SECOND_MS,
ZONE_COLOR_INDEX = 19,
HALF_MULTIPLIER = 0.5,
FIRST_WAIT_TO_COUNT_AVATARS = ONE_SECOND_MS,
WAIT_TO_SHOW_QUESTION = 0.5 * ONE_SECOND_MS,
MIN_PLAYERS = 3,
HFC_INCREMENT = 100,
HFC_HALVER = 0.5,
MIN_PRIZE = 300,
HOST_PERCENTAGE = 0.1;
var tablet = Tablet.getTablet('com.highfidelity.interface.tablet.system'),
appPage = Script.resolvePath('trivia.html?v100'),
button = tablet.addButton({
text: 'TRIVIA',
icon: TABLET_BUTTON_IMAGE,
activeIcon: TABLET_BUTTON_PRESSED
});
var open = false,
gSheetTabName = "Halloween",
intervalBoard,
questionText,
triviaURL = "",
choiceTexts = [],
answerText,
triviaData,
request = Script.require('../entities/modules/request.js').request,
type = null,
category = null,
difficulty = null,
currentChoices = [],
letter = [],
lights = [],
correctHighlights = [],
timer,
gameZone,
gameZoneProperties,
avatarCounter,
formattedQuestion = null,
intervalTimer,
bubble,
bubbleState = false,
introPlayed = false,
correctCount = null,
prizeDisplay,
useGoogle = false,
prizeMoney,
winnerID = null,
correctColor = null;
var formattedAnswer = null;
// The following function from https://stackoverflow.com/questions/3700326/decode-amp-back-to-in-javascript
var htmlEnDeCode = (function() {
var charToEntityRegex,
entityToCharRegex,
charToEntity,
entityToChar;
function resetCharacterEntities() {
charToEntity = {};
entityToChar = {};
// add the default set
addCharacterEntities({
'&': '&',
'>': '>',
'&lt;': '<',
'&quot;': '"',
'&#039;': "'",
'&#39;': "'",
'&lsquo;': '"',
'&rsquo;': '"',
'&ldquo;': '"',
'&Uuml;': 'U',
'&uuml;': 'u',
'&rdquo;': '"',
'&eacute;': 'e',
'&prime;': '\'',
'&Prime': '"'
});
}
function addCharacterEntities(newEntities) {
var charKeys = [],
entityKeys = [],
key, encodedChar;
for (key in newEntities) {
encodedChar = newEntities[key];
entityToChar[key] = encodedChar;
charToEntity[encodedChar] = key;
charKeys.push(encodedChar);
entityKeys.push(key);
}
charToEntityRegex = new RegExp('(' + charKeys.join('|') + ')', 'g');
entityToCharRegex = new RegExp('(' + entityKeys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
}
function htmlEncode(value) {
var htmlEncodeReplace = function(match, capture) {
return charToEntity[capture];
};
return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplace);
}
function htmlDecode(value) {
var htmlDecodeReplaceFn = function(match, capture) {
return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10));
};
return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn);
}
resetCharacterEntities();
return {
htmlEncode: htmlEncode,
htmlDecode: htmlDecode
};
})();
function begin() {
if (Entities.serversExist()) {
try {
if (findTargets()){
bubbleOn();
prizeCalculator("new game");
if (!introPlayed) {
Entities.callEntityServerMethod(gameZoneProperties.id, "playSound", ['GAME_INTRO']);
introPlayed = true;
} else {
Entities.callEntityServerMethod(gameZoneProperties.id, "playSound", ['NEW_GAME_SFX']);
}
Entities.callEntityServerMethod(gameZoneProperties.id, "stopConfetti");
lights.forEach(function(light) {
Entities.callEntityServerMethod(light, "lightsOn");
});
} else {
var data = {"error message": "found no targets"};
data.application = "trivia";
tablet.emitScriptEvent(JSON.stringify(data));
}
} catch (e) {
console.log(e, "error finding targets");
var data = {"error message": e};
data.application = "trivia";
tablet.emitScriptEvent(JSON.stringify(data));
}
} else {
Script.setTimeout(function(){
try {
findTargets();
bubbleOn();
prizeCalculator("new game");
if (!introPlayed) {
Entities.callEntityServerMethod(gameZoneProperties.id, "playSound", ['GAME_INTRO']);
introPlayed = true;
} else {
Entities.callEntityServerMethod(gameZoneProperties.id, "playSound", ['NEW_GAME_SFX']);
}
Entities.callEntityServerMethod(gameZoneProperties.id, "stopConfetti");
lights.forEach(function(light) {
Entities.callEntityServerMethod(light, "lightsOn");
});
} catch (e) {
console.log(e, "error finding targets");
var data = {"error message": e};
data.application = "trivia";
tablet.emitScriptEvent(JSON.stringify(data));
}
}, FIVE_SECONDS);
}
}
function bubbleOn() {
bubbleState = true;
Entities.callEntityServerMethod(bubble, "bubbleOn");
Messages.sendMessage(TRIVIA_CHANNEL, JSON.stringify({
type: "game on"
}));
usersInZone(gameZoneProperties, "begin");
if (!intervalBoard) {
intervalBoard = Script.setInterval(function(){
updateAvatarCounter(false);
Entities.callEntityServerMethod(prizeDisplay, "textUpdate", [prizeMoney, true]);
}, ONE_SECOND_MS);
} else {
Script.clearInterval(intervalBoard);
intervalBoard = false;
intervalBoard = Script.setInterval(function(){
updateAvatarCounter(false);
Entities.callEntityServerMethod(prizeDisplay, "textUpdate", [prizeMoney, true]);
}, ONE_SECOND_MS);
}
}
function bubbleOff() {
bubbleState = false;
Entities.callEntityServerMethod(bubble, "bubbleOff");
usersInZone(gameZoneProperties, "end");
Messages.sendMessage(TRIVIA_CHANNEL, JSON.stringify({ type: "game off" }));
if (intervalBoard) {
Script.clearInterval(intervalBoard);
intervalBoard = false;
}
type = null;
category = null;
difficulty = null;
}
function findTargets() {
Entities.findEntities(MyAvatar.position, SEARCH_RADIUS).forEach(function(element) {
var name = Entities.getEntityProperties(element, ['name']).name;
if (name.indexOf("Trivia") !== -1) {
var serverScriptURL = Entities.getEntityProperties(element, ['serverScripts']).serverScripts;
if (serverScriptURL !== "") {
Entities.getServerScriptStatus(element, (function() {
return function(success, isRunning, status, errorInfo) {
if (!success || !isRunning) {
console.log("Script not running:", element, success, isRunning, status, errorInfo, JSON.stringify(serverScriptURL));
Entities.reloadServerScripts(element);
}
};
})());
}
if (name.indexOf("Light") !== -1) {
lights.push(element);
} else if (name.indexOf("Correct") !== -1) {
correctHighlights.push(element);
} else {
switch (name) {
case "Trivia Question":
questionText = element;
break;
case "Trivia Answer":
answerText = element;
break;
case "Trivia Choice Text Green":
choiceTexts[0] = element;
break;
case "Trivia Choice Text Yellow":
choiceTexts[1] = element;
break;
case "Trivia Choice Text Red":
choiceTexts[2] = element;
break;
case "Trivia Choice Text Blue":
choiceTexts[3] = element;
break;
case "Trivia Timer Countdown":
timer = element;
break;
case "Trivia Avatar Counter Total":
avatarCounter = element;
break;
case "Trivia Player Game Zone":
gameZone = element;
gameZoneProperties = Entities.getEntityProperties(gameZone,
["id", "position", "dimensions", "rotation", "userData"]);
break;
case "Trivia Prize Amount":
prizeDisplay = element;
break;
case "Trivia Bubble":
bubble = element;
break;
case "Trivia Choice Letter Blue Board":
letter[0] = element;
break;
case "Trivia Choice Letter Green Board":
letter[1] = element;
break;
}
}
}
});
return true;
}
function onClicked() {
if (open) {
tablet.gotoHomeScreen();
tablet.webEventReceived.disconnect(onWebEventReceived);
} else {
tablet.gotoWebScreen(appPage);
Script.setTimeout(function(){
if (triviaData) {
if (triviaData.length !== 0 && !useGoogle) {
tablet.emitScriptEvent(JSON.stringify(triviaData[0]));
tablet.emitScriptEvent("gameInProgress");
} else if (bubbleState === true && !useGoogle) {
tablet.emitScriptEvent(JSON.stringify(triviaData[0]));
tablet.emitScriptEvent("noQuestionPosted");
} else if (triviaData.length !== 0 && useGoogle) {
tablet.emitScriptEvent(JSON.stringify(triviaData[0]));
tablet.emitScriptEvent("gameInProgressCustom");
} else if (bubbleState === true && useGoogle) {
tablet.emitScriptEvent(JSON.stringify(triviaData[0]));
tablet.emitScriptEvent("noQuestionPostedCustom");
}
}
}, 500);
}
}
function getQuestion() {
if (intervalTimer) {
Script.clearInterval(intervalTimer);
intervalTimer = false;
}
Entities.callEntityServerMethod(gameZoneProperties.id, "playSound", ['NEXT_QUESTION_SFX']);
if (useGoogle){
try {
if (triviaURL === "") {
triviaURL = SECRETS.trivia_URL;
} else if (triviaURL.indexOf("category=") === -1) {
triviaURL = triviaURL + "category=" + gSheetTabName;
}
var expression = /[-a-zA-Z0-9@:%_\+.~#?&\/=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&\/=]*)?/gi;
var regex = new RegExp(expression);
if (triviaURL.match(regex)) {
request(triviaURL, function (error, data) {
if (error || data.status !== "success") {
data.application = "trivia";
tablet.emitScriptEvent("nothingEntered");
useGoogle = false;
} else {
data.application = "trivia";
tablet.emitScriptEvent(JSON.stringify(data));
triviaData = data;
}
});
} else {
tablet.emitScriptEvent("nothingEntered");
}
} catch (err) {
print("Could not get domain data using userData domainAPIURL");
}
} else {
try {
triviaURL = "https://opentdb.com/api.php?amount=1";
if (type) {
triviaURL = triviaURL + "&type=" + type;
}
if (difficulty) {
triviaURL = triviaURL + "&difficulty=" + difficulty;
}
if (category) {
triviaURL = triviaURL + "&category=" + category;
}
request(triviaURL, function (error, data) {
if (!error) {
data.results[0].application = "trivia";
tablet.emitScriptEvent(JSON.stringify(data.results[0]));
triviaData = data.results;
} else {
data.response_code.application = "trivia";
tablet.emitScriptEvent(JSON.stringify(data.response_code));
}
});
} catch (err) {
print("Could not get domain data using userData domainAPIURL");
}
}
}
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
while (currentIndex !== 0) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
function showQuestion() {
clearBoard();
formattedQuestion = null;
Script.setTimeout(function() {
choiceTexts.forEach(function(choice) {
Entities.callEntityServerMethod(choice, "textUpdate", ["", true]);
});
Entities.callEntityServerMethod(letter[0], "textUpdate", ["C", true]);
Entities.callEntityServerMethod(letter[1], "textUpdate", ["B", true]);
if (useGoogle) {
formattedQuestion = triviaData.question;
} else {
formattedQuestion = htmlEnDeCode.htmlDecode(triviaData[0].question);
}
Entities.callEntityServerMethod(questionText, "textUpdate", [formattedQuestion, true]);
Entities.callEntityServerMethod(answerText, "textUpdate", ["", false]);
}, WAIT_TO_SHOW_QUESTION);
}
function showAnswers() {
if (useGoogle) {
if (triviaData.type === "boolean") {
Entities.callEntityServerMethod(choiceTexts[0], "textUpdate", ["",false]);
Entities.callEntityServerMethod(choiceTexts[1], "textUpdate", ["True", true]);
Entities.callEntityServerMethod(choiceTexts[2], "textUpdate", ["False", true]);
Entities.callEntityServerMethod(choiceTexts[3], "textUpdate", ["", false]);
Entities.callEntityServerMethod(letter[0], "textUpdate", ["C", false]);
Entities.callEntityServerMethod(letter[1], "textUpdate", ["B", false]);
currentChoices = [];
currentChoices.push("True");
currentChoices.push("False");
lights.forEach(function(light) {
var lightName = Entities.getEntityProperties(light, 'name').name;
if ((lightName.indexOf("Green") !== -1) || (lightName.indexOf("Blue") !== -1)) {
Entities.callEntityServerMethod(light, "lightsOff");
}
});
} else {
currentChoices = [];
currentChoices.push({"text": triviaData.correct_answer, "correct": true});
triviaData.incorrect_answers.forEach(function(choice) {
currentChoices.push({"text": choice, "correct": false});
});
shuffle(currentChoices);
currentChoices.forEach(function(choice, index) {
Entities.callEntityServerMethod(choiceTexts[index], "textUpdate", [choice.text, true]);
});
}
} else {
if (triviaData[0].type === "boolean") {
Entities.callEntityServerMethod(choiceTexts[0], "textUpdate", ["",false]);
Entities.callEntityServerMethod(choiceTexts[1], "textUpdate", ["True", true]);
Entities.callEntityServerMethod(choiceTexts[2], "textUpdate", ["False", true]);
Entities.callEntityServerMethod(choiceTexts[3], "textUpdate", ["", false]);
Entities.callEntityServerMethod(letter[0], "textUpdate", ["C", false]);
Entities.callEntityServerMethod(letter[1], "textUpdate", ["B", false]);
currentChoices = [];
currentChoices.push("True");
currentChoices.push("False");
lights.forEach(function(light) {
var lightName = Entities.getEntityProperties(light, 'name').name;
if ((lightName.indexOf("Green") !== -1) || (lightName.indexOf("Blue") !== -1)) {
Entities.callEntityServerMethod(light, "lightsOff");
}
});
} else {
currentChoices = [];
currentChoices.push({"text": triviaData[0].correct_answer, "correct": true});
triviaData[0].incorrect_answers.forEach(function(choice) {
currentChoices.push({"text": choice, "correct": false});
});
shuffle(currentChoices);
currentChoices.forEach(function(choice, index) {
Entities.callEntityServerMethod(choiceTexts[index], "textUpdate", [choice.text, true]);
});
}
}
}
function clearGame(userTriggered) {
correctCount = null;
prizeMoney = 0;
winnerID = null;
triviaData = [];
if (intervalTimer){
Script.clearTimeout(intervalTimer);
intervalTimer = false;
}
if (userTriggered) {
Entities.callEntityServerMethod(gameZoneProperties.id, "stopSound");
}
bubbleOff();
lights.forEach(function(light) {
Entities.callEntityServerMethod(light, "lightsOff");
});
correctHighlights.forEach(function(highlight) {
Entities.callEntityServerMethod(highlight, "lightsOff");
});
Entities.callEntityServerMethod(questionText, "textUpdate", ["Questions will appear here.", true]);
choiceTexts.forEach(function(choice) {
Entities.callEntityServerMethod(choice, "textUpdate", ["Answers will appear here.", true]);
});
Entities.callEntityServerMethod(timer, "textUpdate", ["0", true]);
Entities.callEntityServerMethod(letter[0], "textUpdate", ["C", true]);
Entities.callEntityServerMethod(letter[1], "textUpdate", ["B", true]);
Entities.callEntityServerMethod(answerText, "textUpdate", ["", true]);
Entities.callEntityServerMethod(avatarCounter, "textUpdate", [0, true]);
Entities.callEntityServerMethod(prizeDisplay, "textUpdate", [0, true]);
}
function isPositionInsideBox(position, gameZoneProperties) {
var localPosition = Vec3.multiplyQbyV(Quat.inverse(gameZoneProperties.rotation),
Vec3.subtract(position, gameZoneProperties.position));
var halfDimensions = Vec3.multiply(gameZoneProperties.dimensions, HALF_MULTIPLIER);
return -halfDimensions.x <= localPosition.x &&
halfDimensions.x >= localPosition.x &&
-halfDimensions.y <= localPosition.y &&
halfDimensions.y >= localPosition.y &&
-halfDimensions.z <= localPosition.z &&
halfDimensions.z >= localPosition.z;
}
function usersInZone(gameZoneProperties, state) {
var count = 0;
if (state === undefined) {
AvatarManager.getAvatarIdentifiers().forEach(function(avatarID) {
var avatar = AvatarManager.getAvatar(avatarID);
if (avatar.sessionUUID && isPositionInsideBox(avatar.position, gameZoneProperties)) {
count++;
}
});
return count;
} else if (state === "begin") {
AvatarManager.getAvatarIdentifiers().forEach(function(avatarID) {
var avatar = AvatarManager.getAvatar(avatarID);
if (avatar.sessionUUID && isPositionInsideBox(avatar.position, gameZoneProperties)) {
console.log("created validator", avatar.sessionUUID);
Entities.callEntityServerMethod(gameZone, "rezValidator", [avatar.sessionUUID]);
}
});
} else {
AvatarManager.getAvatarIdentifiers().forEach(function(avatarID) {
var avatar = AvatarManager.getAvatar(avatarID);
if (avatar.sessionUUID && isPositionInsideBox(avatar.position, gameZoneProperties)) {
Entities.callEntityServerMethod(gameZone, "deleteValidator", [avatar.sessionUUID]);
}
});
}
}
function updateAvatarCounter(roundOver) {
var count = usersInZone(gameZoneProperties);
if (roundOver) {
Script.setTimeout(function(){
if (correctCount === 1) {
prizeCalculator("game over");
} else {
prizeCalculator("increase pot");
}
}, 1500);
}
Entities.callEntityServerMethod(avatarCounter, "textUpdate", [count, true]);
}
function prizeCalculator(gameState) {
var count = usersInZone(gameZoneProperties);
switch (gameState) {
case "new game":
if (count <= MIN_PLAYERS) {
prizeMoney = MIN_PRIZE;
} else {
prizeMoney = count * HFC_INCREMENT;
}
break;
case "everyone wrong":
prizeMoney *= HFC_HALVER;
if (prizeMoney <= MIN_PRIZE) {
prizeMoney = MIN_PRIZE;
}
Entities.callEntityServerMethod(gameZoneProperties.id, "playSound", ['POT_DECREASE_SFX']);
// Entities.callEntityServerMethod(gameZoneProperties.id, "loseCoins");
Entities.callEntityServerMethod(gameZoneProperties.id, "halfHFC");
break;
case "increase pot":
prizeMoney += HFC_INCREMENT;
Entities.callEntityServerMethod(gameZoneProperties.id, "playSound", ['POT_INCREASE_SFX']);
// Entities.callEntityServerMethod(gameZoneProperties.id, "winCoins");
Entities.callEntityServerMethod(gameZoneProperties.id, "plusHFC");
break;
case "game over":
prizeMoney += HFC_INCREMENT;
Entities.callEntityServerMethod(gameZoneProperties.id, "playSound", ['WINNER_MUSIC']);
Entities.callEntityServerMethod(gameZoneProperties.id, "startConfetti");
if (prizeMoney >= 300 && winnerID !== MyAvatar.sessionUUID) {
var pot = prizeMoney;
var winnerBanner = AvatarManager.getAvatar(winnerID).sessionDisplayName + " wins " + pot + "HFC!";
Entities.callEntityServerMethod(questionText, "textUpdate", [winnerBanner, true]);
Users.requestUsernameFromID(winnerID);
Script.setTimeout(function(){
clearGame(false);
Entities.callEntityServerMethod(questionText, "textUpdate", [winnerBanner, true]);
}, 2 * ONE_SECOND_MS);
tablet.emitScriptEvent("newGame");
}
break;
}
}
function sendInput(winningUserName) {
if (prizeMoney >= 300 && winnerID !== MyAvatar.sessionUUID && winningUserName !== AccountServices.username) {
var hostPayout = prizeMoney * HOST_PERCENTAGE;
var paramString = encodeURLParams({
date: new Date(),
triviaMasterUserName: AccountServices.username,
triviaMasterPayout: hostPayout,
winnerUserName: winningUserName,
winnings: prizeMoney,
senderID: AccountServices.username
});
var request = new XMLHttpRequest();
request.open('GET', GOOGLE_URL + "?" + paramString);
request.timeout = 10000;
request.send();
}
}
function encodeURLParams(params) {
var paramPairs = [];
for (var key in params) {
paramPairs.push(key + "=" + params[key]);
}
return paramPairs.join("&");
}
function setUserName(uuid, userName) {
sendInput(userName);
}
function clearBoard() {
if (intervalTimer) {
Script.clearInterval(intervalTimer);
intervalTimer = false;
}
lights.forEach(function(light) {
Entities.callEntityServerMethod(light,"lightsOn");
});
correctHighlights.forEach(function(highlight) {
Entities.callEntityServerMethod(highlight, "lightsOff");
});
Entities.callEntityServerMethod(letter[0], "textUpdate", ["C", true]);
Entities.callEntityServerMethod(letter[1], "textUpdate", ["B", true]);
Entities.callEntityServerMethod(questionText, "textUpdate", ["", true]);
choiceTexts.forEach(function(choice) {
Entities.callEntityServerMethod(choice, "textUpdate", ["", true]);
});
Entities.callEntityServerMethod(answerText, "textUpdate", ["", false]);
}
function startTimer() {
if (intervalTimer) {
Script.clearInterval(intervalTimer);
intervalTimer = false;
}
Entities.callEntityServerMethod(gameZoneProperties.id, "playSound", ['TIMER_SOUND']);
var seconds = 10;
Entities.callEntityServerMethod(timer, "textUpdate", [seconds, true]);
intervalTimer = Script.setInterval(function() {
seconds--;
Entities.callEntityServerMethod(timer, "textUpdate", [seconds, true]);
if (seconds <= 0) {
Script.clearInterval(intervalTimer);
intervalTimer = false;
seconds = 0;
}
}, ONE_SECOND_MS);
}
function isAnyAvatarCorrect(correctColor) {
var result = null;
var correctZoneColorID = null;
switch (correctColor){
case "Red":
correctZoneColorID = Entities.findEntitiesByName("Trivia Zone Red", MyAvatar.position, SEARCH_RADIUS)[0];
break;
case "Green":
correctZoneColorID = Entities.findEntitiesByName("Trivia Zone Green", MyAvatar.position, SEARCH_RADIUS)[0];
break;
case "Yellow":
correctZoneColorID = Entities.findEntitiesByName("Trivia Zone Yellow", MyAvatar.position, SEARCH_RADIUS)[0];
break;
case "Blue":
correctZoneColorID = Entities.findEntitiesByName("Trivia Zone Blue", MyAvatar.position, SEARCH_RADIUS)[0];
break;
}
var correctColorZoneProperties = Entities.getEntityProperties(
correctZoneColorID,
["position", "dimensions", "rotation"]);
result = usersInZone(correctColorZoneProperties);
if (result === 1) {
AvatarManager.getAvatarIdentifiers().forEach(function(avatarID) {
var avatar = AvatarManager.getAvatar(avatarID);
if (avatar.sessionUUID !== MyAvatar.sessionUUID) {
if (isPositionInsideBox(avatar.position, correctColorZoneProperties)) {
winnerID = avatar.sessionUUID;
}
}
});
}
return result;
}
function showCorrect() {
if (useGoogle){
formattedAnswer = triviaData.correct_answer;
correctColor = null;
var correctIndex = currentChoices[currentChoices.map(function(e) {
return e.correct;
}).indexOf(true)];
var properties = Entities.getEntityProperties(choiceTexts[currentChoices.indexOf(correctIndex)], ['name']);
correctColor = properties.name.substr(ZONE_COLOR_INDEX);
lights.forEach(function(light) {
var lightName = Entities.getEntityProperties(light, 'name').name;
if (lightName.indexOf(correctColor) === -1) {
Entities.callEntityServerMethod(light, "lightsOff");
}
});
correctHighlights.forEach(function(highlight) {
var highlightName = Entities.getEntityProperties(highlight, 'name').name;
if (highlightName.indexOf(correctColor) !== -1) {
Entities.callEntityServerMethod(highlight, "lightsOn");
}
});
var anyCorrect = isAnyAvatarCorrect(correctColor);
if (anyCorrect === 0) {
Script.setTimeout(function() {
prizeCalculator("everyone wrong");
}, FIRST_WAIT_TO_COUNT_AVATARS);
} else {
Script.setTimeout(function() {
Entities.callEntityServerMethod(bubble, "checkAnswer", [correctColor]);
correctCount = isAnyAvatarCorrect(correctColor);
updateAvatarCounter(true);
}, FIRST_WAIT_TO_COUNT_AVATARS);
}
Entities.callEntityServerMethod(answerText, "textUpdate", [formattedAnswer, true]);
} else {
formattedAnswer = htmlEnDeCode.htmlDecode(triviaData[0].correct_answer);
correctColor = null;
var correctIndex = currentChoices[currentChoices.map(function(e) {
return e.correct;
}).indexOf(true)];
var properties = Entities.getEntityProperties(choiceTexts[currentChoices.indexOf(correctIndex)], ['name']);
correctColor = properties.name.substr(ZONE_COLOR_INDEX);
lights.forEach(function(light) {
var lightName = Entities.getEntityProperties(light, 'name').name;
if (lightName.indexOf(correctColor) === -1) {
Entities.callEntityServerMethod(light, "lightsOff");
}
});
correctHighlights.forEach(function(highlight) {
var highlightName = Entities.getEntityProperties(highlight, 'name').name;
if (highlightName.indexOf(correctColor) !== -1) {
Entities.callEntityServerMethod(highlight, "lightsOn");
}
});
anyCorrect = isAnyAvatarCorrect(correctColor);
if (anyCorrect === 0) {
Script.setTimeout(function() {
prizeCalculator("everyone wrong");
}, FIRST_WAIT_TO_COUNT_AVATARS);
} else {
Script.setTimeout(function() {
Entities.callEntityServerMethod(bubble, "checkAnswer", [correctColor]);
correctCount = isAnyAvatarCorrect(correctColor);
console.log("loading the check answer script for ", correctColor, "and how many are right: ", correctCount);
updateAvatarCounter(true);
}, FIRST_WAIT_TO_COUNT_AVATARS);
}
Entities.callEntityServerMethod(answerText, "textUpdate", [formattedAnswer, true]);
}
}
function onWebEventReceived(event) {
if (typeof event === 'string') {
try {
event = JSON.parse(event);
} catch (e) {
console.log("error parsing web event", e);
return;
}
if (event.app === 'trivia') {
switch (event.type) {
case 'listening':
if (triviaData) {
if (triviaData.length !== 0 && !useGoogle) {
tablet.emitScriptEvent(JSON.stringify(triviaData[0]));
tablet.emitScriptEvent("gameInProgress");
} else if (bubbleState === true && !useGoogle) {
tablet.emitScriptEvent(JSON.stringify(triviaData[0]));
tablet.emitScriptEvent("noQuestionPosted");
} else if (triviaData.length !== 0 && useGoogle) {
tablet.emitScriptEvent(JSON.stringify(triviaData));
tablet.emitScriptEvent("gameInProgressCustom");
} else if (bubbleState === true && useGoogle) {
tablet.emitScriptEvent(JSON.stringify(triviaData));
tablet.emitScriptEvent("noQuestionPostedCustom");
} else {
tablet.emitScriptEvent("newGame");
}
} else {
tablet.emitScriptEvent("newGame");
}
break;
case 'catalog':
switch (event.value) {
case "Default Catalog":
useGoogle = false;
break;
case "Custom Catalog":
useGoogle = true;
triviaURL = SECRETS.trivia_URL;
answer = Window.prompt("What is the tab name of the sheet to use?", "");
if (answer === null) {
tablet.emitScriptEvent("nothingEntered");
useGoogle = false;
} else {
gSheetTabName = answer;
}
break;
case "Misc. Catalog":
var answer = Window.prompt("URL of your GSheets script?", "");
if (answer === null) {
tablet.emitScriptEvent("nothingEntered");
useGoogle = false;
} else {
triviaURL = answer;
answer = Window.prompt("What is the tab name of the sheet to use?", "");
if (answer === null) {
tablet.emitScriptEvent("nothingEntered");
useGoogle = false;
} else {
useGoogle = true;
gSheetTabName = answer;
}
}
break;
}
break;
case 'begin':
begin();
break;
case 'end':
clearGame(true);
break;
case 'type':
switch (event.value) {
case "Any Type":
type = null;
break;
case "Multiple Choice":
type = "multiple";
break;
case "True or False":
type = "boolean";
break;
}
break;
case 'difficulty':
switch (event.value) {
case "Any Difficulty":
difficulty = null;
break;
case "Easy":
difficulty = "easy";
break;
case "Medium":
difficulty = "medium";
break;
case "Hard":
difficulty = "hard";
break;
}
break;
case 'category':
switch (event.value) {
case "Any Category":
category = null;
break;
case "General Knowledge":
category = "9";
break;
case "Books":
category = "10";
break;
case "Film":
category = "11";
break;
case "Music":
category = "12";
break;
case "Musicals and Theatres":
category = "13";
break;
case "Television":
category = "14";
break;
case "Video Games":
category = "15";
break;
case "Board Games":
category = "16";
break;
case "Comics":
category = "29";
break;
case "Japanese Anime and Manga":
category = "31";
break;
case "Cartoon and Animations":
category = "32";
break;
case "Computers":
category = "18";
break;
case "Mathematics":
category = "19";
break;
case "Gadgets":
category = "30";
break;
case "Art":
category = "25";
break;
case "Celebrities":
category = "26";
break;
case "Animals":
category = "27";
break;
case "Vehicles":
category = "28";
break;
case "Mythology":
category = "20";
break;
case "Sports":
category = "21";
break;
case "History":
category = "23";
break;
case "Geography":
category = "22";
break;
case "Politics":
category = "24";
break;
}
break;
case 'newQuestion':
getQuestion();
break;
case 'showQuestion':
showQuestion();
break;
case 'showAnswers':
showAnswers();
startTimer();
Script.setTimeout(function() {
showCorrect();
if (useGoogle) {
tablet.emitScriptEvent("re-enableCustom");
} else {
tablet.emitScriptEvent("re-enable");
}
}, TEN_SECONDS_MS);
break;
default:
print(JSON.stringify(event));
print("error in detecting event.type");
}
}
}
}
function onScreenChanged(type, url) {
open = (url === appPage);
button.editProperties({isActive: open});
if (open) {
tablet.webEventReceived.connect(onWebEventReceived);
}
}
function appEnding() {
if (intervalBoard) {
Script.clearInterval(intervalBoard);
intervalBoard = false;
}
Messages.unsubscribe(TRIVIA_CHANNEL);
clearGame(true);
button.clicked.disconnect(onClicked);
tablet.removeButton(button);
AvatarManager.avatarRemovedEvent.disconnect(updateCountOnAvatarRemoved);
tablet.screenChanged.disconnect(onScreenChanged);
if (open) {
tablet.webEventReceived.disconnect(onWebEventReceived);
}
Users.usernameFromIDReply.disconnect(setUserName);
}
function updateCountOnAvatarRemoved(){
updateAvatarCounter(false);
}
this.unload = function() {
clearGame(true);
introPlayed = false;
};
findTargets();
Messages.subscribe(TRIVIA_CHANNEL);
AvatarManager.avatarRemovedEvent.connect(updateCountOnAvatarRemoved);
Users.usernameFromIDReply.connect(setUserName);
button.clicked.connect(onClicked);
tablet.screenChanged.connect(onScreenChanged);
Script.scriptEnding.connect(appEnding);
}());