8000 Remove hero selection warnings by nwinter · Pull Request #7771 · codecombat/codecombat · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Remove hero selection warnings #7771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 44 additions & 56 deletions app/models/ThangType.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,9 @@ const loadCreateJs = movieClipUrl => fetch(movieClipUrl, { method: 'GET' })
const comp = Object.values(AnimateComposition.compositions)[0]
const lib = comp.getLibrary()
const ss = comp.getSpriteSheet()
const {
ssMetadata
} = lib
const { ssMetadata } = lib

return {
lib,
ss,
ssMetadata
}
return { lib, ss, ssMetadata }
})

let buildQueue = []
Expand Down Expand Up @@ -213,9 +207,7 @@ module.exports = (ThangType = (function () {
addPortrait () {
// The portrait is built very differently than the other animations, so it gets a separate function.
if (!this.actions) { return }
const {
portrait
} = this.actions
const { portrait } = this.actions
if (!portrait) { return }
const scale = portrait.scale || 1
const pt = portrait.positions != null ? portrait.positions.registration : undefined
Expand All @@ -224,9 +216,7 @@ module.exports = (ThangType = (function () {
const mc = this.vectorParser.buildMovieClip(portrait.animation)
mc.nominalBounds = (mc.frameBounds = null) // override what the movie clip says on bounding
this.builder.addMovieClip(mc, rect, scale)
let {
frames
} = this.builder._animations[portrait.animation]
let { frames } = this.builder._animations[portrait.animation]
if (portrait.frames != null) { frames = this.mapFrames(portrait.frames, frames[0]) }
return this.builder.addAnimation('portrait', frames, true)
} else if (portrait.container) {
Expand Down Expand Up @@ -420,9 +410,7 @@ module.exports = (ThangType = (function () {
if (!this.actions) { return }
const canvas = $(`<canvas width='${size}' height='${size}'></canvas>`)
const stage = new createjs.Stage(canvas[0])
const {
portrait
} = this.actions
const { portrait } = this.actions
if (!portrait || (!portrait.animation && !portrait.container)) { return }
const scale = portrait.scale || 1

Expand Down Expand Up @@ -452,7 +440,7 @@ module.exports = (ThangType = (function () {
mimetype: 'image/png',
path: `db/thang.type/${this.get('original')}`,
b64png: src,
force: 'true'
force: 'true',
}
return $.ajax('/file', { type: 'POST', data: body, success: callback || this.onFileUploaded })
}
Expand Down Expand Up @@ -491,40 +479,48 @@ module.exports = (ThangType = (function () {
getHeroStats () {
// Translate from raw hero properties into appropriate display values for the PlayHeroesModal.
// Adapted from https://docs.google.com/a/codecombat.com/spreadsheets/d/1BGI1bzT4xHvWA81aeyIaCKWWw9zxn7-MwDdydmB5vw4/edit#gid=809922675
let equipsConfig, movesConfig
const heroClass = this.get('heroClass')
if (!heroClass) { return }
if (!heroClass) return
if (this.get('kind') === 'Junior Hero') return

const components = this.get('components') || []
if (!(equipsConfig = __guard__(_.find(components, { original: LevelComponent.EquipsID }), x => x.config))) {
return console.warn(this.get('name'), 'is not an equipping hero, but you are asking for its hero stats. (Did you project away components?)')
}
if (!(movesConfig = __guard__(_.find(components, { original: LevelComponent.MovesID }), x1 => x1.config))) {
return console.warn(this.get('name'), 'is not a moving hero, but you are asking for its hero stats.')
const equipsConfig = components.find(c => c.original === LevelComponent.EquipsID)?.config
const movesConfig = components.find(c => c.original === LevelComponent.MovesID)?.config

if (!equipsConfig) {
console.warn(`${this.get('name')} is not an equipping hero, but you are asking for its hero stats. (Did you project away components?)`)
return
}
let programmableConfig = __guard__(_.find(components, { original: LevelComponent.ProgrammableID }), x2 => x2.config)
if (utils.isOzaria) {
programmableConfig = __guard__(_.find(components, c => Array.from(LevelComponent.ProgrammableIDs).includes(c.original)), x3 => x3.config)

if (!movesConfig) {
console.warn(`${this.get('name')} is not a moving hero, but you are asking for its hero stats.`)
return
}

const programmableConfig = components.find(c => LevelComponent.ProgrammableIDs.includes(c.original))?.config
if (!programmableConfig) {
return console.warn(this.get('name'), 'is not a Programmable hero, but you are asking for its hero stats.')
console.warn(`${this.get('name')} is not a Programmable hero, but you are asking for its hero stats.`)
return
}
if (this.classStatAverages == null) {
this.classStatAverages = {
attack: { Warrior: 7.5, Ranger: 5, Wizard: 2.5 },
health: { Warrior: 7.5, Ranger: 5, Wizard: 3.5 }
}

this.classStatAverages ??= {
attack: { Warrior: 7.5, Ranger: 5, Wizard: 2.5 },
health: { Warrior: 7.5, Ranger: 5, Wizard: 3.5 },
}

const rawNumbers = {
attack: equipsConfig.attackDamageFactor ?? 1,
health: equipsConfig.maxHealthFactor ?? 1,
speed: movesConfig.maxSpeed,
}

const stats = {}
const rawNumbers = { attack: equipsConfig.attackDamageFactor != null ? equipsConfig.attackDamageFactor : 1, health: equipsConfig.maxHealthFactor != null ? equipsConfig.maxHealthFactor : 1, speed: movesConfig.maxSpeed }

for (const prop of ['attack', 'health']) {
let classSpecificScore
const stat = rawNumbers[prop]
if (stat < 1) {
classSpecificScore = 10 - (5 / stat)
} else {
classSpecificScore = stat * 5
}
const classAverage = this.classStatAverages[prop][this.get('heroClass')]
const classSpecificScore = stat < 1 ? 10 - (5 / stat) : stat * 5
const classAverage = this.classStatAverages[prop][heroClass]

stats[prop] = {
relative: Math.round(2 * ((classAverage - 2.5) + (classSpecificScore / 2))) / 2 / 10,
absolute: stat
Expand All @@ -545,15 +541,9 @@ module.exports = (ThangType = (function () {
description: `${$.i18n.t('choose_hero.speed_1')} ${rawNumbers.speed} ${$.i18n.t('choose_hero.speed_2')}`
}

stats.skills = ((() => {
const result = []
for (const skill of Array.from(programmableConfig.programmableProperties)) {
if ((skill !== 'say') && !/(Range|Pos|Radius|Damage)$/.test(skill)) {
result.push(_.string.titleize(_.string.humanize(skill)))
}
}
return result
})())
stats.skills = programmableConfig.programmableProperties
.filter(skill => skill !== 'say' && !/(Range|Pos|Radius|Damage)$/.test(skill))
.map(skill => _.string.titleize(_.string.humanize(skill)))

return stats
}
Expand Down Expand Up @@ -623,7 +613,7 @@ module.exports = (ThangType = (function () {
throwDamage: 'attack',
throwRange: 'range',
bashDamage: 'attack',
backstabDamage: 'backstab'
backstabDamage: 'backstab',
}[name]

if (i18nKey) {
Expand Down Expand Up @@ -681,9 +671,7 @@ module.exports = (ThangType = (function () {
if (!rawAnimation) {
console.error('thang type', this.get('name'), 'is missing animation', animation, 'from action', action)
}
let {
containers
} = rawAnimation
let { containers } = rawAnimation
for (animation of Array.from(this.get('raw').animations[animation].animations)) {
containers = containers.concat(this.getContainersForAnimation(animation.gn, action))
}
Expand Down Expand Up @@ -948,7 +936,7 @@ class PrerenderedSpriteSheet extends CocoModel {
this.spriteSheet = new createjs.SpriteSheet({
images: [this.image[0]],
frames: this.get('frames'),
animations: this.get('animations')
animations: this.get('animations'),
})
return this.spriteSheet
}
Expand Down
2 changes: 1 addition & 1 deletion app/views/play/modal/PlayHeroesModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ module.exports = (PlayHeroesModal = (function () {
this.heroes = new CocoCollection([], { model: ThangType })
this.isJunior = this.options.level?.get('product') === 'codecombat-junior' || this.options.campaign?.get('slug') === 'junior'
this.heroes.url = '/db/thang.type?view=' + (this.isJunior ? 'heroes-junior' : 'heroes')
this.heroes.setProjection(['original', 'name', 'slug', 'soundTriggers', 'featureImages', 'gems', 'heroClass', 'description', 'components', 'extendedName', 'shortName', 'unlockLevelName', 'i18n', 'poseImage', 'tier', 'releasePhase', 'ozaria'])
this.heroes.setProjection(['original', 'name', 'slug', 'soundTriggers', 'featureImages', 'gems', 'heroClass', 'description', 'components', 'extendedName', 'shortName', 'unlockLevelName', 'i18n', 'poseImage', 'tier', 'releasePhase', 'ozaria', 'kind'])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Issue Found: Unused 'kind' Field in Hero Projection

The kind field has been added to the hero projection array in PlayHeroesModal.js, but it is not utilized anywhere within the file. Including unused fields can lead to unnecessary data retrieval and increased payload sizes.

  • Recommendation: Remove 'kind' from the projection array in PlayHeroesModal.js to optimize data fetching.
🔗 Analysis chain

Approved: Addition of 'kind' to hero projection, but clarification needed

The addition of 'kind' to the hero projection array is noted. This change seems intentional and likely serves a purpose in the application.

However, to ensure a comprehensive understanding of this modification:

  1. Could you provide more context on why 'kind' was added to the projection?
  2. Are there any new features or changes in other parts of the application that now utilize this 'kind' field?
  3. Have you considered any potential performance implications of fetching this additional field for all heroes?

To verify the usage of the new 'kind' field, we can search for its occurrences in the codebase:


Let's verify if the kind field is actively used within PlayHeroesModal.js after being fetched.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usage of hero 'kind' field
rg "hero.*kind" --type js

Length of output: 1335


Script:

#!/bin/bash
# Search for usage of 'kind' field in PlayHeroesModal.js
rg "kind" app/views/play/modal/PlayHeroesModal.js

Length of output: 306

this.heroes.comparator = 'gems'
this.listenToOnce(this.heroes, 'sync', this.onHeroesLoaded)
this.supermodel.loadCollection(this.heroes, 'heroes')
Expand Down
Loading
0