(context = {})
| 753 | } |
| 754 | |
| 755 | getRenderData (context = {}) { |
| 756 | context = super.getRenderData(context) |
| 757 | context.campaign = this.campaign |
| 758 | context.levels = _.values($.extend(true, {}, this.getLevels() ?? {})) |
| 759 | if ((me.level() < 12) && (this.terrain === 'dungeon') && !this.editorMode) { |
| 760 | context.levels = _.reject(context.levels, { slug: 'signs-and-portents' }) |
| 761 | } |
| 762 | if (me.freeOnly()) { |
| 763 | context.levels = _.reject(context.levels, level => { |
| 764 | if ((['course', 'course-ladder'].includes(level.type)) && me.isStudent() && !this.courseInstance) { return true } // Too much hassle to get Wakka Maul working for CS1 with no classroom |
| 765 | return level.requiresSubscription && !me.isStudent() |
| 766 | }) |
| 767 | } |
| 768 | if (features.brainPop) { |
| 769 | context.levels = _.filter(context.levels, level => ['dungeons-of-kithgard', 'gems-in-the-deep', 'shadow-guard', 'enemy-mine', 'true-names'].includes(level.slug)) |
| 770 | } |
| 771 | this.annotateLevels(context.levels, context.campaign) |
| 772 | const dontCountPracticeLevels = context.campaign?.get('type') === 'junior' || context.campaign?.get('slug') === 'junior' |
| 773 | const count = this.countLevels(context.levels, context.campaign, dontCountPracticeLevels) |
| 774 | if (this.courseStats) { |
| 775 | context.levelsCompleted = this.courseStats.levels.numDone |
| 776 | context.levelsTotal = this.courseStats.levels.size |
| 777 | } else { |
| 778 | context.levelsCompleted = count.completed |
| 779 | context.levelsTotal = count.total |
| 780 | } |
| 781 | |
| 782 | if (this.sessions?.loaded || this.editorMode) { |
| 783 | this.determineNextLevel(context.levels) |
| 784 | } |
| 785 | context.levels = this.collapsePracticeLevels(context.levels) |
| 786 | |
| 787 | // put lower levels in last, so in the world map they layer over one another properly. |
| 788 | context.levels = _.sortBy(context.levels, l => l.position.y).reverse() |
| 789 | if (this.campaign) { |
| 790 | this.campaign.renderedLevels = context.levels |
| 791 | } |
| 792 | |
| 793 | context.levelStatusMap = this.levelStatusMap |
| 794 | context.levelDifficultyMap = this.levelDifficultyMap |
| 795 | context.levelPlayCountMap = this.levelPlayCountMap |
| 796 | context.isIPadApp = application.isIPadApp |
| 797 | context.requiresSubscription = this.requiresSubscription |
| 798 | context.editorMode = this.editorMode |
| 799 | context.scenarios = this.campaign?.get('scenarios') || [] |
| 800 | // Modules: child campaigns rendered as portals on the map. |
| 801 | // Enrich each module with locked state: first by premium, then by levelToUnlock (complete that level to unlock). |
| 802 | const rawModules = this.campaign?.get('modules') || [] |
| 803 | if (!this.editorMode) { |
| 804 | this.loadModuleCampaignStats(rawModules) |
| 805 | } |
| 806 | context.modules = rawModules.map(module => { |
| 807 | const access = module.access || 'paid' |
| 808 | const lockedByPremium = !this.editorMode && access !== 'free' && !me.isPremium() |
| 809 | const levelToUnlock = module.levelToUnlock |
| 810 | const levelNotCompleted = levelToUnlock && this.levelOriginalStatusMap[levelToUnlock] !== COMPLETE_STATUS |
| 811 | const lockedByLevel = !this.editorMode && levelNotCompleted |
| 812 | const locked = lockedByPremium || lockedByLevel |
nothing calls this directly
no test coverage detected