Merge branch 'master' of github.com:highfidelity/hifi into motor-action

This commit is contained in:
Seth Alves 2017-05-08 16:37:19 -07:00
commit f8cab08b19
8 changed files with 659 additions and 88 deletions

View file

@ -17,26 +17,26 @@ Rectangle {
property alias pixelSize: label.font.pixelSize;
property bool selected: false
property bool hovered: false
property bool enabled: false
property int spacing: 2
property var action: function () {}
property string enabledColor: hifi.colors.blueHighlight
property string disabledColor: hifi.colors.blueHighlight
property string highlightColor: hifi.colors.blueHighlight;
width: label.width + 64
height: 32
color: hifi.colors.white
enabled: false
HifiConstants { id: hifi }
RalewaySemiBold {
id: label;
color: enabledColor
color: enabled ? enabledColor : disabledColor
font.pixelSize: 15;
anchors {
horizontalCenter: parent.horizontalCenter;
verticalCenter: parent.verticalCenter;
}
}
Rectangle {
id: indicator

View file

@ -8,6 +8,7 @@ import "../styles" as HifiStyles
import "../styles-uit"
import "../"
import "."
Item {
id: web
HifiConstants { id: hifi }
@ -22,17 +23,14 @@ Item {
property bool keyboardRaised: false
property bool punctuationMode: false
property bool isDesktop: false
property string initialPage: ""
property bool startingUp: true
property alias webView: webview
property alias profile: webview.profile
property bool remove: false
property var urlList: []
property var forwardList: []
property int currentPage: -1 // used as a model for repeater
property alias pagesModel: pagesModel
// Manage own browse history because WebEngineView history is wiped when a new URL is loaded via
// onNewViewRequested, e.g., as happens when a social media share button is clicked.
property var history: []
property int historyIndex: -1
Rectangle {
id: buttons
@ -51,21 +49,22 @@ Item {
TabletWebButton {
id: back
enabledColor: hifi.colors.baseGray
enabled: false
enabledColor: hifi.colors.darkGray
disabledColor: hifi.colors.lightGrayText
enabled: historyIndex > 0
text: "BACK"
MouseArea {
anchors.fill: parent
onClicked: goBack()
hoverEnabled: true
}
}
TabletWebButton {
id: close
enabledColor: hifi.colors.darkGray
disabledColor: hifi.colors.lightGrayText
enabled: true
text: "CLOSE"
MouseArea {
@ -75,7 +74,6 @@ Item {
}
}
RalewaySemiBold {
id: displayUrl
color: hifi.colors.baseGray
@ -90,7 +88,6 @@ Item {
}
}
MouseArea {
anchors.fill: parent
preventStealing: true
@ -98,29 +95,10 @@ Item {
}
}
ListModel {
id: pagesModel
onCountChanged: {
currentPage = count - 1;
if (currentPage > 0) {
back.enabledColor = hifi.colors.darkGray;
} else {
back.enabledColor = hifi.colors.baseGray;
}
}
}
function goBack() {
if (webview.canGoBack) {
forwardList.push(webview.url);
webview.goBack();
} else if (web.urlList.length > 0) {
var url = web.urlList.pop();
loadUrl(url);
} else if (web.forwardList.length > 0) {
var url = web.forwardList.pop();
loadUrl(url);
web.forwardList = [];
if (historyIndex > 0) {
historyIndex--;
loadUrl(history[historyIndex]);
}
}
@ -137,19 +115,12 @@ Item {
}
function goForward() {
if (currentPage < pagesModel.count - 1) {
currentPage++;
if (historyIndex < history.length - 1) {
historyIndex++;
loadUrl(history[historyIndex]);
}
}
function gotoPage(url) {
urlAppend(url)
}
function isUrlLoaded(url) {
return (pagesModel.get(currentPage).webUrl === url);
}
function reloadPage() {
view.reloadAndBypassCache()
view.setActiveFocusOnPress(true);
@ -161,36 +132,8 @@ Item {
web.url = webview.url;
}
function onInitialPage(url) {
return (url === webview.url);
}
function urlAppend(url) {
var lurl = decodeURIComponent(url)
if (lurl[lurl.length - 1] !== "/") {
lurl = lurl + "/"
}
web.urlList.push(url);
setBackButtonStatus();
}
function setBackButtonStatus() {
if (web.urlList.length > 0 || webview.canGoBack) {
back.enabledColor = hifi.colors.darkGray;
back.enabled = true;
} else {
back.enabledColor = hifi.colors.baseGray;
back.enabled = false;
}
}
onUrlChanged: {
loadUrl(url);
if (startingUp) {
web.initialPage = webview.url;
startingUp = false;
}
}
QtObject {
@ -258,6 +201,17 @@ Item {
grantFeaturePermission(securityOrigin, feature, true);
}
onUrlChanged: {
// Record history, skipping null and duplicate items.
var urlString = url + "";
urlString = urlString.replace(/\//g, "%2F"); // Consistent representation of "/"s to avoid false differences.
if (urlString.length > 0 && (historyIndex === -1 || urlString !== history[historyIndex])) {
historyIndex++;
history = history.slice(0, historyIndex);
history.push(urlString);
}
}
onLoadingChanged: {
keyboardRaised = false;
punctuationMode = false;
@ -277,17 +231,11 @@ Item {
}
if (WebEngineView.LoadSucceededStatus == loadRequest.status) {
if (startingUp) {
web.initialPage = webview.url;
startingUp = false;
}
webview.forceActiveFocus();
}
}
onNewViewRequested: {
var currentUrl = webview.url;
urlAppend(currentUrl);
request.openIn(webview);
}
}

View file

@ -149,6 +149,10 @@ void GLBackend::resetUniformStage() {
void GLBackend::do_setUniformBuffer(const Batch& batch, size_t paramOffset) {
GLuint slot = batch._params[paramOffset + 3]._uint;
if (slot >(GLuint)MAX_NUM_UNIFORM_BUFFERS) {
qCDebug(gpugllogging) << "GLBackend::do_setUniformBuffer: Trying to set a uniform Buffer at slot #" << slot << " which doesn't exist. MaxNumUniformBuffers = " << getMaxNumUniformBuffers();
return;
}
BufferPointer uniformBuffer = batch._buffers.get(batch._params[paramOffset + 2]._uint);
GLintptr rangeStart = batch._params[paramOffset + 1]._uint;
GLsizeiptr rangeSize = batch._params[paramOffset + 0]._uint;
@ -203,7 +207,7 @@ void GLBackend::resetResourceStage() {
void GLBackend::do_setResourceBuffer(const Batch& batch, size_t paramOffset) {
GLuint slot = batch._params[paramOffset + 1]._uint;
if (slot >= (GLuint)MAX_NUM_RESOURCE_BUFFERS) {
// "GLBackend::do_setResourceBuffer: Trying to set a resource Buffer at slot #" + slot + " which doesn't exist. MaxNumResourceBuffers = " + getMaxNumResourceBuffers());
qCDebug(gpugllogging) << "GLBackend::do_setResourceBuffer: Trying to set a resource Buffer at slot #" << slot << " which doesn't exist. MaxNumResourceBuffers = " << getMaxNumResourceBuffers();
return;
}
@ -233,7 +237,7 @@ void GLBackend::do_setResourceBuffer(const Batch& batch, size_t paramOffset) {
void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) {
GLuint slot = batch._params[paramOffset + 1]._uint;
if (slot >= (GLuint) MAX_NUM_RESOURCE_TEXTURES) {
// "GLBackend::do_setResourceTexture: Trying to set a resource Texture at slot #" + slot + " which doesn't exist. MaxNumResourceTextures = " + getMaxNumResourceTextures());
qCDebug(gpugllogging) << "GLBackend::do_setResourceTexture: Trying to set a resource Texture at slot #" << slot << " which doesn't exist. MaxNumResourceTextures = " << getMaxNumResourceTextures();
return;
}

View file

@ -573,7 +573,7 @@ bool Model::addToScene(const render::ScenePointer& scene,
bool somethingAdded = false;
if (_collisionGeometry) {
if (_collisionRenderItems.empty()) {
if (_collisionRenderItemsMap.empty()) {
foreach (auto renderItem, _collisionRenderItems) {
auto item = scene->allocateID();
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
@ -583,7 +583,7 @@ bool Model::addToScene(const render::ScenePointer& scene,
transaction.resetItem(item, renderPayload);
_collisionRenderItemsMap.insert(item, renderPayload);
}
somethingAdded = !_collisionRenderItems.empty();
somethingAdded = !_collisionRenderItemsMap.empty();
}
} else {
if (_modelMeshRenderItemsMap.empty()) {
@ -632,7 +632,7 @@ void Model::removeFromScene(const render::ScenePointer& scene, render::Transacti
transaction.removeItem(item);
}
_collisionRenderItems.clear();
_collisionRenderItems.clear();
_collisionRenderItemsMap.clear();
_addedToScene = false;
_renderInfoVertexCount = 0;

View file

@ -0,0 +1,179 @@
//
// Interaction.js
// scripts/interaction
//
// Created by Trevor Berninger on 3/20/17.
// Copyright 2017 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
//
(function(){
print("loading interaction script");
var Avatar = false;
var NPC = false;
var previousNPC = false;
var hasCenteredOnNPC = false;
var distance = 10;
var r = 8;
var player = false;
var baselineX = 0;
var baselineY = 0;
var nodRange = 20;
var shakeRange = 20;
var ticker = false;
var heartbeatTimer = false;
function callOnNPC(message) {
if(NPC)
Messages.sendMessage("interactionComs", NPC + ":" + message);
else
Messages.sendMessage("interactionComs", previousNPC + ":" + message);
}
LimitlessSpeechRecognition.onFinishedSpeaking.connect(function(speech) {
print("Got: " + speech);
callOnNPC("voiceData:" + speech);
});
LimitlessSpeechRecognition.onReceivedTranscription.connect(function(speech) {
callOnNPC("speaking");
});
function setBaselineRotations(rot) {
baselineX = rot.x;
baselineY = rot.y;
}
function findLookedAtNPC() {
var intersection = AvatarList.findRayIntersection({origin: MyAvatar.position, direction: Quat.getFront(Camera.getOrientation())}, true);
if (intersection.intersects && intersection.distance <= distance){
var npcAvatar = AvatarList.getAvatar(intersection.avatarID);
if (npcAvatar.displayName.search("NPC") != -1) {
setBaselineRotations(Quat.safeEulerAngles(Camera.getOrientation()));
return intersection.avatarID;
}
}
return false;
}
function isStillFocusedNPC() {
var avatar = AvatarList.getAvatar(NPC);
if (avatar) {
var avatarPosition = avatar.position;
return Vec3.distance(MyAvatar.position, avatarPosition) <= distance && Math.abs(Quat.dot(Camera.getOrientation(), Quat.lookAtSimple(MyAvatar.position, avatarPosition))) > 0.6;
}
return false; // NPC reference died. Maybe it crashed or we teleported to a new world?
}
function onWeLostFocus() {
print("lost NPC: " + NPC);
callOnNPC("onLostFocused");
var baselineX = 0;
var baselineY = 0;
}
function onWeGainedFocus() {
print("found NPC: " + NPC);
callOnNPC("onFocused");
var rotation = Quat.safeEulerAngles(Camera.getOrientation());
baselineX = rotation.x;
baselineY = rotation.y;
LimitlessSpeechRecognition.setListeningToVoice(true);
}
function checkFocus() {
var newNPC = findLookedAtNPC();
if (NPC && newNPC != NPC && !isStillFocusedNPC()) {
onWeLostFocus();
previousNPC = NPC;
NPC = false;
}
if (!NPC && newNPC != false) {
NPC = newNPC;
onWeGainedFocus();
}
}
function checkGesture() {
var rotation = Quat.safeEulerAngles(Camera.getOrientation());
var deltaX = Math.abs(rotation.x - baselineX);
if (deltaX > 180) {
deltaX -= 180;
}
var deltaY = Math.abs(rotation.y - baselineY);
if (deltaY > 180) {
deltaY -= 180;
}
if (deltaX >= nodRange && deltaY <= shakeRange) {
callOnNPC("onNodReceived");
} else if (deltaY >= shakeRange && deltaX <= nodRange) {
callOnNPC("onShakeReceived");
}
}
function tick() {
checkFocus();
if (NPC) {
checkGesture();
}
}
function heartbeat() {
callOnNPC("beat");
}
Messages.subscribe("interactionComs");
Messages.messageReceived.connect(function (channel, message, sender) {
if(channel === "interactionComs" && player) {
var codeIndex = message.search('clientexec');
if(codeIndex != -1) {
var code = message.substr(codeIndex+11);
Script.evaluate(code, '');
}
}
});
this.enterEntity = function(id) {
player = true;
print("Something entered me: " + id);
LimitlessSpeechRecognition.setAuthKey("testKey");
if (!ticker) {
ticker = Script.setInterval(tick, 333);
}
if(!heartbeatTimer) {
heartbeatTimer = Script.setInterval(heartbeat, 1000);
}
};
this.leaveEntity = function(id) {
LimitlessSpeechRecognition.setListeningToVoice(false);
player = false;
print("Something left me: " + id);
if (previousNPC)
Messages.sendMessage("interactionComs", previousNPC + ":leftArea");
if (ticker) {
ticker.stop();
ticker = false;
}
if (heartbeatTimer) {
heartbeatTimer.stop();
heartbeatTimer = false;
}
};
this.unload = function() {
print("Okay. I'm Unloading!");
if (ticker) {
ticker.stop();
ticker = false;
}
};
print("finished loading interaction script");
});

View file

@ -0,0 +1,179 @@
//
// NPCHelpers.js
// scripts/interaction
//
// Created by Trevor Berninger on 3/20/17.
// Copyright 2017 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
//
var audioInjector = false;
var blocked = false;
var playingResponseAnim = false;
var storyURL = "";
var _qid = "start";
print("TESTTEST");
function strContains(str, sub) {
return str.search(sub) != -1;
}
function callbackOnCondition(conditionFunc, ms, callback, count) {
var thisCount = 0;
if (typeof count !== 'undefined') {
thisCount = count;
}
if (conditionFunc()) {
callback();
} else if (thisCount < 10) {
Script.setTimeout(function() {
callbackOnCondition(conditionFunc, ms, callback, thisCount + 1);
}, ms);
} else {
print("callbackOnCondition timeout");
}
}
function playAnim(animURL, looping, onFinished) {
print("got anim: " + animURL);
print("looping: " + looping);
// Start caching the animation if not already cached.
AnimationCache.getAnimation(animURL);
// Tell the avatar to animate so that we can tell if the animation is ready without crashing
Avatar.startAnimation(animURL, 30, 1, false, false, 0, 1);
// Continually check if the animation is ready
callbackOnCondition(function(){
var details = Avatar.getAnimationDetails();
// if we are running the request animation and are past the first frame, the anim is loaded properly
print("running: " + details.running);
print("url and animURL: " + details.url.trim().replace(/ /g, "%20") + " | " + animURL.trim().replace(/ /g, "%20"));
print("currentFrame: " + details.currentFrame);
return details.running && details.url.trim().replace(/ /g, "%20") == animURL.trim().replace(/ /g, "%20") && details.currentFrame > 0;
}, 250, function(){
var timeOfAnim = ((AnimationCache.getAnimation(animURL).frames.length / 30) * 1000) + 100; // frames to miliseconds plus a small buffer
print("animation loaded. length: " + timeOfAnim);
// Start the animation again but this time with frame information
Avatar.startAnimation(animURL, 30, 1, looping, true, 0, AnimationCache.getAnimation(animURL).frames.length);
if (typeof onFinished !== 'undefined') {
print("onFinished defined. setting the timeout with timeOfAnim");
timers.push(Script.setTimeout(onFinished, timeOfAnim));
}
});
}
function playSound(soundURL, onFinished) {
callbackOnCondition(function() {
return SoundCache.getSound(soundURL).downloaded;
}, 250, function() {
if (audioInjector) {
audioInjector.stop();
}
audioInjector = Audio.playSound(SoundCache.getSound(soundURL), {position: Avatar.position, volume: 1.0});
if (typeof onFinished !== 'undefined') {
audioInjector.finished.connect(onFinished);
}
});
}
function npcRespond(soundURL, animURL, onFinished) {
if (typeof soundURL !== 'undefined' && soundURL != '') {
print("npcRespond got soundURL!");
playSound(soundURL, function(){
print("sound finished");
var animDetails = Avatar.getAnimationDetails();
print("animDetails.lastFrame: " + animDetails.lastFrame);
print("animDetails.currentFrame: " + animDetails.currentFrame);
if (animDetails.lastFrame < animDetails.currentFrame + 1 || !playingResponseAnim) {
onFinished();
}
audioInjector = false;
});
}
if (typeof animURL !== 'undefined' && animURL != '') {
print("npcRespond got animURL!");
playingResponseAnim = true;
playAnim(animURL, false, function() {
print("anim finished");
playingResponseAnim = false;
print("injector: " + audioInjector);
if (!audioInjector || !audioInjector.isPlaying()) {
print("resetting Timer");
print("about to call onFinished");
onFinished();
}
});
}
}
function npcRespondBlocking(soundURL, animURL, onFinished) {
print("blocking response requested");
if (!blocked) {
print("not already blocked");
blocked = true;
npcRespond(soundURL, animURL, function(){
if (onFinished){
onFinished();
}blocked = false;
});
}
}
function npcContinueStory(soundURL, animURL, nextID, onFinished) {
if (!nextID) {
nextID = _qid;
}
npcRespondBlocking(soundURL, animURL, function(){
if (onFinished){
onFinished();
}setQid(nextID);
});
}
function setQid(newQid) {
print("setting quid");
print("_qid: " + _qid);
_qid = newQid;
print("_qid: " + _qid);
doActionFromServer("init");
}
function runOnClient(code) {
Messages.sendMessage("interactionComs", "clientexec:" + code);
}
function doActionFromServer(action, data, useServerCache) {
if (action == "start") {
ignoreCount = 0;
_qid = "start";
}
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://gserv_devel.studiolimitless.com/story", true);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if (xhr.status == 200) {
print("200!");
print("evaluating: " + xhr.responseText);
Script.evaluate(xhr.responseText, "");
} else if (xhr.status == 444) {
print("Limitless Serv 444: API error: " + xhr.responseText);
} else {
print("HTTP Code: " + xhr.status + ": " + xhr.responseText);
}
}
};
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var postData = "url=" + storyURL + "&action=" + action + "&qid=" + _qid;
if (typeof data !== 'undefined' && data != '') {
postData += "&data=" + data;
}
if (typeof useServerCache !== 'undefined' && !useServerCache) {
postData += "&nocache=true";
}
print("Sending: " + postData);
xhr.send(postData);
}

View file

@ -0,0 +1,102 @@
//
// NPC_AC.js
// scripts/interaction
//
// Created by Trevor Berninger on 3/20/17.
// Copyright 2017 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
//
var currentlyUsedIndices = [];
var timers = [];
var currentlyEngaged = false;
var questionNumber = 0;
var heartbeatTimeout = false;
function getRandomRiddle() {
var randIndex = null;
do {
randIndex = Math.floor(Math.random() * 15) + 1;
} while (randIndex in currentlyUsedIndices);
currentlyUsedIndices.push(randIndex);
return randIndex.toString();
}
Script.include("https://raw.githubusercontent.com/Delamare2112/hifi/Interaction/unpublishedScripts/interaction/NPCHelpers.js", function(){
print("NPCHelpers included.");main();
});
var idleAnim = "https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/idle.fbx";
var FST = "https://s3.amazonaws.com/hifi-public/tony/fixed-sphinx/sphinx.fst";
Agent.isAvatar = true;
Avatar.skeletonModelURL = FST;
Avatar.displayName = "NPC";
Avatar.position = {x: 0.3, y: -23.4, z: 8.0};
Avatar.orientation = {x: 0, y: 1, z: 0, w: 0};
// Avatar.position = {x: 1340.3555, y: 4.078, z: -420.1562};
// Avatar.orientation = {x: 0, y: -0.707, z: 0, w: 0.707};
Avatar.scale = 2;
Messages.subscribe("interactionComs");
function endInteraction() {
print("ending interaction");
blocked = false;
currentlyEngaged = false;
if(audioInjector)
audioInjector.stop();
for (var t in timers) {
Script.clearTimeout(timers[t]);
}
if(_qid != "Restarting") {
npcRespondBlocking(
'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/EarlyExit_0' + (Math.floor(Math.random() * 2) + 1).toString() + '.wav',
'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/reversedSphinx.fbx',
function(){
Avatar.startAnimation('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Hifi_Sphinx_Anim_Entrance_Kneel_Combined_with_Intro.fbx', 0);
}
);
}
}
function main() {
storyURL = "https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Sphinx.json";
Messages.messageReceived.connect(function (channel, message, sender) {
if(!strContains(message, 'beat'))
print(sender + " -> NPC @" + Agent.sessionUUID + ": " + message);
if (channel === "interactionComs" && strContains(message, Agent.sessionUUID)) {
if (strContains(message, 'beat')) {
if(heartbeatTimeout) {
Script.clearTimeout(heartbeatTimeout);
heartbeatTimeout = false;
}
heartbeatTimeout = Script.setTimeout(endInteraction, 1500);
}
else if (strContains(message, "onFocused") && !currentlyEngaged) {
blocked = false;
currentlyEngaged = true;
currentlyUsedIndices = [];
doActionFromServer("start");
} else if (strContains(message, "leftArea")) {
} else if (strContains(message, "speaking")) {
} else {
var voiceDataIndex = message.search("voiceData");
if (voiceDataIndex != -1) {
var words = message.substr(voiceDataIndex+10);
if (!isNaN(_qid) && (strContains(words, "repeat") || (strContains(words, "say") && strContains(words, "again")))) {
doActionFromServer("init");
} else {
doActionFromServer("words", words);
}
}
}
}
});
// Script.update.connect(updateGem);
Avatar.startAnimation("https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Hifi_Sphinx_Anim_Entrance_Kneel_Combined_with_Intro.fbx", 0);
}

View file

@ -0,0 +1,159 @@
{
"Name": "10 Questions",
"Defaults":
{
"Actions":
{
"positive": "var x=function(){if(questionNumber>=2){setQid('Finished');return;}var suffix=['A', 'B'][questionNumber++] + '_0' + (Math.floor(Math.random() * 2) + 2).toString() + '.wav';npcContinueStory('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/RightAnswer'+suffix, 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/RightAnswerB_02.fbx', getRandomRiddle());};x();",
"unknown": "var suffix=(Math.floor(Math.random() * 3) + 1).toString();npcContinueStory('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/WrongAnswer_0' + suffix + '.wav','https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/WrongAnswer_0' + suffix + '.fbx', getRandomRiddle());",
"hint": "var suffix=(Math.floor(Math.random() * 2) + 1).toString();npcContinueStory('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Hint_0' + suffix + '.wav','https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Hint_0' + suffix + '.fbx')"
},
"Responses":
{
"positive": ["yes","yup","yeah","yahoo","sure","affirmative","okay","aye","right","exactly","course","naturally","unquestionably","positively","yep","definitely","certainly","fine","absolutely","positive","love","fantastic"],
"thinking": ["oh", "think about", "i know", "what was", "well", "not sure", "one before", "hold", "one moment", "one second", "1 second", "1 sec", "one sec"],
"hint": ["hint", "heads"]
}
},
"Story":
[
{
"QID": "start",
"init": "questionNumber=0;npcContinueStory('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/HiFi_Sphinx_Anim_Combined_Entrance_Audio.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Hifi_Sphinx_Anim_Entrance_Kneel_Combined_with_Intro.fbx', getRandomRiddle());"
},
{
"QID": "1",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Blackboard.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Blackboard.fbx');",
"responses":
{
"positive": ["blackboard", "chalkboard", "chalk board", "slate"]
}
},
{
"QID": "2",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Breath.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Breath.fbx');",
"responses":
{
"positive": ["breath", "death"]
}
},
{
"QID": "3",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Clock.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Clock.fbx');",
"responses":
{
"positive": ["clock", "cock"]
}
},
{
"QID": "4",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Coffin.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Coffin.fbx');",
"responses":
{
"positive": ["coffin", "casket", "possum"]
}
},
{
"QID": "5",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Coin.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Coin.fbx');",
"responses":
{
"positive": ["coin", "boing", "coinage", "coin piece", "change", "join"]
}
},
{
"QID": "6",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Corn.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Corn.fbx');",
"responses":
{
"positive": ["corn", "born", "maize", "maze", "means", "torn", "horn", "worn", "porn"]
}
},
{
"QID": "7",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Darkness.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Darkness.fbx');",
"responses":
{
"positive": ["darkness", "dark", "blackness"]
}
},
{
"QID": "8",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Gloves.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Gloves.fbx');",
"responses":
{
"positive": ["gloves", "love"]
}
},
{
"QID": "9",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Gold.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Gold.fbx');",
"responses":
{
"positive": ["gold", "old", "bold", "cold", "told"]
}
},
{
"QID": "10",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_River.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_River.fbx');",
"responses":
{
"positive": ["river", "bigger", "stream", "creek", "brook"]
}
},
{
"QID": "11",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Secret.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Secret.fbx');",
"responses":
{
"positive": ["secret"]
}
},
{
"QID": "12",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Shadow.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Shadow.fbx');",
"responses":
{
"positive": ["shadow"]
}
},
{
"QID": "13",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Silence.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Silence.fbx');",
"responses":
{
"positive": ["silence", "lance", "quiet"]
}
},
{
"QID": "14",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Stairs.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Stairs.fbx');",
"responses":
{
"positive": ["stairs", "steps", "stair", "stairwell", "there's", "stairway"]
}
},
{
"QID": "15",
"init": "npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/Riddle_Umbrella.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Riddle_Umbrella.fbx');",
"responses":
{
"positive": ["umbrella"]
}
},
{
"QID": "Finished",
"init": "Script.clearTimeout(heartbeatTimeout);heartbeatTimeout = false;npcRespondBlocking('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/ScratchDialogue/ConclusionRight_02.wav', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/ConclusionRight_02.fbx', function(){runOnClient('MyAvatar.goToLocation({x: 5, y: -29, z: -63}, true, true);');setQid('Restarting');});",
"positive": "",
"negative": "",
"unknown": ""
},
{
"QID": "Restarting",
"init": "npcRespondBlocking('', 'https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/reversedSphinx.fbx', function(){Avatar.startAnimation('https://storage.googleapis.com/limitlessserv-144100.appspot.com/hifi%20assets/Animation/Hifi_Sphinx_Anim_Entrance_Kneel_Combined_with_Intro.fbx', 0);_qid='';});",
"positive": "",
"negative": "",
"unknown": ""
}
]
}