diff --git a/src/configs/default.json b/src/configs/default.json
index 711827ed..60a41a0c 100644
--- a/src/configs/default.json
+++ b/src/configs/default.json
@@ -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,
diff --git a/src/data/map.js b/src/data/map.js
index 5b48180d..3d447a43 100644
--- a/src/data/map.js
+++ b/src/data/map.js
@@ -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))) {
@@ -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) {
@@ -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;
@@ -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})`;
}
diff --git a/src/views/index.mustache b/src/views/index.mustache
index 9ae702cc..050bd8a0 100644
--- a/src/views/index.mustache
+++ b/src/views/index.mustache
@@ -367,7 +367,7 @@
{{stats}}: A0-1 & D14 & S15 - {{stats_result}}
{{popup_cp}}: CP2000-3000 - {{cp_result}}
{{not}}: !0-100 - {{not_result}}
- {{pvp}}: GL1-3 | UL1-3 - {{pvp_result}}
+ {{pvp}}: LC1-3 | GL1-3 | UL1-3 - {{pvp_result}}
@@ -387,7 +387,7 @@
{{advanced}}
- {{example}}: (A0-1 & D15 & S15 & (CP1400-1500 | CP2400-2500)) | L34-35,90-100 | GL1-3,UL1-3
+ {{example}}: (A0-1 & D15 & S15 & (CP1400-1500 | CP2400-2500)) | L34-35,90-100 | LC1-3,GL1-3,UL1-3
{{advanced_result}}
diff --git a/static/img/egg/7.png b/static/img/egg/7.png
new file mode 100644
index 00000000..6bb645ad
Binary files /dev/null and b/static/img/egg/7.png differ
diff --git a/static/img/egg/8.png b/static/img/egg/8.png
new file mode 100644
index 00000000..c83f0fb2
Binary files /dev/null and b/static/img/egg/8.png differ
diff --git a/static/img/misc/great.png b/static/img/misc/great.png
index 1a0b9f66..a430c3c4 100644
Binary files a/static/img/misc/great.png and b/static/img/misc/great.png differ
diff --git a/static/img/misc/little.png b/static/img/misc/little.png
new file mode 100644
index 00000000..6f8520ca
Binary files /dev/null and b/static/img/misc/little.png differ
diff --git a/static/img/misc/master.png b/static/img/misc/master.png
new file mode 100644
index 00000000..a4c7c7f7
Binary files /dev/null and b/static/img/misc/master.png differ
diff --git a/static/img/misc/ultra.png b/static/img/misc/ultra.png
index 764c81fc..b94702ae 100644
Binary files a/static/img/misc/ultra.png and b/static/img/misc/ultra.png differ
diff --git a/static/js/index.js b/static/js/index.js
index f124c134..a4488b69 100644
--- a/static/js/index.js
+++ b/static/js/index.js
@@ -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);
@@ -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) {
@@ -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;
}
@@ -3013,7 +3013,6 @@ const getPokemonBestRank = (greatLeague, ultraLeague) => {
}
const getPvpRanks = (league, pokemon) => {
- const getLeague = `pvp_rankings_${league}_league`
let content = `
 |
@@ -3022,8 +3021,9 @@ const getPvpRanks = (league, pokemon) => {
${i18n('popup_lvl')} |
${showPvpPercent ? '% | ' : ''}
`;
- 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 += ``
let pokemonName = ``;
@@ -3070,8 +3070,8 @@ const getPvpRanks = (league, pokemon) => {
if (showPvpPercent && ranking.percentage !== null) {
content += `| ${Math.floor(ranking.percentage*100)} | `;
}
+ content += `
`;
}
- content += ``;
}
return content.includes('#') ? content : '';
}
@@ -3234,11 +3234,16 @@ const getPokemonPopupContent = (pokemon) => {
let content = `
`;
- 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 += `
`
if (content.includes('*')) {
@@ -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
@@ -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;
diff --git a/static/locales/_en.json b/static/locales/_en.json
index 09cbd5fb..0ec472cb 100644
--- a/static/locales/_en.json
+++ b/static/locales/_en.json
@@ -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"
}
diff --git a/static/locales/_pl.json b/static/locales/_pl.json
index b758da8e..22c37a16 100644
--- a/static/locales/_pl.json
+++ b/static/locales/_pl.json
@@ -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"
}