diff --git a/js/pokedex-pokemon.js b/js/pokedex-pokemon.js index e3e7448..ccd0f6e 100644 --- a/js/pokedex-pokemon.js +++ b/js/pokedex-pokemon.js @@ -76,7 +76,10 @@ var PokedexPokemonPanel = PokedexResultPanel.extend({ buf += ''; buf += '
'; - buf += '
Base stats:
'; + buf += '
Defensive effectiveness:
'; + buf += '
'+PokedexTypePanel.prototype.renderDefensiveEffectiveness(pokemon.types)+'
'; + + buf += '
Base stats:
'; var StatTitles = { hp: "HP", diff --git a/js/pokedex.js b/js/pokedex.js index e27a1fd..415335a 100644 --- a/js/pokedex.js +++ b/js/pokedex.js @@ -123,40 +123,135 @@ var PokedexTypePanel = PokedexResultPanel.extend({ var buf = '
'; buf += ' Pokédex'; buf += '

'+this.type+'

'; + buf += '
'; - var atLeastOne = false; + buf += '
Defensive effectiveness:
'+this.renderDefensiveEffectiveness(type)+'
'; + buf += '
Offensive effectiveness:
'+this.renderOffensiveEffectiveness(type)+'
'; + buf += '
'; - buf += '
Weaknesses:
'; - for (var attackType in type.damageTaken) { - if (type.damageTaken[attackType] == 1) { - buf += ''+Dex.getTypeIcon(attackType)+' '; - atLeastOne = true; + // move list + buf += '
'; + buf += '
    '; + buf += '
'; + + buf += '
'; + + this.html(buf); + + setTimeout(this.renderMoveList.bind(this)); + }, + getTypeEffectiveness: function(attacking, defending) { + var attackingName = typeof attacking === 'string' ? attacking : attacking.name; + if (Array.isArray(defending)) { + var total = 0; + for (var i = 0; i < defending.length; i++) { + var defendingType = typeof defending[i] === 'string' ? Dex.types.get(defending[i]) : defending[i]; + switch (defendingType.damageTaken[attackingName]) { + case 1: // super effective + ++total; + break; + case 2: // not very effective + --total; + break; + case 3: // immune + return null; + } } + return total; + } + var defendingType = typeof defending === 'string' ? Dex.types.get(defending) : defending; + switch (defendingType.damageTaken[attackingName]) { + case 1: // super effective + return 1; + case 2: // not very effective + return -1; + case 3: // immune + return null; + default: + return 0; } - if (!atLeastOne) { - buf += 'No weaknesses'; + }, + effectTypes: ['hail', 'sandstorm', 'powder', 'frz', 'brn', 'psn', 'par'], + renderDefensiveEffectiveness: function(defending) { + var imms = []; + if (Array.isArray(defending)) { + for (var i = 0; i < defending.length; i++) { + var defendingType = typeof defending[i] === 'string' ? Dex.types.get(defending[i]) : defending[i]; + for (var j = 0; j < this.effectTypes.length; j++) { + if (defendingType.damageTaken[this.effectTypes[j]] === 3) { + imms.push(this.effectTypes[j]); + } + } + } + } else { + var defendingType = typeof defending === 'string' ? Dex.types.get(defending) : defending; + for (var j = 0; j < this.effectTypes.length; j++) { + if (defendingType.damageTaken[this.effectTypes[j]] === 3) { + imms.push(this.effectTypes[j]); + } + } } - buf += ''; - buf += '
Resistances:
'; - atLeastOne = false; - for (var attackType in type.damageTaken) { - if (type.damageTaken[attackType] == 2) { - buf += ''+Dex.getTypeIcon(attackType)+' '; - atLeastOne = true; + var effs = [[], [], [], [], []]; + for (var types = Dex.types.all(), i = 0; i < types.length; i++) { + var eff = this.getTypeEffectiveness(types[i], defending); + if (eff === null) { + imms.push(types[i].name); + } else { + effs[eff + 2].push(types[i].name); } } - if (!atLeastOne) { - buf += 'No resistances'; + + return this.renderEffectivenessTable(effs, imms, 'defense'); + }, + renderOffensiveEffectiveness: function(attacking) { + var effs = [[], [], [], [], []]; + var imms = []; + for (var types = Dex.types.all(), i = 0; i < types.length; i++) { + var eff = this.getTypeEffectiveness(attacking, types[i]); + if (eff === null) { + imms.push(types[i].name); + } else { + effs[eff + 2].push(types[i].name); + } } - buf += '
'; + return this.renderEffectivenessTable(effs, imms, 'offense'); + }, + renderEffectivenessTable: function(effs, imms, cls) { + var hasDoubles = effs[0].length > 0 || effs[4].length > 0; // any .25x or 4x? + var buf = '
'; + + var i, max; + if (hasDoubles) { + buf += ''; + i = 0; + max = 4; + } else { + buf += ''; + i = 1; + max = 3; + } + + buf += ''; + for (; i <= max; i++) { + if (i === 2) continue; // don't show neutral effectiveness + buf += ''; + } + buf += ''; - buf += '
Immunities:
'; - atLeastOne = false; - for (var attackType in type.damageTaken) { - if (type.damageTaken[attackType] == 3) { - if (attackType === attackType.toLowerCase()) { - switch (attackType) { + if (imms.length > 0) { + buf += '
'; } - buf += ''; - buf += ''; - - // move list - buf += ''; - buf += ''; - - buf += ''; - - this.html(buf); - - setTimeout(this.renderMoveList.bind(this)); + buf += '
.25x.5x2x4x
.5x2x
'; + var atLeastOne = false; + for (let j = 0; j < effs[i].length; j++) { + buf += ''+Dex.getTypeIcon(effs[i][j])+' '; + atLeastOne = true; + } + if (!atLeastOne) buf += '-'; + buf += '
'; + buf += '
Immune:
'; + for (var i = 0; i < imms.length; i++) { + if (imms[i] === imms[i].toLowerCase()) { + switch (imms[i]) { case 'hail': buf += '
Hail damage
'; break; @@ -179,34 +274,15 @@ var PokedexTypePanel = PokedexResultPanel.extend({ buf += '
PAR status
'; break; } - if (!atLeastOne) atLeastOne = null; continue; } - buf += ''+Dex.getTypeIcon(attackType)+' '; - atLeastOne = true; - } - } - if (!atLeastOne) { - if (atLeastOne === null) { - buf += '
No type immunities
'; - } else { - buf += 'No immunities'; + buf += ''+Dex.getTypeIcon(imms[i])+' '; } + buf += '
'; + return buf; }, events: { 'click .tabbar button': 'selectTab' diff --git a/theme/pokedex.css b/theme/pokedex.css index af9567f..9f80531 100644 --- a/theme/pokedex.css +++ b/theme/pokedex.css @@ -409,6 +409,40 @@ a.subtle:hover { .type.special{background-color:#ADB1BD;background:linear-gradient(#ADB1BD,#7D828D);border-color:#A1A5AD;color:#E0E2E4;} .type.status{background-color:#CBC9CB;background:linear-gradient(#CBC9CB,#AAA6AA);border-color:#A99890;color:#F5F4F5;} +.typeeff { + width: 100%; + table-layout: fixed; + border-collapse: collapse; + font-size: 9pt; +} +.typeeff tr { + line-height: 1.25; +} +.typeeff th { + font-size: 7pt; + font-weight: bold; +} +.typeeff td { + padding: 2px 6px 0; + border: 1px solid #AAAAAA; +} +.typeeff.defense td.eff4, .typeeff.offense td.eff0 { + background-color: rgba(255,128,128,.2); +} +.typeeff.defense td.eff3, .typeeff.offense td.eff1 { + background-color: rgba(255,128,128,.1); +} +.typeeff.defense td.eff1, .typeeff.offense td.eff3 { + background-color: rgba(128,255,128,.1); +} +.typeeff.defense td.eff0, .typeeff.offense td.eff4 { + background-color: rgba(128,255,128,.2); +} +.typeeff td.immune { + padding-bottom: 2px; + background-color: rgba(128,128,128,.1); +} + .pokemonicon, .picon { display: inline-block; vertical-align: -6px;