mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-06-02 22:09:20 -05:00
These scripts will eventually replace the old utilichart.js. For now, they're only used in the pokedex.
319 lines
9.8 KiB
JavaScript
319 lines
9.8 KiB
JavaScript
/**
|
|
* Search
|
|
*
|
|
* Basically just an improved version of utilichart
|
|
*
|
|
* Dependencies: jQuery, battledata, search-index
|
|
* Optional dependencies: pokedex, moves, items, abilities
|
|
*
|
|
* @author Guangcong Luo <Zarel>
|
|
*/
|
|
|
|
(function(exports, $){
|
|
'use strict';
|
|
|
|
function Search(elem) {
|
|
this.$el = $(elem);
|
|
this.el = this.$el[0];
|
|
}
|
|
Search.prototype.$ = function(query) {
|
|
return this.$el.find(query);
|
|
};
|
|
|
|
//
|
|
// Search functions
|
|
//
|
|
|
|
Search.prototype.q = '';
|
|
var typeTable = {
|
|
pokemon: 0,
|
|
move: 1,
|
|
item: 2,
|
|
ability: 3
|
|
};
|
|
var typeName = {
|
|
pokemon: 'Pokemon',
|
|
move: 'Moves',
|
|
item: 'Items',
|
|
ability: 'Abilities'
|
|
};
|
|
Search.prototype.find = function(query) {
|
|
query = toId(query);
|
|
|
|
if (query === this.q) {
|
|
return;
|
|
}
|
|
this.q = query;
|
|
if (!query) {
|
|
this.$el.html('');
|
|
return;
|
|
}
|
|
|
|
var i = this.getClosest(query);
|
|
if (!BattleSearchIndex[i]) i--;
|
|
|
|
var bufs = ['','','',''];
|
|
|
|
for (var j=0; j<15; j++) {
|
|
var id = BattleSearchIndex[i+j];
|
|
var type = BattleSearchIndexType[i+j];
|
|
var matchLength = query.length;
|
|
|
|
if (id.substr(0,query.length) !== query) {
|
|
if (j) break;
|
|
matchLength = 0;
|
|
}
|
|
|
|
if (!bufs[typeTable[type]]) bufs[typeTable[type]] = '<li><h3>'+typeName[type]+'</h3></li>';
|
|
bufs[typeTable[type]] += this.renderRow(id, type, 0, matchLength + (BattleSearchIndexOffset[i+j][matchLength-1]||'0').charCodeAt(0)-48);
|
|
}
|
|
|
|
this.$el.html('<ul class="utilichart">'+bufs.join('')+'</ul>');
|
|
};
|
|
|
|
Search.prototype.getClosest = function(query) {
|
|
// binary search through the index!
|
|
var left = 0;
|
|
var right = BattleSearchIndex.length - 1;
|
|
while (right >= left) {
|
|
var mid = Math.floor((right - left) / 2 + left);
|
|
if (BattleSearchIndex[mid] === query) {
|
|
// that's us
|
|
return mid;
|
|
} else if (BattleSearchIndex[mid] < query) {
|
|
left = mid + 1;
|
|
} else {
|
|
right = mid - 1;
|
|
}
|
|
}
|
|
return left;
|
|
};
|
|
|
|
//
|
|
// Rendering functions
|
|
//
|
|
|
|
Search.prototype.renderRow = function(id, type, matchStart, matchLength, errorMessage) {
|
|
switch (type) {
|
|
case 'pokemon':
|
|
var pokemon = Tools.getTemplate(id);
|
|
return this.renderPokemonRow(pokemon, matchStart, matchLength, errorMessage);
|
|
case 'move':
|
|
var move = Tools.getMove(id);
|
|
return this.renderMoveRow(move, matchStart, matchLength, errorMessage);
|
|
case 'item':
|
|
var item = Tools.getItem(id);
|
|
return this.renderItemRow(item, matchStart, matchLength, errorMessage);
|
|
case 'ability':
|
|
var ability = Tools.getAbility(id);
|
|
return this.renderAbilityRow(ability, matchStart, matchLength, errorMessage);
|
|
}
|
|
return 'Error: not found';
|
|
};
|
|
Search.prototype.renderRowByIdLength = function(id, type, idMatchLength, errorMessage) {
|
|
switch (type) {
|
|
case 'pokemon':
|
|
var pokemon = Tools.getTemplate(id);
|
|
idMatchLength += pokemon.species.substr(0, idMatchLength).replace(/[a-zA-Z0-9]+/,'').length;
|
|
return this.renderPokemonRow(pokemon, 0, idMatchLength, errorMessage);
|
|
case 'move':
|
|
var move = Tools.getMove(id);
|
|
idMatchLength += move.name.substr(0, idMatchLength).replace(/[a-zA-Z0-9]+/,'').length;
|
|
return this.renderMoveRow(move, 0, idMatchLength, errorMessage);
|
|
case 'item':
|
|
var item = Tools.getItem(id);
|
|
idMatchLength += item.name.substr(0, idMatchLength).replace(/[a-zA-Z0-9]+/,'').length;
|
|
return this.renderItemRow(item, 0, idMatchLength, errorMessage);
|
|
case 'ability':
|
|
var ability = Tools.getAbility(id);
|
|
idMatchLength += ability.name.substr(0, idMatchLength).replace(/[a-zA-Z0-9]+/,'').length;
|
|
return this.renderAbilityRow(ability, 0, idMatchLength, errorMessage);
|
|
}
|
|
return 'Error: not found';
|
|
};
|
|
Search.prototype.renderPokemonRow = function(pokemon, matchStart, matchLength, errorMessage) {
|
|
var buf = '<li class="result"><a data-name="'+Tools.escapeHTML(pokemon.species)+'">';
|
|
|
|
// number
|
|
buf += '<span class="col numcol">'+(pokemon.num)+'</span> ';
|
|
|
|
// icon
|
|
buf += '<span class="col iconcol">';
|
|
buf += '<span style="'+Tools.getIcon(pokemon)+'"></span>';
|
|
buf += '</span> ';
|
|
|
|
// name
|
|
var name = pokemon.species;
|
|
var tagStart = (pokemon.forme ? name.length-pokemon.forme.length-1 : 0);
|
|
if (tagStart) name = name.substr(0, tagStart);
|
|
if (matchLength) {
|
|
name = name.substr(0, matchStart)+'<b>'+name.substr(matchStart, matchLength)+'</b>'+name.substr(matchStart+matchLength);
|
|
}
|
|
if (tagStart) {
|
|
if (matchLength && matchStart+matchLength > tagStart) {
|
|
if (matchStart < tagStart) {
|
|
matchLength -= tagStart - matchStart;
|
|
matchStart = tagStart;
|
|
}
|
|
name += '<small>'+pokemon.species.substr(tagStart, matchStart-tagStart)+'<b>'+pokemon.species.substr(matchStart, matchLength)+'</b>'+pokemon.species.substr(matchStart+matchLength)+'</small>';
|
|
} else {
|
|
name += '<small>'+pokemon.species.substr(tagStart)+'</small>';
|
|
}
|
|
}
|
|
buf += '<span class="col pokemonnamecol" style="white-space:nowrap">'+name+'</span> ';
|
|
|
|
// error
|
|
if (errorMessage) {
|
|
buf += '<span class="col illegalcol"><em>'+errorMessage+'</em></span> ';
|
|
buf += '</a></li>';
|
|
return buf;
|
|
}
|
|
|
|
// type
|
|
buf += '<span class="col typecol">';
|
|
for (var i=0; i<pokemon.types.length; i++) {
|
|
buf += Tools.getTypeIcon(pokemon.types[i]);
|
|
}
|
|
buf += '</span> ';
|
|
|
|
// abilities
|
|
buf += '<span style="float:left;min-height:26px">';
|
|
if (pokemon.abilities['1']) {
|
|
buf += '<span class="col twoabilitycol">';
|
|
} else {
|
|
buf += '<span class="col abilitycol">';
|
|
}
|
|
for (var i in pokemon.abilities) {
|
|
var ability = pokemon.abilities[i];
|
|
if (!ability) continue;
|
|
|
|
if (i === '1') buf += '<br />';
|
|
if (i === 'DW') ability = '</span><span class="col abilitycol"><em>'+pokemon.abilities[i]+'</em>';
|
|
buf += ability;
|
|
}
|
|
if (!pokemon.abilities['DW']) buf += '</span><span class="col abilitycol">';
|
|
buf += '</span>';
|
|
buf += '</span>';
|
|
|
|
// base stats
|
|
buf += '<span style="float:left;min-height:26px">';
|
|
buf += '<span class="col statcol"><em>HP</em><br />'+pokemon.baseStats.hp+'</span> ';
|
|
buf += '<span class="col statcol"><em>Atk</em><br />'+pokemon.baseStats.atk+'</span> ';
|
|
buf += '<span class="col statcol"><em>Def</em><br />'+pokemon.baseStats.def+'</span> ';
|
|
buf += '<span class="col statcol"><em>SpA</em><br />'+pokemon.baseStats.spa+'</span> ';
|
|
buf += '<span class="col statcol"><em>SpD</em><br />'+pokemon.baseStats.spd+'</span> ';
|
|
buf += '<span class="col statcol"><em>Spe</em><br />'+pokemon.baseStats.spe+'</span> ';
|
|
var bst = 0;
|
|
for (i in pokemon.baseStats) bst += pokemon.baseStats[i];
|
|
buf += '<span class="col bstcol"><em>BST<br />'+bst+'</em></span> ';
|
|
buf += '</span>';
|
|
|
|
buf += '</a></li>';
|
|
|
|
return buf;
|
|
};
|
|
|
|
Search.prototype.renderItemRow = function(item, matchStart, matchLength, errorMessage) {
|
|
var buf = '<li class="result"><a data-name="'+Tools.escapeHTML(item.name)+'">';
|
|
|
|
// icon
|
|
buf += '<span class="col itemiconcol">';
|
|
buf += '<span style="'+Tools.getItemIcon(item)+'"></span>';
|
|
buf += '</span> ';
|
|
|
|
// name
|
|
var name = item.name;
|
|
if (matchLength) {
|
|
name = name.substr(0, matchStart)+'<b>'+name.substr(matchStart, matchLength)+'</b>'+name.substr(matchStart+matchLength);
|
|
}
|
|
buf += '<span class="col namecol">'+name+'</span> ';
|
|
|
|
// error
|
|
if (errorMessage) {
|
|
buf += '<span class="col illegalcol"><em>'+errorMessage+'</em></span> ';
|
|
buf += '</a></li>';
|
|
return buf;
|
|
}
|
|
|
|
// desc
|
|
buf += '<span class="col itemdesccol">'+Tools.escapeHTML(item.shortDesc || item.desc)+'</span> ';
|
|
|
|
buf += '</a></li>';
|
|
|
|
return buf;
|
|
};
|
|
Search.prototype.renderAbilityRow = function(ability, matchStart, matchLength, errorMessage) {
|
|
var buf = '<li class="result"><a data-name="'+Tools.escapeHTML(ability.name)+'">';
|
|
|
|
// name
|
|
var name = ability.name;
|
|
if (matchLength) {
|
|
name = name.substr(0, matchStart)+'<b>'+name.substr(matchStart, matchLength)+'</b>'+name.substr(matchStart+matchLength);
|
|
}
|
|
buf += '<span class="col namecol">'+name+'</span> ';
|
|
|
|
// error
|
|
if (errorMessage) {
|
|
buf += '<span class="col illegalcol"><em>'+errorMessage+'</em></span> ';
|
|
buf += '</a></li>';
|
|
return buf;
|
|
}
|
|
|
|
buf += '<span class="col abilitydesccol">'+Tools.escapeHTML(ability.shortDesc || ability.desc)+'</span> ';
|
|
|
|
buf += '</a></li>';
|
|
|
|
return buf;
|
|
};
|
|
Search.prototype.renderMoveRow = function(move, matchStart, matchLength, errorMessage) {
|
|
var buf = '<li class="result"><a data-name="'+Tools.escapeHTML(move.name)+'">';
|
|
|
|
// name
|
|
var name = move.name;
|
|
var tagStart = (name.substr(0, 12) === 'Hidden Power' ? 12 : 0);
|
|
if (tagStart) name = name.substr(0, tagStart);
|
|
if (matchLength) {
|
|
name = name.substr(0, matchStart)+'<b>'+name.substr(matchStart, matchLength)+'</b>'+name.substr(matchStart+matchLength);
|
|
}
|
|
if (tagStart) {
|
|
if (matchLength && matchStart+matchLength > tagStart) {
|
|
if (matchStart < tagStart) {
|
|
matchLength -= tagStart - matchStart;
|
|
matchStart = tagStart;
|
|
}
|
|
name += '<small>'+move.name.substr(tagStart, matchStart-tagStart)+'<b>'+move.name.substr(matchStart, matchLength)+'</b>'+move.name.substr(matchStart+matchLength)+'</small>';
|
|
} else {
|
|
name += '<small>'+move.name.substr(tagStart)+'</small>';
|
|
}
|
|
}
|
|
buf += '<span class="col movenamecol">'+name+'</span> ';
|
|
|
|
// error
|
|
if (errorMessage) {
|
|
buf += '<span class="col illegalcol"><em>'+errorMessage+'</em></span> ';
|
|
buf += '</a></li>';
|
|
return buf;
|
|
}
|
|
|
|
// type
|
|
buf += '<span class="col typecol">';
|
|
buf += Tools.getTypeIcon(move.type);
|
|
buf += '<img src="' + Tools.resourcePrefix + 'sprites/categories/'+move.category+'.png" alt="'+move.category+'" height="14" width="32" />';
|
|
buf += '</span> ';
|
|
|
|
// power, accuracy
|
|
buf += '<span class="col labelcol">'+(move.category!=='Status'?('<em>Power</em><br />'+(move.basePower||'—')):'')+'</span> ';
|
|
buf += '<span class="col widelabelcol"><em>Accuracy</em><br />'+(move.accuracy && move.accuracy!==true?move.accuracy+'%':'—')+'</span> ';
|
|
|
|
// desc
|
|
buf += '<span class="col movedesccol">'+Tools.escapeHTML(move.shortDesc || move.desc)+'</span> ';
|
|
|
|
buf += '</a></li>';
|
|
|
|
return buf;
|
|
};
|
|
|
|
exports.BattleSearch = Search;
|
|
|
|
})(window, jQuery);
|