From 3635b95c5b36ce963450a6cd95b7bc861334254e Mon Sep 17 00:00:00 2001 From: sLoPPydrive Date: Fri, 5 Jan 2018 15:27:42 +0100 Subject: [PATCH 1/4] Now using Pokemon icons from PogoAssets everywhere - plus more CSS eye candy --- pogom/app.py | 9 +++++-- pogom/dyn_img.py | 37 +++++++++++++++++++--------- static/js/map.common.js | 12 +++++++++ static/js/map.js | 23 ++++++++--------- static/js/statistics.js | 3 ++- static/sass/components/_icon.scss | 6 +++++ static/sass/layout/_gym-details.scss | 2 +- static/sass/layout/_gym.scss | 6 ++++- static/sass/layout/_pokemon.scss | 2 +- static/sass/layout/_pokestop.scss | 2 +- 10 files changed, 73 insertions(+), 29 deletions(-) diff --git a/pogom/app.py b/pogom/app.py index 1d5bb1c327..f0351f20fe 100644 --- a/pogom/app.py +++ b/pogom/app.py @@ -10,7 +10,7 @@ from flask_compress import Compress from datetime import datetime from s2sphere import LatLng -from pogom.dyn_img import get_gym_icon, get_pokemon_icon +from pogom.dyn_img import get_gym_icon, get_pokemon_map_icon, get_pokemon_raw_icon from pogom.pgscout import scout_error, pgscout_encounter from pogom.utils import get_args, get_pokemon_name from bisect import bisect_left @@ -83,12 +83,17 @@ def gym_img(self): return send_file(get_gym_icon(team, level, raidlevel, pkm, is_in_battle), mimetype='image/png') def pokemon_img(self): + raw = 'raw' in request.args pkm = int(request.args.get('pkm')) weather = int(request.args.get('weather')) if 'weather' in request.args else 0 gender = int(request.args.get('gender')) if 'gender' in request.args else None form = int(request.args.get('form')) if 'form' in request.args else None costume = int(request.args.get('costume')) if 'costume' in request.args else None - return send_file(get_pokemon_icon(pkm, weather=weather, gender=gender, form=form, costume=costume), mimetype='image/png') + filename = get_pokemon_raw_icon(pkm, gender=gender, form=form, + costume=costume) if raw else get_pokemon_map_icon(pkm, weather=weather, + gender=gender, form=form, + costume=costume) + return send_file(filename, mimetype='image/png') def scout_pokemon(self): args = get_args() diff --git a/pogom/dyn_img.py b/pogom/dyn_img.py index cabe1485c6..0d9370ec80 100644 --- a/pogom/dyn_img.py +++ b/pogom/dyn_img.py @@ -23,7 +23,6 @@ path_weather = os.path.join(path_images, 'weather') path_generated = os.path.join(path_images, 'generated') path_generated_gym = os.path.join(path_generated, 'gym') -path_generated_pokemon = os.path.join(path_generated, 'pokemon') egg_images = { 1: os.path.join(path_raid, 'egg_normal.png'), @@ -85,7 +84,7 @@ def draw_raid_egg(raidlevel): egg_path = os.path.join(pogo_assets, egg_images_assets[raidlevel]) else: egg_path = egg_images[raidlevel] - return draw_gym_subject(egg_path, 36, 'center') + return draw_gym_subject(egg_path, 36, gravity='center') def draw_gym_level(level): @@ -134,7 +133,6 @@ def battle_indicator_swords(): def get_gym_icon(team, level, raidlevel, pkm, is_in_battle): - init_image_dir(path_generated_gym) level = int(level) if not generate_images: @@ -173,14 +171,25 @@ def get_gym_icon(team, level, raidlevel, pkm, is_in_battle): return run_imagemagick(gym_image, im_lines, out_filename) -def get_pokemon_icon(pkm, weather=None, gender=None, form=None, costume=None): - init_image_dir(path_generated_pokemon) +def get_pokemon_raw_icon(pkm, gender=None, form=None, costume=None): + if pogo_assets: + source, target = pokemon_asset_path(pkm, classifier='icon', gender=gender, form=form, costume=costume) + im_lines = ['-fuzz 0.5% -trim +repage' + ' -scale "96x96>" -unsharp 0x1' + ' -background none -gravity center -extent 96x96' + ] + return run_imagemagick(source, im_lines, target) + else: + return os.path.join(path_icons, '{}.png'.format(pkm)) + +def get_pokemon_map_icon(pkm, weather=None, gender=None, form=None, costume=None): im_lines = [] # Add Pokemon icon if pogo_assets: - source, target = pokemon_asset_path(pkm, gender, form, costume, weather) + source, target = pokemon_asset_path(pkm, classifier='marker', gender=gender, form=form, costume=costume, + weather=weather) target_size = 96 im_lines.append( '-fuzz 0.5% -trim +repage' @@ -194,7 +203,8 @@ def get_pokemon_icon(pkm, weather=None, gender=None, form=None, costume=None): # Extract pokemon icon from spritesheet source = path_pokemon_spritesheet weather_suffix = '_{}'.format(WeatherCondition.Name(weather)) if weather else '' - target = os.path.join(path_generated_pokemon, 'pokemon_{}{}.png'.format(pkm, weather_suffix)) + target_path = os.path.join(path_generated, 'pokemon_spritesheet_marker') + target = os.path.join(target_path, 'pokemon_{}{}.png'.format(pkm, weather_suffix)) target_size = pkm_sprites_size pkm_idx = pkm - 1 @@ -216,7 +226,7 @@ def get_pokemon_icon(pkm, weather=None, gender=None, form=None, costume=None): return run_imagemagick(source, im_lines, target) -def pokemon_asset_path(pkm, gender=GENDER_UNSET, form=None, costume=None, weather=None): +def pokemon_asset_path(pkm, classifier=None, gender=GENDER_UNSET, form=None, costume=None, weather=None): gender_suffix = gender_assets_suffix = '' form_suffix = form_assets_suffix = '' costume_suffix = costume_assets_suffix = '' @@ -245,15 +255,17 @@ def pokemon_asset_path(pkm, gender=GENDER_UNSET, form=None, costume=None, weathe assets_fullname = os.path.join(assets_basedir, 'pokemon_icon_{:03d}{}{}{}.png'.format(pkm, gender_assets_suffix, form_assets_suffix, costume_assets_suffix)) - target_name = os.path.join(path_generated_pokemon, + target_path = os.path.join(path_generated, 'pokemon_{}'.format(classifier)) if classifier else os.path.join( + path_generated, 'pokemon') + target_name = os.path.join(target_path, "pkm_{}{}{}{}{}.png".format(pkm, gender_suffix, form_suffix, costume_suffix, - weather_suffix)) + weather_suffix)) if os.path.isfile(assets_fullname): return assets_fullname, target_name else: if gender == MALE: raise Exception("Cannot find PogoAssets file {}".format(assets_fullname)) - return pokemon_asset_path(pkm, MALE, form, costume, weather) + return pokemon_asset_path(pkm, classifier=classifier, gender=MALE, form=form, costume=costume, weather=weather) def draw_gym_subject(image, size, gravity='north', trim=False): @@ -300,6 +312,9 @@ def default_gym_image(team, level, raidlevel, pkm): def run_imagemagick(source, im_lines, out_filename): if not os.path.isfile(out_filename): + # Make sure, target path exists + init_image_dir(os.path.split(out_filename)[0]) + cmd = '{} "{}" {} "{}"'.format(imagemagick_executable, source, join(im_lines), out_filename) if os.name != 'nt': cmd = cmd.replace(" ( ", " \( ").replace(" ) ", " \) ") diff --git a/static/js/map.common.js b/static/js/map.common.js index ee62e78bb5..e52c9d2824 100644 --- a/static/js/map.common.js +++ b/static/js/map.common.js @@ -1253,3 +1253,15 @@ function cssPercentageCircle(text, value, perfect_val, good_val, ok_val, meh_val ` } + +function get_pokemon_raw_icon_url(p) { + var url = 'pkm_img?raw=1&pkm=' + p.pokemon_id + var props = ['gender', 'form', 'costume'] + for (var i = 0; i < props.length; i++) { + var prop = props[i] + if (prop in p && p[prop] != null) { + url += '&' + prop + '=' + p[prop] + } + } + return url +} diff --git a/static/js/map.js b/static/js/map.js index b9a08cf033..bedd779076 100644 --- a/static/js/map.js +++ b/static/js/map.js @@ -662,6 +662,8 @@ function pokemonLabel(item) { var hideLabel = excludedPokemon.indexOf(id) < 0 ? "Hide" : "Unhide" var notifyLabel = notifiedPokemon.indexOf(id) < 0 ? "Notify" : "Unnotify" + var pokemon_icon = get_pokemon_raw_icon_url(item) + if (cp !== null && cpMultiplier !== null) { var pokemonLevel = getPokemonLevel(cpMultiplier) @@ -676,7 +678,7 @@ function pokemonLabel(item) {
- +
CP ${cp}
@@ -724,7 +726,7 @@ function pokemonLabel(item) {
- + @@ -831,13 +833,12 @@ function gymLabel(gym, includeMembers = true) { if (isRaidStarted) { // Use Pokémon-specific image. + var pokemon_icon = get_pokemon_raw_icon_url(raid) if (raid.pokemon_id !== null) { image = `
-
- -
+
@@ -897,20 +898,20 @@ function gymLabel(gym, includeMembers = true) {
Last Modified: ${lastModifiedStr}
-
-
` +
` if (includeMembers) { memberStr = '
' gym.pokemon.forEach((member) => { + var pokemon_icon = generateImages ? `` : `` memberStr += `
- + ${pokemon_icon}
${member.pokemon_name} @@ -935,7 +936,7 @@ function gymLabel(gym, includeMembers = true) { ${imageLbl}
${navInfo} -
+
${memberStr}
` @@ -1201,7 +1202,7 @@ function customizePokemonMarker(marker, item, skipNotification) { if (isNotifyPoke(item)) { if (!skipNotification) { playPokemonSound(item['pokemon_id'], cryFileTypes) - sendNotification(notifyText.fav_title, notifyText.fav_text, 'static/icons/' + item['pokemon_id'] + '.png', item['latitude'], item['longitude']) + sendNotification(notifyText.fav_title, notifyText.fav_text, get_pokemon_raw_icon_url(item), item['latitude'], item['longitude']) } if (marker.animationDisabled !== true) { marker.setAnimation(google.maps.Animation.BOUNCE) @@ -2362,7 +2363,7 @@ function getSidebarGymMember(pokemon) { return ` - +
${pokemon.pokemon_name}
diff --git a/static/js/statistics.js b/static/js/statistics.js index c5d0377ae4..53545cff94 100644 --- a/static/js/statistics.js +++ b/static/js/statistics.js @@ -55,10 +55,11 @@ function processSeen(seen) { var pokemonItem = seen.pokemon[i] var seenPercent = (pokemonItem.count / seen.total) * 100 + var pokemon_icon = generateImages ? `` : `` $('#stats_table > tbody') .append(` - + ${pokemon_icon} ${pokemonItem.pokemon_id} diff --git a/static/sass/components/_icon.scss b/static/sass/components/_icon.scss index 1de0218729..33f1ddc442 100644 --- a/static/sass/components/_icon.scss +++ b/static/sass/components/_icon.scss @@ -9,3 +9,9 @@ display: none; } } + + img.pokemon_icon { + width: 32px; + height: 32px; + filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #888); + } diff --git a/static/sass/layout/_gym-details.scss b/static/sass/layout/_gym-details.scss index 7712d17f90..e663e0ff20 100644 --- a/static/sass/layout/_gym-details.scss +++ b/static/sass/layout/_gym-details.scss @@ -347,7 +347,7 @@ display: block; height: 96px; width: 96px; - -webkit-filter: drop-shadow(grey 3px 3px .2em); + filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #888); &.pokemon { @media screen and (max-width: 480px) { diff --git a/static/sass/layout/_gym.scss b/static/sass/layout/_gym.scss index f3c6b00945..fafb1424bf 100644 --- a/static/sass/layout/_gym.scss +++ b/static/sass/layout/_gym.scss @@ -8,6 +8,10 @@ justify-content: center; } + &.member_list { + padding-right: 4px; + } + &.member { display: inline-block; margin-left: 1px; @@ -25,7 +29,7 @@ height: 64px; width: 64px; margin: 5px 0px 5px 0px; - -webkit-filter: drop-shadow(grey 3px 3px .2em); + filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #888); } &.info { diff --git a/static/sass/layout/_pokemon.scss b/static/sass/layout/_pokemon.scss index 3ed535315c..6f9544c70d 100644 --- a/static/sass/layout/_pokemon.scss +++ b/static/sass/layout/_pokemon.scss @@ -83,7 +83,7 @@ &.sprite { display: block; width: 64px; - -webkit-filter: drop-shadow(grey 3px 3px .2em); + filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #888); margin-bottom: 6px; } diff --git a/static/sass/layout/_pokestop.scss b/static/sass/layout/_pokestop.scss index e856868153..159ddc216f 100644 --- a/static/sass/layout/_pokestop.scss +++ b/static/sass/layout/_pokestop.scss @@ -68,5 +68,5 @@ a.pokestop:link { width: 32px; margin-left: auto; margin-right: auto; - -webkit-filter: drop-shadow(grey 3px 3px .2em); + filter: drop-shadow(2px 2px 2px #888); } From 9c22652dac8e384c7298edec2ef4e28844d7fba5 Mon Sep 17 00:00:00 2001 From: sLoPPydrive Date: Sat, 6 Jan 2018 01:09:59 +0100 Subject: [PATCH 2/4] Gym-Pokemon show gender, form, costume, shiny state --- pogom/app.py | 10 +- pogom/dyn_img.py | 207 +++++++++++++++--------------- pogom/models.py | 66 +++++++++- static/js/map.common.js | 7 +- static/js/map.js | 23 +++- static/sass/components/_icon.scss | 15 ++- 6 files changed, 213 insertions(+), 115 deletions(-) diff --git a/pogom/app.py b/pogom/app.py index f0351f20fe..d3985d53b1 100644 --- a/pogom/app.py +++ b/pogom/app.py @@ -89,10 +89,12 @@ def pokemon_img(self): gender = int(request.args.get('gender')) if 'gender' in request.args else None form = int(request.args.get('form')) if 'form' in request.args else None costume = int(request.args.get('costume')) if 'costume' in request.args else None - filename = get_pokemon_raw_icon(pkm, gender=gender, form=form, - costume=costume) if raw else get_pokemon_map_icon(pkm, weather=weather, - gender=gender, form=form, - costume=costume) + shiny = 'shiny' in request.args + if raw: + filename = get_pokemon_raw_icon(pkm, gender=gender, form=form, costume=costume, weather=weather, + shiny=shiny) + else: + filename = get_pokemon_map_icon(pkm, weather=weather, gender=gender, form=form, costume=costume) return send_file(filename, mimetype='image/png') def scout_pokemon(self): diff --git a/pogom/dyn_img.py b/pogom/dyn_img.py index 0d9370ec80..5241e562c3 100644 --- a/pogom/dyn_img.py +++ b/pogom/dyn_img.py @@ -69,6 +69,100 @@ font_pointsize = 25 +def get_pokemon_raw_icon(pkm, gender=None, form=None, costume=None, weather=None, shiny=False): + if generate_images and pogo_assets: + source, target = pokemon_asset_path(pkm, classifier='icon', gender=gender, form=form, costume=costume, weather=weather, shiny=shiny) + im_lines = ['-fuzz 0.5% -trim +repage' + ' -scale "96x96>" -unsharp 0x1' + ' -background none -gravity center -extent 96x96' + ] + return run_imagemagick(source, im_lines, target) + else: + return os.path.join(path_icons, '{}.png'.format(pkm)) + + +def get_pokemon_map_icon(pkm, weather=None, gender=None, form=None, costume=None): + im_lines = [] + + # Add Pokemon icon + if pogo_assets: + source, target = pokemon_asset_path(pkm, classifier='marker', gender=gender, form=form, costume=costume, + weather=weather) + target_size = 96 + im_lines.append( + '-fuzz 0.5% -trim +repage' + ' -scale "133x133>" -unsharp 0x1' + ' -background none -gravity center -extent 139x139' + ' -background black -alpha background -channel A -blur 0x1 -level 0,10%' + ' -adaptive-resize {size}x{size}' + ' -modulate 100,110'.format(size=target_size) + ) + else: + # Extract pokemon icon from spritesheet + source = path_pokemon_spritesheet + weather_suffix = '_{}'.format(WeatherCondition.Name(weather)) if weather else '' + target_path = os.path.join(path_generated, 'pokemon_spritesheet_marker') + target = os.path.join(target_path, 'pokemon_{}{}.png'.format(pkm, weather_suffix)) + + target_size = pkm_sprites_size + pkm_idx = pkm - 1 + x = (pkm_idx % pkm_sprites_cols) * pkm_sprites_size + y = (pkm_idx / pkm_sprites_cols) * pkm_sprites_size + im_lines.append('-crop {size}x{size}+{x}+{y} +repage'.format(size=target_size, x=x, y=y)) + + if weather: + radius = 20 + x = target_size - radius - 2 + y = radius + 1 + y2 = 1 + im_lines.append( + '-gravity northeast' + ' -fill "#FFFD" -stroke black -draw "circle {x},{y} {x},{y2}"' + ' -draw "image over 1,1 42,42 \'{weather_img}\'"'.format(x=x, y=y, y2=y2, weather_img=weather_images[weather]) + ) + + return run_imagemagick(source, im_lines, target) + + +def get_gym_icon(team, level, raidlevel, pkm, is_in_battle): + level = int(level) + + if not generate_images: + return default_gym_image(team, level, raidlevel, pkm) + + im_lines = ['-font "{}" -pointsize {}'.format(font, font_pointsize)] + if pkm and pkm != 'null': + # Gym with ongoing raid + out_filename = os.path.join(path_generated_gym, "{}_L{}_R{}_P{}.png".format(team, level, raidlevel, pkm)) + im_lines.extend(draw_raid_pokemon(pkm)) + im_lines.extend(draw_raid_level(raidlevel)) + if level > 0: + im_lines.extend(draw_gym_level(level)) + elif raidlevel: + # Gym with upcoming raid (egg) + raidlevel = int(raidlevel) + out_filename = os.path.join(path_generated_gym, "{}_L{}_R{}.png".format(team, level, raidlevel)) + im_lines.extend(draw_raid_egg(raidlevel)) + im_lines.extend(draw_raid_level(raidlevel)) + if level > 0: + im_lines.extend(draw_gym_level(level)) + elif level > 0: + # Occupied gym + out_filename = os.path.join(path_generated_gym, '{}_L{}.png'.format(team, level)) + im_lines.extend(draw_gym_level(level)) + else: + # Neutral gym + return os.path.join(path_gym, '{}.png'.format(team)) + + # Battle Indicator + if is_in_battle: + out_filename = out_filename.replace('.png', '_B.png') + im_lines.extend(draw_battle_indicator()) + + gym_image = os.path.join(path_gym, '{}.png'.format(team)) + return run_imagemagick(gym_image, im_lines, out_filename) + + def draw_raid_pokemon(pkm): if pogo_assets: pkm_path, dummy = pokemon_asset_path(int(pkm)) @@ -132,111 +226,18 @@ def battle_indicator_swords(): ] -def get_gym_icon(team, level, raidlevel, pkm, is_in_battle): - level = int(level) - - if not generate_images: - return default_gym_image(team, level, raidlevel, pkm) - - im_lines = ['-font "{}" -pointsize {}'.format(font, font_pointsize)] - if pkm and pkm != 'null': - # Gym with ongoing raid - out_filename = os.path.join(path_generated_gym, "{}_L{}_R{}_P{}.png".format(team, level, raidlevel, pkm)) - im_lines.extend(draw_raid_pokemon(pkm)) - im_lines.extend(draw_raid_level(raidlevel)) - if level > 0: - im_lines.extend(draw_gym_level(level)) - elif raidlevel: - # Gym with upcoming raid (egg) - raidlevel = int(raidlevel) - out_filename = os.path.join(path_generated_gym, "{}_L{}_R{}.png".format(team, level, raidlevel)) - im_lines.extend(draw_raid_egg(raidlevel)) - im_lines.extend(draw_raid_level(raidlevel)) - if level > 0: - im_lines.extend(draw_gym_level(level)) - elif level > 0: - # Occupied gym - out_filename = os.path.join(path_generated_gym, '{}_L{}.png'.format(team, level)) - im_lines.extend(draw_gym_level(level)) - else: - # Neutral gym - return os.path.join(path_gym, '{}.png'.format(team)) - - # Battle Indicator - if is_in_battle: - out_filename = out_filename.replace('.png', '_B.png') - im_lines.extend(draw_battle_indicator()) - - gym_image = os.path.join(path_gym, '{}.png'.format(team)) - return run_imagemagick(gym_image, im_lines, out_filename) - - -def get_pokemon_raw_icon(pkm, gender=None, form=None, costume=None): - if pogo_assets: - source, target = pokemon_asset_path(pkm, classifier='icon', gender=gender, form=form, costume=costume) - im_lines = ['-fuzz 0.5% -trim +repage' - ' -scale "96x96>" -unsharp 0x1' - ' -background none -gravity center -extent 96x96' - ] - return run_imagemagick(source, im_lines, target) - else: - return os.path.join(path_icons, '{}.png'.format(pkm)) - - -def get_pokemon_map_icon(pkm, weather=None, gender=None, form=None, costume=None): - im_lines = [] - - # Add Pokemon icon - if pogo_assets: - source, target = pokemon_asset_path(pkm, classifier='marker', gender=gender, form=form, costume=costume, - weather=weather) - target_size = 96 - im_lines.append( - '-fuzz 0.5% -trim +repage' - ' -scale "133x133>" -unsharp 0x1' - ' -background none -gravity center -extent 139x139' - ' -background black -alpha background -channel A -blur 0x1 -level 0,10%' - ' -adaptive-resize {size}x{size}' - ' -modulate 100,110'.format(size=target_size) - ) - else: - # Extract pokemon icon from spritesheet - source = path_pokemon_spritesheet - weather_suffix = '_{}'.format(WeatherCondition.Name(weather)) if weather else '' - target_path = os.path.join(path_generated, 'pokemon_spritesheet_marker') - target = os.path.join(target_path, 'pokemon_{}{}.png'.format(pkm, weather_suffix)) - - target_size = pkm_sprites_size - pkm_idx = pkm - 1 - x = (pkm_idx % pkm_sprites_cols) * pkm_sprites_size - y = (pkm_idx / pkm_sprites_cols) * pkm_sprites_size - im_lines.append('-crop {size}x{size}+{x}+{y} +repage'.format(size=target_size, x=x, y=y)) - - if weather: - radius = 20 - x = target_size - radius - 2 - y = radius + 1 - y2 = 1 - im_lines.append( - '-gravity northeast' - ' -fill "#FFFD" -stroke black -draw "circle {x},{y} {x},{y2}"' - ' -draw "image over 1,1 42,42 \'{weather_img}\'"'.format(x=x, y=y, y2=y2, weather_img=weather_images[weather]) - ) - - return run_imagemagick(source, im_lines, target) - - -def pokemon_asset_path(pkm, classifier=None, gender=GENDER_UNSET, form=None, costume=None, weather=None): +def pokemon_asset_path(pkm, classifier=None, gender=GENDER_UNSET, form=None, costume=None, weather=None, shiny=False): gender_suffix = gender_assets_suffix = '' form_suffix = form_assets_suffix = '' costume_suffix = costume_assets_suffix = '' weather_suffix = '_{}'.format(WeatherCondition.Name(weather)) if weather else '' + shiny_suffix = '_shiny' if shiny else '' if gender in (MALE, FEMALE): gender_assets_suffix = '_{:02d}'.format(gender - 1) gender_suffix = '_{}'.format(Gender.Name(gender)) elif gender in (GENDER_UNSET, GENDERLESS): - gender_assets_suffix = '_00' + gender_assets_suffix = '_00' if pkm > 0 else '' if form: # Form = no gender @@ -249,22 +250,24 @@ def pokemon_asset_path(pkm, classifier=None, gender=GENDER_UNSET, form=None, cos costume_suffix = '_{}'.format(Costume.Name(costume)) if not gender_assets_suffix and not form_assets_suffix and not costume_assets_suffix: - gender_assets_suffix = '_16' if pkm == 201 else '_00' + gender_assets_suffix = '_16' if pkm == 201 else '_00' if pkm > 0 else '' assets_basedir = os.path.join(pogo_assets, 'decrypted_assets') assets_fullname = os.path.join(assets_basedir, - 'pokemon_icon_{:03d}{}{}{}.png'.format(pkm, gender_assets_suffix, form_assets_suffix, - costume_assets_suffix)) + 'pokemon_icon_{:03d}{}{}{}{}.png'.format(pkm, gender_assets_suffix, form_assets_suffix, + costume_assets_suffix, shiny_suffix)) target_path = os.path.join(path_generated, 'pokemon_{}'.format(classifier)) if classifier else os.path.join( path_generated, 'pokemon') target_name = os.path.join(target_path, - "pkm_{}{}{}{}{}.png".format(pkm, gender_suffix, form_suffix, costume_suffix, - weather_suffix)) + "pkm_{:03d}{}{}{}{}{}.png".format(pkm, gender_suffix, form_suffix, costume_suffix, + weather_suffix, shiny_suffix)) if os.path.isfile(assets_fullname): return assets_fullname, target_name else: if gender == MALE: - raise Exception("Cannot find PogoAssets file {}".format(assets_fullname)) + log.warning("Cannot find PogoAssets file {}".format(assets_fullname)) + # Dummy Pokemon icon + return os.path.join(assets_basedir, 'pokemon_icon_000.png'), os.path.join(target_path, 'pkm_000.png') return pokemon_asset_path(pkm, classifier=classifier, gender=MALE, form=form, costume=costume, weather=weather) diff --git a/pogom/models.py b/pogom/models.py index a6b2f61fc3..234ce3817b 100644 --- a/pogom/models.py +++ b/pogom/models.py @@ -48,7 +48,7 @@ flaskDb = FlaskDB() cache = TTLCache(maxsize=100, ttl=60 * 5) -db_schema_version = 24 +db_schema_version = 25 class MyRetryDB(RetryOperationalError, PooledMySQLDatabase): @@ -463,6 +463,11 @@ class Gym(LatLongModel): longitude = DoubleField() total_cp = SmallIntegerField() is_in_battle = BooleanField() + gender = SmallIntegerField(null=True) + form = SmallIntegerField(null=True) + costume = SmallIntegerField(null=True) + weather_boosted_condition = SmallIntegerField(null=True) + shiny = BooleanField(null=True) last_modified = DateTimeField(index=True) last_scanned = DateTimeField(default=datetime.utcnow, index=True) @@ -533,6 +538,11 @@ def get_gyms(swLat, swLng, neLat, neLng, timestamp=0, oSwLat=None, GymMember.deployment_time, GymMember.last_scanned, GymPokemon.pokemon_id, + GymPokemon.gender, + GymPokemon.form, + GymPokemon.costume, + GymPokemon.weather_boosted_condition, + GymPokemon.shiny, Trainer.name.alias('trainer_name'), Trainer.level.alias('trainer_level')) .join(Gym, on=(GymMember.gym_id == Gym.gym_id)) @@ -585,6 +595,11 @@ def get_gym(id): GymDetails.name, GymDetails.description, Gym.guard_pokemon_id, + Gym.gender, + Gym.form, + Gym.costume, + Gym.weather_boosted_condition, + Gym.shiny, Gym.slots_available, Gym.latitude, Gym.longitude, @@ -616,6 +631,11 @@ def get_gym(id): GymPokemon.iv_attack, GymPokemon.iv_defense, GymPokemon.iv_stamina, + GymPokemon.gender, + GymPokemon.form, + GymPokemon.costume, + GymPokemon.weather_boosted_condition, + GymPokemon.shiny, Trainer.name.alias('trainer_name'), Trainer.level.alias('trainer_level')) .join(Gym, on=(GymMember.gym_id == Gym.gym_id)) @@ -1775,6 +1795,11 @@ class GymPokemon(BaseModel): iv_defense = SmallIntegerField(null=True) iv_stamina = SmallIntegerField(null=True) iv_attack = SmallIntegerField(null=True) + gender = SmallIntegerField(null=True) + form = SmallIntegerField(null=True) + costume = SmallIntegerField(null=True) + weather_boosted_condition = SmallIntegerField(null=True) + shiny = BooleanField(null=True) last_seen = DateTimeField(default=datetime.utcnow) @@ -2430,6 +2455,16 @@ def parse_map(args, map_dict, scan_coords, scan_location, db_update_queue, f.owned_by_team, 'guard_pokemon_id': f.guard_pokemon_id, + 'gender': + f.guard_pokemon_display.gender, + 'form': + f.guard_pokemon_display.form, + 'costume': + f.guard_pokemon_display.costume, + 'weather_boosted_condition': + f.guard_pokemon_display.weather_boosted_condition, + 'shiny': + f.guard_pokemon_display.shiny, 'slots_available': gym_display.slots_available, 'total_cp': @@ -2785,6 +2820,11 @@ def parse_gyms(args, gym_responses, wh_update_queue, db_update_queue): 'iv_defense': pokemon.individual_defense, 'iv_stamina': pokemon.individual_stamina, 'iv_attack': pokemon.individual_attack, + 'gender': pokemon.pokemon_display.gender, + 'form': pokemon.pokemon_display.form, + 'costume': pokemon.pokemon_display.costume, + 'weather_boosted_condition': pokemon.pokemon_display.weather_boosted_condition, + 'shiny': pokemon.pokemon_display.shiny, 'last_seen': datetime.utcnow(), } @@ -3346,5 +3386,29 @@ def database_migrate(db, old_ver): SmallIntegerField(null=True)) ) + if old_ver < 25: + migrate( + migrator.add_column('gympokemon', 'gender', + SmallIntegerField(null=True)), + migrator.add_column('gympokemon', 'form', + SmallIntegerField(null=True)), + migrator.add_column('gympokemon', 'costume', + SmallIntegerField(null=True)), + migrator.add_column('gympokemon', 'weather_boosted_condition', + SmallIntegerField(null=True)), + migrator.add_column('gympokemon', 'shiny', + BooleanField(null=True)), + migrator.add_column('gym', 'gender', + SmallIntegerField(null=True)), + migrator.add_column('gym', 'form', + SmallIntegerField(null=True)), + migrator.add_column('gym', 'costume', + SmallIntegerField(null=True)), + migrator.add_column('gym', 'weather_boosted_condition', + SmallIntegerField(null=True)), + migrator.add_column('gym', 'shiny', + BooleanField(null=True)) + ) + # Always log that we're done. log.info('Schema upgrade complete.') diff --git a/static/js/map.common.js b/static/js/map.common.js index e52c9d2824..8b0b8364f1 100644 --- a/static/js/map.common.js +++ b/static/js/map.common.js @@ -1255,11 +1255,14 @@ function cssPercentageCircle(text, value, perfect_val, good_val, ok_val, meh_val } function get_pokemon_raw_icon_url(p) { + if (!generateImages) { + return `static/icons/${p.pokemon_id}.png` + } var url = 'pkm_img?raw=1&pkm=' + p.pokemon_id - var props = ['gender', 'form', 'costume'] + var props = ['gender', 'form', 'costume', 'shiny'] for (var i = 0; i < props.length; i++) { var prop = props[i] - if (prop in p && p[prop] != null) { + if (prop in p && p[prop] != null && p[prop]) { url += '&' + prop + '=' + p[prop] } } diff --git a/static/js/map.js b/static/js/map.js index bedd779076..aced6c144e 100644 --- a/static/js/map.js +++ b/static/js/map.js @@ -905,7 +905,7 @@ function gymLabel(gym, includeMembers = true) { memberStr = '
' gym.pokemon.forEach((member) => { - var pokemon_icon = generateImages ? `` : `` + var pokemon_icon = generateImages ? `` : `` memberStr += `
@@ -2324,10 +2324,17 @@ function showGymDetails(id) { // eslint-disable-line no-unused-vars } else if (result.team_id === 0) { pokemonHtml = '' } else { + var pokemon_icon + if (generateImages) { + result.pokemon_id = result.guard_pokemon_id + pokemon_icon = `` + } else { + pokemon_icon = `` + } pokemonHtml = `
Gym Leader:
-
+ ${pokemon_icon}
${result.guard_pokemon_name}

@@ -2359,11 +2366,11 @@ function getSidebarGymMember(pokemon) { var perfectPercent = getIv(pokemon.iv_attack, pokemon.iv_defense, pokemon.iv_stamina) var moveEnergy = Math.round(100 / pokemon.move_2_energy) - + var pokemon_image = get_pokemon_raw_icon_url(pokemon) return ` - +

${pokemon.pokemon_name}
@@ -2721,8 +2728,14 @@ $(function () { if (!state.id) { return state.text } + var pokemon_icon + if (generateImages) { + pokemon_icon = `` + } else { + pokemon_icon = `` + } var $state = $( - ' ' + state.text + '' + `${pokemon_icon} ${state.text}` ) return $state } diff --git a/static/sass/components/_icon.scss b/static/sass/components/_icon.scss index 33f1ddc442..7f9fb06986 100644 --- a/static/sass/components/_icon.scss +++ b/static/sass/components/_icon.scss @@ -10,8 +10,21 @@ } } - img.pokemon_icon { + img.guard-pokemon-icon { + width: 96px; + height: 96px; + filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #888); + } + + img.pokemon-icon { width: 32px; height: 32px; filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #888); } + + img.pokemon-select-icon { + width: 32px; + height: 32px; + filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #aaa); + vertical-align: bottom; + } From 0f3c750392d9ceca93df2dd7002311f14a4ffe09 Mon Sep 17 00:00:00 2001 From: sLoPPydrive Date: Sat, 6 Jan 2018 01:28:07 +0100 Subject: [PATCH 3/4] Tweaked drop shadows --- static/sass/components/_icon.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/sass/components/_icon.scss b/static/sass/components/_icon.scss index 7f9fb06986..8ba8702e9c 100644 --- a/static/sass/components/_icon.scss +++ b/static/sass/components/_icon.scss @@ -13,13 +13,13 @@ img.guard-pokemon-icon { width: 96px; height: 96px; - filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #888); + filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #aaa); } img.pokemon-icon { width: 32px; height: 32px; - filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #888); + filter: drop-shadow(0px 0px 0px #000) drop-shadow(2px 2px 2px #aaa); } img.pokemon-select-icon { From 8a87fa004e66a91685e9d4030f05cc3658a5fa57 Mon Sep 17 00:00:00 2001 From: sLoPPydrive Date: Sat, 6 Jan 2018 15:17:35 +0100 Subject: [PATCH 4/4] Asset icons for Pokemon stats --- static/js/stats.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/static/js/stats.js b/static/js/stats.js index 4a2c5b9b90..02a099b682 100644 --- a/static/js/stats.js +++ b/static/js/stats.js @@ -44,9 +44,10 @@ function countMarkers(map) { // eslint-disable-line no-unused-vars for (i = 0; i < pkmnCount.length; i++) { if (pkmnCount[i] && pkmnCount[i].Count > 0) { + var pokemon_icon = get_pokemon_raw_icon_url({'pokemon_id': pkmnCount[i].ID}) pokeCounts.push( [ - '', + '', '' + pkmnCount[i].Name + '', pkmnCount[i].Count, (Math.round(pkmnCount[i].Count * 100 / pkmnTotal * 10) / 10) + '%'