From 2ae2c577d8d6613f21ced7bdfbae5eeb43ba06bc Mon Sep 17 00:00:00 2001 From: Sean Davis Date: Sat, 16 Nov 2024 01:25:11 +0000 Subject: [PATCH 1/4] Update requirements to never be completed, generate weather --- bundle.js | 4 ++-- scripts/game.js | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/bundle.js b/bundle.js index bba8fcb0..59b5c632 100644 --- a/bundle.js +++ b/bundle.js @@ -77325,8 +77325,8 @@ themes.options.sort((a, b) => (a.text).localeCompare(b.text)); // Suppress game notifications Notifier.notify = () => {}; -// Ensure weather never satisfies requirements so they are always shown -Weather.currentWeather = () => -1; +// Ensure requirements are never satisfied so they are always shown +Requirement.prototype.isCompleted = () => false; // Not sure why but this was causing an error on load after the v0.10.22 update SortModules = () => {}; diff --git a/scripts/game.js b/scripts/game.js index e26e8b30..628efe96 100644 --- a/scripts/game.js +++ b/scripts/game.js @@ -22,8 +22,8 @@ themes.options.sort((a, b) => (a.text).localeCompare(b.text)); // Suppress game notifications Notifier.notify = () => {}; -// Ensure weather never satisfies requirements so they are always shown -Weather.currentWeather = () => -1; +// Ensure requirements are never satisfied so they are always shown +Requirement.prototype.isCompleted = () => false; // Not sure why but this was causing an error on load after the v0.10.22 update SortModules = () => {}; @@ -78,6 +78,7 @@ GemDeals.generateDeals(); ShardDeal.generateDeals(); GenericDeal.generateDeals(); SafariPokemonList.generateSafariLists(); // This needs to be after anything that generates shopmon due to Friend Safari calcs +Weather.generateWeather(now); // Farm Simulator App.game.farming.plotList.forEach((p) => p.isUnlocked = true); // All plots unlocked From 9b687c8f60421c409ef53931724f31f16eb46625 Mon Sep 17 00:00:00 2001 From: Sean Davis Date: Sat, 16 Nov 2024 01:25:30 +0000 Subject: [PATCH 2/4] Improve gem pages and add new type catch quest pages --- bundle.js | 165 ++++++++++++++++++++++++++++-- pages/Catch Type Quests/main.html | 75 ++++++++++++++ pages/Gems/main.html | 57 +++-------- scripts/main.js | 1 + scripts/pages/dungeonTokens.js | 2 +- scripts/pages/gems.js | 138 +++++++++++++++++++++++++ scripts/typeahead.js | 5 + 7 files changed, 392 insertions(+), 51 deletions(-) create mode 100644 pages/Catch Type Quests/main.html create mode 100644 scripts/pages/gems.js diff --git a/bundle.js b/bundle.js index 59b5c632..7dbc0588 100644 --- a/bundle.js +++ b/bundle.js @@ -77381,6 +77381,7 @@ GemDeals.generateDeals(); ShardDeal.generateDeals(); GenericDeal.generateDeals(); SafariPokemonList.generateSafariLists(); // This needs to be after anything that generates shopmon due to Friend Safari calcs +Weather.generateWeather(now); // Farm Simulator App.game.farming.plotList.forEach((p) => p.isUnlocked = true); // All plots unlocked @@ -77757,11 +77758,12 @@ window.Wiki = { shopMon: require('./pages/shopMon'), dungeonTokens: require('./pages/dungeonTokens'), oakItems: require('./pages/oakItems'), + gems: require('./pages/gems'), getDealChains: require('./pages/dealChains').getDealChains, ...require('./navigation'), } -},{"../pokeclicker/package.json":502,"./components":503,"./datatables":504,"./discord":505,"./game":506,"./gameHelper":507,"./markdown-renderer":514,"./navigation":515,"./notifications":516,"./pages/dealChains":517,"./pages/dreamOrbs":518,"./pages/dungeonTokens":519,"./pages/dungeons":520,"./pages/farm":521,"./pages/farmSimulator":522,"./pages/items":523,"./pages/oakItems":524,"./pages/pokemon":525,"./pages/shopMon":526,"./typeahead":528}],509:[function(require,module,exports){ +},{"../pokeclicker/package.json":502,"./components":503,"./datatables":504,"./discord":505,"./game":506,"./gameHelper":507,"./markdown-renderer":514,"./navigation":515,"./notifications":516,"./pages/dealChains":517,"./pages/dreamOrbs":518,"./pages/dungeonTokens":519,"./pages/dungeons":520,"./pages/farm":521,"./pages/farmSimulator":522,"./pages/gems":523,"./pages/items":524,"./pages/oakItems":525,"./pages/pokemon":526,"./pages/shopMon":527,"./typeahead":529}],509:[function(require,module,exports){ const { md } = require('./markdown-renderer'); const getContent = (editor) => editor.value().split('\n').map(l => l.trimEnd()).join('\n'); @@ -78251,7 +78253,7 @@ module.exports = { gotoPageClick, }; -},{"./datatables":504,"./markdown-editor":509,"./markdown-renderer":514,"./redirections":527}],516:[function(require,module,exports){ +},{"./datatables":504,"./markdown-editor":509,"./markdown-renderer":514,"./redirections":528}],516:[function(require,module,exports){ const alert = (message, type = 'primary', timeout = 5e3) => { const wrapper = document.createElement('div'); wrapper.classList.add('alert', `alert-${type}`, 'alert-dismissible', 'fade', 'show'); @@ -78523,7 +78525,7 @@ const highestRoute = (region, weather) => { const GBMB = (DT* (catchChanceAV+.15))/(2); const UB = (DT* (catchChanceAV+.1))/(1.75) const UBMB = (DT* (catchChanceAV+.2))/(1.75); - routeArr.push( [Routes.getRoute(region,route.number).routeName, DT.toLocaleString(), +(PB). toFixed(2), +(PBMB). toFixed(2), +(GB). toFixed(2), +(GBMB). toFixed(2), +(UB). toFixed(2), +(UBMB). toFixed(2)] ); + routeArr.push([Routes.getRoute(region,route.number).routeName, DT.toLocaleString(), +(PB).toFixed(2), +(PBMB).toFixed(2), +(GB).toFixed(2), +(GBMB).toFixed(2), +(UB).toFixed(2), +(UBMB).toFixed(2)]) }) var highestPB = routeArr.reduce((max, dt) => { @@ -79296,6 +79298,146 @@ module.exports = { } },{}],523:[function(require,module,exports){ +// routeAvgHp copied from PokemonFactory.generateWildPokemon +const routeAvgHp = (region, route) => { + const poke = [...new Set(Object.values(Routes.getRoute(region, route).pokemon).flat().map(p => p.pokemon ?? p).flat())]; + const total = poke.map(p => pokemonMap[p].base.hitpoints).reduce((s, a) => s + a, 0); + return total / poke.length; +}; + +const getStandardEncounters = (route) => { + return Object.values(route.pokemon).flat().filter((p) => typeof p === 'string'); +} + +const maxRouteHp = (regionRoutes, routeName) => { + const route = regionRoutes.find((r) => r.routeName === routeName); + const allMons = getStandardEncounters(route); + const maxHpStat = Math.max(...allMons.map((p) => PokemonHelper.getPokemonByName(p).hitpoints)); + return Math.round(PokemonFactory.routeHealth(route.number, route.region) * (0.9 + (maxHpStat / routeAvgHp(route.region, route.number)) / 10)); +} + +const maxGymHp = (gymName) => { + return Math.max(...GymList[gymName].pokemons.map((p) => p.maxHealth)); +} + +const gemsPerPokemon = (pokemonName, gemType) => { + const pokemon = PokemonHelper.getPokemonByName(pokemonName); + const targetType = PokemonType[gemType]; + if (pokemon.type2 === PokemonType.None) { + return pokemon.type1 === targetType ? 2 : 0; + } else { + return (pokemon.type1 === targetType || pokemon.type2 === targetType) ? 1 : 0; + } +} + +const gemsPerGymEncounter = (gymName, gemType) => { + const gym = GymList[gymName]; + const totalMons = gym.pokemons.length; + const totalGemsOfType = gym.pokemons.reduce((acc, p) => acc + 5 * gemsPerPokemon(p.name, gemType), 0); + return totalGemsOfType / totalMons; +} + +const gemsPerRouteEncounter = (route, gemType) => { + const allMons = getStandardEncounters(route); + const totalMons = allMons.length; + const totalGemsOfType = allMons.reduce((acc, p) => acc + gemsPerPokemon(p, gemType), 0); + return totalGemsOfType / totalMons; +} + +const bestGemsPerRegion = (region, gemType) => { + const regionRoutes = Routes.regionRoutes.filter((r) => r.region == region); + const allRouteGems = regionRoutes.map((route) => ({ + battleType: "Route", + name: route.routeName, + gemsPerEncounter: gemsPerRouteEncounter(route, gemType), + })); + + const regionGyms = GameConstants.RegionGyms[region].filter((g) => !g.includes('Trial')); + const allGymGems = regionGyms.map((gym) => ({ + battleType: "Gym", + name: gym, + gemsPerEncounter: gemsPerGymEncounter(gym, gemType), + })); + + return allRouteGems.concat(allGymGems) + .filter((battle) => battle.gemsPerEncounter > 0) + .sort((a, b) => b.gemsPerEncounter - a.gemsPerEncounter) + .splice(0, 2) + .map((gemData) => { + gemData.maxHealth = gemData.battleType === "Route" ? maxRouteHp(regionRoutes, gemData.name) : maxGymHp(gemData.name); + return gemData; + }); +} + +const bestCaptureRoutesPerRegion = (region, type) => { + const regionRoutes = Routes.regionRoutes.filter((r) => r.region == region); + const currentWeather = Weather.regionalWeather[region](); + const today = GameHelper.today().getDay(); + const allRegionRoutesTypeCatchChance = regionRoutes.map((route) => { + const normalEncounters = getStandardEncounters(route); + const specialEncounters = route.pokemon.special.flatMap((special) => { + if (special.req instanceof OneFromManyRequirement || special.req instanceof SpecialEventRandomRequirement) { + // OneFromMany is Santa Jynx only + return []; + } + if (special.req instanceof WeatherRequirement) { + return special.req.weather.includes(currentWeather) ? special.pokemon : []; + } + if (special.req instanceof DayOfWeekRequirement) { + return special.req.DayOfWeekNum === today ? special.pokemon : []; + } + if (special.req instanceof MultiRequirement) { + // This might not cover all permutations of requirements + if (special.req.requirements.find((req) => req instanceof SpecialEventRequirement)) return []; + const weatherReq = special.req.requirements.find((req) => req instanceof WeatherRequirement); + if (weatherReq) return weatherReq.weather.includes(currentWeather) ? special.pokemon : []; + const dayReq = special.req.requirements.find((req) => req instanceof DayOfWeekRequirement); + if (dayReq) return dayReq.DayOfWeekNum === today ? special.pokemon : []; + } + return special.pokemon + }); + + const allEncounters = normalEncounters.concat(specialEncounters); + const typeCatchChances = allEncounters.map((p) => { + const pokemon = PokemonHelper.getPokemonByName(p); + return (pokemon.type1 === type || pokemon.type2 === type) ? PokemonFactory.catchRateHelper(pokemon.catchRate, true) : 0; + }); + return { + route: route, + catchChances: typeCatchChances, + }; + }); + + const allRoutesWithType = allRegionRoutesTypeCatchChance.filter((route) => route.catchChances.some((chance) => chance > 0)); + const allRoutesWithCatchBonuses = allRoutesWithType.map((route) => { + const encounters = route.catchChances.length; + return { + route: route.route, + pokeball: route.catchChances.reduce((a, b) => a + b, 0) / encounters, + ultraball: route.catchChances.map((chance) => chance > 0 ? chance + 10 : chance).reduce((a, b) => a + b, 0) / encounters, + ultraballMagicBall: route.catchChances.map((chance) => chance > 0 ? chance + 20 : chance).reduce((a, b) => a + b, 0) / encounters, + } + }); + return allRoutesWithCatchBonuses + .sort((a, b) => b.ultraballMagicBall - a.ultraballMagicBall) + .splice(0, 2) + .map((route) => { + return { + ...route, + weather: currentWeather, + today: today, + maxHealth: maxRouteHp(regionRoutes, route.route.routeName), + } + }); +} + + +module.exports = { + bestGemsPerRegion, + bestCaptureRoutesPerRegion, +} + +},{}],524:[function(require,module,exports){ const getItemName = (itemType, itemId) => { switch (itemType) { case ItemType.item: @@ -79387,7 +79529,7 @@ module.exports = { getItemCategoryAndPageFromObject, }; -},{}],524:[function(require,module,exports){ +},{}],525:[function(require,module,exports){ const getOakItemBonus = (oakItem, level) => { const bonus = oakItem.bonusList[level]; switch (oakItem.name) { @@ -79461,7 +79603,7 @@ module.exports = { getOakItemBonus, getOakItemUpgradeReq, }; -},{}],525:[function(require,module,exports){ +},{}],526:[function(require,module,exports){ const getBreedingAttackBonus = (vitaminsUsed, baseAttack) => { const attackBonusPercent = (GameConstants.BREEDING_ATTACK_BONUS + vitaminsUsed[GameConstants.VitaminType.Calcium]) / 100; @@ -79551,7 +79693,7 @@ module.exports = { battleCafeToHumanReadableString, } -},{}],526:[function(require,module,exports){ +},{}],527:[function(require,module,exports){ function getShopItemsByCurrencyAndFilter(currency, itemFilter) { var towns = Object.values(TownList).filter(t => t.region <= GameConstants.MAX_AVAILABLE_REGION); var filteredTowns = []; @@ -79597,7 +79739,7 @@ module.exports = { getShopItems, getUniqueItems, }; -},{}],527:[function(require,module,exports){ +},{}],528:[function(require,module,exports){ const redirections = [ ({type, name}) => { if (type === 'Pokemon') { @@ -79649,7 +79791,7 @@ module.exports = { redirections }; -},{}],528:[function(require,module,exports){ +},{}],529:[function(require,module,exports){ const { gotoPage } = require('./navigation'); const { getAvailablePokemon } = require('./pages/pokemon'); @@ -79712,6 +79854,11 @@ const searchOptions = [ type: 'Gems', page: t, })), + ...GameHelper.enumStrings(PokemonType).filter(t => t != 'None').map(t => ({ + display: `${t} Catch Type Quests`, + type: 'Catch Type Quests', + page: t, + })), // Berries { display: 'Berries', @@ -80119,4 +80266,4 @@ module.exports = { searchOptions, }; -},{"./navigation":515,"./pages/pokemon":525}]},{},[508]); +},{"./navigation":515,"./pages/pokemon":526}]},{},[508]); diff --git a/pages/Catch Type Quests/main.html b/pages/Catch Type Quests/main.html new file mode 100644 index 00000000..41be0d1d --- /dev/null +++ b/pages/Catch Type Quests/main.html @@ -0,0 +1,75 @@ +
+ +

