Skip to content

Commit 6152f5a

Browse files
authored
Add Gen 7 animated sprites (#207)
* add support download animated * update rename script to support gif, add animated forms to handle different sprite variants
1 parent c638a2d commit 6152f5a

482 files changed

Lines changed: 126 additions & 26 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

scripts/forms-animated.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"19": "raticate-alola",
3+
"20_1": "raticate-alola",
4+
"26_1": "raichu-alola",
5+
"27_1": "sandshrew-alola",
6+
"28_1": "sandslash-alola",
7+
"37_1": "vulpix-alola",
8+
"50_1": "dugtrio-alola",
9+
"51_1": "dugtrio-alola",
10+
"52_1": "meowth-alola",
11+
"53_1": "persian-alola",
12+
"74_1": "geodude-alola",
13+
"75_1": "graveler-alola",
14+
"76_1": "golem-alola",
15+
"88_1": "grimer-alola",
16+
"89_1": "muk-alola",
17+
"105_1": "marowak-alola"
18+
}

scripts/renameSmogon.sh

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Usage: $0 <generationID>
33
# If not submitted, generationID will be 6
44

5-
regex="^([0-9]+)_?([0-9]+)?([sbfg]+)?.png$"
5+
regex="^([0-9]+)_?([0-9]+)?([sbfg]+)?\.(png|gif)$"
66

