Skip to content

Commit

Permalink
Update PVP filtering & Add Little Cup filtering support (#400)
Browse files Browse the repository at this point in the history
* Update pvp filtering and add little cup filtering support

* Use maxRank value for each league

* fix typos

* update help text

* Enable level 50 cap stats by default for pvp

* update pvp league icons and add little cup icon

* Add missing raid egg icons

* Fix pokemon glow
  • Loading branch information
versx authored Nov 2, 2023
1 parent 2c7fe66 commit 5fe70f3
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 62 deletions.
24 changes: 19 additions & 5 deletions src/configs/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,30 @@
"maxZoom": 18,
"pvp": {
"useName": true,
"maxRank": 100,
"onlyShopTop5": false,
"minCpGreat": 1400,
"minCpUltra": 2400,
"megaStats": true,
"experimentalStats": false,
"l40stats": true,
"l41stats": false,
"l50stats": false,
"l51stats": false
"l50stats": true,
"l51stats": false,
"limits": {
"little": {
"minCp": 400,
"maxCp": 500,
"maxRank": 100
},
"great": {
"minCp": 1400,
"maxCp": 1500,
"maxRank": 100
},
"ultra": {
"minCp": 2350,
"maxCp": 2500,
"maxRank": 100
}
}
},
"devicePathColor": "red",
"nestPolygons": true,
Expand Down
35 changes: 18 additions & 17 deletions src/data/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,9 @@ const getPokemon = async (minLat, maxLat, minLon, maxLon, showPVP, showIV, updat
}
}
if (showPVP && interestedLevelCaps.length > 0) {
// TODO: Filter pvp rankings
/*
const { minCpGreat, minCpUltra } = config.map.pvp;
const filterLeagueStats = (result, target, minCp) => {
const filterLeagueStats = (league, result, target, minCp) => {
let last;
for (const entry of JSON.parse(result)) {
for (const entry of result) {
if (minCp && entry.cp < minCp || entry.cap !== undefined && (entry.capped
? interestedLevelCaps[interestedLevelCaps.length - 1] < entry.cap
: !interestedLevelCaps.includes(entry.cap))) {
Expand All @@ -177,18 +174,20 @@ const getPokemon = async (minLat, maxLat, minLon, maxLon, showPVP, showIV, updat
last.capped = true;
}
} else {
target.push(entry);
target[league].push(entry);
last = entry;
}
}
};
if (result.pvp_rankings_great_league) {
filterLeagueStats(result.pvp_rankings_great_league, filtered.pvp_rankings_great_league = [], minCpGreat);
}
if (result.pvp_rankings_ultra_league) {
filterLeagueStats(result.pvp_rankings_ultra_league, filtered.pvp_rankings_ultra_league = [], minCpUltra);
if (result.pvp && result.atk_iv) {
const pvpRankings = JSON.parse(result.pvp);
const keys = Object.keys(pvpRankings);
for (const league of keys) {
const rankings = pvpRankings[league];
const limits = config.map.pvp.limits[league];
filterLeagueStats(league, rankings, filtered.pvp = { [league]: [] }, limits.minCp);
}
}
*/
}
let pokemonFilter = result.form === 0 ? pokemonLookup[result.pokemon_id] : formLookup[result.form];
if (pokemonFilter === undefined) {
Expand Down Expand Up @@ -1413,7 +1412,7 @@ const getPolygon = (s2cellId) => {
// need to keep consistency with client-side implementation checkIVFilterValid
const jsifyIvFilter = (filter) => {
const input = filter.toUpperCase();
let tokenizer = /\s*([()|&!,]|([ADSL]?|CP|[GU]L)\s*([0-9]+(?:\.[0-9]*)?)(?:\s*-\s*([0-9]+(?:\.[0-9]*)?))?)/g;
let tokenizer = /\s*([()|&!,]|([ADSL]?|CP|[GU]L|LC)\s*([0-9]+(?:\.[0-9]*)?)(?:\s*-\s*([0-9]+(?:\.[0-9]*)?))?)/g;
let result = '';
let expectClause = true; // expect a clause or '('
let stack = 0;
Expand All @@ -1433,15 +1432,17 @@ const jsifyIvFilter = (filter) => {
case 'S': column = 'sta_iv'; break;
case 'L': column = 'level'; break;
case 'CP': column = 'cp'; break;
case 'GL': column = 'pvp_rankings_great_league'; break;
case 'UL': column = 'pvp_rankings_ultra_league'; break;
case 'LC': column = 'little'; break;
case 'GL': column = 'great'; break;
case 'UL': column = 'ultra'; break;
}
let upper = lower;
if (match[4] !== undefined) {
upper = parseFloat(match[4]);
}
if (column.endsWith('_league')) {
result += `((pokemon['${column}'] || []).some(x => x.rank >= ${lower} && x.rank <= ${upper}))`;
const leagues = Object.keys(config.map.pvp.limits);
if (leagues.includes(column)) {
result += `(pokemon.pvp && pokemon.pvp['${column}'] && (pokemon.pvp['${column}'] || []).some(x => x.rank >= ${lower} && x.rank <= ${upper}))`;
} else {
result += `(pokemon['${column}'] !== null && pokemon['${column}'] >= ${lower} && pokemon['${column}'] <= ${upper})`;
}
Expand Down
4 changes: 2 additions & 2 deletions src/views/index.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@
{{stats}}: <kbd>A0-1 & D14 & S15</kbd> - {{stats_result}}<br>
{{popup_cp}}: <kbd>CP2000-3000</kbd> - {{cp_result}}<br>
{{not}}: <kbd>!0-100</kbd> - {{not_result}}<br>
{{pvp}}: <kbd>GL1-3 | UL1-3</kbd> - {{pvp_result}}<br><br>
{{pvp}}: <kbd>LC1-3 | GL1-3 | UL1-3</kbd> - {{pvp_result}}<br><br>
</p>
</div>

Expand All @@ -387,7 +387,7 @@
<div class="help-title"><b>{{advanced}}</b></div>
<div class="help-description">
<p>
{{example}}: <kbd>(A0-1 & D15 & S15 & (CP1400-1500 | CP2400-2500)) | L34-35,90-100 | GL1-3,UL1-3</kbd><br>
{{example}}: <kbd>(A0-1 & D15 & S15 & (CP1400-1500 | CP2400-2500)) | L34-35,90-100 | LC1-3,GL1-3,UL1-3</kbd><br>
{{advanced_result}}
</p>
</div>
Expand Down
Binary file added static/img/egg/7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/egg/8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified static/img/misc/great.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/misc/little.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/misc/master.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified static/img/misc/ultra.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 41 additions & 36 deletions static/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2725,6 +2725,7 @@ function loadScanAreaPolygons () {
// MARK: - Filters

function getPokemonIndex (pokemon) {
const pvpLimits = configPvp.limits;
const id = pokemon.form === 0 ? pokemon.pokemon_id : `${pokemon.pokemon_id}-${pokemon.form}`;
if (pokemonFilter[id] === undefined) {
// TODO: console.log('Pokemon index undefined:', id);
Expand All @@ -2734,18 +2735,18 @@ function getPokemonIndex (pokemon) {
if (pokemon.atk_iv === 15 && pokemon.def_iv === 15 && pokemon.sta_iv === 15) {
return 9;
}
if (pokemon.pvp_rankings_great_league !== null && pokemon.pvp_rankings_ultra_league !== null) {
if (pokemon.pvp && pokemon.pvp !== null) {
let bestRank = 4;
$.each(pokemon.pvp_rankings_great_league, function (index, ranking) {
if (ranking.rank !== null && ranking.rank < bestRank && ranking.rank <= configPvp.maxRank && ranking.cp >= configPvp.minCpGreat && ranking.cp <= 1500) {
bestRank = ranking.rank;
}
});
$.each(pokemon.pvp_rankings_ultra_league, function (index, ranking) {
if (ranking.rank !== null && ranking.rank < bestRank && ranking.rank <= configPvp.maxRank && ranking.cp >= configPvp.minCpUltra && ranking.cp <= 2500) {
bestRank = ranking.rank;
}
});
const keys = Object.keys(pokemon.pvp);
for (const key of keys) {
const rankings = pokemon.pvp[key];
$.each(rankings, function (index, ranking) {
const limits = pvpLimits[key];
if (ranking.rank !== null && ranking.rank < bestRank && ranking.rank <= limits.maxRank && ranking.cp >= limits.minCp && ranking.cp <= limits.maxCp) {
bestRank = ranking.rank;
}
});
}
if (bestRank === 1) {
return 7;
} else if (bestRank === 2) {
Expand Down Expand Up @@ -2987,24 +2988,23 @@ function updateMapTimers () {
});
}

const hasRelevantLeagueStats = (leagueStats) => {
const maxRank = configPvp.maxRank;
const hasRelevantLeagueStats = (league, leagueStats) => {
const maxRank = configPvp.limits[league].maxRank;
return leagueStats && leagueStats.some(entry => entry.rank <= maxRank);
}

const getPokemonBestRank = (greatLeague, ultraLeague) => {
if ((greatLeague !== null) || (ultraLeague !== null)) {
const getPokemonBestRank = (pvp) => {
if (pvp && pvp !== null) {
let bestRank = 4;
$.each(greatLeague, function (index, ranking) {
if (ranking.rank !== null && ranking.rank < bestRank) {
bestRank = ranking.rank;
}
});
$.each(ultraLeague, function (index, ranking) {
if (ranking.rank !== null && ranking.rank < bestRank) {
bestRank = ranking.rank;
}
});
const keys = Object.keys(pvp);
for (const key of keys) {
const rankings = pvp[key];
$.each(rankings, function (index, ranking) {
if (ranking.rank !== null && ranking.rank < bestRank) {
bestRank = ranking.rank;
}
});
}
if (bestRank <= 3) {
return bestRank;
}
Expand All @@ -3013,7 +3013,6 @@ const getPokemonBestRank = (greatLeague, ultraLeague) => {
}

const getPvpRanks = (league, pokemon) => {
const getLeague = `pvp_rankings_${league}_league`
let content = `
<tr>
<td><img src="/img/misc/${league}.png" height="20"></td>
Expand All @@ -3022,8 +3021,9 @@ const getPvpRanks = (league, pokemon) => {
<td><b>${i18n('popup_lvl')}</b></td>
${showPvpPercent ? '<td><b>%</td>' : ''}
</tr>`;
let maxRankingToUse = showOnlyRank5Pvp ? 5 : configPvp.maxRank;
for (const [i, ranking] of Object.entries(pokemon[getLeague])) {
let maxRankingToUse = showOnlyRank5Pvp ? 5 : configPvp.limits[league].maxRank;
const pvpRankings = pokemon.pvp[league];
for (const ranking of pvpRankings) {
if (ranking.rank <= maxRankingToUse) {
content += `<tr>`
let pokemonName = ``;
Expand Down Expand Up @@ -3070,8 +3070,8 @@ const getPvpRanks = (league, pokemon) => {
if (showPvpPercent && ranking.percentage !== null) {
content += `<td>${Math.floor(ranking.percentage*100)}</td>`;
}
content += `</tr>`;
}
content += `</tr>`;
}
return content.includes('#') ? content : '';
}
Expand Down Expand Up @@ -3234,11 +3234,16 @@ const getPokemonPopupContent = (pokemon) => {
let content = `
<div class="pokemon-pvp-stats">
<table class="table-pvp">`;
if (pokemon.pvp_rankings_great_league !== undefined && pokemon.pvp_rankings_great_league !== null && hasRelevantLeagueStats(pokemon.pvp_rankings_great_league, true)) {
content += getPvpRanks('great', pokemon);
}
if (pokemon.pvp_rankings_ultra_league !== undefined && pokemon.pvp_rankings_ultra_league !== null && hasRelevantLeagueStats(pokemon.pvp_rankings_ultra_league, false)) {
content += getPvpRanks('ultra', pokemon);
if (pokemon.pvp) {
const keys = Object.keys(pokemon.pvp);
for (const league of keys) {
if (pokemon.pvp && pokemon.pvp[league] !== undefined && pokemon.pvp[league] !== null) {
const rankings = pokemon.pvp[league];
if (hasRelevantLeagueStats(league, rankings)) {
content += getPvpRanks(league, pokemon);
}
}
}
}
content += `</table>`
if (content.includes('*')) {
Expand Down Expand Up @@ -4303,7 +4308,7 @@ function getPokemonMarkerIcon (pokemon, ts) {
const size = getIconSize('pokemon', pokemon.pokemon_id, pokemon.form, pokemon.weight);
const pokemonIdString = getPokemonIcon(pokemon.pokemon_id, pokemon.form, 0, pokemon.gender, pokemon.costume);
const iv = calcIV(pokemon.atk_iv, pokemon.def_iv, pokemon.sta_iv);
const bestRank = getPokemonBestRank(pokemon.pvp_rankings_great_league, pokemon.pvp_rankings_ultra_league);
const bestRank = getPokemonBestRank(pokemon.pvp);
const bestRankIcon = bestRank === 3
? 'third'
: bestRank === 2
Expand Down Expand Up @@ -6070,7 +6075,7 @@ function manageGlobalStardustCountPopup (id, filter) {

function checkIVFilterValid (filter) {
const input = filter.toUpperCase();
let tokenizer = /\s*([()|&!,]|([ADSL]?|CP|[GU]L)\s*([0-9]+(?:\.[0-9]*)?)(?:\s*-\s*([0-9]+(?:\.[0-9]*)?))?)/g;
let tokenizer = /\s*([()|&!,]|([ADSL]?|CP|[GU]L|LC)\s*([0-9]+(?:\.[0-9]*)?)(?:\s*-\s*([0-9]+(?:\.[0-9]*)?))?)/g;
let expectClause = true;
let stack = 0;
let lastIndex = 0;
Expand Down
2 changes: 1 addition & 1 deletion static/locales/_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@
"and_explanation": "AND operator, for chaining conditions together",
"and_result": "All Pokemon with IVs between 80-100, are L25-30, AND have stats of 15/10/10",
"advanced": "Advanced",
"advanced_result": "Returns all Pokemon that have either CP1400-1500 OR CP2400-2500 AND have 0-1 Attack, 15 Defense, 15 Stamina, OR level 34-35 OR 90-100% IVs OR PVP Great or Ultra league rank between 1-3.",
"advanced_result": "Returns all Pokemon that have either CP1400-1500 OR CP2400-2500 AND have 0-1 Attack, 15 Defense, 15 Stamina, OR level 34-35 OR 90-100% IVs OR PVP Litte, Great, or Ultra league rank between 1-3.",
"popup_area": "Area",
"popup_size": "Size"
}
2 changes: 1 addition & 1 deletion static/locales/_pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@
"and_explanation": "Operator ORAZ do łączenia warunków ze sobą",
"and_result": "Wszystkie Pokémony z: 80-100% IV ORAZ poziomem pomiędzy 25 a 30 ORAZ statystykami 15/10/10",
"advanced": "Zaawansowane",
"advanced_result": "Zwraca wszystkie Pokémony które spełniają warunek: (Od 0 do 1 ataku ORAZ 15 obrony ORAZ 15 staminy ORAZ (CP pomiędzy 1400 a 1500 ALBO CP pomiędzy 2400 a 2500)) ALBO (Poziomem pomiędzy 34 a 35 ALBO 90-100% IV) ALBO (Pozycją pomiędzy 1 a 3 Great lub Ultra ligi).",
"advanced_result": "Zwraca wszystkie Pokémony które spełniają warunek: (Od 0 do 1 ataku ORAZ 15 obrony ORAZ 15 staminy ORAZ (CP pomiędzy 1400 a 1500 ALBO CP pomiędzy 2400 a 2500)) ALBO (Poziomem pomiędzy 34 a 35 ALBO 90-100% IV) ALBO (Pozycją pomiędzy 1 a 3 Little, Great, lub Ultra ligi).",
"popup_area": "Obszar",
"popup_size": "Powierzchnia"
}

0 comments on commit 5fe70f3

Please sign in to comment.