Pokémon type not found...

+ + +
+

+

The top two locations from each Region are listed below, if they exist.

+

Current weather and day of week are taken into account for Route encounters, but other requirements (such as previously caught) are assumed to be met.

+

The number shown is the chance that any single encounter on that route will be a successful catch of the desired type, while using the equipment specified.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
RegionCurrent WeatherLocationMaximum HP + + + + + + or  + + + + + +
+ + +
+
+

Refresh if the weather in the regions above are out of sync with your game.

+
+ +
\ No newline at end of file diff --git a/pages/Gems/main.html b/pages/Gems/main.html index f01476eb..51b42c43 100644 --- a/pages/Gems/main.html +++ b/pages/Gems/main.html @@ -1,12 +1,12 @@
-

Gem type not found...

+

Gem type not found...

- -

Best locations

+

+

The top two locations from each Region are listed below, if they exist.

Pokémon that appear during certain weather or other special conditions are not included in the route calculation.

@@ -15,48 +15,23 @@

Best locations

+ + - + + - - - - - - - + + + + + +
Region Battle Type LocationMaximum HPAverage Gems Per Pokémon
Gym
Route + + +
diff --git a/scripts/main.js b/scripts/main.js index efcbc4da..4c9a328e 100644 --- a/scripts/main.js +++ b/scripts/main.js @@ -20,6 +20,7 @@ window.Wiki = { shopMon: require('./pages/shopMon'), dungeonTokens: require('./pages/dungeonTokens'), oakItems: require('./pages/oakItems'), + gems: require('./pages/gems'), getDealChains: require('./pages/dealChains').getDealChains, ...require('./navigation'), } diff --git a/scripts/pages/dungeonTokens.js b/scripts/pages/dungeonTokens.js index d974f692..573f7c47 100644 --- a/scripts/pages/dungeonTokens.js +++ b/scripts/pages/dungeonTokens.js @@ -51,7 +51,7 @@ const highestRoute = (region, weather) => { const GBMB = (DT* (catchChanceAV+.15))/(2); const UB = (DT* (catchChanceAV+.1))/(1.75) const UBMB = (DT* (catchChanceAV+.2))/(1.75); - routeArr.push( [Routes.getRoute(region,route.number).routeName, DT.toLocaleString(), +(PB). toFixed(2), +(PBMB). toFixed(2), +(GB). toFixed(2), +(GBMB). toFixed(2), +(UB). toFixed(2), +(UBMB). toFixed(2)] ); + routeArr.push([Routes.getRoute(region,route.number).routeName, DT.toLocaleString(), +(PB).toFixed(2), +(PBMB).toFixed(2), +(GB).toFixed(2), +(GBMB).toFixed(2), +(UB).toFixed(2), +(UBMB).toFixed(2)]) }) var highestPB = routeArr.reduce((max, dt) => { diff --git a/scripts/pages/gems.js b/scripts/pages/gems.js new file mode 100644 index 00000000..bfe268ac --- /dev/null +++ b/scripts/pages/gems.js @@ -0,0 +1,138 @@ +// routeAvgHp copied from PokemonFactory.generateWildPokemon +const routeAvgHp = (region, route) => { + const poke = [...new Set(Object.values(Routes.getRoute(region, route).pokemon).flat().map(p => p.pokemon ?? p).flat())]; + const total = poke.map(p => pokemonMap[p].base.hitpoints).reduce((s, a) => s + a, 0); + return total / poke.length; +}; + +const getStandardEncounters = (route) => { + return Object.values(route.pokemon).flat().filter((p) => typeof p === 'string'); +} + +const maxRouteHp = (regionRoutes, routeName) => { + const route = regionRoutes.find((r) => r.routeName === routeName); + const allMons = getStandardEncounters(route); + const maxHpStat = Math.max(...allMons.map((p) => PokemonHelper.getPokemonByName(p).hitpoints)); + return Math.round(PokemonFactory.routeHealth(route.number, route.region) * (0.9 + (maxHpStat / routeAvgHp(route.region, route.number)) / 10)); +} + +const maxGymHp = (gymName) => { + return Math.max(...GymList[gymName].pokemons.map((p) => p.maxHealth)); +} + +const gemsPerPokemon = (pokemonName, gemType) => { + const pokemon = PokemonHelper.getPokemonByName(pokemonName); + const targetType = PokemonType[gemType]; + if (pokemon.type2 === PokemonType.None) { + return pokemon.type1 === targetType ? 2 : 0; + } else { + return (pokemon.type1 === targetType || pokemon.type2 === targetType) ? 1 : 0; + } +} + +const gemsPerGymEncounter = (gymName, gemType) => { + const gym = GymList[gymName]; + const totalMons = gym.pokemons.length; + const totalGemsOfType = gym.pokemons.reduce((acc, p) => acc + 5 * gemsPerPokemon(p.name, gemType), 0); + return totalGemsOfType / totalMons; +} + +const gemsPerRouteEncounter = (route, gemType) => { + const allMons = getStandardEncounters(route); + const totalMons = allMons.length; + const totalGemsOfType = allMons.reduce((acc, p) => acc + gemsPerPokemon(p, gemType), 0); + return totalGemsOfType / totalMons; +} + +const bestGemsPerRegion = (region, gemType) => { + const regionRoutes = Routes.regionRoutes.filter((r) => r.region == region); + const allRouteGems = regionRoutes.map((route) => ({ + battleType: "Route", + name: route.routeName, + gemsPerEncounter: gemsPerRouteEncounter(route, gemType), + })); + + const regionGyms = GameConstants.RegionGyms[region].filter((g) => !g.includes('Trial')); + const allGymGems = regionGyms.map((gym) => ({ + battleType: "Gym", + name: gym, + gemsPerEncounter: gemsPerGymEncounter(gym, gemType), + })); + + return allRouteGems.concat(allGymGems) + .filter((battle) => battle.gemsPerEncounter > 0) + .sort((a, b) => b.gemsPerEncounter - a.gemsPerEncounter) + .splice(0, 2) + .map((gemData) => { + gemData.maxHealth = gemData.battleType === "Route" ? maxRouteHp(regionRoutes, gemData.name) : maxGymHp(gemData.name); + return gemData; + }); +} + +const bestCaptureRoutesPerRegion = (region, type) => { + const regionRoutes = Routes.regionRoutes.filter((r) => r.region == region); + const currentWeather = Weather.regionalWeather[region](); + const today = GameHelper.today().getDay(); + const allRegionRoutesTypeCatchChance = regionRoutes.map((route) => { + const normalEncounters = getStandardEncounters(route); + const specialEncounters = route.pokemon.special.flatMap((special) => { + if (special.req instanceof OneFromManyRequirement || special.req instanceof SpecialEventRandomRequirement) { + // OneFromMany is Santa Jynx only + return []; + } + if (special.req instanceof WeatherRequirement) { + return special.req.weather.includes(currentWeather) ? special.pokemon : []; + } + if (special.req instanceof DayOfWeekRequirement) { + return special.req.DayOfWeekNum === today ? special.pokemon : []; + } + if (special.req instanceof MultiRequirement) { + // This might not cover all permutations of requirements + if (special.req.requirements.find((req) => req instanceof SpecialEventRequirement)) return []; + const weatherReq = special.req.requirements.find((req) => req instanceof WeatherRequirement); + if (weatherReq) return weatherReq.weather.includes(currentWeather) ? special.pokemon : []; + const dayReq = special.req.requirements.find((req) => req instanceof DayOfWeekRequirement); + if (dayReq) return dayReq.DayOfWeekNum === today ? special.pokemon : []; + } + return special.pokemon + }); + + const allEncounters = normalEncounters.concat(specialEncounters); + const typeCatchChances = allEncounters.map((p) => { + const pokemon = PokemonHelper.getPokemonByName(p); + return (pokemon.type1 === type || pokemon.type2 === type) ? PokemonFactory.catchRateHelper(pokemon.catchRate, true) : 0; + }); + return { + route: route, + catchChances: typeCatchChances, + }; + }); + + const allRoutesWithType = allRegionRoutesTypeCatchChance.filter((route) => route.catchChances.some((chance) => chance > 0)); + const allRoutesWithCatchBonuses = allRoutesWithType.map((route) => { + const encounters = route.catchChances.length; + return { + route: route.route, + pokeball: route.catchChances.reduce((a, b) => a + b, 0) / encounters, + ultraball: route.catchChances.map((chance) => chance > 0 ? chance + 10 : chance).reduce((a, b) => a + b, 0) / encounters, + ultraballMagicBall: route.catchChances.map((chance) => chance > 0 ? chance + 20 : chance).reduce((a, b) => a + b, 0) / encounters, + } + }); + return allRoutesWithCatchBonuses + .sort((a, b) => b.ultraballMagicBall - a.ultraballMagicBall) + .splice(0, 2) + .map((route) => { + return { + ...route, + weather: currentWeather, + today: today, + maxHealth: maxRouteHp(regionRoutes, route.route.routeName), + } + }); +} + + +module.exports = { + bestGemsPerRegion, + bestCaptureRoutesPerRegion, +} diff --git a/scripts/typeahead.js b/scripts/typeahead.js index e82aa194..d3f6222b 100644 --- a/scripts/typeahead.js +++ b/scripts/typeahead.js @@ -60,6 +60,11 @@ const searchOptions = [ type: 'Gems', page: t, })), + ...GameHelper.enumStrings(PokemonType).filter(t => t != 'None').map(t => ({ + display: `${t} Catch Type Quests`, + type: 'Catch Type Quests', + page: t, + })), // Berries { display: 'Berries', From 344a7f98597d136768874e961681542387a3351b Mon Sep 17 00:00:00 2001 From: Sean Davis Date: Sat, 16 Nov 2024 06:24:45 +0000 Subject: [PATCH 3/4] Update type badges to match game --- styles.css | 7 +++++++ templates/pokemon-summary.html | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/styles.css b/styles.css index 1a1b2bea..91ce6e7a 100644 --- a/styles.css +++ b/styles.css @@ -450,3 +450,10 @@ td.tight { .obtain-methods .accordion-button img { padding-right: 10px; } + +.type-icon { + line-height: normal; + text-shadow: 0px 0px 1px black, 0px 0px 1px black, 0px 0px 1px black, 0px 0px 2px black, 0px 0px 2px black, 0px 0px 3px black; + text-transform: uppercase; + color: #f5f5f5; +} diff --git a/templates/pokemon-summary.html b/templates/pokemon-summary.html index 79fa0095..e10518f3 100644 --- a/templates/pokemon-summary.html +++ b/templates/pokemon-summary.html @@ -84,7 +84,7 @@ Type(s) - + From ccb0de3de741c65fef2fdd419b90ed1699ac38d4 Mon Sep 17 00:00:00 2001 From: Sean Davis Date: Sat, 16 Nov 2024 06:25:19 +0000 Subject: [PATCH 4/4] Add overview page for Catch Type Quests --- data/Catch Type Quests/overview_description.md | 5 +++++ pages/Catch Type Quests/overview.html | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 data/Catch Type Quests/overview_description.md create mode 100644 pages/Catch Type Quests/overview.html diff --git a/data/Catch Type Quests/overview_description.md b/data/Catch Type Quests/overview_description.md new file mode 100644 index 00000000..5a7f6ada --- /dev/null +++ b/data/Catch Type Quests/overview_description.md @@ -0,0 +1,5 @@ +"Capture or Hatch X-type Pokémon" quests are random repeatable quests that can be completed for [[Quest Points]]. + +These quests can be completed by filtering the [[Hatchery]] to the specific type, and by going to [[Routes]] that have a large number of that type. + +The best routes to farm can be found by choosing a type below \ No newline at end of file diff --git a/pages/Catch Type Quests/overview.html b/pages/Catch Type Quests/overview.html new file mode 100644 index 00000000..d52887eb --- /dev/null +++ b/pages/Catch Type Quests/overview.html @@ -0,0 +1,7 @@ +
+ + + + + +
\ No newline at end of file