diff --git a/app/models/LevelComponent.coffee b/app/models/LevelComponent.coffee index 100ced453..a54f130a7 100644 --- a/app/models/LevelComponent.coffee +++ b/app/models/LevelComponent.coffee @@ -13,6 +13,7 @@ module.exports = class LevelComponent extends CocoModel @CollidesID: '524b7b857fc0f6d519000012' @PlansID: '524b7b517fc0f6d51900000d' @ProgrammableID: '524b7b5a7fc0f6d51900000e' + @MovesID: '524b7b8c7fc0f6d519000013' urlRoot: '/db/level.component' set: (key, val, options) -> diff --git a/app/models/ThangType.coffee b/app/models/ThangType.coffee index 407e2a68f..848c82f29 100644 --- a/app/models/ThangType.coffee +++ b/app/models/ThangType.coffee @@ -305,30 +305,34 @@ module.exports = class ThangType extends CocoModel ['Warrior', 'Ranger', 'Wizard'] getHeroStats: -> + # Translate from raw hero properties into appropriate display values for the ChooseHeroView. + # Adapted from https://docs.google.com/a/codecombat.com/spreadsheets/d/1BGI1bzT4xHvWA81aeyIaCKWWw9zxn7-MwDdydmB5vw4/edit#gid=809922675 return unless heroClass = @get('heroClass') - - return switch heroClass - when 'Warrior' then { - attack: 0.8 - health: 0.85 - speed: 0.6 - skills: [] - } + components = @get('components') or [] + unless equipsConfig = _.find(components, original: LevelComponent.EquipsID)?.config + return console.warn @get('name'), 'is not an equipping hero, but you are asking for its hero stats. (Did you project away components?)' + unless movesConfig = _.find(components, original: LevelComponent.MovesID)?.config + return console.warn @get('name'), 'is not a moving hero, but you are asking for its hero stats.' + @classStatAverages ?= + attack: {Warrior: 7.5, Ranger: 5, Wizard: 2.5} + health: {Warrior: 7.5, Ranger: 5, Wizard: 3.5} + stats = {skills: []} # TODO: find skills + rawNumbers = attack: equipsConfig.attackDamageFactor ? 1, health: equipsConfig.maxHealthFactor ? 1, speed: movesConfig.maxSpeed + for prop in ['attack', 'health'] + stat = rawNumbers[prop] + if stat < 1 + classSpecificScore = 10 - 5 / stat + else + classSpecificScore = stat * 5 + classAverage = @classStatAverages[prop][@get('heroClass')] + stats[prop] = Math.round(2 * ((classAverage - 2.5) + classSpecificScore / 2)) / 2 / 10 + minSpeed = 4 + maxSpeed = 16 + speedRange = maxSpeed - minSpeed + speedPoints = rawNumbers.speed - minSpeed + stats.speed = Math.round(20 * speedPoints / speedRange) / 2 / 10 + stats - when 'Ranger' then { - attack: 0.6 - health: 0.7 - speed: 0.8 - skills: [] - } - - when 'Wizard' then { - attack: 0.5 - health: 0.45 - speed: 0.25 - skills: [] - } - getFrontFacingStats: -> components = @get('components') or [] unless itemConfig = _.find(components, original: LevelComponent.ItemID)?.config diff --git a/app/views/game-menu/ChooseHeroView.coffee b/app/views/game-menu/ChooseHeroView.coffee index b322d3ed8..d88eff8e1 100644 --- a/app/views/game-menu/ChooseHeroView.coffee +++ b/app/views/game-menu/ChooseHeroView.coffee @@ -23,7 +23,7 @@ module.exports = class ChooseHeroView extends CocoView constructor: (options) -> super options @heroes = new CocoCollection([], {model: ThangType}) - @heroes.url = '/db/thang.type?view=heroes&project=original,name,slug,soundTriggers,featureImage,gems,heroClass,description' + @heroes.url = '/db/thang.type?view=heroes&project=original,name,slug,soundTriggers,featureImage,gems,heroClass,description,components' @supermodel.loadCollection(@heroes, 'heroes') @stages = {} diff --git a/app/views/play/WorldMapView.coffee b/app/views/play/WorldMapView.coffee index 79d87188a..c26fd611f 100644 --- a/app/views/play/WorldMapView.coffee +++ b/app/views/play/WorldMapView.coffee @@ -86,6 +86,7 @@ module.exports = class WorldMapView extends RootView level.locked = index > 0 and not me.ownsLevel level.original window.levelUnlocksNotWorking = true if level.locked and level.id is @nextLevel # Temporary level.locked = false if window.levelUnlocksNotWorking # Temporary; also possible in HeroVictoryModal + level.locked = false if @levelStatusMap[level.id] in ['started', 'complete'] level.color = 'rgb(255, 80, 60)' if level.practice level.color = 'rgb(80, 130, 200)' unless me.getBranchingGroup() is 'all-practice'