diff --git a/unpublishedScripts/marketplace/shortbow/displayServerEntity.js b/unpublishedScripts/marketplace/shortbow/displayServerEntity.js deleted file mode 100644 index 85de03d78b..0000000000 --- a/unpublishedScripts/marketplace/shortbow/displayServerEntity.js +++ /dev/null @@ -1,43 +0,0 @@ -// -// Created by Ryan Huffman on 1/10/2017 -// 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() { - Script.include('utils.js'); - - Display = function() { - }; - Display.prototype = { - preload: function(entityID) { - this.entityID = entityID; - - var props = Entities.getEntityProperties(this.entityID, ['userData', 'parentID']); - var data = utils.parseJSON(props.userData); - if (data !== undefined && data.displayType !== undefined) { - this.commChannel = data.displayType + "-" + props.parentID; - } else { - print("scoreboardEntity.js | ERROR: userData does not contain a game channel and/or team number"); - } - - Messages.subscribe(this.commChannel); - Messages.messageReceived.connect(this, this.onReceivedMessage); - }, - unload: function() { - Messages.unsubscribe(this.commChannel); - Messages.messageReceived.disconnect(this, this.onReceivedMessage); - }, - onReceivedMessage: function(channel, message, senderID) { - if (channel === this.commChannel) { - Entities.editEntity(this.entityID, { - text: message - }); - } - }, - }; - - return new Display(); -}); diff --git a/unpublishedScripts/marketplace/shortbow/shortbowGameManager.js b/unpublishedScripts/marketplace/shortbow/shortbowGameManager.js index 0af875815d..c6fd24a731 100644 --- a/unpublishedScripts/marketplace/shortbow/shortbowGameManager.js +++ b/unpublishedScripts/marketplace/shortbow/shortbowGameManager.js @@ -45,7 +45,7 @@ function encodeURLParams(params) { return paramPairs.join("&"); } -function sendAndUpdateHighScore(highScoreChannel, entityID, score, wave, numPlayers) { +function sendAndUpdateHighScore(entityID, score, wave, numPlayers, onResposeReceived) { const URL = 'https://script.google.com/macros/s/AKfycbwbjCm9mGd1d5BzfAHmVT_XKmWyUYRkjCEqDOKm1368oM8nqWni/exec'; print("Sending high score"); @@ -63,7 +63,7 @@ function sendAndUpdateHighScore(highScoreChannel, entityID, score, wave, numPlay print("Got response for high score: ", req.response); var response = JSON.parse(req.responseText); if (response.highScore !== undefined) { - Messages.sendMessage(highScoreChannel, response.highScore); + onResposeReceived(response.highScore); } } }; @@ -128,9 +128,46 @@ var baseEnemyProperties = { serverScripts: Script.resolvePath('enemyServerEntity.js') }; +function searchForChildren(parentID, names, callback, timeoutMs) { + // Map from name to entity ID for the children that have been found + var foundEntities = {}; + for (var i = 0; i < names.length; ++i) { + foundEntities[names[i]] = null; + } + + const CHECK_EVERY_MS = 500; + const maxChecks = Math.ceil(timeoutMs / CHECK_EVERY_MS); + + var check = 0; + var intervalID = Script.setInterval(function() { + check++; + + var childrenIDs = Entities.getChildrenIDs(parentID); + print("\tNumber of children:", childrenIDs.length); + + for (var i = 0; i < childrenIDs.length; ++i) { + print("\t\t" + i + ".", Entities.getEntityProperties(childrenIDs[i]).name); + var id = childrenIDs[i]; + var name = Entities.getEntityProperties(id, 'name').name; + var idx = names.indexOf(name); + if (idx > -1) { + foundEntities[name] = id; + print(name, id); + names.splice(idx, 1); + } + } + + if (names.length == 0 || check >= maxChecks) { + Script.clearInterval(intervalID); + callback(foundEntities); + } + }, 500); +} ShortbowGameManager = function(rootEntityID, bowPositions, spawnPositions) { print("Starting game manager"); + var self = this; + this.gameState = GAME_STATES.IDLE; this.rootEntityID = rootEntityID; @@ -138,6 +175,34 @@ ShortbowGameManager = function(rootEntityID, bowPositions, spawnPositions) { this.rootPosition = null; this.spawnPositions = spawnPositions; + this.loadedChildren = false; + + const START_BUTTON_NAME = 'SB.StartButton'; + const WAVE_DISPLAY_NAME = 'SB.DisplayWave'; + const SCORE_DISPLAY_NAME = 'SB.DisplayScore'; + const LIVES_DISPLAY_NAME = 'SB.DisplayLives'; + const HIGH_SCORE_DISPLAY_NAME = 'SB.DisplayHighScore'; + + searchForChildren(rootEntityID, [ + START_BUTTON_NAME, + WAVE_DISPLAY_NAME, + SCORE_DISPLAY_NAME, + LIVES_DISPLAY_NAME, + HIGH_SCORE_DISPLAY_NAME + ], function(children) { + print("ENTITES FOUND"); + self.loadedChildren = true; + self.startButtonID = children[START_BUTTON_NAME]; + self.waveDisplayID = children[WAVE_DISPLAY_NAME]; + self.scoreDisplayID = children[SCORE_DISPLAY_NAME]; + self.livesDisplayID = children[LIVES_DISPLAY_NAME]; + self.highScoreDisplayID = children[HIGH_SCORE_DISPLAY_NAME]; + + sendAndUpdateHighScore(self.rootEntityID, self.score, self.waveNumber, 1, self.setHighScore.bind(self)); + + self.reset(); + }, 5000); + // Gameplay state this.waveNumber = 0; this.livesLeft = 5; @@ -147,7 +212,6 @@ ShortbowGameManager = function(rootEntityID, bowPositions, spawnPositions) { this.remainingEnemies = []; this.bowIDs = []; - this.highscoreChannelName = "highscore-" + this.rootEntityID; this.startButtonChannelName = 'button-' + this.rootEntityID; // Entity client and server scripts will send messages to this channel @@ -155,13 +219,11 @@ ShortbowGameManager = function(rootEntityID, bowPositions, spawnPositions) { Messages.subscribe(this.commChannelName); Messages.messageReceived.connect(this, this.onReceivedMessage); print("Listening on: ", this.commChannelName); - - this.reset(); - sendAndUpdateHighScore(this.highscoreChannelName, this.rootEntityID, this.score, this.waveNumber, 1); + Messages.sendMessage(this.commChannelName, 'hi'); } ShortbowGameManager.prototype = { reset: function() { - Messages.sendMessage(this.startButtonChannelName, 'show'); + Entities.editEntity(this.startButtonID, { visible: true }); }, cleanup: function() { Messages.unsubscribe(this.commChannelName); @@ -189,11 +251,16 @@ ShortbowGameManager.prototype = { return; } + if (this.loadedChildren === false) { + print('shortbowGameManager.js | Children have not loaded, not allowing game to start'); + return; + } + print("Game started!!"); this.rootPosition = Entities.getEntityProperties(this.rootEntityID, 'position').position; - Messages.sendMessage(this.startButtonChannelName, 'hide'); + Entities.editEntity(this.startButtonID, { visible: false }); // Spawn bows for (var i = 0; i < this.bowPositions.length; ++i) { @@ -257,12 +324,6 @@ ShortbowGameManager.prototype = { var self = this; }, - // Set the display text of one of the numbers on the scoreboard. - // Types: highscore, score, wave, lives - setDisplayText: function(type, value) { - var channel = type + '-' + this.rootEntityID; - Messages.sendMessage(channel, value); - }, startNextWave: function() { if (this.gameState !== GAME_STATES.BETWEEN_WAVES) { return; @@ -275,7 +336,7 @@ ShortbowGameManager.prototype = { this.spawnQueue = []; this.spawnStartTime = Date.now(); - this.setDisplayText('wave', this.waveNumber); + Entities.editEntity(this.waveDisplayID, { text: this.waveNumber}); var numberOfEnemiesLeftToSpawn = this.waveNumber * 2; var delayBetweenSpawns = 2000 / Math.max(1, Math.log(this.waveNumber)); @@ -316,14 +377,18 @@ ShortbowGameManager.prototype = { }, 1500); } }, + setHighScore: function(highScore) { + print("Setting high score to:", this.highScoreDisplayID, highScore); + Entities.editEntity(this.highScoreDisplayID, { text: highScore }); + }, setLivesLeft: function(lives) { lives = Math.max(0, lives); this.livesLeft = lives; - this.setDisplayText('lives', this.livesLeft); + Entities.editEntity(this.livesDisplayID, { text: this.livesLeft }); }, setScore: function(score) { this.score = score; - this.setDisplayText('score', this.score); + Entities.editEntity(this.scoreDisplayID, { text: this.score }); }, checkEnemies: function() { if (this.gameState !== GAME_STATES.PLAYING) { @@ -399,7 +464,7 @@ ShortbowGameManager.prototype = { print("GAME OVER"); // Update high score - sendAndUpdateHighScore(this.highscoreChannelName, this.rootEntityID, this.score, this.waveNumber, 1); + sendAndUpdateHighScore(this.rootEntityID, this.score, this.waveNumber, 1, this.setHighScore.bind(this)); // Cleanup Script.clearTimeout(this.nextWaveTimer); @@ -426,7 +491,7 @@ ShortbowGameManager.prototype = { } Script.setTimeout(function() { - Messages.sendMessage(this.startButtonChannelName, 'show'); + Entities.editEntity(this.startButtonID, { visible: true }); this.gameState = GAME_STATES.IDLE; }.bind(this), 3000); @@ -436,7 +501,7 @@ ShortbowGameManager.prototype = { this.remainingEnemies = []; }, onReceivedMessage: function(channel, messageJSON, senderID) { - print("shortbowGameManager.js | Recieved: " + messageJSON + " from " + senderID, channel, this.commChannelName); + //print("shortbowGameManager.js | Recieved: " + messageJSON + " from " + senderID, channel, this.commChannelName); if (channel === this.commChannelName) { var message = utils.parseJSON(messageJSON); diff --git a/unpublishedScripts/marketplace/shortbow/shortbowServerEntity.js b/unpublishedScripts/marketplace/shortbow/shortbowServerEntity.js index de432ac331..cdac290913 100644 --- a/unpublishedScripts/marketplace/shortbow/shortbowServerEntity.js +++ b/unpublishedScripts/marketplace/shortbow/shortbowServerEntity.js @@ -18,14 +18,7 @@ this.preload = function(entityID) { this.entityID = entityID; - var props = Entities.getEntityProperties(entityID, ['position', 'userData']); - var data = utils.parseJSON(props.userData); - if (data === undefined) { - print("Error parsing shortbow entity userData, returning"); - return; - } - - var rootPosition = props.position; + var rootPosition = Entities.getEntityProperties(entityID, 'position').position; var bowPositions = []; var spawnPositions = []; diff --git a/unpublishedScripts/marketplace/shortbow/spawnShortbow.js b/unpublishedScripts/marketplace/shortbow/spawnShortbow.js index affce379cc..978edb34e9 100644 --- a/unpublishedScripts/marketplace/shortbow/spawnShortbow.js +++ b/unpublishedScripts/marketplace/shortbow/spawnShortbow.js @@ -99,7 +99,6 @@ function createLocalGame() { buttonID = spawnTemplate("SB.StartButton", { parentID: scoreboardID, script: Script.resolvePath("startGameButtonClientEntity.js"), - serverScripts: Script.resolvePath("startGameButtonServerEntity.js"), userData: JSON.stringify({ grabbableKey: { wantsTrigger: true @@ -114,7 +113,6 @@ function createLocalGame() { userData: JSON.stringify({ displayType: "wave" }), - serverScripts: Script.resolvePath("displayServerEntity.js") }); entityIDs.push(waveDisplayID); @@ -123,7 +121,6 @@ function createLocalGame() { userData: JSON.stringify({ displayType: "score" }), - serverScripts: Script.resolvePath("displayServerEntity.js") }); entityIDs.push(scoreDisplayID); @@ -132,7 +129,6 @@ function createLocalGame() { userData: JSON.stringify({ displayType: "lives" }), - serverScripts: Script.resolvePath("displayServerEntity.js") }); entityIDs.push(livesDisplayID); @@ -141,7 +137,6 @@ function createLocalGame() { userData: JSON.stringify({ displayType: "highscore" }), - serverScripts: Script.resolvePath("displayServerEntity.js") }); entityIDs.push(highScoreDisplayID); @@ -157,14 +152,6 @@ function createLocalGame() { entityIDs.push(platformID); Entities.editEntity(scoreboardID, { - userData: JSON.stringify({ - platformID: platformID, - buttonID: buttonID, - waveDisplayID: waveDisplayID, - scoreDisplayID: scoreDisplayID, - livesDisplayID: livesDisplayID, - highScoreDisplayID: highScoreDisplayID, - }), serverScripts: Script.resolvePath('shortbowServerEntity.js') }); diff --git a/unpublishedScripts/marketplace/shortbow/startGameButtonServerEntity.js b/unpublishedScripts/marketplace/shortbow/startGameButtonServerEntity.js deleted file mode 100644 index a6f98b13d7..0000000000 --- a/unpublishedScripts/marketplace/shortbow/startGameButtonServerEntity.js +++ /dev/null @@ -1,39 +0,0 @@ -// -// Created by Ryan Huffman on 1/10/2017 -// 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() { - Script.include('utils.js'); - - Button = function() { - }; - Button.prototype = { - preload: function(entityID) { - print("Loaded enemy entity"); - this.entityID = entityID; - - var props = Entities.getEntityProperties(this.entityID, 'parentID'); - this.gameChannel = 'button-' + props.parentID; - - Messages.subscribe(this.gameChannel); - Messages.messageReceived.connect(this, this.onReceivedMessage); - }, - unload: function() { - Messages.unsubscribe(this.gameChannel); - Messages.messageReceived.disconnect(this, this.onReceivedMessage); - }, - onReceivedMessage: function(channel, message, senderID) { - if (channel === this.gameChannel) { - Entities.editEntity(this.entityID, { - visible: message === 'show' - }); - } - }, - }; - - return new Button(); -});