// // ballDrop.js // // Created by Rebecca Stankus on 12/06/2018 // Copyright High Fidelity 2018 // // Licensed under the Apache 2.0 License // See accompanying license file or http://apache.org/ // (function () { var _this; var TIME_CHECK_INTERVAL_MS = 50; var FIREWORK_INTERVAL = 500; var ONE_THOUSAND = 1000; var SECONDS_PER_MINUTE = 60; var MINUTES_PER_HOUR = 60; var TWO_DIGITS = 10; var TARGET_TIME_INDEX = 13; var BALL_START_POSITION = { x: -30.8416, y: 21.7429, z: -110.2663 }; var INTERVAL_DROP_DISTANCE_M = 0.0090; var SONGS = [ SoundCache.getSound(Script.resolvePath("assets/audio/auldBoogie.mp3")), SoundCache.getSound(Script.resolvePath("assets/audio/auldBrassy.mp3")), SoundCache.getSound(Script.resolvePath("assets/audio/auldElectro.mp3")), SoundCache.getSound(Script.resolvePath("assets/audio/auldGamey.mp3")), SoundCache.getSound(Script.resolvePath("assets/audio/auldJazzy.mp3")), SoundCache.getSound(Script.resolvePath("assets/audio/auldJimi.mp3")), SoundCache.getSound(Script.resolvePath("assets/audio/auldMarchy.mp3")) ]; var NUMBER_OF_SONGS = 7; var EXPLOSION = SoundCache.getSound(Script.resolvePath("assets/audio/explosion.mp3")); var FIREWORK = SoundCache.getSound(Script.resolvePath("assets/audio/firework.mp3")); var TICK = SoundCache.getSound(Script.resolvePath("assets/audio/tick.wav")); var TOCK = SoundCache.getSound(Script.resolvePath("assets/audio/tock.wav")); var HOURS_PER_DAY = 24; var MAX_NUMBER_OF_DROPS = 5; var PRE_COUNTDOWN_TEXT = "Countdown Starts Soon!"; var currentSongDuration; var songVersion = 0; var injector; var ballDropInterval; var currentPosition = { x: -30.8416, y: 21.7429, z: -110.2663 }; var confetti; var ball = "{6414271b-f0f4-4a62-b196-ac83dfd95253}"; var innerBall = "{42910458-c9e3-4a83-93d4-f5732b6a516e}"; var ballParticle = "{9d774699-e4f7-4de5-a264-d6ed212eec5f}"; var cityListText = "{80823bd4-5bd7-410d-8e3e-c3d019760a8f}"; var fireworks = ["{8eaf6f0a-9410-4929-9294-2956cb80c08c}", "{f8e6b4cc-20b4-4316-a2c3-4d29b25f6380}", "{d9e7b29b-16d7-4dfa-8f3d-45afbbd50eb6}", "{5f05aeb7-14cf-424e-8c4c-8c04f5719548}"]; var targetName; var targetDate; var targetTime; var targetHour; var targetDay; var targetMonth = "Dec"; var targetYear; var numberOfDrops = 0; var currentCities; var lastSecond; var tick = true; var cities = ["Seattle, San Francisco, Las Vegas", "Anchorage, Fairbanks, Unalaska", "Honolulu, Rarotonga, Papeete", "Alofi, Midway, Pago Pago", "Baker Island, Howland Island"]; var Countdown = function() { _this = this; }; Countdown.prototype = { interval: null, targetTime: null, preload: function(entityID) { Entities.editEntity(ball, { position: BALL_START_POSITION, animation: { hold: true, currentFrame: 1 } }); Entities.editEntity(innerBall, { position: BALL_START_POSITION }); Entities.editEntity(cityListText, { text: PRE_COUNTDOWN_TEXT }); _this.entityID = entityID; _this.getTargetTime(); _this.startSyncing(); Entities.getChildrenIDs(_this.entityID).forEach(function(child) { var name = Entities.getEntityProperties(child, 'name').name; if (name === "New Year's Confetti") { confetti = child; } }); Entities.editEntity(ballParticle, { isEmitting: false }); Entities.editEntity(confetti, { isEmitting: false }); }, startSyncing: function() { currentPosition = { x: -30.8416, y: 21.7429, z: -110.2663 }; _this.interval = Script.setInterval(function() { _this.synchronize(); }, TIME_CHECK_INTERVAL_MS); }, getTargetTime: function() { targetName = Entities.getEntityProperties(_this.entityID, 'name').name; targetDate = new Date(targetName.substring(TARGET_TIME_INDEX, (targetName.length))); targetTime = targetDate.getTime(); targetYear = targetDate.getFullYear(); targetDay = targetDate.getDate(); targetHour = targetDate.getHours(); }, synchronize: function() { var currentTime = new Date().getTime(); var untilTargetTime = targetTime - currentTime; var targetPassed = false; var hours = Math.floor((untilTargetTime % (ONE_THOUSAND * SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY)) / (ONE_THOUSAND * SECONDS_PER_MINUTE * MINUTES_PER_HOUR )); if (hours > 0) { Entities.editEntity(cityListText, { text: PRE_COUNTDOWN_TEXT }); Entities.editEntity(_this.entityID, { text: "--:--" }); return; } else { if (Entities.getEntityProperties(cityListText, 'text').text === PRE_COUNTDOWN_TEXT) { currentCities = 0; Entities.editEntity(cityListText, { text: cities[currentCities] }); } } var minutes = Math.floor((untilTargetTime % (ONE_THOUSAND * SECONDS_PER_MINUTE * MINUTES_PER_HOUR )) / (ONE_THOUSAND * SECONDS_PER_MINUTE)); var seconds = Math.floor((untilTargetTime % (ONE_THOUSAND * SECONDS_PER_MINUTE)) / ONE_THOUSAND); if (minutes < 1) { currentPosition.y -= INTERVAL_DROP_DISTANCE_M; Entities.editEntity(ball, { position: currentPosition }); Entities.editEntity(innerBall, { position: currentPosition }); if (seconds < 1) { targetPassed = true; } } minutes = minutes < TWO_DIGITS ? "0" + minutes : minutes; seconds = seconds < TWO_DIGITS ? "0" + seconds : seconds; if (targetPassed) { Entities.editEntity(_this.entityID, { text: "2019!" }); _this.timeUp(); } else { if (lastSecond !== seconds) { if (minutes < 1 && hours < 1) { lastSecond = seconds; if (tick) { _this.playSound(TICK, Entities.getEntityProperties( cityListText, 'position').position); tick = false; } else { _this.playSound(TOCK, Entities.getEntityProperties( cityListText, 'position').position); tick = true; } } Entities.editEntity(_this.entityID, { text: minutes + ":" + seconds }); } } }, timeUp: function() { _this.playSound("auldLang", currentPosition); _this.playSound(EXPLOSION, currentPosition); numberOfDrops++; Script.clearInterval(_this.interval); _this.interval = Script.setInterval(function() { var msToExplode = Math.random() * 1000; var currentFirework = Math.floor(Math.random() * 4); var newX = (Math.random() * 60) + (BALL_START_POSITION.x - 30); var newY = (Math.random() * 20) + (BALL_START_POSITION.y + 5); var newZ = (Math.random() * 60) + (BALL_START_POSITION.z - 30); var newPosition = { x: newX, y: newY, z: newZ }; Script.setTimeout(function() { Entities.editEntity(fireworks[currentFirework], { position: newPosition, isEmitting: true }); _this.playSound(FIREWORK, Entities.getEntityProperties( newPosition, 'position').position); Script.setTimeout(function() { Entities.editEntity(fireworks[currentFirework], { isEmitting: false }); }, ONE_THOUSAND); }, msToExplode); }, FIREWORK_INTERVAL); Entities.editEntity(ballParticle, { isEmitting: true }); Entities.editEntity(ball, { animation: { hold: false }}); currentPosition = BALL_START_POSITION; Entities.editEntity(confetti, { isEmitting: true }); Script.setTimeout(function() { Script.clearInterval(_this.interval); fireworks.forEach(function(firework) { var newX = (Math.random() * 60) + (BALL_START_POSITION.x - 30); var newY = (Math.random() * 20) + (BALL_START_POSITION.y + 5); var newZ = (Math.random() * 60) + (BALL_START_POSITION.z - 30); var newPosition = { x: newX, y: newY, z: newZ }; Entities.editEntity(firework, { position: newPosition, isEmitting: true }); _this.playSound(FIREWORK, Entities.getEntityProperties( newPosition, 'position').position); }); Entities.editEntity(ball, { position: BALL_START_POSITION, animation: { hold: true, currentFrame: 1 } }); Entities.editEntity(innerBall, { position: BALL_START_POSITION}); Entities.editEntity(confetti, { isEmitting: false }); Script.setTimeout(function() { Entities.editEntity(ballParticle, { isEmitting: false }); if (numberOfDrops === MAX_NUMBER_OF_DROPS) { Entities.editEntity(_this.entityID, { text: "2019!" }); Entities.editEntity(cityListText, { text: "HAPPY NEW YEAR EVERYONE!" }); } else { targetHour++; if (targetHour > 23) { targetHour -= 24; targetDay++; if (targetDay > 30) { targetDay-= 31; targetMonth = "Jan"; targetYear = 2019; } } targetTime = new Date(targetMonth + " " + targetDay + ", " + targetYear + " " + targetHour + ":00:00").getTime(); currentCities++; Entities.editEntity(cityListText, { text: cities[currentCities] }); _this.startSyncing(); } }, 500); }, currentSongDuration); Script.setTimeout(function() { fireworks.forEach(function (firework) { Entities.editEntity(firework, { isEmitting: false }); }); }, currentSongDuration + 1000); }, playSound: function(sound, position) { if (sound === "auldLang") { if (SONGS[songVersion].downloaded) { currentSongDuration = SONGS[songVersion].duration * 1000; injector = Audio.playSound(SONGS[songVersion], { position: Entities.getEntityProperties(ball, 'position').position, volume: 1 }); songVersion++; if (songVersion === NUMBER_OF_SONGS) { songVersion = 0; } } } else if (sound.downloaded) { injector = Audio.playSound(sound, { position: Entities.getEntityProperties(ball, 'position').position, volume: 1 }); } }, unload: function() { if (injector) { injector.stop(); } if (_this.interval) { Script.clearInterval(_this.interval); } if (ballDropInterval) { Script.clearInterval(ballDropInterval); } } }; return new Countdown; });