77
ensureCommands(){
88
local commands="jq"
@@ -36,15 +36,21 @@ convert(){
3636
# Folder where images downloaded from the Smogon spreadsheet are stored.
3737
local files="downloads/"
3838
local formDS
39+
local formDSAnimated
3940
formDS=$(jq . forms.json)
41+
formDSAnimated="$formDS" # default to same as formDS
42+
if [ -f forms-animated.json ]; then
43+
# Merge forms-animated.json into forms.json (animated overrides original)
44+
formDSAnimated=$(jq -n --argjson base "$formDS" --argjson animated "$(jq . forms-animated.json)" '$base * $animated')
45+
fi
4046
# echo "$formDS" | jq -r '.["885"]'
4147

4248
cd "$files" || exit
4349

4450
local destinationRoot='../../sprites/pokemon'
4551
local bwDestinationRoot="$destinationRoot/versions/generation-v/black-white"
4652

47-
for smogonName in *.png; do
53+
for smogonName in *.png *.gif; do
4854
id=""
4955
form=""
5056
isFemale=""
@@ -54,13 +60,21 @@ convert(){
5460
speciesName=""
5561
pokemonID=""
5662
pokemonName=""
63+
fileExt=""
5764
destination="$destinationRoot"
5865
bwDestination="$bwDestinationRoot"
5966

6067
if [[ $smogonName =~ $regex ]]; then
6168
#id=$(echo "${BASH_REMATCH[1]}" | sed 's/^0*//') # Extremely slow
6269
id=$(removeLeadingZero "${BASH_REMATCH[1]}") # Slow if function
6370
form="${BASH_REMATCH[2]}"
71+
fileExt="${BASH_REMATCH[4]}"
72+
73+
# For .gif files, use animated directory
74+
if [ "$fileExt" == "gif" ]; then
75+
bwDestination="$bwDestination/animated"
76+
fi
77+
6478
if [[ "${BASH_REMATCH[3]}" == *b* ]]; then
6579
isBack="back"
6680
destination="$destination/back"
@@ -85,13 +99,20 @@ convert(){
8599
if [ $? -ne 0 ]; then
86100
echo "[-] Pkmn $speciesName-$isGmax wasn't found in PokeAPI"
87101
else
88-
echo "[+] Copying GMax $smogonName to $destination/$pokemonID.png"
89-
cp "$smogonName" "$destination/$pokemonID.png"
90-
cp "$smogonName" "$bwDestination/$pokemonID.png"
102+
echo "[+] Copying GMax $smogonName to $bwDestination/$pokemonID.$fileExt"
103+
if [ "$fileExt" == "png" ]; then
104+
mv "$smogonName" "$destination/$pokemonID.$fileExt"
105+
fi
106+
mv "$smogonName" "$bwDestination/$pokemonID.$fileExt"
91107
fi
92108
fi
93109
if [ "$form" ]; then
94-
pokemonName=$(echo "$formDS" | jq -r ".[\"${id}_${form}\"]")
110+
# Use animated forms for .gif, regular forms for .png
111+
if [ "$fileExt" == "gif" ]; then
112+
pokemonName=$(echo "$formDSAnimated" | jq -r ".[\"${id}_${form}\"]")
113+
else
114+
pokemonName=$(echo "$formDS" | jq -r ".[\"${id}_${form}\"]")
115+
fi
95116

96117
if [ $? -ne 0 ] || [ "$pokemonName" == 'null' ]; then
97118
echo "[-] Form ${id}_${form} wasn't found in the JSON mapping"
@@ -101,9 +122,11 @@ convert(){
101122
pokemonID=$(echo "$response" | jq -r '.id' 2>/dev/null)
102123

103124
if [ -n "$pokemonID" ] && [ "$pokemonID" != "null" ]; then
104-
echo "[+] Found variety by name: Moving $smogonName to $destination/$pokemonID.png"
105-
cp "$smogonName" "$destination/$pokemonID.png"
106-
cp "$smogonName" "$bwDestination/$pokemonID.png"
125+
echo "[+] Found variety by name: Moving $smogonName to $bwDestination/$pokemonID.$fileExt"
126+
if [ "$fileExt" == "png" ]; then
127+
mv "$smogonName" "$destination/$pokemonID.$fileExt"
128+
fi
129+
mv "$smogonName" "$bwDestination/$pokemonID.$fileExt"
107130
else
108131
# Search all forms from Pokémon API
109132
echo "[!] Variety '$pokemonName' not found directly. Searching in Pokémon forms..."
@@ -116,25 +139,29 @@ convert(){
116139
'.forms[] | select(.name == $name) | .name | sub("^[^#-]+-"; "")' 2>/dev/null)
117140

118141
if [ -n "$formSuffix" ] && [ "$formSuffix" != "null" ] && [ "$formSuffix" != "$pokemonName" ]; then
119-
destFile="${id}-${formSuffix}.png"
142+
destFile="${id}-${formSuffix}.$fileExt"
120143
mkdir -p "$destination"
121144
mkdir -p "$bwDestination"
122145

123-
echo "[+] Found in forms: Moving $smogonName to $destination/$destFile"
124-
cp "$smogonName" "$destination/$destFile"
125-
cp "$smogonName" "$bwDestination/$destFile"
146+
echo "[+] Found in forms: Moving $smogonName to $bwDestination/$destFile"
147+
if [ "$fileExt" == "png" ]; then
148+
mv "$smogonName" "$destination/$destFile"
149+
fi
150+
mv "$smogonName" "$bwDestination/$destFile"
126151
else
127152
echo "[!] No matching form found for $pokemonName."
128153
fi
129154
fi
130155
fi
131156
fi
132157
if [ ! "$form" ] && [ ! "$isGmax" ]; then
133-
echo "[+] Copying Pkmn $smogonName $destination/$id.png"
158+
echo "[+] Copying Pkmn $smogonName to $bwDestination/$id.$fileExt"
134159
mkdir -p "$destination"
135160
mkdir -p "$bwDestination"
136-
cp "$smogonName" "$destination/$id.png"
137-
cp "$smogonName" "$bwDestination/$id.png"
161+
if [ "$fileExt" == "png" ]; then
162+
mv "$smogonName" "$destination/$id.$fileExt"
163+
fi
164+
mv "$smogonName" "$bwDestination/$id.$fileExt"
138165
fi
139166
fi
140167
done

scripts/smogon_download.py

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import requests
22
import re
3+
import json
34
from pathlib import Path
45

56
# Image URLs collected from the Smogon Sprite Project spreadsheet
@@ -8,36 +9,90 @@
89
# Smogon thread:
910
# https://www.smogon.com/forums/threads/smogon-sprite-project.3647722/
1011
urls = [
11-
"https://www.smogon.com/forums/attachments/964-png.603593/",
12-
"https://www.smogon.com/forums/attachments/964s-png.603594/",
13-
# "https://www.smogon.com/forums/attachments/964-png.536964/",
14-
# "https://www.smogon.com/forums/attachments/964s-png.536965/",
12+
"https://www.smogon.com/forums/attachments/019-gif.171350/",
13+
"https://www.smogon.com/forums/attachments/19b-gif.177101/",
14+
"https://www.smogon.com/forums/attachments/019s-gif.173309/",
15+
"https://www.smogon.com/forums/attachments/19sb-gif.177103/",
1516
]
1617

1718
# Set a User-Agent to prevent Smogon from blocking the request
1819
HEADERS = {
1920
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.31"
2021
}
2122

23+
# Mapping Showdown directories to filename suffixes
24+
SHOWDOWN_SUFFIX_MAP = {
25+
"gen5ani": "",
26+
"gen5ani-back": "b",
27+
"gen5ani-shiny": "s",
28+
"gen5ani-back-shiny": "sb",
29+
}
30+
31+
32+
def load_forms_map(script_dir):
33+
"""Loads forms.json and inverts it to {name: id} for easy lookup."""
34+
forms_path = script_dir / "forms.json"
35+
if not forms_path.exists():
36+
print("⚠️ Warning: forms.json not found. Showdown downloads may fail.")
37+
return {}
38+
39+
with open(forms_path, "r") as f:
40+
data = json.load(f)
41+
# Invert {"764": "comfey"} -> {"comfey": "764"}
42+
return {v.lower(): k for k, v in data.items()}
43+
2244

2345
def download_sprites():
2446
script_dir = Path(__file__).resolve().parent
2547
download_dir = script_dir / "downloads"
2648
download_dir.mkdir(exist_ok=True)
2749

50+
name_to_id = load_forms_map(script_dir)
51+
2852
print(f"📁 Directory ready: {download_dir.absolute()}")
2953
print(f"🚀 Starting download of {len(urls)} files...")
3054

3155
for url in urls:
3256
try:
57+
filename = None
58+
3359
# 1. Extract filename from URL
34-
# Example: 652sb-png.492504/ -> 652sb.png
35-
match = re.search(r"attachments/([\w-]+)-png\.\d+/?", url)
36-
if match:
37-
filename = f"{match.group(1)}.png"
60+
# --- Pokemon Showdown ---
61+
if "play.pokemonshowdown.com" in url:
62+
# Extract the directory and the name (e.g., gen5ani-back and comfey)
63+
# URL pattern: .../sprites/{directory}/{name}.gif
64+
parts = url.rstrip("/").split("/")
65+
directory = parts[-2]
66+
name_with_ext = parts[-1]
67+
name = name_with_ext.split(".")[0].lower()
68+
extension = name_with_ext.split(".")[-1]
69+
70+
pokemon_id = name_to_id.get(name)
71+
suffix = SHOWDOWN_SUFFIX_MAP.get(directory)
72+
73+
if pokemon_id is not None and suffix is not None:
74+
filename = f"{pokemon_id}{suffix}.{extension}"
75+
else:
76+
print(f"⚠️ Could not map Showdown URL: {url}")
77+
continue
78+
79+
# --- Smogon Forums ---
3880
else:
39-
# Fallback if regex fails
40-
filename = f"{Path(url).parts[-1].split('-')[0]}.png"
81+
# Capture the name and the extension type (e.g., 762-gif.369401 -> 762 and gif)
82+
match = re.search(r"attachments/([\w-]+)-(png|gif)\.\d+/?", url)
83+
if match:
84+
base_name = match.group(1)
85+
extension = match.group(2)
86+
filename = f"{base_name}.{extension}"
87+
else:
88+
# Handles cases where the regex might miss a specific format
89+
raw_part = Path(url).parts[-1].split(".")[0] # e.g., "762-gif"
90+
if "-" in raw_part:
91+
name, ext = raw_part.rsplit("-", 1)
92+
filename = f"{name}.{ext}"
93+
else:
94+
print(f"⚠️ Could not parse Smogon URL: {url}")
95+
continue
4196

4297
save_path = download_dir / filename
4398

74.7 KB
32.1 KB
64.7 KB
64.4 KB
64.8 KB
64.6 KB
102 KB

0 commit comments

Comments
 (0)