(orderedLevels)
| 1330 | } |
| 1331 | |
| 1332 | determineNextLevel (orderedLevels) { |
| 1333 | if (this.isClassroom()) { |
| 1334 | if (this.courseStats) { this.applyCourseLogicToLevels(orderedLevels) } |
| 1335 | return true |
| 1336 | } |
| 1337 | |
| 1338 | const dontPointTo = ['lost-viking', 'kithgard-mastery'] // Challenge levels we don't want most players bashing heads against |
| 1339 | const subscriptionPrompts = [{ slug: 'boom-and-bust', unless: 'defense-of-plainswood' }] |
| 1340 | |
| 1341 | if (this.campaign?.get('type') === 'hoc') { |
| 1342 | // HoC: Just order left-to-right instead of looking at unlocks, which we don't use for this copycat campaign |
| 1343 | orderedLevels = _.sortBy(orderedLevels, level => level.position.x) |
| 1344 | for (const level of orderedLevels) { |
| 1345 | if (this.levelStatusMap[level.slug] !== COMPLETE_STATUS) { |
| 1346 | level.next = true |
| 1347 | // Unlock and re-annotate this level |
| 1348 | // May not be unlocked/awarded due to different HoC progression using mostly shared levels |
| 1349 | level.locked = false |
| 1350 | level.hidden = level.locked |
| 1351 | level.disabled = false |
| 1352 | level.color = colors.jayBlue |
| 1353 | return |
| 1354 | } |
| 1355 | } |
| 1356 | } |
| 1357 | |
| 1358 | const findNextLevel = (level, practiceOnly) => { |
| 1359 | for (const nextLevelOriginal of level.nextLevels) { |
| 1360 | const nextLevel = _.find(orderedLevels, { original: nextLevelOriginal }) |
| 1361 | if (!nextLevel || nextLevel.locked) { continue } |
| 1362 | if (practiceOnly && !this.campaign.levelIsPractice(nextLevel)) { continue } |
| 1363 | if (this.campaign.levelIsAssessment(nextLevel)) { continue } |
| 1364 | if (this.campaign.levelIsAssessment(level) && this.campaign.levelIsPractice(nextLevel)) { continue } |
| 1365 | |
| 1366 | // // If it's a challenge level, we efficiently determine whether we actually do want to point it out. |
| 1367 | // // 2021-09-21: disabling for now, guessing it doesn't work well and makes experiments harder |
| 1368 | // if (false && (nextLevel.slug === 'kithgard-mastery') && !this.levelStatusMap[nextLevel.slug] && (this.calculateExperienceScore() >= 3)) { |
| 1369 | // const timesPointedOut = storage.load(`pointed-out-${nextLevel.slug}`) || 0 |
| 1370 | // if (timesPointedOut <= 3) { |
| 1371 | // // We may determineNextLevel more than once per render, so we can't just do this once. But we do give up after a couple highlights. |
| 1372 | // dontPointTo = _.without(dontPointTo, nextLevel.slug) |
| 1373 | // storage.save(`pointed-out-${nextLevel.slug}`, timesPointedOut + 1) |
| 1374 | // } |
| 1375 | // } |
| 1376 | |
| 1377 | // Should we point this level out? |
| 1378 | if (!nextLevel.disabled && (this.levelStatusMap[nextLevel.slug] !== COMPLETE_STATUS) && !dontPointTo.includes(nextLevel.slug) && |
| 1379 | !nextLevel.replayable && ( |
| 1380 | me.isPremium() || !nextLevel.requiresSubscription || // nextLevel.adventurer or # Disable adventurer stuff for now |
| 1381 | _.any(subscriptionPrompts, prompt => (nextLevel.slug === prompt.slug) && !this.levelStatusMap[prompt.unless]) |
| 1382 | )) { |
| 1383 | if (nextLevel.practice === true && nextLevel.slug.match(level.slug.replace(/-[a-z]$/, ''))) { |
| 1384 | // If this is a practice level for the current level, we don't want to point it out |
| 1385 | // This is a bit of a hack, but it's the best way to handle this for now |
| 1386 | // It works for the Junior levels where they have the same slug with a -a or -b at the end |
| 1387 | continue |
| 1388 | } else { |
| 1389 | nextLevel.next = true |
no test coverage detected