Showing the changes to tutorial/tutorial.js (1 of 1 file). Show all
Unified · Split
| @@ -58,11 +58,6 @@ function info() { · 57 unmodified lines | ||
| 58 | 58 | } |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | −// Return a number between min (inclusive) and max (exclusive) | |
| 62 | −function randomInt(min, max) { | |
| 63 | − return min + Math.floor(Math.random() * (max - min)) | |
| 64 | −} | |
| 65 | − | |
| 66 | 61 | var NEAR_BOX_SPAWN_NAME = "tutorial/nearGrab/box_spawn"; |
| 67 | 62 | var FAR_BOX_SPAWN_NAME = "tutorial/farGrab/box_spawn"; |
| 68 | 63 | var GUN_SPAWN_NAME = "tutorial/gun_spawn"; |
| @@ -78,10 +73,6 @@ function setAwayEnabled(value) { · 9 unmodified lines | ||
| 78 | 73 | Messages.sendLocalMessage(CHANNEL_AWAY_ENABLE, message); |
| 79 | 74 | } |
| 80 | 75 | |
| 81 | −function beginsWithFilter(value, key) { | |
| 82 | − return value.indexOf(properties[key]) == 0; | |
| 83 | −} | |
| 84 | − | |
| 85 | 76 | findEntity = function(properties, searchRadius, filterFn) { |
| 86 | 77 | var entities = findEntities(properties, searchRadius, filterFn); |
| 87 | 78 | return entities.length > 0 ? entities[0] : null; |
| @@ -116,18 +107,29 @@ findEntities = function(properties, searchRadius, filterFn) { · 28 unmodified lines | ||
| 116 | 107 | return matchedEntities; |
| 117 | 108 | } |
| 118 | 109 | |
| 119 | −function setControllerPartsVisible(parts) { | |
| 120 | − Messages.sendLocalMessage('Controller-Display-Parts', JSON.stringify(parts)); | |
| 110 | +function findEntitiesWithTag(tag) { | |
| 111 | + return findEntities({ userData: "" }, 10000, function(properties, key, value) { | |
| 112 | + data = parseJSON(value); | |
| 113 | + return data.tag === tag; | |
| 114 | + }); | |
| 121 | 115 | } |
| 122 | 116 | |
| 117 | +/** | |
| 118 | + * A controller in made up of parts, and each part can have multiple "layers," | |
| 119 | + * which are really just different texures. For example, the "trigger" part | |
| 120 | + * has "normal" and "highlight" layers. | |
| 121 | + */ | |
| 123 | 122 | function setControllerPartLayer(part, layer) { |
| 124 | 123 | data = {}; |
| 125 | 124 | data[part] = layer; |
| 126 | 125 | Messages.sendLocalMessage('Controller-Set-Part-Layer', JSON.stringify(data)); |
| 127 | 126 | } |
| 128 | 127 | |
| 129 | −function spawn(entityData, transform, modifyFn) { | |
| 130 | − debug("Creating: ", entityData); | |
| 128 | +/** | |
| 129 | + * @param {object[]} entityPropertiesList A list of properties to | |
| 130 | + */ | |
| 131 | +function spawn(entityPropertiesList, transform, modifyFn) { | |
| 132 | + debug("Creating: ", entityPropertiesList); | |
| 131 | 133 | if (!transform) { |
| 132 | 134 | transform = { |
| 133 | 135 | position: { x: 0, y: 0, z: 0 }, |
| @@ -135,8 +137,8 @@ function spawn(entityData, transform, modifyFn) { · 1 unmodified line | ||
| 135 | 137 | } |
| 136 | 138 | } |
| 137 | 139 | var ids = []; |
| 138 | − for (var i = 0; i < entityData.length; ++i) { | |
| 139 | − var data = entityData[i]; | |
| 140 | + for (var i = 0; i < entityPropertiesList.length; ++i) { | |
| 141 | + var data = entityPropertiesList[i]; | |
| 140 | 142 | debug("Creating: ", data.name); |
| 141 | 143 | data.position = Vec3.sum(transform.position, data.position); |
| 142 | 144 | data.rotation = Quat.multiply(data.rotation, transform.rotation); |
| @@ -150,6 +152,12 @@ function spawn(entityData, transform, modifyFn) { · 7 unmodified lines | ||
| 150 | 152 | return ids; |
| 151 | 153 | } |
| 152 | 154 | |
| 155 | +/** | |
| 156 | + * @function parseJSON | |
| 157 | + * @param {string} jsonString The string to parse. | |
| 158 | + * @return {object} Return an empty if the string was not valid JSON, otherwise | |
| 159 | + * the parsed object is returned. | |
| 160 | + */ | |
| 153 | 161 | function parseJSON(jsonString) { |
| 154 | 162 | var data; |
| 155 | 163 | try { |
| @@ -160,6 +168,10 @@ function parseJSON(jsonString) { · 4 unmodified lines | ||
| 160 | 168 | return data; |
| 161 | 169 | } |
| 162 | 170 | |
| 171 | +/** | |
| 172 | + * Spawn entities with `tag` in the userData. | |
| 173 | + * @function spawnWithTag | |
| 174 | + */ | |
| 163 | 175 | function spawnWithTag(entityData, transform, tag) { |
| 164 | 176 | function modifyFn(data) { |
| 165 | 177 | var userData = parseJSON(data.userData); |
| @@ -171,6 +183,10 @@ function spawnWithTag(entityData, transform, tag) { · 5 unmodified lines | ||
| 171 | 183 | return spawn(entityData, transform, modifyFn); |
| 172 | 184 | } |
| 173 | 185 | |
| 186 | +/** | |
| 187 | + * Delete all entities with the tag `tag` in their userData. | |
| 188 | + * @function deleteEntitiesWithTag | |
| 189 | + */ | |
| 174 | 190 | function deleteEntitiesWithTag(tag) { |
| 175 | 191 | debug("searching for...:", tag); |
| 176 | 192 | var entityIDs = findEntitiesWithTag(tag); |
| @@ -178,6 +194,7 @@ function deleteEntitiesWithTag(tag) { · 1 unmodified line | ||
| 178 | 194 | Entities.deleteEntity(entityIDs[i]); |
| 179 | 195 | } |
| 180 | 196 | } |
| 197 | + | |
| 181 | 198 | function editEntitiesWithTag(tag, propertiesOrFn) { |
| 182 | 199 | var entities = TUTORIAL_TAG_TO_ENTITY_IDS_MAP[tag]; |
| 183 | 200 | |
| @@ -194,19 +211,117 @@ function editEntitiesWithTag(tag, propertiesOrFn) { · 10 unmodified lines | ||
| 194 | 211 | } |
| 195 | 212 | } |
| 196 | 213 | |
| 197 | −function findEntitiesWithTag(tag) { | |
| 198 | − return findEntities({ userData: "" }, 10000, function(properties, key, value) { | |
| 199 | − data = parseJSON(value); | |
| 200 | − return data.tag == tag; | |
| 201 | − }); | |
| 202 | −} | |
| 203 | − | |
| 204 | 214 | // From http://stackoverflow.com/questions/5999998/how-can-i-check-if-a-javascript-variable-is-function-type |
| 205 | 215 | function isFunction(functionToCheck) { |
| 206 | 216 | var getType = {}; |
| 207 | 217 | return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; |
| 208 | 218 | } |
| 209 | 219 | |
| 220 | +/** | |
| 221 | + * Return `true` if `entityID` can be found in the local entity tree, otherwise `false`. | |
| 222 | + */ | |
| 223 | +function isEntityInLocalTree(entityID) { | |
| 224 | + return Entities.getEntityProperties(entityID, 'visible').visible !== undefined; | |
| 225 | +} | |
| 226 | + | |
| 227 | +/** | |
| 228 | + * | |
| 229 | + */ | |
| 230 | +function showEntitiesWithTag(tag) { | |
| 231 | + var entities = TUTORIAL_TAG_TO_ENTITY_IDS_MAP[tag]; | |
| 232 | + if (entities) { | |
| 233 | + for (entityID in entities) { | |
| 234 | + var data = entities[entityID]; | |
| 235 | + | |
| 236 | + var collisionless = data.visible === false ? true : false; | |
| 237 | + if (data.collidable !== undefined) { | |
| 238 | + collisionless = data.collidable === true ? false : true; | |
| 239 | + } | |
| 240 | + if (data.soundKey) { | |
| 241 | + data.soundKey.playing = true; | |
| 242 | + } | |
| 243 | + var newProperties = { | |
| 244 | + visible: data.visible == false ? false : true, | |
| 245 | + collisionless: collisionless, | |
| 246 | + userData: JSON.stringify(data), | |
| 247 | + }; | |
| 248 | + debug("Showing: ", entityID, ", Is in local tree: ", isEntityInLocalTree(entityID)); | |
| 249 | + Entities.editEntity(entityID, newProperties); | |
| 250 | + } | |
| 251 | + } | |
| 252 | + | |
| 253 | + // Dynamic method, suppressed for now | |
| 254 | + return; | |
| 255 | + editEntitiesWithTag(tag, function(entityID) { | |
| 256 | + var userData = Entities.getEntityProperties(entityID, "userData").userData; | |
| 257 | + var data = parseJSON(userData); | |
| 258 | + var collisionless = data.visible === false ? true : false; | |
| 259 | + if (data.collidable !== undefined) { | |
| 260 | + collisionless = data.collidable === true ? false : true; | |
| 261 | + } | |
| 262 | + if (data.soundKey) { | |
| 263 | + data.soundKey.playing = true; | |
| 264 | + } | |
| 265 | + var newProperties = { | |
| 266 | + visible: data.visible == false ? false : true, | |
| 267 | + collisionless: collisionless, | |
| 268 | + userData: JSON.stringify(data), | |
| 269 | + }; | |
| 270 | + Entities.editEntity(entityID, newProperties); | |
| 271 | + }); | |
| 272 | +} | |
| 273 | + | |
| 274 | +/** | |
| 275 | + * @function hideEntitiesWithTag | |
| 276 | + */ | |
| 277 | +function hideEntitiesWithTag(tag) { | |
| 278 | + var entities = TUTORIAL_TAG_TO_ENTITY_IDS_MAP[tag]; | |
| 279 | + if (entities) { | |
| 280 | + for (entityID in entities) { | |
| 281 | + var data = entities[entityID]; | |
| 282 | + | |
| 283 | + if (data.soundKey) { | |
| 284 | + data.soundKey.playing = false; | |
| 285 | + } | |
| 286 | + var newProperties = { | |
| 287 | + visible: false, | |
| 288 | + collisionless: 1, | |
| 289 | + ignoreForCollisions: 1, | |
| 290 | + userData: JSON.stringify(data), | |
| 291 | + }; | |
| 292 | + | |
| 293 | + debug("Hiding: ", entityID, ", Is in local tree: ", isEntityInLocalTree(entityID)); | |
| 294 | + Entities.editEntity(entityID, newProperties); | |
| 295 | + } | |
| 296 | + } | |
| 297 | + | |
| 298 | + // Dynamic method, suppressed for now | |
| 299 | + return; | |
| 300 | + editEntitiesWithTag(tag, function(entityID) { | |
| 301 | + var userData = Entities.getEntityProperties(entityID, "userData").userData; | |
| 302 | + var data = parseJSON(userData); | |
| 303 | + if (data.soundKey) { | |
| 304 | + data.soundKey.playing = false; | |
| 305 | + } | |
| 306 | + var newProperties = { | |
| 307 | + visible: false, | |
| 308 | + collisionless: 1, | |
| 309 | + ignoreForCollisions: 1, | |
| 310 | + userData: JSON.stringify(data), | |
| 311 | + }; | |
| 312 | + Entities.editEntity(entityID, newProperties); | |
| 313 | + }); | |
| 314 | +} | |
| 315 | + | |
| 316 | +// Return the entity properties for an entity with a given name if it is in our | |
| 317 | +// cached list of entities. Otherwise, return undefined. | |
| 318 | +function getEntityWithName(name) { | |
| 319 | + debug("Getting entity with name:", name); | |
| 320 | + var entityID = TUTORIAL_NAME_TO_ENTITY_PROPERTIES_MAP[name]; | |
| 321 | + debug("Entity id: ", entityID, ", Is in local tree: ", isEntityInLocalTree(entityID)); | |
| 322 | + return entityID; | |
| 323 | +} | |
| 324 | + | |
| 210 | 325 | function playSuccessSound() { |
| 211 | 326 | Audio.playSound(successSound, { |
| 212 | 327 | position: MyAvatar.position, |
| @@ -215,7 +330,6 @@ function playSuccessSound() { · 2 unmodified lines | ||
| 215 | 330 | }); |
| 216 | 331 | } |
| 217 | 332 | |
| 218 | − | |
| 219 | 333 | function playFirecrackerSound(position) { |
| 220 | 334 | Audio.playSound(firecrackerSound, { |
| 221 | 335 | position: position, |
| @@ -400,7 +514,6 @@ stepNearGrab.prototype = { · 178 unmodified lines | ||
| 400 | 514 | |
| 401 | 515 | setControllerPartLayer('tips', 'trigger'); |
| 402 | 516 | setControllerPartLayer('trigger', 'highlight'); |
| 403 | − var tag = this.tag; | |
| 404 | 517 | |
| 405 | 518 | // Spawn content set |
| 406 | 519 | showEntitiesWithTag(this.tag, { visible: true }); |
| @@ -871,101 +984,6 @@ stepCleanupFinish.prototype = { · 464 unmodified lines | ||
| 871 | 984 | |
| 872 | 985 | |
| 873 | 986 | |
| 874 | −function isEntityInLocalTree(entityID) { | |
| 875 | − return Entities.getEntityProperties(entityID, 'visible').visible !== undefined; | |
| 876 | −} | |
| 877 | − | |
| 878 | −function showEntitiesWithTag(tag) { | |
| 879 | − var entities = TUTORIAL_TAG_TO_ENTITY_IDS_MAP[tag]; | |
| 880 | − if (entities) { | |
| 881 | − for (entityID in entities) { | |
| 882 | − var data = entities[entityID]; | |
| 883 | − | |
| 884 | − var collisionless = data.visible === false ? true : false; | |
| 885 | − if (data.collidable !== undefined) { | |
| 886 | − collisionless = data.collidable === true ? false : true; | |
| 887 | − } | |
| 888 | − if (data.soundKey) { | |
| 889 | − data.soundKey.playing = true; | |
| 890 | − } | |
| 891 | − var newProperties = { | |
| 892 | − visible: data.visible == false ? false : true, | |
| 893 | − collisionless: collisionless, | |
| 894 | − userData: JSON.stringify(data), | |
| 895 | − }; | |
| 896 | − debug("Showing: ", entityID, ", Is in local tree: ", isEntityInLocalTree(entityID)); | |
| 897 | − Entities.editEntity(entityID, newProperties); | |
| 898 | − } | |
| 899 | − } | |
| 900 | − | |
| 901 | − // Dynamic method, suppressed for now | |
| 902 | − return; | |
| 903 | − editEntitiesWithTag(tag, function(entityID) { | |
| 904 | − var userData = Entities.getEntityProperties(entityID, "userData").userData; | |
| 905 | − var data = parseJSON(userData); | |
| 906 | − var collisionless = data.visible === false ? true : false; | |
| 907 | − if (data.collidable !== undefined) { | |
| 908 | − collisionless = data.collidable === true ? false : true; | |
| 909 | − } | |
| 910 | − if (data.soundKey) { | |
| 911 | − data.soundKey.playing = true; | |
| 912 | − } | |
| 913 | − var newProperties = { | |
| 914 | − visible: data.visible == false ? false : true, | |
| 915 | − collisionless: collisionless, | |
| 916 | − userData: JSON.stringify(data), | |
| 917 | − }; | |
| 918 | − Entities.editEntity(entityID, newProperties); | |
| 919 | − }); | |
| 920 | −} | |
| 921 | − | |
| 922 | −function hideEntitiesWithTag(tag) { | |
| 923 | − var entities = TUTORIAL_TAG_TO_ENTITY_IDS_MAP[tag]; | |
| 924 | − if (entities) { | |
| 925 | − for (entityID in entities) { | |
| 926 | − var data = entities[entityID]; | |
| 927 | − | |
| 928 | − if (data.soundKey) { | |
| 929 | − data.soundKey.playing = false; | |
| 930 | − } | |
| 931 | − var newProperties = { | |
| 932 | − visible: false, | |
| 933 | − collisionless: 1, | |
| 934 | − ignoreForCollisions: 1, | |
| 935 | − userData: JSON.stringify(data), | |
| 936 | − }; | |
| 937 | − | |
| 938 | − debug("Hiding: ", entityID, ", Is in local tree: ", isEntityInLocalTree(entityID)); | |
| 939 | − Entities.editEntity(entityID, newProperties); | |
| 940 | − } | |
| 941 | − } | |
| 942 | − | |
| 943 | − // Dynamic method, suppressed for now | |
| 944 | − return; | |
| 945 | − editEntitiesWithTag(tag, function(entityID) { | |
| 946 | − var userData = Entities.getEntityProperties(entityID, "userData").userData; | |
| 947 | − var data = parseJSON(userData); | |
| 948 | − if (data.soundKey) { | |
| 949 | − data.soundKey.playing = false; | |
| 950 | − } | |
| 951 | − var newProperties = { | |
| 952 | − visible: false, | |
| 953 | − collisionless: 1, | |
| 954 | − ignoreForCollisions: 1, | |
| 955 | − userData: JSON.stringify(data), | |
| 956 | − }; | |
| 957 | − Entities.editEntity(entityID, newProperties); | |
| 958 | − }); | |
| 959 | −} | |
| 960 | − | |
| 961 | −// Return the entity properties for an entity with a given name if it is in our | |
| 962 | −// cached list of entities. Otherwise, return undefined. | |
| 963 | −function getEntityWithName(name) { | |
| 964 | − debug("Getting entity with name:", name); | |
| 965 | − var entityID = TUTORIAL_NAME_TO_ENTITY_PROPERTIES_MAP[name]; | |
| 966 | − debug("Entity id: ", entityID, ", Is in local tree: ", isEntityInLocalTree(entityID)); | |
| 967 | − return entityID; | |
| 968 | −} | |
| 969 | 987 | |
| 970 | 988 | |
| 971 | 989 | TutorialManager = function() { |
| @@ -1085,6 +1103,25 @@ TutorialManager = function() { · 113 unmodified lines | ||
| 1085 | 1103 | |
| 1086 | 1104 | // To run the tutorial: |
| 1087 | 1105 | // |
| 1088 | −// var tutorialManager = new TutorialManager(); | |
| 1089 | −// tutorialManager.startTutorial(); | |
| 1090 | −// | |
| 1106 | +var tutorialManager = new TutorialManager(); | |
| 1107 | +tutorialManager.startTutorial(); | |
| 1108 | + | |
| 1109 | + | |
| 1110 | +var keyReleaseHandler = function(event) { | |
| 1111 | + if (event.isShifted && event.isAlt) { | |
| 1112 | + print('here', event.text); | |
| 1113 | + if (event.text == "F12") { | |
| 1114 | + if (!tutorialManager.startNextStep()) { | |
| 1115 | + tutorialManager.startTutorial(); | |
| 1116 | + } | |
| 1117 | + } else if (event.text == "F11") { | |
| 1118 | + tutorialManager.restartStep(); | |
| 1119 | + } else if (event.text == "F10") { | |
| 1120 | + MyAvatar.shouldRenderLocally = !MyAvatar.shouldRenderLocally; | |
| 1121 | + } else if (event.text == "r") { | |
| 1122 | + tutorialManager.stopTutorial(); | |
| 1123 | + tutorialManager.startTutorial(); | |
| 1124 | + } | |
| 1125 | + } | |
| 1126 | +}; | |
| 1127 | +Controller.keyReleaseEvent.connect(keyReleaseHandler); | |