bKGD Fix
@ -1,21 +1,21 @@
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def rename_subdirs(rootDir, old, new):
|
||||
for root, dirs, files in os.walk(rootDir):
|
||||
for name in files:
|
||||
originalName = os.path.join(root, name)
|
||||
if root.endswith(old) and os.path.isfile(originalName):
|
||||
newName = originalName.replace(old + '/', new + '/')
|
||||
print(originalName + " -> " + newName)
|
||||
if (not os.path.isdir(root.replace(old, '') + new)):
|
||||
os.mkdir(root.replace(old, '') + new)
|
||||
os.rename(originalName, newName)
|
||||
|
||||
rename_subdirs("graphics/pokemon", '/alolan', "/alola")
|
||||
rename_subdirs("graphics/pokemon", '/galarian', "/galar")
|
||||
rename_subdirs("graphics/pokemon", '/hisuian', "/hisui")
|
||||
rename_subdirs("graphics/pokemon", '/gigantamax', "/gmax")
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def rename_subdirs(rootDir, old, new):
|
||||
for root, dirs, files in os.walk(rootDir):
|
||||
for name in files:
|
||||
originalName = os.path.join(root, name)
|
||||
if root.endswith(old) and os.path.isfile(originalName):
|
||||
newName = originalName.replace(old + '/', new + '/')
|
||||
print(originalName + " -> " + newName)
|
||||
if (not os.path.isdir(root.replace(old, '') + new)):
|
||||
os.mkdir(root.replace(old, '') + new)
|
||||
os.rename(originalName, newName)
|
||||
|
||||
rename_subdirs("graphics/pokemon", '/alolan', "/alola")
|
||||
rename_subdirs("graphics/pokemon", '/galarian', "/galar")
|
||||
rename_subdirs("graphics/pokemon", '/hisuian', "/hisui")
|
||||
rename_subdirs("graphics/pokemon", '/gigantamax', "/gmax")
|
||||
|
||||
@ -1,110 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
""" Extract sprites from HGSS follower spritesheets. """
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
from glob import glob
|
||||
|
||||
import png
|
||||
|
||||
|
||||
SPRITESHEETS = [('gen1.png', 15, 11, 1)]
|
||||
output_dir = 'sprites'
|
||||
index_to_name = {}
|
||||
with open('names.txt', 'r') as f:
|
||||
for line in f:
|
||||
index, name = line.split(' ')[:2]
|
||||
name = name.strip()
|
||||
index_to_name[int(index)] = name.lower()
|
||||
name_to_index = {v: k for k, v in index_to_name.items()}
|
||||
PKMN_GRAPHICS = os.path.join('graphics', 'pokemon')
|
||||
|
||||
|
||||
def extract_sprites(spritesheet):
|
||||
path, width, height, offset = spritesheet
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
if x == 3 and y == 0 or x == 10 and y == 1:
|
||||
continue
|
||||
output_path = os.path.join(output_dir, f'{offset:03d}.png')
|
||||
subprocess.run(['convert', '-extract', f'64x128+{x*(64+1)}+{y*(128+1)}', path, output_path], check=True)
|
||||
offset += 1
|
||||
|
||||
|
||||
def stack_sprite(name, path):
|
||||
joinp = os.path.join
|
||||
frames = [joinp(path, 'down', name), joinp(path, 'down', 'frame2', name),
|
||||
joinp(path, 'up', name), joinp(path, 'up', 'frame2', name),
|
||||
joinp(path, 'left', name), joinp(path, 'left', 'frame2', name)]
|
||||
output = joinp(path, name)
|
||||
subprocess.run(['convert'] + frames + ['+append', output], check=True)
|
||||
print(f'Stacked {output}')
|
||||
|
||||
def canonicalize_names():
|
||||
for path in glob('overworld/**/*.png', recursive=True):
|
||||
head, tail = os.path.split(path)
|
||||
name, ext = os.path.splitext(tail)
|
||||
try:
|
||||
num = int(name)
|
||||
except ValueError:
|
||||
continue
|
||||
new_name = f'{num:03d}'
|
||||
new_path = os.path.join(head, new_name+ext)
|
||||
os.rename(path, new_path)
|
||||
print(path, '->', new_path)
|
||||
|
||||
def closest_color(c, palette):
|
||||
min_d = float('inf')
|
||||
best = 0
|
||||
r1, g1, b1 = c
|
||||
for i, (r2, g2, b2) in enumerate(palette[1:], 1):
|
||||
# Color diff from https://stackoverflow.com/questions/1847092/given-an-rgb-value-what-would-be-the-best-way-to-find-the-closest-match-in-the-d
|
||||
d = ((r2-r1)*0.30)**2 + ((g2-g1)*0.59)**2 + ((b2-b1)*0.11)**2
|
||||
if d < min_d:
|
||||
min_d = d
|
||||
best = i
|
||||
return best
|
||||
|
||||
def apply_palette(palette_file, input_file, output_file): # Apply one file's palette to another
|
||||
plt = png.Reader(palette_file)
|
||||
plt.read()
|
||||
target_palette = tuple(c[:3] for c in plt.palette())
|
||||
inp = png.Reader(input_file)
|
||||
w, h, rows, _ = inp.read()
|
||||
src_palette = tuple(c[:3] for c in inp.palette())
|
||||
with open(output_file, 'wb') as f:
|
||||
new_rows = []
|
||||
for row in rows:
|
||||
new_rows.append([closest_color(src_palette[c], target_palette) if c else 0 for c in row])
|
||||
w = png.Writer(width=w, height=h, bitdepth=4, palette=target_palette)
|
||||
w.write(f, new_rows)
|
||||
|
||||
def paletteify(path, output_path=None):
|
||||
output_path = output_path or path
|
||||
joinp = os.path.join
|
||||
_, tail = os.path.split(path)
|
||||
species, _ = os.path.splitext(tail)
|
||||
front = png.Reader(joinp(PKMN_GRAPHICS, species, 'anim_front.png'))
|
||||
front.read()
|
||||
target_palette = tuple(c[:3] for c in front.palette())
|
||||
r, g, b = target_palette[0]
|
||||
color = f'rgb({r},{g},{b})'
|
||||
# Strip alpha color
|
||||
subprocess.run(['convert', path, '-background', color, '-alpha', 'remove', output_path], check=True)
|
||||
apply_palette(joinp(PKMN_GRAPHICS, species, 'anim_front.png'), output_path, output_path)
|
||||
|
||||
# Sprites from https://veekun.com/dex/downloads
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:]
|
||||
if args:
|
||||
paletteify(args[0])
|
||||
else:
|
||||
for path in sorted(glob('overworld/*.png')):
|
||||
_, tail = os.path.split(path)
|
||||
name, _ = os.path.splitext(tail)
|
||||
output_path = os.path.join('graphics/object_events/pics/pokemon', f'{name}.png')
|
||||
try:
|
||||
paletteify(path, output_path)
|
||||
except Exception as e:
|
||||
print(name, e.__class__.__name__, e, file=sys.stderr)
|
||||
#!/usr/bin/env python3
|
||||
""" Extract sprites from HGSS follower spritesheets. """
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
from glob import glob
|
||||
|
||||
import png
|
||||
|
||||
|
||||
SPRITESHEETS = [('gen1.png', 15, 11, 1)]
|
||||
output_dir = 'sprites'
|
||||
index_to_name = {}
|
||||
with open('names.txt', 'r') as f:
|
||||
for line in f:
|
||||
index, name = line.split(' ')[:2]
|
||||
name = name.strip()
|
||||
index_to_name[int(index)] = name.lower()
|
||||
name_to_index = {v: k for k, v in index_to_name.items()}
|
||||
PKMN_GRAPHICS = os.path.join('graphics', 'pokemon')
|
||||
|
||||
|
||||
def extract_sprites(spritesheet):
|
||||
path, width, height, offset = spritesheet
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
if x == 3 and y == 0 or x == 10 and y == 1:
|
||||
continue
|
||||
output_path = os.path.join(output_dir, f'{offset:03d}.png')
|
||||
subprocess.run(['convert', '-extract', f'64x128+{x*(64+1)}+{y*(128+1)}', path, output_path], check=True)
|
||||
offset += 1
|
||||
|
||||
|
||||
def stack_sprite(name, path):
|
||||
joinp = os.path.join
|
||||
frames = [joinp(path, 'down', name), joinp(path, 'down', 'frame2', name),
|
||||
joinp(path, 'up', name), joinp(path, 'up', 'frame2', name),
|
||||
joinp(path, 'left', name), joinp(path, 'left', 'frame2', name)]
|
||||
output = joinp(path, name)
|
||||
subprocess.run(['convert'] + frames + ['+append', output], check=True)
|
||||
print(f'Stacked {output}')
|
||||
|
||||
def canonicalize_names():
|
||||
for path in glob('overworld/**/*.png', recursive=True):
|
||||
head, tail = os.path.split(path)
|
||||
name, ext = os.path.splitext(tail)
|
||||
try:
|
||||
num = int(name)
|
||||
except ValueError:
|
||||
continue
|
||||
new_name = f'{num:03d}'
|
||||
new_path = os.path.join(head, new_name+ext)
|
||||
os.rename(path, new_path)
|
||||
print(path, '->', new_path)
|
||||
|
||||
def closest_color(c, palette):
|
||||
min_d = float('inf')
|
||||
best = 0
|
||||
r1, g1, b1 = c
|
||||
for i, (r2, g2, b2) in enumerate(palette[1:], 1):
|
||||
# Color diff from https://stackoverflow.com/questions/1847092/given-an-rgb-value-what-would-be-the-best-way-to-find-the-closest-match-in-the-d
|
||||
d = ((r2-r1)*0.30)**2 + ((g2-g1)*0.59)**2 + ((b2-b1)*0.11)**2
|
||||
if d < min_d:
|
||||
min_d = d
|
||||
best = i
|
||||
return best
|
||||
|
||||
def apply_palette(palette_file, input_file, output_file): # Apply one file's palette to another
|
||||
plt = png.Reader(palette_file)
|
||||
plt.read()
|
||||
target_palette = tuple(c[:3] for c in plt.palette())
|
||||
inp = png.Reader(input_file)
|
||||
w, h, rows, _ = inp.read()
|
||||
src_palette = tuple(c[:3] for c in inp.palette())
|
||||
with open(output_file, 'wb') as f:
|
||||
new_rows = []
|
||||
for row in rows:
|
||||
new_rows.append([closest_color(src_palette[c], target_palette) if c else 0 for c in row])
|
||||
w = png.Writer(width=w, height=h, bitdepth=4, palette=target_palette)
|
||||
w.write(f, new_rows)
|
||||
|
||||
def paletteify(path, output_path=None):
|
||||
output_path = output_path or path
|
||||
joinp = os.path.join
|
||||
_, tail = os.path.split(path)
|
||||
species, _ = os.path.splitext(tail)
|
||||
front = png.Reader(joinp(PKMN_GRAPHICS, species, 'anim_front.png'))
|
||||
front.read()
|
||||
target_palette = tuple(c[:3] for c in front.palette())
|
||||
r, g, b = target_palette[0]
|
||||
color = f'rgb({r},{g},{b})'
|
||||
# Strip alpha color
|
||||
subprocess.run(['convert', path, '-background', color, '-alpha', 'remove', output_path], check=True)
|
||||
apply_palette(joinp(PKMN_GRAPHICS, species, 'anim_front.png'), output_path, output_path)
|
||||
|
||||
# Sprites from https://veekun.com/dex/downloads
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:]
|
||||
if args:
|
||||
paletteify(args[0])
|
||||
else:
|
||||
for path in sorted(glob('overworld/*.png')):
|
||||
_, tail = os.path.split(path)
|
||||
name, _ = os.path.splitext(tail)
|
||||
output_path = os.path.join('graphics/object_events/pics/pokemon', f'{name}.png')
|
||||
try:
|
||||
paletteify(path, output_path)
|
||||
except Exception as e:
|
||||
print(name, e.__class__.__name__, e, file=sys.stderr)
|
||||
|
||||
@ -1,50 +1,50 @@
|
||||
""" Processes & outputs follower emotion messages """
|
||||
import sys
|
||||
import re
|
||||
import textwrap
|
||||
|
||||
blank_regex = re.compile(r'\(?_+\)?')
|
||||
|
||||
|
||||
# Converts a series of message lines to a better format
|
||||
def convert_messages(infile, outfile='emotions.txt'):
|
||||
with open(infile, 'r') as f_in, open(outfile, 'w') as f_out:
|
||||
for line in f_in:
|
||||
line = line.rstrip('\n')
|
||||
if line and line[0] == '-':
|
||||
line = line[1:]
|
||||
line = line.lstrip()
|
||||
if not line:
|
||||
continue
|
||||
line = blank_regex.sub('{STR_VAR_1}', line)
|
||||
if line[-1] not in ('.', '?', '!', ':'):
|
||||
line += '.'
|
||||
print(line)
|
||||
f_out.write('\n' + line)
|
||||
|
||||
# Prepares a string for field-message display, performing line-wrapping, etc
|
||||
# Does not add a terminator, as this is done by _("")
|
||||
def prepare_string(s):
|
||||
lines = textwrap.wrap(s, width=36) # Width of message window
|
||||
s = lines[0]
|
||||
for i, line in enumerate(lines[1:]):
|
||||
ending = r'\p' if i % 2 else r'\n'
|
||||
s += ending + line
|
||||
return s
|
||||
|
||||
|
||||
# Exports up to n messages in C format to outfile
|
||||
def export_messages(infile, outfile, n=None, indent=0, start=0):
|
||||
with open(infile, 'r') as f_in:
|
||||
lines = f_in.readlines()
|
||||
if n is not None:
|
||||
lines = lines[:n]
|
||||
with open(outfile, 'w') as f_out:
|
||||
codelines = [' '*indent + f'static const u8 sCondMsg{start+i:02d}[] = _("{prepare_string(s)}");' for i, s in enumerate(lines)]
|
||||
f_out.write('\n'.join(codelines))
|
||||
print(f'{len(lines)} lines written')
|
||||
return len(lines)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
export_messages('emotions.txt', 'emotions.h', n=1, start=7)
|
||||
""" Processes & outputs follower emotion messages """
|
||||
import sys
|
||||
import re
|
||||
import textwrap
|
||||
|
||||
blank_regex = re.compile(r'\(?_+\)?')
|
||||
|
||||
|
||||
# Converts a series of message lines to a better format
|
||||
def convert_messages(infile, outfile='emotions.txt'):
|
||||
with open(infile, 'r') as f_in, open(outfile, 'w') as f_out:
|
||||
for line in f_in:
|
||||
line = line.rstrip('\n')
|
||||
if line and line[0] == '-':
|
||||
line = line[1:]
|
||||
line = line.lstrip()
|
||||
if not line:
|
||||
continue
|
||||
line = blank_regex.sub('{STR_VAR_1}', line)
|
||||
if line[-1] not in ('.', '?', '!', ':'):
|
||||
line += '.'
|
||||
print(line)
|
||||
f_out.write('\n' + line)
|
||||
|
||||
# Prepares a string for field-message display, performing line-wrapping, etc
|
||||
# Does not add a terminator, as this is done by _("")
|
||||
def prepare_string(s):
|
||||
lines = textwrap.wrap(s, width=36) # Width of message window
|
||||
s = lines[0]
|
||||
for i, line in enumerate(lines[1:]):
|
||||
ending = r'\p' if i % 2 else r'\n'
|
||||
s += ending + line
|
||||
return s
|
||||
|
||||
|
||||
# Exports up to n messages in C format to outfile
|
||||
def export_messages(infile, outfile, n=None, indent=0, start=0):
|
||||
with open(infile, 'r') as f_in:
|
||||
lines = f_in.readlines()
|
||||
if n is not None:
|
||||
lines = lines[:n]
|
||||
with open(outfile, 'w') as f_out:
|
||||
codelines = [' '*indent + f'static const u8 sCondMsg{start+i:02d}[] = _("{prepare_string(s)}");' for i, s in enumerate(lines)]
|
||||
f_out.write('\n'.join(codelines))
|
||||
print(f'{len(lines)} lines written')
|
||||
return len(lines)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
export_messages('emotions.txt', 'emotions.h', n=1, start=7)
|
||||
|
||||
@ -1,77 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
""" Extract sprites from HGSS follower spritesheets. """
|
||||
import os.path
|
||||
from os.path import join as joinp
|
||||
import subprocess
|
||||
import sys
|
||||
from glob import glob
|
||||
|
||||
import png
|
||||
from tqdm import tqdm
|
||||
|
||||
import shutil
|
||||
|
||||
def stack_sprite(name, path):
|
||||
frames = [joinp(path, 'down', name), joinp(path, 'down', 'frame2', name),
|
||||
joinp(path, 'up', name), joinp(path, 'up', 'frame2', name),
|
||||
joinp(path, 'left', name), joinp(path, 'left', 'frame2', name)]
|
||||
output = joinp(path, name)
|
||||
subprocess.run(['convert'] + frames + ['+append', output], check=True)
|
||||
print(f'Stacked {output}')
|
||||
|
||||
def closest_color(c, palette):
|
||||
min_d = float('inf')
|
||||
best = 0
|
||||
r1, g1, b1 = c
|
||||
for i, (r2, g2, b2) in enumerate(palette[1:], 1):
|
||||
# Color diff from https://stackoverflow.com/questions/1847092/given-an-rgb-value-what-would-be-the-best-way-to-find-the-closest-match-in-the-d
|
||||
d = ((r2-r1)*0.30)**2 + ((g2-g1)*0.59)**2 + ((b2-b1)*0.11)**2
|
||||
if d < min_d:
|
||||
min_d = d
|
||||
best = i
|
||||
return best
|
||||
|
||||
def apply_palette(palette_file, input_file, output_file): # Apply one file's palette to another
|
||||
plt = png.Reader(palette_file)
|
||||
plt.read()
|
||||
target_palette = tuple(c[:3] for c in plt.palette())
|
||||
inp = png.Reader(input_file)
|
||||
w, h, rows, info = inp.read()
|
||||
src_palette = tuple(c[:3] for c in inp.palette())
|
||||
new_rows = [[closest_color(src_palette[c][:3], target_palette) if c else 0 for c in row] for row in rows]
|
||||
with open(output_file, 'wb') as f:
|
||||
w = png.Writer(width=w, height=h, bitdepth=4, palette=target_palette)
|
||||
w.write(f, new_rows)
|
||||
|
||||
# Sprites from https://veekun.com/dex/downloads
|
||||
|
||||
def apply_front_palettes(ow_dir, project_root=''):
|
||||
mon_graphics = joinp(project_root, 'graphics', 'pokemon')
|
||||
for x in os.walk(ow_dir):
|
||||
current_dir = x[0]
|
||||
sub_dir = current_dir[len(ow_dir) + 1:1000]
|
||||
t = tqdm(sorted(glob(joinp(current_dir, '*.png'))))
|
||||
spaces = 0
|
||||
for path in t:
|
||||
name, _ = os.path.splitext(os.path.basename(path))
|
||||
name = joinp(sub_dir, name)
|
||||
# old_path = joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', f'{name}.png')
|
||||
# new_path = joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', name, 'follower.png')
|
||||
# os.mkdir(joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', name))
|
||||
# shutil.move(old_path, new_path)
|
||||
spaces = min(max(len(name), spaces), 10)
|
||||
t.set_description(name + ' '*(spaces-len(name)))
|
||||
output_path = joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', f'{name}.png')
|
||||
palette_path = joinp(mon_graphics, name, 'anim_front.png')
|
||||
try:
|
||||
apply_palette(palette_path, path, output_path)
|
||||
except Exception as e:
|
||||
palette_path = joinp(mon_graphics, name, 'front.png')
|
||||
try:
|
||||
apply_palette(palette_path, path, output_path)
|
||||
except Exception as e2:
|
||||
t.write(f'{name}: {e2.__class__.__name__}: {e2}', file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
apply_front_palettes('graphics/object_events/pics/pokemon')
|
||||
#!/usr/bin/env python3
|
||||
""" Extract sprites from HGSS follower spritesheets. """
|
||||
import os.path
|
||||
from os.path import join as joinp
|
||||
import subprocess
|
||||
import sys
|
||||
from glob import glob
|
||||
|
||||
import png
|
||||
from tqdm import tqdm
|
||||
|
||||
import shutil
|
||||
|
||||
def stack_sprite(name, path):
|
||||
frames = [joinp(path, 'down', name), joinp(path, 'down', 'frame2', name),
|
||||
joinp(path, 'up', name), joinp(path, 'up', 'frame2', name),
|
||||
joinp(path, 'left', name), joinp(path, 'left', 'frame2', name)]
|
||||
output = joinp(path, name)
|
||||
subprocess.run(['convert'] + frames + ['+append', output], check=True)
|
||||
print(f'Stacked {output}')
|
||||
|
||||
def closest_color(c, palette):
|
||||
min_d = float('inf')
|
||||
best = 0
|
||||
r1, g1, b1 = c
|
||||
for i, (r2, g2, b2) in enumerate(palette[1:], 1):
|
||||
# Color diff from https://stackoverflow.com/questions/1847092/given-an-rgb-value-what-would-be-the-best-way-to-find-the-closest-match-in-the-d
|
||||
d = ((r2-r1)*0.30)**2 + ((g2-g1)*0.59)**2 + ((b2-b1)*0.11)**2
|
||||
if d < min_d:
|
||||
min_d = d
|
||||
best = i
|
||||
return best
|
||||
|
||||
def apply_palette(palette_file, input_file, output_file): # Apply one file's palette to another
|
||||
plt = png.Reader(palette_file)
|
||||
plt.read()
|
||||
target_palette = tuple(c[:3] for c in plt.palette())
|
||||
inp = png.Reader(input_file)
|
||||
w, h, rows, info = inp.read()
|
||||
src_palette = tuple(c[:3] for c in inp.palette())
|
||||
new_rows = [[closest_color(src_palette[c][:3], target_palette) if c else 0 for c in row] for row in rows]
|
||||
with open(output_file, 'wb') as f:
|
||||
w = png.Writer(width=w, height=h, bitdepth=4, palette=target_palette)
|
||||
w.write(f, new_rows)
|
||||
|
||||
# Sprites from https://veekun.com/dex/downloads
|
||||
|
||||
def apply_front_palettes(ow_dir, project_root=''):
|
||||
mon_graphics = joinp(project_root, 'graphics', 'pokemon')
|
||||
for x in os.walk(ow_dir):
|
||||
current_dir = x[0]
|
||||
sub_dir = current_dir[len(ow_dir) + 1:1000]
|
||||
t = tqdm(sorted(glob(joinp(current_dir, '*.png'))))
|
||||
spaces = 0
|
||||
for path in t:
|
||||
name, _ = os.path.splitext(os.path.basename(path))
|
||||
name = joinp(sub_dir, name)
|
||||
# old_path = joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', f'{name}.png')
|
||||
# new_path = joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', name, 'follower.png')
|
||||
# os.mkdir(joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', name))
|
||||
# shutil.move(old_path, new_path)
|
||||
spaces = min(max(len(name), spaces), 10)
|
||||
t.set_description(name + ' '*(spaces-len(name)))
|
||||
output_path = joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', f'{name}.png')
|
||||
palette_path = joinp(mon_graphics, name, 'anim_front.png')
|
||||
try:
|
||||
apply_palette(palette_path, path, output_path)
|
||||
except Exception as e:
|
||||
palette_path = joinp(mon_graphics, name, 'front.png')
|
||||
try:
|
||||
apply_palette(palette_path, path, output_path)
|
||||
except Exception as e2:
|
||||
t.write(f'{name}: {e2.__class__.__name__}: {e2}', file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
apply_front_palettes('graphics/object_events/pics/pokemon')
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
#!/usr/bin/python3
|
||||
""" Extract a GBA-compatible palette from a PNG. """
|
||||
import sys
|
||||
import os.path
|
||||
import png
|
||||
|
||||
PAL_PRELUDE = 'JASC-PAL\n0100\n'
|
||||
|
||||
|
||||
def extract_palette(path):
|
||||
r = png.Reader(path)
|
||||
r.read()
|
||||
root, _ = os.path.splitext(path)
|
||||
out_path = root + '.pal'
|
||||
with open(out_path, 'w', newline='\r\n') as f:
|
||||
f.write(PAL_PRELUDE)
|
||||
colors = r.palette()
|
||||
if len(colors) < 16:
|
||||
colors += [(0, 0, 0) for _ in range(16-len(colors))]
|
||||
f.write(f'{len(colors)}\n')
|
||||
for r, g, b in colors:
|
||||
f.write(f'{r} {g} {b}\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
extract_palette(*sys.argv[1:])
|
||||
#!/usr/bin/python3
|
||||
""" Extract a GBA-compatible palette from a PNG. """
|
||||
import sys
|
||||
import os.path
|
||||
import png
|
||||
|
||||
PAL_PRELUDE = 'JASC-PAL\n0100\n'
|
||||
|
||||
|
||||
def extract_palette(path):
|
||||
r = png.Reader(path)
|
||||
r.read()
|
||||
root, _ = os.path.splitext(path)
|
||||
out_path = root + '.pal'
|
||||
with open(out_path, 'w', newline='\r\n') as f:
|
||||
f.write(PAL_PRELUDE)
|
||||
colors = r.palette()
|
||||
if len(colors) < 16:
|
||||
colors += [(0, 0, 0) for _ in range(16-len(colors))]
|
||||
f.write(f'{len(colors)}\n')
|
||||
for r, g, b in colors:
|
||||
f.write(f'{r} {g} {b}\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
extract_palette(*sys.argv[1:])
|
||||
|
||||
@ -1,24 +1,24 @@
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# THIS IS A TEMPORARY SCRIPT MADE TO RENAME FILES WITH THE "FOLLOWER" NAME TO "OVERWORLD",
|
||||
# AS THESE GRAPHICS CAN ALSO BE USED OUTSIDE THE FOLLOWER FEATURE.
|
||||
#
|
||||
# I'M SAVING IT HERE IN CASE IT'S NEEDED SOMEWHERE IN THE FUTURE, THOUGH TWEAKING MIGHT BE NEEDED.
|
||||
# - AsparagusEduardo
|
||||
|
||||
def rename_files(dir, old, new):
|
||||
for root, dirs, files in os.walk(dir):
|
||||
for name in files:
|
||||
if name.endswith(old):
|
||||
originalName = os.path.join(root, name)
|
||||
newName = originalName.replace(old, new)
|
||||
print(originalName + " -> " + newName)
|
||||
os.rename(originalName, newName)
|
||||
|
||||
rename_files("graphics/pokemon", 'follower.png', "overworld.png")
|
||||
rename_files("graphics/pokemon", 'follow_normal.pal', "overworld_normal.pal")
|
||||
rename_files("graphics/pokemon", 'follow_shiny.pal', "overworld_shiny.pal")
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# THIS IS A TEMPORARY SCRIPT MADE TO RENAME FILES WITH THE "FOLLOWER" NAME TO "OVERWORLD",
|
||||
# AS THESE GRAPHICS CAN ALSO BE USED OUTSIDE THE FOLLOWER FEATURE.
|
||||
#
|
||||
# I'M SAVING IT HERE IN CASE IT'S NEEDED SOMEWHERE IN THE FUTURE, THOUGH TWEAKING MIGHT BE NEEDED.
|
||||
# - AsparagusEduardo
|
||||
|
||||
def rename_files(dir, old, new):
|
||||
for root, dirs, files in os.walk(dir):
|
||||
for name in files:
|
||||
if name.endswith(old):
|
||||
originalName = os.path.join(root, name)
|
||||
newName = originalName.replace(old, new)
|
||||
print(originalName + " -> " + newName)
|
||||
os.rename(originalName, newName)
|
||||
|
||||
rename_files("graphics/pokemon", 'follower.png', "overworld.png")
|
||||
rename_files("graphics/pokemon", 'follow_normal.pal', "overworld_normal.pal")
|
||||
rename_files("graphics/pokemon", 'follow_shiny.pal', "overworld_shiny.pal")
|
||||
|
||||
@ -1,64 +1,64 @@
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# THIS IS A TEMPORARY SCRIPT MADE TO MOVE EXISTING FOLLOWER GRAPHICS FROM A SINGLE DIRECTORY.
|
||||
# IT TAKES FOLLOWER GRAPHICS FROM a 'followers' FOLDER IN THE ROOT FOLDER AND MOVES THEM BASED ON THEIR NAME.
|
||||
# EG. 'followers/bulbasaur.png' WILL BE MOVED to 'graphics/pokemon/bulbasaur/follower.png'.
|
||||
#
|
||||
# I'M SAVING IT HERE IN CASE IT'S NEEDED SOMEWHERE IN THE FUTURE, THOUGH TWEAKING MIGHT BE NEEDED.
|
||||
# - AsparagusEduardo
|
||||
|
||||
def rellocate_follower_graphics():
|
||||
dict_out = {}
|
||||
count = 0
|
||||
for pth in sorted(glob.glob('followers/*.png')):
|
||||
name = pth.replace(".png", "").replace("followers/", "")
|
||||
count+=1
|
||||
#if (count == 2):
|
||||
# break
|
||||
print(name)
|
||||
newname = name
|
||||
newname = newname.replace("_female", "/female")
|
||||
newname = newname.replace("_hisuian", "/hisuian")
|
||||
newname = newname.replace("_galarian", "/galarian")
|
||||
newname = newname.replace("_origin", "/origin")
|
||||
newname = newname.replace("_therian", "/therian")
|
||||
newname = newname.replace("_east_sea", "/east_sea")
|
||||
newname = newname.replace("_crowned", "/crowned")
|
||||
|
||||
newname = newname.replace("arceus_", "arceus/")
|
||||
newname = newname.replace("burmy_", "burmy/")
|
||||
newname = newname.replace("basculin_", "basculin/")
|
||||
newname = newname.replace("castform_", "castform/")
|
||||
newname = newname.replace("calyrex_", "calyrex/")
|
||||
newname = newname.replace("deerling_", "deerling/")
|
||||
newname = newname.replace("deoxys_", "deoxys/")
|
||||
newname = newname.replace("flabebe_", "flabebe/")
|
||||
newname = newname.replace("floette_", "floette/")
|
||||
newname = newname.replace("florges_", "florges/")
|
||||
newname = newname.replace("furfrou_", "furfrou/")
|
||||
newname = newname.replace("hoopa_", "hoopa/")
|
||||
newname = newname.replace("lycanroc_", "lycanroc/")
|
||||
newname = newname.replace("meloetta_", "meloetta/")
|
||||
newname = newname.replace("necrozma_", "necrozma/")
|
||||
newname = newname.replace("pichu_", "pichu/")
|
||||
newname = newname.replace("rotom_", "rotom/")
|
||||
newname = newname.replace("sawsbuck_", "sawsbuck/")
|
||||
newname = newname.replace("toxtricity_", "toxtricity/")
|
||||
newname = newname.replace("unown_", "unown/")
|
||||
newname = newname.replace("ursaluna_", "ursaluna/")
|
||||
newname = newname.replace("vivillon_", "vivillon/")
|
||||
newname = newname.replace("wormadam_", "wormadam/")
|
||||
|
||||
if (os.path.exists('followers/' + newname) == False):
|
||||
os.mkdir('followers/' + newname)
|
||||
os.rename('followers/' + name + '.png', 'followers/' + newname + '/follower.png')
|
||||
#os.popen('cp followers/' + name + '.png followers/' + name + '/follower.png')
|
||||
#os.remove('followers/' + name + '.png')
|
||||
#print(pth)
|
||||
#subprocess.run(["tools/gbagfx/gbagfx " + name +".png " + name + "_normal.pal'" + str(count) + "'"])
|
||||
|
||||
rellocate_follower_graphics()
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# THIS IS A TEMPORARY SCRIPT MADE TO MOVE EXISTING FOLLOWER GRAPHICS FROM A SINGLE DIRECTORY.
|
||||
# IT TAKES FOLLOWER GRAPHICS FROM a 'followers' FOLDER IN THE ROOT FOLDER AND MOVES THEM BASED ON THEIR NAME.
|
||||
# EG. 'followers/bulbasaur.png' WILL BE MOVED to 'graphics/pokemon/bulbasaur/follower.png'.
|
||||
#
|
||||
# I'M SAVING IT HERE IN CASE IT'S NEEDED SOMEWHERE IN THE FUTURE, THOUGH TWEAKING MIGHT BE NEEDED.
|
||||
# - AsparagusEduardo
|
||||
|
||||
def rellocate_follower_graphics():
|
||||
dict_out = {}
|
||||
count = 0
|
||||
for pth in sorted(glob.glob('followers/*.png')):
|
||||
name = pth.replace(".png", "").replace("followers/", "")
|
||||
count+=1
|
||||
#if (count == 2):
|
||||
# break
|
||||
print(name)
|
||||
newname = name
|
||||
newname = newname.replace("_female", "/female")
|
||||
newname = newname.replace("_hisuian", "/hisuian")
|
||||
newname = newname.replace("_galarian", "/galarian")
|
||||
newname = newname.replace("_origin", "/origin")
|
||||
newname = newname.replace("_therian", "/therian")
|
||||
newname = newname.replace("_east_sea", "/east_sea")
|
||||
newname = newname.replace("_crowned", "/crowned")
|
||||
|
||||
newname = newname.replace("arceus_", "arceus/")
|
||||
newname = newname.replace("burmy_", "burmy/")
|
||||
newname = newname.replace("basculin_", "basculin/")
|
||||
newname = newname.replace("castform_", "castform/")
|
||||
newname = newname.replace("calyrex_", "calyrex/")
|
||||
newname = newname.replace("deerling_", "deerling/")
|
||||
newname = newname.replace("deoxys_", "deoxys/")
|
||||
newname = newname.replace("flabebe_", "flabebe/")
|
||||
newname = newname.replace("floette_", "floette/")
|
||||
newname = newname.replace("florges_", "florges/")
|
||||
newname = newname.replace("furfrou_", "furfrou/")
|
||||
newname = newname.replace("hoopa_", "hoopa/")
|
||||
newname = newname.replace("lycanroc_", "lycanroc/")
|
||||
newname = newname.replace("meloetta_", "meloetta/")
|
||||
newname = newname.replace("necrozma_", "necrozma/")
|
||||
newname = newname.replace("pichu_", "pichu/")
|
||||
newname = newname.replace("rotom_", "rotom/")
|
||||
newname = newname.replace("sawsbuck_", "sawsbuck/")
|
||||
newname = newname.replace("toxtricity_", "toxtricity/")
|
||||
newname = newname.replace("unown_", "unown/")
|
||||
newname = newname.replace("ursaluna_", "ursaluna/")
|
||||
newname = newname.replace("vivillon_", "vivillon/")
|
||||
newname = newname.replace("wormadam_", "wormadam/")
|
||||
|
||||
if (os.path.exists('followers/' + newname) == False):
|
||||
os.mkdir('followers/' + newname)
|
||||
os.rename('followers/' + name + '.png', 'followers/' + newname + '/follower.png')
|
||||
#os.popen('cp followers/' + name + '.png followers/' + name + '/follower.png')
|
||||
#os.remove('followers/' + name + '.png')
|
||||
#print(pth)
|
||||
#subprocess.run(["tools/gbagfx/gbagfx " + name +".png " + name + "_normal.pal'" + str(count) + "'"])
|
||||
|
||||
rellocate_follower_graphics()
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# THIS IS A TEMPORARY SCRIPT MADE TO DELETE FILES WITH THE "footprint.png" NAME
|
||||
# FROM THE "graphics/pokemon_old" folder, AS MOST OF THEM ALREADY EXISTED IN "graphics/pokemon".
|
||||
#
|
||||
# I'M SAVING IT HERE IN CASE IT'S NEEDED SOMEWHERE IN THE FUTURE, THOUGH TWEAKING MIGHT BE NEEDED.
|
||||
# - AsparagusEduardo
|
||||
|
||||
def rename_files(dir, filename):
|
||||
for root, dirs, files in os.walk(dir):
|
||||
for name in files:
|
||||
if name.endswith(filename):
|
||||
fullName = os.path.join(root, name)
|
||||
print(fullName + " deleted.")
|
||||
os.remove(fullName)
|
||||
|
||||
rename_files("graphics/pokemon_old", 'footprint.png')
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# THIS IS A TEMPORARY SCRIPT MADE TO DELETE FILES WITH THE "footprint.png" NAME
|
||||
# FROM THE "graphics/pokemon_old" folder, AS MOST OF THEM ALREADY EXISTED IN "graphics/pokemon".
|
||||
#
|
||||
# I'M SAVING IT HERE IN CASE IT'S NEEDED SOMEWHERE IN THE FUTURE, THOUGH TWEAKING MIGHT BE NEEDED.
|
||||
# - AsparagusEduardo
|
||||
|
||||
def rename_files(dir, filename):
|
||||
for root, dirs, files in os.walk(dir):
|
||||
for name in files:
|
||||
if name.endswith(filename):
|
||||
fullName = os.path.join(root, name)
|
||||
print(fullName + " deleted.")
|
||||
os.remove(fullName)
|
||||
|
||||
rename_files("graphics/pokemon_old", 'footprint.png')
|
||||
|
||||
@ -1,22 +1,22 @@
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def rename_files(dirOld, dirNew, old, new):
|
||||
for root, dirs, files in os.walk(dirOld):
|
||||
for name in files:
|
||||
if name.endswith(old):
|
||||
originalName = os.path.join(root, name)
|
||||
newName = originalName.replace(old, new)
|
||||
newName = newName.replace(dirOld, dirNew)
|
||||
print(originalName + " -> " + newName)
|
||||
os.rename(originalName, newName)
|
||||
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'anim_front.png', "anim_front_gba.png")
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'normal.pal', "normal_gba.pal")
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'shiny.pal', "shiny_gba.pal")
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'back.png', "back_gba.png")
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'icon.png', "icon_gba.png")
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'footprint.png', "footprint_gba.png")
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def rename_files(dirOld, dirNew, old, new):
|
||||
for root, dirs, files in os.walk(dirOld):
|
||||
for name in files:
|
||||
if name.endswith(old):
|
||||
originalName = os.path.join(root, name)
|
||||
newName = originalName.replace(old, new)
|
||||
newName = newName.replace(dirOld, dirNew)
|
||||
print(originalName + " -> " + newName)
|
||||
os.rename(originalName, newName)
|
||||
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'anim_front.png', "anim_front_gba.png")
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'normal.pal', "normal_gba.pal")
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'shiny.pal', "shiny_gba.pal")
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'back.png', "back_gba.png")
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'icon.png', "icon_gba.png")
|
||||
rename_files("graphics/pokemon_old", "graphics/pokemon", 'footprint.png', "footprint_gba.png")
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
[book]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "."
|
||||
title = "pokeemerald-expansion"
|
||||
|
||||
[output.html]
|
||||
git-repository-url = "https://github.com/rh-hideout/pokeemerald-expansion"
|
||||
edit-url-template = "https://github.com/rh-hideout/pokeemerald-expansion/edit/master/docs/{path}"
|
||||
site-url = "/pokeemerald-expansion/"
|
||||
|
||||
[preprocessor.fix_links]
|
||||
command = "python3 fix_links.py"
|
||||
after = [ "links" ]
|
||||
[book]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "."
|
||||
title = "pokeemerald-expansion"
|
||||
|
||||
[output.html]
|
||||
git-repository-url = "https://github.com/rh-hideout/pokeemerald-expansion"
|
||||
edit-url-template = "https://github.com/rh-hideout/pokeemerald-expansion/edit/master/docs/{path}"
|
||||
site-url = "/pokeemerald-expansion/"
|
||||
|
||||
[preprocessor.fix_links]
|
||||
command = "python3 fix_links.py"
|
||||
after = [ "links" ]
|
||||
|
||||
@ -1,51 +1,51 @@
|
||||
# workarounds to avoid changing current directory structure
|
||||
# autolink logic based on https://github.com/zopieux/py-gfm/blob/fd7b33ed138d240d24dfb659acff7d4ce3f43745/gfm/autolink.py
|
||||
|
||||
import json
|
||||
import sys
|
||||
import re
|
||||
|
||||
URL_RE = re.compile(
|
||||
r"(```(?s:.)+?```|`.+?`|<.+?>)|"
|
||||
r"\b((?:(?i:ftp|https?)://|(?i:www)\d{0,3}[.])(?:[^\s()<>]+|"
|
||||
r"\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()"
|
||||
r"<>]+\)))*\)|[^\s`!()\[\]{};:" + r"'" + r'".,<>?«»“”‘’*]))'
|
||||
)
|
||||
PROTOCOL_RE = re.compile(r"^(?i:ftp|https?)://")
|
||||
|
||||
ANCHOR_RE = re.compile(r"(\]\((?:[^)#]+\.md)?#)([^)]+\))")
|
||||
|
||||
def handle_url(m):
|
||||
code = m.group(1)
|
||||
if code:
|
||||
return code
|
||||
href = m.group(2)
|
||||
if not PROTOCOL_RE.match(href):
|
||||
href = "http://%s" % href
|
||||
return f'<{href}>'
|
||||
|
||||
def handle_anchor(m):
|
||||
page = m.group(1)
|
||||
anchor = m.group(2)
|
||||
return page + anchor.lower()
|
||||
|
||||
def proc_items(items):
|
||||
for item in items:
|
||||
if 'Chapter' in item:
|
||||
s = item['Chapter']['content']
|
||||
s = s.replace('](README.md)', '](./)')
|
||||
s = s.replace('](/INSTALL.md', '](INSTALL.md')
|
||||
s = s.replace('](docs/', '](')
|
||||
s = URL_RE.sub(handle_url, s)
|
||||
item['Chapter']['content'] = ANCHOR_RE.sub(handle_anchor, s)
|
||||
proc_items(item['Chapter']['sub_items'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) > 1:
|
||||
if sys.argv[1] == "supports":
|
||||
sys.exit(0)
|
||||
|
||||
context, book = json.load(sys.stdin)
|
||||
proc_items(book['sections'])
|
||||
|
||||
print(json.dumps(book))
|
||||
# workarounds to avoid changing current directory structure
|
||||
# autolink logic based on https://github.com/zopieux/py-gfm/blob/fd7b33ed138d240d24dfb659acff7d4ce3f43745/gfm/autolink.py
|
||||
|
||||
import json
|
||||
import sys
|
||||
import re
|
||||
|
||||
URL_RE = re.compile(
|
||||
r"(```(?s:.)+?```|`.+?`|<.+?>)|"
|
||||
r"\b((?:(?i:ftp|https?)://|(?i:www)\d{0,3}[.])(?:[^\s()<>]+|"
|
||||
r"\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()"
|
||||
r"<>]+\)))*\)|[^\s`!()\[\]{};:" + r"'" + r'".,<>?«»“”‘’*]))'
|
||||
)
|
||||
PROTOCOL_RE = re.compile(r"^(?i:ftp|https?)://")
|
||||
|
||||
ANCHOR_RE = re.compile(r"(\]\((?:[^)#]+\.md)?#)([^)]+\))")
|
||||
|
||||
def handle_url(m):
|
||||
code = m.group(1)
|
||||
if code:
|
||||
return code
|
||||
href = m.group(2)
|
||||
if not PROTOCOL_RE.match(href):
|
||||
href = "http://%s" % href
|
||||
return f'<{href}>'
|
||||
|
||||
def handle_anchor(m):
|
||||
page = m.group(1)
|
||||
anchor = m.group(2)
|
||||
return page + anchor.lower()
|
||||
|
||||
def proc_items(items):
|
||||
for item in items:
|
||||
if 'Chapter' in item:
|
||||
s = item['Chapter']['content']
|
||||
s = s.replace('](README.md)', '](./)')
|
||||
s = s.replace('](/INSTALL.md', '](INSTALL.md')
|
||||
s = s.replace('](docs/', '](')
|
||||
s = URL_RE.sub(handle_url, s)
|
||||
item['Chapter']['content'] = ANCHOR_RE.sub(handle_anchor, s)
|
||||
proc_items(item['Chapter']['sub_items'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) > 1:
|
||||
if sys.argv[1] == "supports":
|
||||
sys.exit(0)
|
||||
|
||||
context, book = json.load(sys.stdin)
|
||||
proc_items(book['sections'])
|
||||
|
||||
print(json.dumps(book))
|
||||
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1003 B After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 383 B After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 714 B After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 622 B After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 946 B After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1011 B After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 275 B After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 354 B After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 838 B After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 2.8 KiB |
@ -1,188 +1,188 @@
|
||||
ENTRY(Start)
|
||||
|
||||
gNumMusicPlayers = 4;
|
||||
gMaxLines = 0;
|
||||
gInitialMainCB2 = CB2_InitCopyrightScreenAfterBootup;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
EWRAM (rwx) : ORIGIN = 0x2000000, LENGTH = 256K
|
||||
IWRAM (rwx) : ORIGIN = 0x3000000, LENGTH = 32K
|
||||
ROM (rx) : ORIGIN = 0x8000000, LENGTH = 32M
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
|
||||
|
||||
.ewram ORIGIN(EWRAM) : AT (__ewram_lma)
|
||||
ALIGN(4)
|
||||
{
|
||||
__ewram_start = .;
|
||||
*(.ewram*)
|
||||
. = ALIGN(4);
|
||||
__ewram_end = .;
|
||||
} > EWRAM
|
||||
|
||||
.ewram.sbss (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.sbss);
|
||||
} > EWRAM
|
||||
|
||||
.iwram ORIGIN(IWRAM) : AT (__iwram_lma)
|
||||
ALIGN(4)
|
||||
{
|
||||
__iwram_start = .;
|
||||
*(.iwram*);
|
||||
. = ALIGN(4);
|
||||
__iwram_end = .;
|
||||
} > IWRAM
|
||||
|
||||
.iwram.bss (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.bss);
|
||||
data/*.o(.bss);
|
||||
*libc.a:*.o(.bss*);
|
||||
*libnosys.a:*.o(.bss*);
|
||||
|
||||
src/m4a.o(.bss.code);
|
||||
|
||||
src/*.o(common_data);
|
||||
src/*.o(COMMON);
|
||||
*libc.a:*.o(COMMON);
|
||||
*libnosys.a:*.o(COMMON);
|
||||
} > IWRAM
|
||||
|
||||
/* BEGIN ROM DATA */
|
||||
|
||||
.text ORIGIN(ROM) :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/rom_header.o(.text*);
|
||||
src/rom_header_gf.o(.text.*);
|
||||
src/rom_header_rhh.o(.text.*);
|
||||
src/crt0.o(.text);
|
||||
src/main.o(.text);
|
||||
src/*.o(.text*);
|
||||
asm/*.o(.text*);
|
||||
} > ROM =0
|
||||
|
||||
script_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
data/*.o(script_data);
|
||||
} > ROM =0
|
||||
|
||||
lib_text :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/libgcnmultiboot.o(.text);
|
||||
src/m4a_1.o(.text);
|
||||
src/m4a.o(.text);
|
||||
src/agb_flash.o(.text);
|
||||
src/agb_flash_1m.o(.text);
|
||||
src/agb_flash_mx.o(.text);
|
||||
src/siirtc.o(.text);
|
||||
src/librfu_stwi.o(.text);
|
||||
src/librfu_intr.o(.text);
|
||||
src/librfu_rfu.o(.text);
|
||||
src/librfu_sio32id.o(.text);
|
||||
*libagbsyscall.a:*.o(.text*);
|
||||
*libgcc.a:*.o(.text*);
|
||||
*libc.a:*.o(.text*);
|
||||
*libnosys.a:*.o(.text*);
|
||||
src/libisagbprn.o(.text);
|
||||
} > ROM =0
|
||||
|
||||
.rodata :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.rodata*);
|
||||
data/*.o(.rodata*);
|
||||
} > ROM =0
|
||||
|
||||
song_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
sound/songs/*.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
lib_rodata :
|
||||
SUBALIGN(4)
|
||||
{
|
||||
src/m4a.o(.rodata);
|
||||
src/agb_flash.o(.rodata);
|
||||
src/agb_flash_1m.o(.rodata);
|
||||
src/agb_flash_mx.o(.rodata);
|
||||
src/agb_flash_le.o(.rodata);
|
||||
src/siirtc.o(.rodata);
|
||||
src/librfu_rfu.o(.rodata);
|
||||
src/librfu_sio32id.o(.rodata);
|
||||
*libgcc.a:*.o(.rodata*);
|
||||
*libc.a:*.o(.rodata*);
|
||||
*libc.a:*.o(.data*);
|
||||
src/libisagbprn.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
multiboot_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
data/multiboot_ereader.o(.rodata);
|
||||
data/multiboot_berry_glitch_fix.o(.rodata);
|
||||
data/multiboot_pokemon_colosseum.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
gfx_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/graphics.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
.data.iwram :
|
||||
ALIGN(4)
|
||||
{
|
||||
__iwram_lma = .;
|
||||
. = . + (__iwram_end - __iwram_start);
|
||||
} > ROM = 0
|
||||
|
||||
.data.ewram :
|
||||
ALIGN(4)
|
||||
{
|
||||
__ewram_lma = .;
|
||||
. = . + (__ewram_end - __ewram_start);
|
||||
} > ROM = 0
|
||||
|
||||
__rom_end = .;
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
|
||||
/* Discard everything not specifically mentioned above. */
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(*);
|
||||
}
|
||||
}
|
||||
ENTRY(Start)
|
||||
|
||||
gNumMusicPlayers = 4;
|
||||
gMaxLines = 0;
|
||||
gInitialMainCB2 = CB2_InitCopyrightScreenAfterBootup;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
EWRAM (rwx) : ORIGIN = 0x2000000, LENGTH = 256K
|
||||
IWRAM (rwx) : ORIGIN = 0x3000000, LENGTH = 32K
|
||||
ROM (rx) : ORIGIN = 0x8000000, LENGTH = 32M
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
|
||||
|
||||
.ewram ORIGIN(EWRAM) : AT (__ewram_lma)
|
||||
ALIGN(4)
|
||||
{
|
||||
__ewram_start = .;
|
||||
*(.ewram*)
|
||||
. = ALIGN(4);
|
||||
__ewram_end = .;
|
||||
} > EWRAM
|
||||
|
||||
.ewram.sbss (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.sbss);
|
||||
} > EWRAM
|
||||
|
||||
.iwram ORIGIN(IWRAM) : AT (__iwram_lma)
|
||||
ALIGN(4)
|
||||
{
|
||||
__iwram_start = .;
|
||||
*(.iwram*);
|
||||
. = ALIGN(4);
|
||||
__iwram_end = .;
|
||||
} > IWRAM
|
||||
|
||||
.iwram.bss (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.bss);
|
||||
data/*.o(.bss);
|
||||
*libc.a:*.o(.bss*);
|
||||
*libnosys.a:*.o(.bss*);
|
||||
|
||||
src/m4a.o(.bss.code);
|
||||
|
||||
src/*.o(common_data);
|
||||
src/*.o(COMMON);
|
||||
*libc.a:*.o(COMMON);
|
||||
*libnosys.a:*.o(COMMON);
|
||||
} > IWRAM
|
||||
|
||||
/* BEGIN ROM DATA */
|
||||
|
||||
.text ORIGIN(ROM) :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/rom_header.o(.text*);
|
||||
src/rom_header_gf.o(.text.*);
|
||||
src/rom_header_rhh.o(.text.*);
|
||||
src/crt0.o(.text);
|
||||
src/main.o(.text);
|
||||
src/*.o(.text*);
|
||||
asm/*.o(.text*);
|
||||
} > ROM =0
|
||||
|
||||
script_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
data/*.o(script_data);
|
||||
} > ROM =0
|
||||
|
||||
lib_text :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/libgcnmultiboot.o(.text);
|
||||
src/m4a_1.o(.text);
|
||||
src/m4a.o(.text);
|
||||
src/agb_flash.o(.text);
|
||||
src/agb_flash_1m.o(.text);
|
||||
src/agb_flash_mx.o(.text);
|
||||
src/siirtc.o(.text);
|
||||
src/librfu_stwi.o(.text);
|
||||
src/librfu_intr.o(.text);
|
||||
src/librfu_rfu.o(.text);
|
||||
src/librfu_sio32id.o(.text);
|
||||
*libagbsyscall.a:*.o(.text*);
|
||||
*libgcc.a:*.o(.text*);
|
||||
*libc.a:*.o(.text*);
|
||||
*libnosys.a:*.o(.text*);
|
||||
src/libisagbprn.o(.text);
|
||||
} > ROM =0
|
||||
|
||||
.rodata :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.rodata*);
|
||||
data/*.o(.rodata*);
|
||||
} > ROM =0
|
||||
|
||||
song_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
sound/songs/*.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
lib_rodata :
|
||||
SUBALIGN(4)
|
||||
{
|
||||
src/m4a.o(.rodata);
|
||||
src/agb_flash.o(.rodata);
|
||||
src/agb_flash_1m.o(.rodata);
|
||||
src/agb_flash_mx.o(.rodata);
|
||||
src/agb_flash_le.o(.rodata);
|
||||
src/siirtc.o(.rodata);
|
||||
src/librfu_rfu.o(.rodata);
|
||||
src/librfu_sio32id.o(.rodata);
|
||||
*libgcc.a:*.o(.rodata*);
|
||||
*libc.a:*.o(.rodata*);
|
||||
*libc.a:*.o(.data*);
|
||||
src/libisagbprn.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
multiboot_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
data/multiboot_ereader.o(.rodata);
|
||||
data/multiboot_berry_glitch_fix.o(.rodata);
|
||||
data/multiboot_pokemon_colosseum.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
gfx_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/graphics.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
.data.iwram :
|
||||
ALIGN(4)
|
||||
{
|
||||
__iwram_lma = .;
|
||||
. = . + (__iwram_end - __iwram_start);
|
||||
} > ROM = 0
|
||||
|
||||
.data.ewram :
|
||||
ALIGN(4)
|
||||
{
|
||||
__ewram_lma = .;
|
||||
. = . + (__ewram_end - __ewram_start);
|
||||
} > ROM = 0
|
||||
|
||||
__rom_end = .;
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
|
||||
/* Discard everything not specifically mentioned above. */
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(*);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,182 +1,182 @@
|
||||
ENTRY(Start)
|
||||
|
||||
gNumMusicPlayers = 4;
|
||||
gMaxLines = 0;
|
||||
gInitialMainCB2 = CB2_TestRunner;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
EWRAM (rwx) : ORIGIN = 0x2000000, LENGTH = 256K
|
||||
IWRAM (rwx) : ORIGIN = 0x3000000, LENGTH = 32K
|
||||
ROM (rx) : ORIGIN = 0x8000000, LENGTH = 32M
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
|
||||
.ewram ORIGIN(EWRAM) : AT (__ewram_lma)
|
||||
ALIGN(4)
|
||||
{
|
||||
__ewram_start = .;
|
||||
*(.ewram*)
|
||||
__ewram_end = .;
|
||||
} > EWRAM
|
||||
|
||||
.ewram.sbss (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.sbss);
|
||||
test/*.o(.sbss);
|
||||
. = ALIGN(4);
|
||||
} > EWRAM
|
||||
|
||||
.iwram ORIGIN(IWRAM) : AT (__iwram_lma)
|
||||
ALIGN(4)
|
||||
{
|
||||
__iwram_start = .;
|
||||
*(.iwram*);
|
||||
. = ALIGN(4);
|
||||
__iwram_end = .;
|
||||
} > IWRAM
|
||||
|
||||
.iwram.bss (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.bss);
|
||||
data/*.o(.bss);
|
||||
test/*.o(.bss);
|
||||
*libc.a:*.o(.bss*);
|
||||
*libgcc.a:*.o(.bss*);
|
||||
*libnosys.a:*.o(.bss*);
|
||||
|
||||
src/m4a.o(.bss.code);
|
||||
|
||||
src/*.o(common_data);
|
||||
src/*.o(COMMON);
|
||||
data/*.o(COMMON);
|
||||
test/*.o(COMMON);
|
||||
*libc.a:sbrkr.o(COMMON);
|
||||
} > IWRAM
|
||||
|
||||
/* .persistent starts at 0x3007F00 */
|
||||
/* WARNING: This is the end of the IRQ stack, if there's too
|
||||
* much data it WILL be overwritten. */
|
||||
|
||||
. = 0x03007F00;
|
||||
.iwram.persistent (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
test/*.o(.persistent);
|
||||
} > IWRAM
|
||||
|
||||
/* BEGIN ROM DATA */
|
||||
. = 0x8000000;
|
||||
|
||||
.text :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/rom_header.o(.text);
|
||||
src/rom_header_gf.o(.text.*);
|
||||
src/rom_header_rhh.o(.text.*);
|
||||
src/*.o(.text);
|
||||
} > ROM =0
|
||||
|
||||
script_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
data/*.o(script_data);
|
||||
} > ROM =0
|
||||
|
||||
lib_text :
|
||||
ALIGN(4)
|
||||
{
|
||||
*libagbsyscall.a:*.o(.text*);
|
||||
*libgcc.a:*.o(.text*);
|
||||
*libc.a:*.o(.text*);
|
||||
*libnosys.a:*.o(.text*);
|
||||
} > ROM =0
|
||||
|
||||
.rodata :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.rodata*);
|
||||
data/*.o(.rodata*);
|
||||
} > ROM =0
|
||||
|
||||
song_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
sound/songs/*.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
lib_rodata :
|
||||
SUBALIGN(4)
|
||||
{
|
||||
*libgcc.a:*.o(.rodata*);
|
||||
*libc.a:*.o(.rodata*);
|
||||
*libc.a:*.o(.data*);
|
||||
src/libisagbprn.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
.data.iwram :
|
||||
ALIGN(8)
|
||||
{
|
||||
__iwram_lma = .;
|
||||
. = . + (__iwram_end - __iwram_start);
|
||||
} > ROM = 0
|
||||
|
||||
.data.ewram :
|
||||
ALIGN(4)
|
||||
{
|
||||
__ewram_lma = .;
|
||||
. = . + (__ewram_end - __ewram_start);
|
||||
} > ROM = 0
|
||||
|
||||
tests :
|
||||
ALIGN(4)
|
||||
{
|
||||
__start_tests = .;
|
||||
test/*.o(.tests);
|
||||
__stop_tests = .;
|
||||
test/*.o(.text);
|
||||
test/*.o(.rodata*);
|
||||
} > ROM =0
|
||||
|
||||
__rom_end = .;
|
||||
|
||||
dacs 0x9FFC000 :
|
||||
ALIGN(4)
|
||||
{
|
||||
test/*.o(.dacs);
|
||||
} > ROM =0
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
|
||||
/* Discard everything not specifically mentioned above. */
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(*);
|
||||
}
|
||||
}
|
||||
ENTRY(Start)
|
||||
|
||||
gNumMusicPlayers = 4;
|
||||
gMaxLines = 0;
|
||||
gInitialMainCB2 = CB2_TestRunner;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
EWRAM (rwx) : ORIGIN = 0x2000000, LENGTH = 256K
|
||||
IWRAM (rwx) : ORIGIN = 0x3000000, LENGTH = 32K
|
||||
ROM (rx) : ORIGIN = 0x8000000, LENGTH = 32M
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
|
||||
.ewram ORIGIN(EWRAM) : AT (__ewram_lma)
|
||||
ALIGN(4)
|
||||
{
|
||||
__ewram_start = .;
|
||||
*(.ewram*)
|
||||
__ewram_end = .;
|
||||
} > EWRAM
|
||||
|
||||
.ewram.sbss (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.sbss);
|
||||
test/*.o(.sbss);
|
||||
. = ALIGN(4);
|
||||
} > EWRAM
|
||||
|
||||
.iwram ORIGIN(IWRAM) : AT (__iwram_lma)
|
||||
ALIGN(4)
|
||||
{
|
||||
__iwram_start = .;
|
||||
*(.iwram*);
|
||||
. = ALIGN(4);
|
||||
__iwram_end = .;
|
||||
} > IWRAM
|
||||
|
||||
.iwram.bss (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.bss);
|
||||
data/*.o(.bss);
|
||||
test/*.o(.bss);
|
||||
*libc.a:*.o(.bss*);
|
||||
*libgcc.a:*.o(.bss*);
|
||||
*libnosys.a:*.o(.bss*);
|
||||
|
||||
src/m4a.o(.bss.code);
|
||||
|
||||
src/*.o(common_data);
|
||||
src/*.o(COMMON);
|
||||
data/*.o(COMMON);
|
||||
test/*.o(COMMON);
|
||||
*libc.a:sbrkr.o(COMMON);
|
||||
} > IWRAM
|
||||
|
||||
/* .persistent starts at 0x3007F00 */
|
||||
/* WARNING: This is the end of the IRQ stack, if there's too
|
||||
* much data it WILL be overwritten. */
|
||||
|
||||
. = 0x03007F00;
|
||||
.iwram.persistent (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
test/*.o(.persistent);
|
||||
} > IWRAM
|
||||
|
||||
/* BEGIN ROM DATA */
|
||||
. = 0x8000000;
|
||||
|
||||
.text :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/rom_header.o(.text);
|
||||
src/rom_header_gf.o(.text.*);
|
||||
src/rom_header_rhh.o(.text.*);
|
||||
src/*.o(.text);
|
||||
} > ROM =0
|
||||
|
||||
script_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
data/*.o(script_data);
|
||||
} > ROM =0
|
||||
|
||||
lib_text :
|
||||
ALIGN(4)
|
||||
{
|
||||
*libagbsyscall.a:*.o(.text*);
|
||||
*libgcc.a:*.o(.text*);
|
||||
*libc.a:*.o(.text*);
|
||||
*libnosys.a:*.o(.text*);
|
||||
} > ROM =0
|
||||
|
||||
.rodata :
|
||||
ALIGN(4)
|
||||
{
|
||||
src/*.o(.rodata*);
|
||||
data/*.o(.rodata*);
|
||||
} > ROM =0
|
||||
|
||||
song_data :
|
||||
ALIGN(4)
|
||||
{
|
||||
sound/songs/*.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
lib_rodata :
|
||||
SUBALIGN(4)
|
||||
{
|
||||
*libgcc.a:*.o(.rodata*);
|
||||
*libc.a:*.o(.rodata*);
|
||||
*libc.a:*.o(.data*);
|
||||
src/libisagbprn.o(.rodata);
|
||||
} > ROM =0
|
||||
|
||||
.data.iwram :
|
||||
ALIGN(8)
|
||||
{
|
||||
__iwram_lma = .;
|
||||
. = . + (__iwram_end - __iwram_start);
|
||||
} > ROM = 0
|
||||
|
||||
.data.ewram :
|
||||
ALIGN(4)
|
||||
{
|
||||
__ewram_lma = .;
|
||||
. = . + (__ewram_end - __ewram_start);
|
||||
} > ROM = 0
|
||||
|
||||
tests :
|
||||
ALIGN(4)
|
||||
{
|
||||
__start_tests = .;
|
||||
test/*.o(.tests);
|
||||
__stop_tests = .;
|
||||
test/*.o(.text);
|
||||
test/*.o(.rodata*);
|
||||
} > ROM =0
|
||||
|
||||
__rom_end = .;
|
||||
|
||||
dacs 0x9FFC000 :
|
||||
ALIGN(4)
|
||||
{
|
||||
test/*.o(.dacs);
|
||||
} > ROM =0
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
|
||||
/* Discard everything not specifically mentioned above. */
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(*);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,45 +1,45 @@
|
||||
import glob
|
||||
import re
|
||||
import os
|
||||
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from your root folder.")
|
||||
quit()
|
||||
|
||||
# Read contest_opponents.h
|
||||
for file in glob.glob('./src/data/contest_opponents.h'):
|
||||
with open(file, 'r') as f:
|
||||
source_content = f.read()
|
||||
|
||||
# Extract party info from contest_opponents.h
|
||||
source_pattern = re.compile(r'(\[CONTEST_OPPONENT_.*\])\s*=\s(CONTEST_FILTER_.*)*')
|
||||
source_data = {}
|
||||
for match in source_pattern.findall(source_content):
|
||||
if len(match) == 2:
|
||||
trainer_name, contest_filter = match
|
||||
source_data[trainer_name] = (contest_filter)
|
||||
|
||||
# Read contest_opponents.h content
|
||||
for file in glob.glob('./src/data/contest_opponents.h'):
|
||||
with open(file, 'r') as f:
|
||||
destination_content = f.read()
|
||||
|
||||
# Modify contest_opponents.h content
|
||||
def add_filter_data(match):
|
||||
trainer_name = match.group(1)
|
||||
if trainer_name in source_data:
|
||||
contest_filter = source_data[trainer_name]
|
||||
print(f"Updating {trainer_name}: adding {contest_filter}")
|
||||
#return f'{trainer_name} = {{\n .filter = {contest_filter}'
|
||||
return f'{match.group(0)}\n .filter = {contest_filter}'
|
||||
else:
|
||||
return match.group(0)
|
||||
|
||||
destination_pattern = re.compile(r'(\[CONTEST_OPPONENT_[A-Z_0-9]+\])\s*=\s*{')
|
||||
modified_content = destination_pattern.sub(add_filter_data, destination_content)
|
||||
|
||||
# Write the modified content back to contest_opponents.h
|
||||
for file in glob.glob('./src/data/contest_opponents.h'):
|
||||
with open(file, 'w') as f:
|
||||
f.write(modified_content)
|
||||
print("contest_opponents.h has been updated")
|
||||
import glob
|
||||
import re
|
||||
import os
|
||||
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from your root folder.")
|
||||
quit()
|
||||
|
||||
# Read contest_opponents.h
|
||||
for file in glob.glob('./src/data/contest_opponents.h'):
|
||||
with open(file, 'r') as f:
|
||||
source_content = f.read()
|
||||
|
||||
# Extract party info from contest_opponents.h
|
||||
source_pattern = re.compile(r'(\[CONTEST_OPPONENT_.*\])\s*=\s(CONTEST_FILTER_.*)*')
|
||||
source_data = {}
|
||||
for match in source_pattern.findall(source_content):
|
||||
if len(match) == 2:
|
||||
trainer_name, contest_filter = match
|
||||
source_data[trainer_name] = (contest_filter)
|
||||
|
||||
# Read contest_opponents.h content
|
||||
for file in glob.glob('./src/data/contest_opponents.h'):
|
||||
with open(file, 'r') as f:
|
||||
destination_content = f.read()
|
||||
|
||||
# Modify contest_opponents.h content
|
||||
def add_filter_data(match):
|
||||
trainer_name = match.group(1)
|
||||
if trainer_name in source_data:
|
||||
contest_filter = source_data[trainer_name]
|
||||
print(f"Updating {trainer_name}: adding {contest_filter}")
|
||||
#return f'{trainer_name} = {{\n .filter = {contest_filter}'
|
||||
return f'{match.group(0)}\n .filter = {contest_filter}'
|
||||
else:
|
||||
return match.group(0)
|
||||
|
||||
destination_pattern = re.compile(r'(\[CONTEST_OPPONENT_[A-Z_0-9]+\])\s*=\s*{')
|
||||
modified_content = destination_pattern.sub(add_filter_data, destination_content)
|
||||
|
||||
# Write the modified content back to contest_opponents.h
|
||||
for file in glob.glob('./src/data/contest_opponents.h'):
|
||||
with open(file, 'w') as f:
|
||||
f.write(modified_content)
|
||||
print("contest_opponents.h has been updated")
|
||||
|
||||
@ -1,44 +1,44 @@
|
||||
import glob
|
||||
import re
|
||||
import os
|
||||
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from your root folder.")
|
||||
quit()
|
||||
|
||||
# Read battle_frontier_trainer_mons.h and extract the party information
|
||||
for file in glob.glob('./src/data/battle_frontier/battle_frontier_trainer_mons.h'):
|
||||
with open(file, 'r') as f:
|
||||
source_content = f.read()
|
||||
|
||||
# Extract party info from battle_frontier_trainer_mons.h
|
||||
source_pattern = re.compile(r'gBattleFrontierTrainerMons_(.*)\[\]\s*=\s*\n\{\n\s*(FRONTIER.*)')
|
||||
source_data = {}
|
||||
for match in source_pattern.findall(source_content):
|
||||
if len(match) == 2:
|
||||
trainer_name, party_group = match
|
||||
source_data[trainer_name] = (party_group)
|
||||
|
||||
# Read battle_frontier_trainers.h content
|
||||
for file in glob.glob('./src/data/battle_frontier/battle_frontier_trainers.h'):
|
||||
with open(file, 'r') as f:
|
||||
destination_content = f.read()
|
||||
|
||||
# Modify battle_frontier_trainers.h content
|
||||
def add_party_data(match):
|
||||
trainer_name = match.group(1)
|
||||
if trainer_name in source_data:
|
||||
party_group = source_data[trainer_name]
|
||||
print(f"Updating {trainer_name}: adding {party_group}")
|
||||
return f'(const u16[]){{{party_group}}}'
|
||||
else:
|
||||
return match.group(0)
|
||||
|
||||
destination_pattern = re.compile(r'gBattleFrontierTrainerMons_(.*)')
|
||||
modified_content = destination_pattern.sub(add_party_data, destination_content)
|
||||
|
||||
# Write the modified content back to battle_frontier_trainers.h
|
||||
for file in glob.glob('./src/data/battle_frontier/battle_frontier_trainers.h'):
|
||||
with open(file, 'w') as f:
|
||||
f.write(modified_content)
|
||||
print("battle_frontier_trainers.h has been updated")
|
||||
import glob
|
||||
import re
|
||||
import os
|
||||
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from your root folder.")
|
||||
quit()
|
||||
|
||||
# Read battle_frontier_trainer_mons.h and extract the party information
|
||||
for file in glob.glob('./src/data/battle_frontier/battle_frontier_trainer_mons.h'):
|
||||
with open(file, 'r') as f:
|
||||
source_content = f.read()
|
||||
|
||||
# Extract party info from battle_frontier_trainer_mons.h
|
||||
source_pattern = re.compile(r'gBattleFrontierTrainerMons_(.*)\[\]\s*=\s*\n\{\n\s*(FRONTIER.*)')
|
||||
source_data = {}
|
||||
for match in source_pattern.findall(source_content):
|
||||
if len(match) == 2:
|
||||
trainer_name, party_group = match
|
||||
source_data[trainer_name] = (party_group)
|
||||
|
||||
# Read battle_frontier_trainers.h content
|
||||
for file in glob.glob('./src/data/battle_frontier/battle_frontier_trainers.h'):
|
||||
with open(file, 'r') as f:
|
||||
destination_content = f.read()
|
||||
|
||||
# Modify battle_frontier_trainers.h content
|
||||
def add_party_data(match):
|
||||
trainer_name = match.group(1)
|
||||
if trainer_name in source_data:
|
||||
party_group = source_data[trainer_name]
|
||||
print(f"Updating {trainer_name}: adding {party_group}")
|
||||
return f'(const u16[]){{{party_group}}}'
|
||||
else:
|
||||
return match.group(0)
|
||||
|
||||
destination_pattern = re.compile(r'gBattleFrontierTrainerMons_(.*)')
|
||||
modified_content = destination_pattern.sub(add_party_data, destination_content)
|
||||
|
||||
# Write the modified content back to battle_frontier_trainers.h
|
||||
for file in glob.glob('./src/data/battle_frontier/battle_frontier_trainers.h'):
|
||||
with open(file, 'w') as f:
|
||||
f.write(modified_content)
|
||||
print("battle_frontier_trainers.h has been updated")
|
||||
|
||||
@ -1,85 +1,85 @@
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from your root folder.")
|
||||
quit()
|
||||
|
||||
# scan incs
|
||||
incs_to_check = glob.glob('./data/scripts/*.inc') # all .incs in the script folder
|
||||
incs_to_check += glob.glob('./data/maps/*/scripts.inc') # all map scripts
|
||||
pories_to_check = glob.glob('./data/scripts/*.pory') ## all .porys in the script folder
|
||||
pories_to_check += glob.glob('./data/maps/*/scripts.pory') # all map scripts
|
||||
|
||||
array = []
|
||||
array_pories = []
|
||||
|
||||
# make a list of which script corresponds to which item
|
||||
for file in incs_to_check:
|
||||
with open(file, "r") as f2:
|
||||
raw = f2.read()
|
||||
array += re.findall("(.*)::\n[ ]*finditem (.*)\n[ ]*end", raw)
|
||||
|
||||
# since this doesn't catch poryscript-generated inc files, do the same for poryscript
|
||||
for file in pories_to_check:
|
||||
with open(file, "r") as f2:
|
||||
raw = f2.read()
|
||||
array_pories += re.findall("script ([\w]*)[ \n]*\{[ \n]*finditem\((.*)\)[ \n]*\}", raw)
|
||||
|
||||
dict = {}
|
||||
# poryscript values are prioritised because they would overwrite inc files anyway if different
|
||||
for x in array_pories:
|
||||
dict[x[0]] = x[1]
|
||||
for x in array:
|
||||
if not x[0] in dict:
|
||||
dict[x[0]] = x[1]
|
||||
|
||||
# apply changes to inc files
|
||||
for map in glob.glob('./data/maps/*/map.json'):
|
||||
with open(map, "r") as f2:
|
||||
data = json.load(f2)
|
||||
if not 'object_events' in data:
|
||||
continue
|
||||
for objevent in data['object_events']:
|
||||
if objevent["script"] in dict:
|
||||
objevent["trainer_sight_or_berry_tree_id"] = dict[objevent["script"]]
|
||||
objevent["script"] = "Common_EventScript_FindItem"
|
||||
with open(map, "w") as f2:
|
||||
f2.write(json.dumps(data, indent=2) + "\n")
|
||||
|
||||
# do another map search to find out which finditem scripts would somehow be still in use
|
||||
still_in_use = []
|
||||
for map in glob.glob('./data/maps/*/map.json'):
|
||||
with open(map, "r") as f2:
|
||||
data = json.load(f2)
|
||||
if not 'object_events' in data:
|
||||
continue
|
||||
for objevent in data['object_events']:
|
||||
if objevent["script"] in dict and not objevent["script"] in still_in_use:
|
||||
still_in_use.append(objevent["script"])
|
||||
|
||||
for x in list(dict.keys()):
|
||||
if x in still_in_use:
|
||||
del dict[x]
|
||||
|
||||
# clean up scripts that are now no longer in use
|
||||
for file in incs_to_check:
|
||||
with open(file, "r") as f2:
|
||||
raw = f2.read()
|
||||
for unused in list(dict.keys()):
|
||||
raw = re.sub("%s::\n[ ]*finditem (.*)\n[ ]*end\n*" % unused, "", raw)
|
||||
with open(file, "w") as f2:
|
||||
f2.write(raw)
|
||||
|
||||
# also clean up pory files
|
||||
for file in pories_to_check:
|
||||
with open(file, "r") as f2:
|
||||
raw = f2.read()
|
||||
for unused in list(dict.keys()):
|
||||
raw = re.sub("script %s[ \n]*\{[ \n]*finditem\((.*)\)[ \n]*\}[ \n]*" % unused, "", raw)
|
||||
with open(file, "w") as f2:
|
||||
f2.write(raw)
|
||||
|
||||
print("Done!")
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from your root folder.")
|
||||
quit()
|
||||
|
||||
# scan incs
|
||||
incs_to_check = glob.glob('./data/scripts/*.inc') # all .incs in the script folder
|
||||
incs_to_check += glob.glob('./data/maps/*/scripts.inc') # all map scripts
|
||||
pories_to_check = glob.glob('./data/scripts/*.pory') ## all .porys in the script folder
|
||||
pories_to_check += glob.glob('./data/maps/*/scripts.pory') # all map scripts
|
||||
|
||||
array = []
|
||||
array_pories = []
|
||||
|
||||
# make a list of which script corresponds to which item
|
||||
for file in incs_to_check:
|
||||
with open(file, "r") as f2:
|
||||
raw = f2.read()
|
||||
array += re.findall("(.*)::\n[ ]*finditem (.*)\n[ ]*end", raw)
|
||||
|
||||
# since this doesn't catch poryscript-generated inc files, do the same for poryscript
|
||||
for file in pories_to_check:
|
||||
with open(file, "r") as f2:
|
||||
raw = f2.read()
|
||||
array_pories += re.findall("script ([\w]*)[ \n]*\{[ \n]*finditem\((.*)\)[ \n]*\}", raw)
|
||||
|
||||
dict = {}
|
||||
# poryscript values are prioritised because they would overwrite inc files anyway if different
|
||||
for x in array_pories:
|
||||
dict[x[0]] = x[1]
|
||||
for x in array:
|
||||
if not x[0] in dict:
|
||||
dict[x[0]] = x[1]
|
||||
|
||||
# apply changes to inc files
|
||||
for map in glob.glob('./data/maps/*/map.json'):
|
||||
with open(map, "r") as f2:
|
||||
data = json.load(f2)
|
||||
if not 'object_events' in data:
|
||||
continue
|
||||
for objevent in data['object_events']:
|
||||
if objevent["script"] in dict:
|
||||
objevent["trainer_sight_or_berry_tree_id"] = dict[objevent["script"]]
|
||||
objevent["script"] = "Common_EventScript_FindItem"
|
||||
with open(map, "w") as f2:
|
||||
f2.write(json.dumps(data, indent=2) + "\n")
|
||||
|
||||
# do another map search to find out which finditem scripts would somehow be still in use
|
||||
still_in_use = []
|
||||
for map in glob.glob('./data/maps/*/map.json'):
|
||||
with open(map, "r") as f2:
|
||||
data = json.load(f2)
|
||||
if not 'object_events' in data:
|
||||
continue
|
||||
for objevent in data['object_events']:
|
||||
if objevent["script"] in dict and not objevent["script"] in still_in_use:
|
||||
still_in_use.append(objevent["script"])
|
||||
|
||||
for x in list(dict.keys()):
|
||||
if x in still_in_use:
|
||||
del dict[x]
|
||||
|
||||
# clean up scripts that are now no longer in use
|
||||
for file in incs_to_check:
|
||||
with open(file, "r") as f2:
|
||||
raw = f2.read()
|
||||
for unused in list(dict.keys()):
|
||||
raw = re.sub("%s::\n[ ]*finditem (.*)\n[ ]*end\n*" % unused, "", raw)
|
||||
with open(file, "w") as f2:
|
||||
f2.write(raw)
|
||||
|
||||
# also clean up pory files
|
||||
for file in pories_to_check:
|
||||
with open(file, "r") as f2:
|
||||
raw = f2.read()
|
||||
for unused in list(dict.keys()):
|
||||
raw = re.sub("script %s[ \n]*\{[ \n]*finditem\((.*)\)[ \n]*\}[ \n]*" % unused, "", raw)
|
||||
with open(file, "w") as f2:
|
||||
f2.write(raw)
|
||||
|
||||
print("Done!")
|
||||
|
||||
@ -1,62 +1,62 @@
|
||||
import re
|
||||
|
||||
def battle_frontier_mons(data):
|
||||
data = re.sub(re.escape(".itemTableId = BATTLE_FRONTIER_"), ".heldItem = ", data)
|
||||
data = re.sub(re.escape("FacilityMon"), "TrainerMon", data)
|
||||
data = re.sub(re.escape(".evSpread = 0,"), ".ev = NULL,", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 0, 0, 0, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 170, 170, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 252, 0, 0, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED,"), ".ev = TRAINER_PARTY_EVS(0, 0, 0, 252, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 170, 170, 0, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 170, 0, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 0, 170, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 0, 170, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 170, 0, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE,"), ".ev = TRAINER_PARTY_EVS(0, 0, 170, 170, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 0, 170, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 170, 0, 0, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 0, 0, 0, 252, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 252, 0, 0, 252, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE,"), ".ev = TRAINER_PARTY_EVS(0, 0, 252, 0, 252, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED,"), ".ev = TRAINER_PARTY_EVS(0, 0, 0, 252, 252, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(102, 102, 102, 102, 0, 102),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 128, 128, 0, 128, 128),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE,"), ".ev = TRAINER_PARTY_EVS(0, 0, 170, 0, 170, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(84, 84, 84, 84, 84, 84),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 128, 128, 128, 0, 128),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 170, 0, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(102, 0, 102, 102, 102, 102),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 0, 0, 170, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(128, 0, 128, 0, 128, 128),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(128, 128, 128, 0, 0, 128),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 0, 170, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 0, 170, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 0, 0, 0, 0, 252),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE,"), ".ev = TRAINER_PARTY_EVS(0, 0, 170, 170, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(128, 0, 128, 128, 0, 128),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 0, 0, 170, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 170, 0, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 170, 0, 0, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 252, 0, 0, 0, 252),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 0, 0, 0, 252, 252),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_DEFENSE,"), ".ev = TRAINER_PARTY_EVS(0, 0, 252, 0, 0, 252),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 252, 0, 0, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 0, 0, 252, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 170, 170, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 170, 0, 170, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 252, 0, 252, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 0, 252, 0, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 252, 252, 0, 0, 0),", data)
|
||||
|
||||
return data
|
||||
|
||||
with open('src/data/battle_frontier/battle_frontier_mons.h', 'r') as file:
|
||||
data = file.read()
|
||||
with open('src/data/battle_frontier/battle_frontier_mons.h', 'w') as file:
|
||||
file.write(battle_frontier_mons(data))
|
||||
|
||||
with open('src/data/battle_frontier/battle_tent.h', 'r') as file:
|
||||
data = file.read()
|
||||
with open('src/data/battle_frontier/battle_tent.h', 'w') as file:
|
||||
file.write(battle_frontier_mons(data))
|
||||
import re
|
||||
|
||||
def battle_frontier_mons(data):
|
||||
data = re.sub(re.escape(".itemTableId = BATTLE_FRONTIER_"), ".heldItem = ", data)
|
||||
data = re.sub(re.escape("FacilityMon"), "TrainerMon", data)
|
||||
data = re.sub(re.escape(".evSpread = 0,"), ".ev = NULL,", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 0, 0, 0, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 170, 170, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 252, 0, 0, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED,"), ".ev = TRAINER_PARTY_EVS(0, 0, 0, 252, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 170, 170, 0, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 170, 0, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 0, 170, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 0, 170, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 170, 0, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE,"), ".ev = TRAINER_PARTY_EVS(0, 0, 170, 170, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 0, 170, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 170, 0, 0, 170, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 0, 0, 0, 252, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 252, 0, 0, 252, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE,"), ".ev = TRAINER_PARTY_EVS(0, 0, 252, 0, 252, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED,"), ".ev = TRAINER_PARTY_EVS(0, 0, 0, 252, 252, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(102, 102, 102, 102, 0, 102),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 128, 128, 0, 128, 128),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE,"), ".ev = TRAINER_PARTY_EVS(0, 0, 170, 0, 170, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(84, 84, 84, 84, 84, 84),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 128, 128, 128, 0, 128),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 170, 0, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(102, 0, 102, 102, 102, 102),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 0, 0, 170, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(128, 0, 128, 0, 128, 128),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(128, 128, 128, 0, 0, 128),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 0, 170, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 170, 0, 170, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 0, 0, 0, 0, 252),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE,"), ".ev = TRAINER_PARTY_EVS(0, 0, 170, 170, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(128, 0, 128, 128, 0, 128),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 0, 0, 170, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 170, 0, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 170, 0, 0, 0, 170),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 252, 0, 0, 0, 252),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_SP_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 0, 0, 0, 252, 252),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SP_DEFENSE | F_EV_SPREAD_DEFENSE,"), ".ev = TRAINER_PARTY_EVS(0, 0, 252, 0, 0, 252),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 252, 0, 0, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 0, 0, 252, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED | F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 0, 170, 170, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED | F_EV_SPREAD_ATTACK | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(170, 170, 0, 170, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_SPEED | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 252, 0, 252, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_DEFENSE | F_EV_SPREAD_HP,"), ".ev = TRAINER_PARTY_EVS(252, 0, 252, 0, 0, 0),", data)
|
||||
data = re.sub(re.escape(".evSpread = F_EV_SPREAD_DEFENSE | F_EV_SPREAD_ATTACK,"), ".ev = TRAINER_PARTY_EVS(0, 252, 252, 0, 0, 0),", data)
|
||||
|
||||
return data
|
||||
|
||||
with open('src/data/battle_frontier/battle_frontier_mons.h', 'r') as file:
|
||||
data = file.read()
|
||||
with open('src/data/battle_frontier/battle_frontier_mons.h', 'w') as file:
|
||||
file.write(battle_frontier_mons(data))
|
||||
|
||||
with open('src/data/battle_frontier/battle_tent.h', 'r') as file:
|
||||
data = file.read()
|
||||
with open('src/data/battle_frontier/battle_tent.h', 'w') as file:
|
||||
file.write(battle_frontier_mons(data))
|
||||
|
||||
@ -1,45 +1,45 @@
|
||||
import glob
|
||||
import re
|
||||
import os
|
||||
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from your root folder.")
|
||||
quit()
|
||||
|
||||
# Read item_icon_table.h and extract the icon and palette information
|
||||
for file in glob.glob('./src/data/item_icon_table.h'):
|
||||
with open(file, 'r') as f:
|
||||
icon_table_content = f.read()
|
||||
|
||||
# Extract item icon and palette data from item_icon_table.h
|
||||
icon_table_pattern = re.compile(r'\[(ITEM_[A-Z_0-9]+)\]\s*=\s*\{([^,]+),\s*([^}]+)\}', re.MULTILINE)
|
||||
icon_table_data = {}
|
||||
for match in icon_table_pattern.findall(icon_table_content):
|
||||
if len(match) == 3:
|
||||
item_name, icon_pic, icon_palette = match
|
||||
icon_table_data[item_name] = (icon_pic, icon_palette)
|
||||
|
||||
# Read items.h content
|
||||
for file in glob.glob('./src/data/items.h'):
|
||||
with open(file, 'r') as f:
|
||||
items_content = f.read()
|
||||
|
||||
# Modify items.h content
|
||||
def add_icon_data(match):
|
||||
item_name = match.group(1)
|
||||
item_content = match.group(2)
|
||||
if item_name in icon_table_data:
|
||||
icon_pic, icon_palette = icon_table_data[item_name]
|
||||
print(f"Updating {item_name}: adding iconPic = {icon_pic}, iconPalette = {icon_palette}")
|
||||
return f'[{item_name}] =\n {{{item_content} .iconPic = {icon_pic},\n .iconPalette = {icon_palette},\n }},'
|
||||
else:
|
||||
return match.group(0)
|
||||
|
||||
item_pattern = re.compile(r'\[(ITEM_[A-Z_0-9]+)\]\s*=\s*\{([\s\S]*?)\},', re.DOTALL)
|
||||
modified_items_content = item_pattern.sub(add_icon_data, items_content)
|
||||
|
||||
# Write the modified content back to items.h
|
||||
for file in glob.glob('./src/data/items.h'):
|
||||
with open(file, 'w') as f:
|
||||
f.write(modified_items_content)
|
||||
print("items.h has been updated")
|
||||
import glob
|
||||
import re
|
||||
import os
|
||||
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from your root folder.")
|
||||
quit()
|
||||
|
||||
# Read item_icon_table.h and extract the icon and palette information
|
||||
for file in glob.glob('./src/data/item_icon_table.h'):
|
||||
with open(file, 'r') as f:
|
||||
icon_table_content = f.read()
|
||||
|
||||
# Extract item icon and palette data from item_icon_table.h
|
||||
icon_table_pattern = re.compile(r'\[(ITEM_[A-Z_0-9]+)\]\s*=\s*\{([^,]+),\s*([^}]+)\}', re.MULTILINE)
|
||||
icon_table_data = {}
|
||||
for match in icon_table_pattern.findall(icon_table_content):
|
||||
if len(match) == 3:
|
||||
item_name, icon_pic, icon_palette = match
|
||||
icon_table_data[item_name] = (icon_pic, icon_palette)
|
||||
|
||||
# Read items.h content
|
||||
for file in glob.glob('./src/data/items.h'):
|
||||
with open(file, 'r') as f:
|
||||
items_content = f.read()
|
||||
|
||||
# Modify items.h content
|
||||
def add_icon_data(match):
|
||||
item_name = match.group(1)
|
||||
item_content = match.group(2)
|
||||
if item_name in icon_table_data:
|
||||
icon_pic, icon_palette = icon_table_data[item_name]
|
||||
print(f"Updating {item_name}: adding iconPic = {icon_pic}, iconPalette = {icon_palette}")
|
||||
return f'[{item_name}] =\n {{{item_content} .iconPic = {icon_pic},\n .iconPalette = {icon_palette},\n }},'
|
||||
else:
|
||||
return match.group(0)
|
||||
|
||||
item_pattern = re.compile(r'\[(ITEM_[A-Z_0-9]+)\]\s*=\s*\{([\s\S]*?)\},', re.DOTALL)
|
||||
modified_items_content = item_pattern.sub(add_icon_data, items_content)
|
||||
|
||||
# Write the modified content back to items.h
|
||||
for file in glob.glob('./src/data/items.h'):
|
||||
with open(file, 'w') as f:
|
||||
f.write(modified_items_content)
|
||||
print("items.h has been updated")
|
||||
|
||||
@ -1,319 +1,319 @@
|
||||
# If you have extra members in 'TrainerMon':
|
||||
# 1. Add a regular expression which matches that member (e.g. 'shadow_definition').
|
||||
# 2. Match that regular expression in 'convert' and write into 'attributes' with the key that 'trainerproc' should parse.
|
||||
# 3. Add the key used in 'attributes' to 'pokemon_attribute_order'.
|
||||
# 4. Update 'trainerproc.c' to parse the new key.
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
is_blank = re.compile(r'^[ \t]*(//.*)?$')
|
||||
|
||||
begin_party_definition = re.compile(r'struct TrainerMon (\w+)\[\] =')
|
||||
end_party_definition = re.compile(r'^};')
|
||||
begin_pokemon_definition = re.compile(r'^ { *$')
|
||||
end_pokemon_definition = re.compile(r'^ },? *$')
|
||||
level_definition = re.compile(r'\.lvl = (\d+)')
|
||||
species_definition = re.compile(r'\.species = SPECIES_(\w+)')
|
||||
gender_definition = re.compile(r'\.gender = TRAINER_MON_(\w+)')
|
||||
nickname_definition = re.compile(r'\.nickname = COMPOUND_STRING\("([^"]+)"\)')
|
||||
item_definition = re.compile(r'\.heldItem = ITEM_(\w+)')
|
||||
ball_definition = re.compile(r'\.ball = ITEM_(\w+)')
|
||||
ability_definition = re.compile(r'\.ability = ABILITY_(\w+)')
|
||||
friendship_definition = re.compile(r'\.friendship = (\d+)')
|
||||
shiny_definition = re.compile(r'\.isShiny = (\w+)')
|
||||
ivs_definition = re.compile(r'\.iv = TRAINER_PARTY_IVS\(([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+)\)')
|
||||
evs_definition = re.compile(r'\.ev = TRAINER_PARTY_EVS\(([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+)\)')
|
||||
moves_definition = re.compile(r'\.moves = \{([^}]+)\}')
|
||||
move_definition = re.compile(r'MOVE_(\w+)')
|
||||
nature_definition = re.compile(r'\.nature = NATURE_(\w+)')
|
||||
|
||||
# NOTE: These are just for aesthetics, the Pokemon would still compile
|
||||
# without them.
|
||||
species_replacements = {
|
||||
"CHIEN_PAO": "Chien-Pao",
|
||||
"CHI_YU": "Chi-Yu",
|
||||
"HAKAMO_O": "Hakamo-o",
|
||||
"HO_OH": "Ho-Oh",
|
||||
"JANGMO_O": "Jangmo-o",
|
||||
"KOMMO_O": "Kommo-o",
|
||||
"PORYGON_Z": "Porygon-Z",
|
||||
"ROTOM_": "Rotom-",
|
||||
"TING_LU": "Ting-Lu",
|
||||
"TYPE_NULL": "Type: Null",
|
||||
"WO_CHIEN": "Wo-Chien",
|
||||
|
||||
"_ALOLAN": "-Alola",
|
||||
"_AQUA_BREED": "-Aqua",
|
||||
"_BATTLE_BOND": "-Bond",
|
||||
"_BLAZE_BREED": "-Blaze",
|
||||
"_CAP": "",
|
||||
"_CLOAK": "",
|
||||
"_COMBAT_BREED": "-Combat",
|
||||
"_CROWED_SHIELD": "-Crowned",
|
||||
"_CROWED_SWORD": "-Crowned",
|
||||
"_DRIVE": "",
|
||||
"_EAST_SEA": "-East",
|
||||
"_FAMILY_OF_FOUR": "-Four",
|
||||
"_FEMALE": "-F",
|
||||
"_FLOWER": "",
|
||||
"_GALARIAN": "-Galar",
|
||||
"_GIGANTAMAX": "-Gmax",
|
||||
"_HISUIAN": "-Hisui",
|
||||
"_ICE_RIDER": "-Ice",
|
||||
"_NOICE_FACE": "-Noice",
|
||||
"_ORIGIN": "-Origin",
|
||||
"_ORIGINAL_COLOR": "-Original",
|
||||
"_PALDEAN": "-Paldea",
|
||||
"_PLUMAGE": "",
|
||||
"_POKE_BALL": "-Pokeball",
|
||||
"_SHADOW_RIDER": "-Shadow",
|
||||
"_STRIKE_STYLE": "-Style",
|
||||
"_TOTEM": "-Totem",
|
||||
"_ZEN_MODE": "-Zen",
|
||||
}
|
||||
|
||||
pokemon_attribute_order = ['Level', 'Ability', 'IVs', 'EVs', 'Happiness', 'Shiny', 'Ball']
|
||||
|
||||
class Pokemon:
|
||||
def __init__(self):
|
||||
self.nickname = None
|
||||
self.species = None
|
||||
self.gender = None
|
||||
self.item = None
|
||||
self.nature = None
|
||||
self.attributes = {}
|
||||
self.attributes['IVs'] = "0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe"
|
||||
self.moves = []
|
||||
|
||||
def convert_parties(in_path, in_h):
|
||||
party_identifier = None
|
||||
party = None
|
||||
pokemon = None
|
||||
parties = {}
|
||||
|
||||
for line_no, line in enumerate(in_h, 1):
|
||||
try:
|
||||
line = line[:-1]
|
||||
if m := begin_party_definition.search(line):
|
||||
if party:
|
||||
raise Exception(f"unexpected start of party")
|
||||
[identifier] = m.groups()
|
||||
party_identifier = identifier
|
||||
party = []
|
||||
elif end_party_definition.search(line):
|
||||
if not party:
|
||||
raise Exception(f"unexpected end of party")
|
||||
parties[party_identifier] = party
|
||||
party = None
|
||||
elif begin_pokemon_definition.search(line):
|
||||
if pokemon:
|
||||
raise Exception(f"unexpected start of Pokemon")
|
||||
pokemon = Pokemon()
|
||||
elif end_pokemon_definition.search(line):
|
||||
if not pokemon:
|
||||
raise Exception(f"unexpected end of Pokemon")
|
||||
else:
|
||||
party.append(pokemon)
|
||||
pokemon = None
|
||||
elif m := level_definition.search(line):
|
||||
[level] = m.groups()
|
||||
pokemon.attributes['Level'] = level
|
||||
elif m := species_definition.search(line):
|
||||
[species_] = m.groups()
|
||||
for match, replacement in species_replacements.items():
|
||||
species_ = species_.replace(match, replacement)
|
||||
pokemon.species = species_.replace("_", " ").title()
|
||||
elif m := gender_definition.search(line):
|
||||
[gender_] = m.groups()
|
||||
if gender_ == 'MALE':
|
||||
pokemon.gender = 'M'
|
||||
elif gender_ == 'FEMALE':
|
||||
pokemon.gender = 'F'
|
||||
else:
|
||||
raise Exception(f"unknown gender: '{gender_}'")
|
||||
elif m := nickname_definition.search(line):
|
||||
[nickname] = m.groups()
|
||||
pokemon.nickname = nickname
|
||||
elif m := item_definition.search(line):
|
||||
[item_] = m.groups()
|
||||
pokemon.item = item_.replace("_", " ").title()
|
||||
elif m := ball_definition.search(line):
|
||||
[ball] = m.groups()
|
||||
pokemon.attributes['Ball'] = ball.replace("_", " ").title()
|
||||
elif m := ability_definition.search(line):
|
||||
[ability] = m.groups()
|
||||
pokemon.attributes['Ability'] = ability.replace("_", " ").title()
|
||||
elif m := friendship_definition.search(line):
|
||||
[friendship] = m.groups()
|
||||
pokemon.attributes['Happiness'] = friendship
|
||||
elif m := shiny_definition.search(line):
|
||||
[shiny] = m.groups()
|
||||
if shiny == 'TRUE':
|
||||
pokemon.attributes['Shiny'] = 'Yes'
|
||||
elif shiny == 'FALSE':
|
||||
pokemon.attributes['Shiny'] = 'No'
|
||||
else:
|
||||
raise Exception(f"unknown isShiny: '{shiny}'")
|
||||
elif m := ivs_definition.search(line):
|
||||
[hp, attack, defense, speed, special_attack, special_defense] = [stat.strip() for stat in m.groups()]
|
||||
stats = {"HP": hp, "Atk": attack, "Def": defense, "SpA": special_attack, "SpD": special_defense, "Spe": speed}
|
||||
pokemon.attributes['IVs'] = ' / '.join(f"{value} {key}" for key, value in stats.items())
|
||||
elif m := evs_definition.search(line):
|
||||
[hp, attack, defense, speed, special_attack, special_defense] = [stat.strip() for stat in m.groups()]
|
||||
stats = {"HP": hp, "Atk": attack, "Def": defense, "SpA": special_attack, "SpD": special_defense, "Spe": speed}
|
||||
pokemon.attributes['EVs'] = ' / '.join(f"{value} {key}" for key, value in stats.items() if value != '0')
|
||||
elif m := moves_definition.search(line):
|
||||
[moves_] = m.groups()
|
||||
pokemon.moves = [move.replace("_", " ").title() for move in move_definition.findall(moves_) if move != "NONE"]
|
||||
elif m := nature_definition.search(line):
|
||||
[nature_] = m.groups()
|
||||
pokemon.nature = nature_.replace("_", " ").title()
|
||||
elif is_blank.search(line):
|
||||
pass
|
||||
else:
|
||||
raise Exception(f"could not parse '{line.strip()}'")
|
||||
except Exception as e:
|
||||
print(f"{in_path}:{line_no}: {e}")
|
||||
return parties
|
||||
|
||||
is_trainer_skip = re.compile(r'(const struct Trainer gBattlePartners\[\] = \{)|(^ \{$)|(\.partySize =)|(\.party = NULL)|(\.mugshotEnabled = TRUE)|(\};)')
|
||||
|
||||
begin_trainer_definition = re.compile(r' \[(PARTNER_\w+)\] =')
|
||||
end_trainer_definition = re.compile(r' }')
|
||||
trainer_class_definition = re.compile(r'\.trainerClass = TRAINER_CLASS_(\w+)')
|
||||
encounter_music_gender_definition = re.compile(r'\.encounterMusic_gender = (F_TRAINER_FEMALE \| )?TRAINER_ENCOUNTER_MUSIC_(\w+)')
|
||||
trainer_pic_definition = re.compile(r'\.trainerPic = TRAINER_BACK_PIC_(\w+)')
|
||||
trainer_name_definition = re.compile(r'\.trainerName = _\("([^"]*)"\)')
|
||||
trainer_items_definition = re.compile(r'\.items = \{([^}]*)\}')
|
||||
trainer_item_definition = re.compile(r'ITEM_(\w+)')
|
||||
trainer_ai_flags_definition = re.compile(r'\.aiFlags = (.*)')
|
||||
trainer_ai_flag_definition = re.compile(r'AI_FLAG_(\w+)')
|
||||
trainer_party_definition = re.compile(r'\.party = TRAINER_PARTY\((\w+)\)')
|
||||
trainer_mugshot_definition = re.compile(r'\.mugshotColor = MUGSHOT_COLOR_(\w+)')
|
||||
trainer_starting_status_definition = re.compile(r'\.startingStatus = STARTING_STATUS_(\w+)')
|
||||
|
||||
class_fixups = {
|
||||
"Rs": "RS",
|
||||
}
|
||||
|
||||
pic_fixups = {
|
||||
"Rs": "RS",
|
||||
}
|
||||
|
||||
class Trainer:
|
||||
def __init__(self, id_):
|
||||
self.id = id_
|
||||
self.class_ = None
|
||||
self.encounter_music = None
|
||||
self.gender = None
|
||||
self.pic = None
|
||||
self.name = None
|
||||
self.items = []
|
||||
self.ai_flags = None
|
||||
self.mugshot = None
|
||||
self.starting_status = None
|
||||
self.party = None
|
||||
|
||||
def convert_trainers(in_path, in_h, parties, out_party):
|
||||
newlines = 0
|
||||
trainer = None
|
||||
for line_no, line in enumerate(in_h, 1):
|
||||
try:
|
||||
line = line[:-1]
|
||||
if m := begin_trainer_definition.search(line):
|
||||
if trainer:
|
||||
raise Exception(f"unexpected start of trainer")
|
||||
[id_] = m.groups()
|
||||
trainer = Trainer(id_)
|
||||
elif m := trainer_class_definition.search(line):
|
||||
[class_] = m.groups()
|
||||
class_ = class_.replace("_", " ").title()
|
||||
for match, replacement in class_fixups.items():
|
||||
class_ = class_.replace(match, replacement)
|
||||
trainer.class_ = class_
|
||||
elif m := encounter_music_gender_definition.search(line):
|
||||
[is_female, music] = m.groups()
|
||||
trainer.gender = 'Female' if is_female else 'Male'
|
||||
trainer.encounter_music = music.replace("_", " ").title()
|
||||
elif m := trainer_pic_definition.search(line):
|
||||
[pic] = m.groups()
|
||||
pic = pic.replace("_", " ").title()
|
||||
for match, replacement in pic_fixups.items():
|
||||
pic = pic.replace(match, replacement)
|
||||
trainer.pic = pic
|
||||
elif m := trainer_name_definition.search(line):
|
||||
[name] = m.groups()
|
||||
trainer.name = name
|
||||
elif m := trainer_items_definition.search(line):
|
||||
[items] = m.groups()
|
||||
trainer.items = " / ".join(item.replace("_", " ").title() for item in trainer_item_definition.findall(items) if item != "NONE")
|
||||
elif m := trainer_ai_flags_definition.search(line):
|
||||
[ai_flags] = m.groups()
|
||||
trainer.ai_flags = " / ".join(ai_flag.replace("_", " ").title() for ai_flag in trainer_ai_flag_definition.findall(ai_flags))
|
||||
elif m := trainer_mugshot_definition.search(line):
|
||||
[color] = m.groups()
|
||||
trainer.mugshot = color.title()
|
||||
elif m := trainer_starting_status_definition.search(line):
|
||||
[starting_status] = m.groups()
|
||||
trainer.starting_status = starting_status.replace("_", " ").title()
|
||||
elif m := trainer_party_definition.search(line):
|
||||
[party] = m.groups()
|
||||
trainer.party = parties[party]
|
||||
elif end_trainer_definition.search(line):
|
||||
if not trainer:
|
||||
raise Exception(f"unexpected end of trainer")
|
||||
while newlines > 0:
|
||||
out_party.write(f"\n")
|
||||
newlines -= 1
|
||||
newlines = 1
|
||||
out_party.write(f"=== {trainer.id} ===\n")
|
||||
out_party.write(f"Name: {trainer.name}\n")
|
||||
out_party.write(f"Class: {trainer.class_}\n")
|
||||
out_party.write(f"Pic: {trainer.pic}\n")
|
||||
out_party.write(f"Gender: {trainer.gender}\n")
|
||||
out_party.write(f"Music: {trainer.encounter_music}\n")
|
||||
if trainer.items:
|
||||
out_party.write(f"Items: {trainer.items}\n")
|
||||
if trainer.ai_flags:
|
||||
out_party.write(f"AI: {trainer.ai_flags}\n")
|
||||
if trainer.mugshot:
|
||||
out_party.write(f"Mugshot: {trainer.mugshot}\n")
|
||||
if trainer.starting_status:
|
||||
out_party.write(f"Starting Status: {trainer.starting_status}\n")
|
||||
if trainer.party:
|
||||
for i, pokemon in enumerate(trainer.party):
|
||||
out_party.write(f"\n")
|
||||
if pokemon.nickname:
|
||||
out_party.write(f"{pokemon.nickname} ({pokemon.species})")
|
||||
else:
|
||||
out_party.write(f"{pokemon.species}")
|
||||
if pokemon.gender:
|
||||
out_party.write(f" ({pokemon.gender})")
|
||||
if pokemon.item and pokemon.item != 'None':
|
||||
out_party.write(f" @ {pokemon.item}")
|
||||
out_party.write(f"\n")
|
||||
if pokemon.nature:
|
||||
out_party.write(f"{pokemon.nature} Nature\n")
|
||||
for key in pokemon_attribute_order:
|
||||
if key in pokemon.attributes:
|
||||
out_party.write(f"{key}: {pokemon.attributes[key]}\n")
|
||||
for move in pokemon.moves:
|
||||
out_party.write(f"- {move}\n")
|
||||
trainer = None
|
||||
elif is_blank.search(line) or is_trainer_skip.search(line):
|
||||
pass
|
||||
else:
|
||||
raise Exception(f"could not parse '{line.strip()}'")
|
||||
except Exception as e:
|
||||
print(f"{in_path}:{line_no}: {e}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
[argv0, trainers_in_path, parties_in_path, out_path] = sys.argv
|
||||
except:
|
||||
print(f"usage: python3 {sys.argv[0]} <trainers.h> <trainer_parties.h> <out>")
|
||||
else:
|
||||
with open(trainers_in_path, "r") as trainers_in_h, open(parties_in_path, "r") as parties_in_h, open(out_path, "w") as out_party:
|
||||
parties = convert_parties(parties_in_path, parties_in_h)
|
||||
trainers = convert_trainers(trainers_in_path, trainers_in_h, parties, out_party)
|
||||
# If you have extra members in 'TrainerMon':
|
||||
# 1. Add a regular expression which matches that member (e.g. 'shadow_definition').
|
||||
# 2. Match that regular expression in 'convert' and write into 'attributes' with the key that 'trainerproc' should parse.
|
||||
# 3. Add the key used in 'attributes' to 'pokemon_attribute_order'.
|
||||
# 4. Update 'trainerproc.c' to parse the new key.
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
is_blank = re.compile(r'^[ \t]*(//.*)?$')
|
||||
|
||||
begin_party_definition = re.compile(r'struct TrainerMon (\w+)\[\] =')
|
||||
end_party_definition = re.compile(r'^};')
|
||||
begin_pokemon_definition = re.compile(r'^ { *$')
|
||||
end_pokemon_definition = re.compile(r'^ },? *$')
|
||||
level_definition = re.compile(r'\.lvl = (\d+)')
|
||||
species_definition = re.compile(r'\.species = SPECIES_(\w+)')
|
||||
gender_definition = re.compile(r'\.gender = TRAINER_MON_(\w+)')
|
||||
nickname_definition = re.compile(r'\.nickname = COMPOUND_STRING\("([^"]+)"\)')
|
||||
item_definition = re.compile(r'\.heldItem = ITEM_(\w+)')
|
||||
ball_definition = re.compile(r'\.ball = ITEM_(\w+)')
|
||||
ability_definition = re.compile(r'\.ability = ABILITY_(\w+)')
|
||||
friendship_definition = re.compile(r'\.friendship = (\d+)')
|
||||
shiny_definition = re.compile(r'\.isShiny = (\w+)')
|
||||
ivs_definition = re.compile(r'\.iv = TRAINER_PARTY_IVS\(([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+)\)')
|
||||
evs_definition = re.compile(r'\.ev = TRAINER_PARTY_EVS\(([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+)\)')
|
||||
moves_definition = re.compile(r'\.moves = \{([^}]+)\}')
|
||||
move_definition = re.compile(r'MOVE_(\w+)')
|
||||
nature_definition = re.compile(r'\.nature = NATURE_(\w+)')
|
||||
|
||||
# NOTE: These are just for aesthetics, the Pokemon would still compile
|
||||
# without them.
|
||||
species_replacements = {
|
||||
"CHIEN_PAO": "Chien-Pao",
|
||||
"CHI_YU": "Chi-Yu",
|
||||
"HAKAMO_O": "Hakamo-o",
|
||||
"HO_OH": "Ho-Oh",
|
||||
"JANGMO_O": "Jangmo-o",
|
||||
"KOMMO_O": "Kommo-o",
|
||||
"PORYGON_Z": "Porygon-Z",
|
||||
"ROTOM_": "Rotom-",
|
||||
"TING_LU": "Ting-Lu",
|
||||
"TYPE_NULL": "Type: Null",
|
||||
"WO_CHIEN": "Wo-Chien",
|
||||
|
||||
"_ALOLAN": "-Alola",
|
||||
"_AQUA_BREED": "-Aqua",
|
||||
"_BATTLE_BOND": "-Bond",
|
||||
"_BLAZE_BREED": "-Blaze",
|
||||
"_CAP": "",
|
||||
"_CLOAK": "",
|
||||
"_COMBAT_BREED": "-Combat",
|
||||
"_CROWED_SHIELD": "-Crowned",
|
||||
"_CROWED_SWORD": "-Crowned",
|
||||
"_DRIVE": "",
|
||||
"_EAST_SEA": "-East",
|
||||
"_FAMILY_OF_FOUR": "-Four",
|
||||
"_FEMALE": "-F",
|
||||
"_FLOWER": "",
|
||||
"_GALARIAN": "-Galar",
|
||||
"_GIGANTAMAX": "-Gmax",
|
||||
"_HISUIAN": "-Hisui",
|
||||
"_ICE_RIDER": "-Ice",
|
||||
"_NOICE_FACE": "-Noice",
|
||||
"_ORIGIN": "-Origin",
|
||||
"_ORIGINAL_COLOR": "-Original",
|
||||
"_PALDEAN": "-Paldea",
|
||||
"_PLUMAGE": "",
|
||||
"_POKE_BALL": "-Pokeball",
|
||||
"_SHADOW_RIDER": "-Shadow",
|
||||
"_STRIKE_STYLE": "-Style",
|
||||
"_TOTEM": "-Totem",
|
||||
"_ZEN_MODE": "-Zen",
|
||||
}
|
||||
|
||||
pokemon_attribute_order = ['Level', 'Ability', 'IVs', 'EVs', 'Happiness', 'Shiny', 'Ball']
|
||||
|
||||
class Pokemon:
|
||||
def __init__(self):
|
||||
self.nickname = None
|
||||
self.species = None
|
||||
self.gender = None
|
||||
self.item = None
|
||||
self.nature = None
|
||||
self.attributes = {}
|
||||
self.attributes['IVs'] = "0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe"
|
||||
self.moves = []
|
||||
|
||||
def convert_parties(in_path, in_h):
|
||||
party_identifier = None
|
||||
party = None
|
||||
pokemon = None
|
||||
parties = {}
|
||||
|
||||
for line_no, line in enumerate(in_h, 1):
|
||||
try:
|
||||
line = line[:-1]
|
||||
if m := begin_party_definition.search(line):
|
||||
if party:
|
||||
raise Exception(f"unexpected start of party")
|
||||
[identifier] = m.groups()
|
||||
party_identifier = identifier
|
||||
party = []
|
||||
elif end_party_definition.search(line):
|
||||
if not party:
|
||||
raise Exception(f"unexpected end of party")
|
||||
parties[party_identifier] = party
|
||||
party = None
|
||||
elif begin_pokemon_definition.search(line):
|
||||
if pokemon:
|
||||
raise Exception(f"unexpected start of Pokemon")
|
||||
pokemon = Pokemon()
|
||||
elif end_pokemon_definition.search(line):
|
||||
if not pokemon:
|
||||
raise Exception(f"unexpected end of Pokemon")
|
||||
else:
|
||||
party.append(pokemon)
|
||||
pokemon = None
|
||||
elif m := level_definition.search(line):
|
||||
[level] = m.groups()
|
||||
pokemon.attributes['Level'] = level
|
||||
elif m := species_definition.search(line):
|
||||
[species_] = m.groups()
|
||||
for match, replacement in species_replacements.items():
|
||||
species_ = species_.replace(match, replacement)
|
||||
pokemon.species = species_.replace("_", " ").title()
|
||||
elif m := gender_definition.search(line):
|
||||
[gender_] = m.groups()
|
||||
if gender_ == 'MALE':
|
||||
pokemon.gender = 'M'
|
||||
elif gender_ == 'FEMALE':
|
||||
pokemon.gender = 'F'
|
||||
else:
|
||||
raise Exception(f"unknown gender: '{gender_}'")
|
||||
elif m := nickname_definition.search(line):
|
||||
[nickname] = m.groups()
|
||||
pokemon.nickname = nickname
|
||||
elif m := item_definition.search(line):
|
||||
[item_] = m.groups()
|
||||
pokemon.item = item_.replace("_", " ").title()
|
||||
elif m := ball_definition.search(line):
|
||||
[ball] = m.groups()
|
||||
pokemon.attributes['Ball'] = ball.replace("_", " ").title()
|
||||
elif m := ability_definition.search(line):
|
||||
[ability] = m.groups()
|
||||
pokemon.attributes['Ability'] = ability.replace("_", " ").title()
|
||||
elif m := friendship_definition.search(line):
|
||||
[friendship] = m.groups()
|
||||
pokemon.attributes['Happiness'] = friendship
|
||||
elif m := shiny_definition.search(line):
|
||||
[shiny] = m.groups()
|
||||
if shiny == 'TRUE':
|
||||
pokemon.attributes['Shiny'] = 'Yes'
|
||||
elif shiny == 'FALSE':
|
||||
pokemon.attributes['Shiny'] = 'No'
|
||||
else:
|
||||
raise Exception(f"unknown isShiny: '{shiny}'")
|
||||
elif m := ivs_definition.search(line):
|
||||
[hp, attack, defense, speed, special_attack, special_defense] = [stat.strip() for stat in m.groups()]
|
||||
stats = {"HP": hp, "Atk": attack, "Def": defense, "SpA": special_attack, "SpD": special_defense, "Spe": speed}
|
||||
pokemon.attributes['IVs'] = ' / '.join(f"{value} {key}" for key, value in stats.items())
|
||||
elif m := evs_definition.search(line):
|
||||
[hp, attack, defense, speed, special_attack, special_defense] = [stat.strip() for stat in m.groups()]
|
||||
stats = {"HP": hp, "Atk": attack, "Def": defense, "SpA": special_attack, "SpD": special_defense, "Spe": speed}
|
||||
pokemon.attributes['EVs'] = ' / '.join(f"{value} {key}" for key, value in stats.items() if value != '0')
|
||||
elif m := moves_definition.search(line):
|
||||
[moves_] = m.groups()
|
||||
pokemon.moves = [move.replace("_", " ").title() for move in move_definition.findall(moves_) if move != "NONE"]
|
||||
elif m := nature_definition.search(line):
|
||||
[nature_] = m.groups()
|
||||
pokemon.nature = nature_.replace("_", " ").title()
|
||||
elif is_blank.search(line):
|
||||
pass
|
||||
else:
|
||||
raise Exception(f"could not parse '{line.strip()}'")
|
||||
except Exception as e:
|
||||
print(f"{in_path}:{line_no}: {e}")
|
||||
return parties
|
||||
|
||||
is_trainer_skip = re.compile(r'(const struct Trainer gBattlePartners\[\] = \{)|(^ \{$)|(\.partySize =)|(\.party = NULL)|(\.mugshotEnabled = TRUE)|(\};)')
|
||||
|
||||
begin_trainer_definition = re.compile(r' \[(PARTNER_\w+)\] =')
|
||||
end_trainer_definition = re.compile(r' }')
|
||||
trainer_class_definition = re.compile(r'\.trainerClass = TRAINER_CLASS_(\w+)')
|
||||
encounter_music_gender_definition = re.compile(r'\.encounterMusic_gender = (F_TRAINER_FEMALE \| )?TRAINER_ENCOUNTER_MUSIC_(\w+)')
|
||||
trainer_pic_definition = re.compile(r'\.trainerPic = TRAINER_BACK_PIC_(\w+)')
|
||||
trainer_name_definition = re.compile(r'\.trainerName = _\("([^"]*)"\)')
|
||||
trainer_items_definition = re.compile(r'\.items = \{([^}]*)\}')
|
||||
trainer_item_definition = re.compile(r'ITEM_(\w+)')
|
||||
trainer_ai_flags_definition = re.compile(r'\.aiFlags = (.*)')
|
||||
trainer_ai_flag_definition = re.compile(r'AI_FLAG_(\w+)')
|
||||
trainer_party_definition = re.compile(r'\.party = TRAINER_PARTY\((\w+)\)')
|
||||
trainer_mugshot_definition = re.compile(r'\.mugshotColor = MUGSHOT_COLOR_(\w+)')
|
||||
trainer_starting_status_definition = re.compile(r'\.startingStatus = STARTING_STATUS_(\w+)')
|
||||
|
||||
class_fixups = {
|
||||
"Rs": "RS",
|
||||
}
|
||||
|
||||
pic_fixups = {
|
||||
"Rs": "RS",
|
||||
}
|
||||
|
||||
class Trainer:
|
||||
def __init__(self, id_):
|
||||
self.id = id_
|
||||
self.class_ = None
|
||||
self.encounter_music = None
|
||||
self.gender = None
|
||||
self.pic = None
|
||||
self.name = None
|
||||
self.items = []
|
||||
self.ai_flags = None
|
||||
self.mugshot = None
|
||||
self.starting_status = None
|
||||
self.party = None
|
||||
|
||||
def convert_trainers(in_path, in_h, parties, out_party):
|
||||
newlines = 0
|
||||
trainer = None
|
||||
for line_no, line in enumerate(in_h, 1):
|
||||
try:
|
||||
line = line[:-1]
|
||||
if m := begin_trainer_definition.search(line):
|
||||
if trainer:
|
||||
raise Exception(f"unexpected start of trainer")
|
||||
[id_] = m.groups()
|
||||
trainer = Trainer(id_)
|
||||
elif m := trainer_class_definition.search(line):
|
||||
[class_] = m.groups()
|
||||
class_ = class_.replace("_", " ").title()
|
||||
for match, replacement in class_fixups.items():
|
||||
class_ = class_.replace(match, replacement)
|
||||
trainer.class_ = class_
|
||||
elif m := encounter_music_gender_definition.search(line):
|
||||
[is_female, music] = m.groups()
|
||||
trainer.gender = 'Female' if is_female else 'Male'
|
||||
trainer.encounter_music = music.replace("_", " ").title()
|
||||
elif m := trainer_pic_definition.search(line):
|
||||
[pic] = m.groups()
|
||||
pic = pic.replace("_", " ").title()
|
||||
for match, replacement in pic_fixups.items():
|
||||
pic = pic.replace(match, replacement)
|
||||
trainer.pic = pic
|
||||
elif m := trainer_name_definition.search(line):
|
||||
[name] = m.groups()
|
||||
trainer.name = name
|
||||
elif m := trainer_items_definition.search(line):
|
||||
[items] = m.groups()
|
||||
trainer.items = " / ".join(item.replace("_", " ").title() for item in trainer_item_definition.findall(items) if item != "NONE")
|
||||
elif m := trainer_ai_flags_definition.search(line):
|
||||
[ai_flags] = m.groups()
|
||||
trainer.ai_flags = " / ".join(ai_flag.replace("_", " ").title() for ai_flag in trainer_ai_flag_definition.findall(ai_flags))
|
||||
elif m := trainer_mugshot_definition.search(line):
|
||||
[color] = m.groups()
|
||||
trainer.mugshot = color.title()
|
||||
elif m := trainer_starting_status_definition.search(line):
|
||||
[starting_status] = m.groups()
|
||||
trainer.starting_status = starting_status.replace("_", " ").title()
|
||||
elif m := trainer_party_definition.search(line):
|
||||
[party] = m.groups()
|
||||
trainer.party = parties[party]
|
||||
elif end_trainer_definition.search(line):
|
||||
if not trainer:
|
||||
raise Exception(f"unexpected end of trainer")
|
||||
while newlines > 0:
|
||||
out_party.write(f"\n")
|
||||
newlines -= 1
|
||||
newlines = 1
|
||||
out_party.write(f"=== {trainer.id} ===\n")
|
||||
out_party.write(f"Name: {trainer.name}\n")
|
||||
out_party.write(f"Class: {trainer.class_}\n")
|
||||
out_party.write(f"Pic: {trainer.pic}\n")
|
||||
out_party.write(f"Gender: {trainer.gender}\n")
|
||||
out_party.write(f"Music: {trainer.encounter_music}\n")
|
||||
if trainer.items:
|
||||
out_party.write(f"Items: {trainer.items}\n")
|
||||
if trainer.ai_flags:
|
||||
out_party.write(f"AI: {trainer.ai_flags}\n")
|
||||
if trainer.mugshot:
|
||||
out_party.write(f"Mugshot: {trainer.mugshot}\n")
|
||||
if trainer.starting_status:
|
||||
out_party.write(f"Starting Status: {trainer.starting_status}\n")
|
||||
if trainer.party:
|
||||
for i, pokemon in enumerate(trainer.party):
|
||||
out_party.write(f"\n")
|
||||
if pokemon.nickname:
|
||||
out_party.write(f"{pokemon.nickname} ({pokemon.species})")
|
||||
else:
|
||||
out_party.write(f"{pokemon.species}")
|
||||
if pokemon.gender:
|
||||
out_party.write(f" ({pokemon.gender})")
|
||||
if pokemon.item and pokemon.item != 'None':
|
||||
out_party.write(f" @ {pokemon.item}")
|
||||
out_party.write(f"\n")
|
||||
if pokemon.nature:
|
||||
out_party.write(f"{pokemon.nature} Nature\n")
|
||||
for key in pokemon_attribute_order:
|
||||
if key in pokemon.attributes:
|
||||
out_party.write(f"{key}: {pokemon.attributes[key]}\n")
|
||||
for move in pokemon.moves:
|
||||
out_party.write(f"- {move}\n")
|
||||
trainer = None
|
||||
elif is_blank.search(line) or is_trainer_skip.search(line):
|
||||
pass
|
||||
else:
|
||||
raise Exception(f"could not parse '{line.strip()}'")
|
||||
except Exception as e:
|
||||
print(f"{in_path}:{line_no}: {e}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
[argv0, trainers_in_path, parties_in_path, out_path] = sys.argv
|
||||
except:
|
||||
print(f"usage: python3 {sys.argv[0]} <trainers.h> <trainer_parties.h> <out>")
|
||||
else:
|
||||
with open(trainers_in_path, "r") as trainers_in_h, open(parties_in_path, "r") as parties_in_h, open(out_path, "w") as out_party:
|
||||
parties = convert_parties(parties_in_path, parties_in_h)
|
||||
trainers = convert_trainers(trainers_in_path, trainers_in_h, parties, out_party)
|
||||
|
||||
@ -1,330 +1,330 @@
|
||||
# If you have extra members in 'TrainerMon':
|
||||
# 1. Add a regular expression which matches that member (e.g. 'shadow_definition').
|
||||
# 2. Match that regular expression in 'convert' and write into 'attributes' with the key that 'trainerproc' should parse.
|
||||
# 3. Add the key used in 'attributes' to 'pokemon_attribute_order'.
|
||||
# 4. Update 'trainerproc.c' to parse the new key.
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
is_blank = re.compile(r'^[ \t]*(//.*)?$')
|
||||
|
||||
begin_party_definition = re.compile(r'struct TrainerMon (\w+)\[\] =')
|
||||
end_party_definition = re.compile(r'^};')
|
||||
begin_pokemon_definition = re.compile(r'^ { *$')
|
||||
end_pokemon_definition = re.compile(r'^ },? *$')
|
||||
level_definition = re.compile(r'\.lvl = (\d+)')
|
||||
species_definition = re.compile(r'\.species = SPECIES_(\w+)')
|
||||
gender_definition = re.compile(r'\.gender = TRAINER_MON_(\w+)')
|
||||
nickname_definition = re.compile(r'\.nickname = COMPOUND_STRING\("([^"]+)"\)')
|
||||
item_definition = re.compile(r'\.heldItem = ITEM_(\w+)')
|
||||
ball_definition = re.compile(r'\.ball = ITEM_(\w+)')
|
||||
ability_definition = re.compile(r'\.ability = ABILITY_(\w+)')
|
||||
friendship_definition = re.compile(r'\.friendship = (\d+)')
|
||||
shiny_definition = re.compile(r'\.isShiny = (\w+)')
|
||||
ivs_definition = re.compile(r'\.iv = TRAINER_PARTY_IVS\(([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+)\)')
|
||||
evs_definition = re.compile(r'\.ev = TRAINER_PARTY_EVS\(([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+)\)')
|
||||
moves_definition = re.compile(r'\.moves = \{([^}]+)\}')
|
||||
move_definition = re.compile(r'MOVE_(\w+)')
|
||||
nature_definition = re.compile(r'\.nature = NATURE_(\w+)')
|
||||
|
||||
# NOTE: These are just for aesthetics, the Pokemon would still compile
|
||||
# without them.
|
||||
species_replacements = {
|
||||
"CHIEN_PAO": "Chien-Pao",
|
||||
"CHI_YU": "Chi-Yu",
|
||||
"HAKAMO_O": "Hakamo-o",
|
||||
"HO_OH": "Ho-Oh",
|
||||
"JANGMO_O": "Jangmo-o",
|
||||
"KOMMO_O": "Kommo-o",
|
||||
"PORYGON_Z": "Porygon-Z",
|
||||
"ROTOM_": "Rotom-",
|
||||
"TING_LU": "Ting-Lu",
|
||||
"TYPE_NULL": "Type: Null",
|
||||
"WO_CHIEN": "Wo-Chien",
|
||||
|
||||
"_ALOLAN": "-Alola",
|
||||
"_AQUA_BREED": "-Aqua",
|
||||
"_BATTLE_BOND": "-Bond",
|
||||
"_BLAZE_BREED": "-Blaze",
|
||||
"_CAP": "",
|
||||
"_CLOAK": "",
|
||||
"_COMBAT_BREED": "-Combat",
|
||||
"_CROWED_SHIELD": "-Crowned",
|
||||
"_CROWED_SWORD": "-Crowned",
|
||||
"_DRIVE": "",
|
||||
"_EAST_SEA": "-East",
|
||||
"_FAMILY_OF_FOUR": "-Four",
|
||||
"_FEMALE": "-F",
|
||||
"_FLOWER": "",
|
||||
"_GALARIAN": "-Galar",
|
||||
"_GIGANTAMAX": "-Gmax",
|
||||
"_HISUIAN": "-Hisui",
|
||||
"_ICE_RIDER": "-Ice",
|
||||
"_NOICE_FACE": "-Noice",
|
||||
"_ORIGIN": "-Origin",
|
||||
"_ORIGINAL_COLOR": "-Original",
|
||||
"_PALDEAN": "-Paldea",
|
||||
"_PLUMAGE": "",
|
||||
"_POKE_BALL": "-Pokeball",
|
||||
"_SHADOW_RIDER": "-Shadow",
|
||||
"_STRIKE_STYLE": "-Style",
|
||||
"_TOTEM": "-Totem",
|
||||
"_ZEN_MODE": "-Zen",
|
||||
}
|
||||
|
||||
pokemon_attribute_order = ['Level', 'Ability', 'IVs', 'EVs', 'Happiness', 'Shiny', 'Ball']
|
||||
|
||||
class Pokemon:
|
||||
def __init__(self):
|
||||
self.nickname = None
|
||||
self.species = None
|
||||
self.gender = None
|
||||
self.item = None
|
||||
self.nature = None
|
||||
self.attributes = {}
|
||||
self.attributes['IVs'] = "0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe"
|
||||
self.moves = []
|
||||
|
||||
def convert_parties(in_path, in_h):
|
||||
party_identifier = None
|
||||
party = None
|
||||
pokemon = None
|
||||
parties = {}
|
||||
|
||||
for line_no, line in enumerate(in_h, 1):
|
||||
try:
|
||||
line = line[:-1]
|
||||
if m := begin_party_definition.search(line):
|
||||
if party:
|
||||
raise Exception(f"unexpected start of party")
|
||||
[identifier] = m.groups()
|
||||
party_identifier = identifier
|
||||
party = []
|
||||
elif end_party_definition.search(line):
|
||||
if not party:
|
||||
raise Exception(f"unexpected end of party")
|
||||
parties[party_identifier] = party
|
||||
party = None
|
||||
elif begin_pokemon_definition.search(line):
|
||||
if pokemon:
|
||||
raise Exception(f"unexpected start of Pokemon")
|
||||
pokemon = Pokemon()
|
||||
elif end_pokemon_definition.search(line):
|
||||
if not pokemon:
|
||||
raise Exception(f"unexpected end of Pokemon")
|
||||
else:
|
||||
party.append(pokemon)
|
||||
pokemon = None
|
||||
elif m := level_definition.search(line):
|
||||
[level] = m.groups()
|
||||
pokemon.attributes['Level'] = level
|
||||
elif m := species_definition.search(line):
|
||||
[species_] = m.groups()
|
||||
for match, replacement in species_replacements.items():
|
||||
species_ = species_.replace(match, replacement)
|
||||
pokemon.species = species_.replace("_", " ").title()
|
||||
elif m := gender_definition.search(line):
|
||||
[gender_] = m.groups()
|
||||
if gender_ == 'MALE':
|
||||
pokemon.gender = 'M'
|
||||
elif gender_ == 'FEMALE':
|
||||
pokemon.gender = 'F'
|
||||
else:
|
||||
raise Exception(f"unknown gender: '{gender_}'")
|
||||
elif m := nickname_definition.search(line):
|
||||
[nickname] = m.groups()
|
||||
pokemon.nickname = nickname
|
||||
elif m := item_definition.search(line):
|
||||
[item_] = m.groups()
|
||||
pokemon.item = item_.replace("_", " ").title()
|
||||
elif m := ball_definition.search(line):
|
||||
[ball] = m.groups()
|
||||
pokemon.attributes['Ball'] = ball.replace("_", " ").title()
|
||||
elif m := ability_definition.search(line):
|
||||
[ability] = m.groups()
|
||||
pokemon.attributes['Ability'] = ability.replace("_", " ").title()
|
||||
elif m := friendship_definition.search(line):
|
||||
[friendship] = m.groups()
|
||||
pokemon.attributes['Happiness'] = friendship
|
||||
elif m := shiny_definition.search(line):
|
||||
[shiny] = m.groups()
|
||||
if shiny == 'TRUE':
|
||||
pokemon.attributes['Shiny'] = 'Yes'
|
||||
elif shiny == 'FALSE':
|
||||
pokemon.attributes['Shiny'] = 'No'
|
||||
else:
|
||||
raise Exception(f"unknown isShiny: '{shiny}'")
|
||||
elif m := ivs_definition.search(line):
|
||||
[hp, attack, defense, speed, special_attack, special_defense] = [stat.strip() for stat in m.groups()]
|
||||
stats = {"HP": hp, "Atk": attack, "Def": defense, "SpA": special_attack, "SpD": special_defense, "Spe": speed}
|
||||
pokemon.attributes['IVs'] = ' / '.join(f"{value} {key}" for key, value in stats.items())
|
||||
elif m := evs_definition.search(line):
|
||||
[hp, attack, defense, speed, special_attack, special_defense] = [stat.strip() for stat in m.groups()]
|
||||
stats = {"HP": hp, "Atk": attack, "Def": defense, "SpA": special_attack, "SpD": special_defense, "Spe": speed}
|
||||
pokemon.attributes['EVs'] = ' / '.join(f"{value} {key}" for key, value in stats.items() if value != '0')
|
||||
elif m := moves_definition.search(line):
|
||||
[moves_] = m.groups()
|
||||
pokemon.moves = [move.replace("_", " ").title() for move in move_definition.findall(moves_) if move != "NONE"]
|
||||
elif m := nature_definition.search(line):
|
||||
[nature_] = m.groups()
|
||||
pokemon.nature = nature_.replace("_", " ").title()
|
||||
elif is_blank.search(line):
|
||||
pass
|
||||
else:
|
||||
raise Exception(f"could not parse '{line.strip()}'")
|
||||
except Exception as e:
|
||||
print(f"{in_path}:{line_no}: {e}")
|
||||
return parties
|
||||
|
||||
is_trainer_skip = re.compile(r'(const struct Trainer gTrainers\[\] = \{)|(^ \{$)|(\.partySize =)|(\.party = NULL)|(\.mugshotEnabled = TRUE)|(\};)')
|
||||
|
||||
begin_trainer_definition = re.compile(r' \[(TRAINER_\w+)\] =')
|
||||
end_trainer_definition = re.compile(r' }')
|
||||
trainer_class_definition = re.compile(r'\.trainerClass = TRAINER_CLASS_(\w+)')
|
||||
encounter_music_gender_definition = re.compile(r'\.encounterMusic_gender = (F_TRAINER_FEMALE \| )?TRAINER_ENCOUNTER_MUSIC_(\w+)')
|
||||
trainer_pic_definition = re.compile(r'\.trainerPic = TRAINER_PIC_(\w+)')
|
||||
trainer_name_definition = re.compile(r'\.trainerName = _\("([^"]*)"\)')
|
||||
trainer_items_definition = re.compile(r'\.items = \{([^}]*)\}')
|
||||
trainer_item_definition = re.compile(r'ITEM_(\w+)')
|
||||
trainer_double_battle_definition = re.compile(r'\.doubleBattle = (\w+)')
|
||||
trainer_ai_flags_definition = re.compile(r'\.aiFlags = (.*)')
|
||||
trainer_ai_flag_definition = re.compile(r'AI_FLAG_(\w+)')
|
||||
trainer_party_definition = re.compile(r'\.party = TRAINER_PARTY\((\w+)\)')
|
||||
trainer_mugshot_definition = re.compile(r'\.mugshotColor = MUGSHOT_COLOR_(\w+)')
|
||||
trainer_starting_status_definition = re.compile(r'\.startingStatus = STARTING_STATUS_(\w+)')
|
||||
|
||||
class_fixups = {
|
||||
"Rs": "RS",
|
||||
}
|
||||
|
||||
pic_fixups = {
|
||||
"Rs": "RS",
|
||||
}
|
||||
|
||||
class Trainer:
|
||||
def __init__(self, id_):
|
||||
self.id = id_
|
||||
self.class_ = None
|
||||
self.encounter_music = None
|
||||
self.gender = None
|
||||
self.pic = None
|
||||
self.name = None
|
||||
self.items = []
|
||||
self.double_battle = None
|
||||
self.ai_flags = None
|
||||
self.mugshot = None
|
||||
self.starting_status = None
|
||||
self.party = None
|
||||
|
||||
def convert_trainers(in_path, in_h, parties, out_party):
|
||||
newlines = 0
|
||||
trainer = None
|
||||
for line_no, line in enumerate(in_h, 1):
|
||||
try:
|
||||
line = line[:-1]
|
||||
if m := begin_trainer_definition.search(line):
|
||||
if trainer:
|
||||
raise Exception(f"unexpected start of trainer")
|
||||
[id_] = m.groups()
|
||||
trainer = Trainer(id_)
|
||||
elif m := trainer_class_definition.search(line):
|
||||
[class_] = m.groups()
|
||||
class_ = class_.replace("_", " ").title()
|
||||
for match, replacement in class_fixups.items():
|
||||
class_ = class_.replace(match, replacement)
|
||||
trainer.class_ = class_
|
||||
elif m := encounter_music_gender_definition.search(line):
|
||||
[is_female, music] = m.groups()
|
||||
trainer.gender = 'Female' if is_female else 'Male'
|
||||
trainer.encounter_music = music.replace("_", " ").title()
|
||||
elif m := trainer_pic_definition.search(line):
|
||||
[pic] = m.groups()
|
||||
pic = pic.replace("_", " ").title()
|
||||
for match, replacement in pic_fixups.items():
|
||||
pic = pic.replace(match, replacement)
|
||||
trainer.pic = pic
|
||||
elif m := trainer_name_definition.search(line):
|
||||
[name] = m.groups()
|
||||
trainer.name = name
|
||||
elif m := trainer_items_definition.search(line):
|
||||
[items] = m.groups()
|
||||
trainer.items = " / ".join(item.replace("_", " ").title() for item in trainer_item_definition.findall(items) if item != "NONE")
|
||||
elif m := trainer_double_battle_definition.search(line):
|
||||
[double_battle] = m.groups()
|
||||
if double_battle == 'TRUE':
|
||||
trainer.double_battle = "Yes"
|
||||
elif double_battle == 'FALSE':
|
||||
trainer.double_battle = "No"
|
||||
else:
|
||||
raise Exception(f"unknown doubleBattle: '{double_battle}'")
|
||||
elif m := trainer_ai_flags_definition.search(line):
|
||||
[ai_flags] = m.groups()
|
||||
trainer.ai_flags = " / ".join(ai_flag.replace("_", " ").title() for ai_flag in trainer_ai_flag_definition.findall(ai_flags))
|
||||
elif m := trainer_mugshot_definition.search(line):
|
||||
[color] = m.groups()
|
||||
trainer.mugshot = color.title()
|
||||
elif m := trainer_starting_status_definition.search(line):
|
||||
[starting_status] = m.groups()
|
||||
trainer.starting_status = starting_status.replace("_", " ").title()
|
||||
elif m := trainer_party_definition.search(line):
|
||||
[party] = m.groups()
|
||||
trainer.party = parties[party]
|
||||
elif end_trainer_definition.search(line):
|
||||
if not trainer:
|
||||
raise Exception(f"unexpected end of trainer")
|
||||
while newlines > 0:
|
||||
out_party.write(f"\n")
|
||||
newlines -= 1
|
||||
newlines = 1
|
||||
out_party.write(f"=== {trainer.id} ===\n")
|
||||
out_party.write(f"Name: {trainer.name}\n")
|
||||
out_party.write(f"Class: {trainer.class_}\n")
|
||||
out_party.write(f"Pic: {trainer.pic}\n")
|
||||
out_party.write(f"Gender: {trainer.gender}\n")
|
||||
out_party.write(f"Music: {trainer.encounter_music}\n")
|
||||
if trainer.items:
|
||||
out_party.write(f"Items: {trainer.items}\n")
|
||||
out_party.write(f"Double Battle: {trainer.double_battle}\n")
|
||||
if trainer.ai_flags:
|
||||
out_party.write(f"AI: {trainer.ai_flags}\n")
|
||||
if trainer.mugshot:
|
||||
out_party.write(f"Mugshot: {trainer.mugshot}\n")
|
||||
if trainer.starting_status:
|
||||
out_party.write(f"Starting Status: {trainer.starting_status}\n")
|
||||
if trainer.party:
|
||||
for i, pokemon in enumerate(trainer.party):
|
||||
out_party.write(f"\n")
|
||||
if pokemon.nickname:
|
||||
out_party.write(f"{pokemon.nickname} ({pokemon.species})")
|
||||
else:
|
||||
out_party.write(f"{pokemon.species}")
|
||||
if pokemon.gender:
|
||||
out_party.write(f" ({pokemon.gender})")
|
||||
if pokemon.item and pokemon.item != 'None':
|
||||
out_party.write(f" @ {pokemon.item}")
|
||||
out_party.write(f"\n")
|
||||
if pokemon.nature:
|
||||
out_party.write(f"{pokemon.nature} Nature\n")
|
||||
for key in pokemon_attribute_order:
|
||||
if key in pokemon.attributes:
|
||||
out_party.write(f"{key}: {pokemon.attributes[key]}\n")
|
||||
for move in pokemon.moves:
|
||||
out_party.write(f"- {move}\n")
|
||||
trainer = None
|
||||
elif is_blank.search(line) or is_trainer_skip.search(line):
|
||||
pass
|
||||
else:
|
||||
raise Exception(f"could not parse '{line.strip()}'")
|
||||
except Exception as e:
|
||||
print(f"{in_path}:{line_no}: {e}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
[argv0, trainers_in_path, parties_in_path, out_path] = sys.argv
|
||||
except:
|
||||
print(f"usage: python3 {sys.argv[0]} <trainers.h> <trainer_parties.h> <out>")
|
||||
else:
|
||||
with open(trainers_in_path, "r") as trainers_in_h, open(parties_in_path, "r") as parties_in_h, open(out_path, "w") as out_party:
|
||||
parties = convert_parties(parties_in_path, parties_in_h)
|
||||
trainers = convert_trainers(trainers_in_path, trainers_in_h, parties, out_party)
|
||||
# If you have extra members in 'TrainerMon':
|
||||
# 1. Add a regular expression which matches that member (e.g. 'shadow_definition').
|
||||
# 2. Match that regular expression in 'convert' and write into 'attributes' with the key that 'trainerproc' should parse.
|
||||
# 3. Add the key used in 'attributes' to 'pokemon_attribute_order'.
|
||||
# 4. Update 'trainerproc.c' to parse the new key.
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
is_blank = re.compile(r'^[ \t]*(//.*)?$')
|
||||
|
||||
begin_party_definition = re.compile(r'struct TrainerMon (\w+)\[\] =')
|
||||
end_party_definition = re.compile(r'^};')
|
||||
begin_pokemon_definition = re.compile(r'^ { *$')
|
||||
end_pokemon_definition = re.compile(r'^ },? *$')
|
||||
level_definition = re.compile(r'\.lvl = (\d+)')
|
||||
species_definition = re.compile(r'\.species = SPECIES_(\w+)')
|
||||
gender_definition = re.compile(r'\.gender = TRAINER_MON_(\w+)')
|
||||
nickname_definition = re.compile(r'\.nickname = COMPOUND_STRING\("([^"]+)"\)')
|
||||
item_definition = re.compile(r'\.heldItem = ITEM_(\w+)')
|
||||
ball_definition = re.compile(r'\.ball = ITEM_(\w+)')
|
||||
ability_definition = re.compile(r'\.ability = ABILITY_(\w+)')
|
||||
friendship_definition = re.compile(r'\.friendship = (\d+)')
|
||||
shiny_definition = re.compile(r'\.isShiny = (\w+)')
|
||||
ivs_definition = re.compile(r'\.iv = TRAINER_PARTY_IVS\(([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+)\)')
|
||||
evs_definition = re.compile(r'\.ev = TRAINER_PARTY_EVS\(([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+),([0-9 ]+)\)')
|
||||
moves_definition = re.compile(r'\.moves = \{([^}]+)\}')
|
||||
move_definition = re.compile(r'MOVE_(\w+)')
|
||||
nature_definition = re.compile(r'\.nature = NATURE_(\w+)')
|
||||
|
||||
# NOTE: These are just for aesthetics, the Pokemon would still compile
|
||||
# without them.
|
||||
species_replacements = {
|
||||
"CHIEN_PAO": "Chien-Pao",
|
||||
"CHI_YU": "Chi-Yu",
|
||||
"HAKAMO_O": "Hakamo-o",
|
||||
"HO_OH": "Ho-Oh",
|
||||
"JANGMO_O": "Jangmo-o",
|
||||
"KOMMO_O": "Kommo-o",
|
||||
"PORYGON_Z": "Porygon-Z",
|
||||
"ROTOM_": "Rotom-",
|
||||
"TING_LU": "Ting-Lu",
|
||||
"TYPE_NULL": "Type: Null",
|
||||
"WO_CHIEN": "Wo-Chien",
|
||||
|
||||
"_ALOLAN": "-Alola",
|
||||
"_AQUA_BREED": "-Aqua",
|
||||
"_BATTLE_BOND": "-Bond",
|
||||
"_BLAZE_BREED": "-Blaze",
|
||||
"_CAP": "",
|
||||
"_CLOAK": "",
|
||||
"_COMBAT_BREED": "-Combat",
|
||||
"_CROWED_SHIELD": "-Crowned",
|
||||
"_CROWED_SWORD": "-Crowned",
|
||||
"_DRIVE": "",
|
||||
"_EAST_SEA": "-East",
|
||||
"_FAMILY_OF_FOUR": "-Four",
|
||||
"_FEMALE": "-F",
|
||||
"_FLOWER": "",
|
||||
"_GALARIAN": "-Galar",
|
||||
"_GIGANTAMAX": "-Gmax",
|
||||
"_HISUIAN": "-Hisui",
|
||||
"_ICE_RIDER": "-Ice",
|
||||
"_NOICE_FACE": "-Noice",
|
||||
"_ORIGIN": "-Origin",
|
||||
"_ORIGINAL_COLOR": "-Original",
|
||||
"_PALDEAN": "-Paldea",
|
||||
"_PLUMAGE": "",
|
||||
"_POKE_BALL": "-Pokeball",
|
||||
"_SHADOW_RIDER": "-Shadow",
|
||||
"_STRIKE_STYLE": "-Style",
|
||||
"_TOTEM": "-Totem",
|
||||
"_ZEN_MODE": "-Zen",
|
||||
}
|
||||
|
||||
pokemon_attribute_order = ['Level', 'Ability', 'IVs', 'EVs', 'Happiness', 'Shiny', 'Ball']
|
||||
|
||||
class Pokemon:
|
||||
def __init__(self):
|
||||
self.nickname = None
|
||||
self.species = None
|
||||
self.gender = None
|
||||
self.item = None
|
||||
self.nature = None
|
||||
self.attributes = {}
|
||||
self.attributes['IVs'] = "0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe"
|
||||
self.moves = []
|
||||
|
||||
def convert_parties(in_path, in_h):
|
||||
party_identifier = None
|
||||
party = None
|
||||
pokemon = None
|
||||
parties = {}
|
||||
|
||||
for line_no, line in enumerate(in_h, 1):
|
||||
try:
|
||||
line = line[:-1]
|
||||
if m := begin_party_definition.search(line):
|
||||
if party:
|
||||
raise Exception(f"unexpected start of party")
|
||||
[identifier] = m.groups()
|
||||
party_identifier = identifier
|
||||
party = []
|
||||
elif end_party_definition.search(line):
|
||||
if not party:
|
||||
raise Exception(f"unexpected end of party")
|
||||
parties[party_identifier] = party
|
||||
party = None
|
||||
elif begin_pokemon_definition.search(line):
|
||||
if pokemon:
|
||||
raise Exception(f"unexpected start of Pokemon")
|
||||
pokemon = Pokemon()
|
||||
elif end_pokemon_definition.search(line):
|
||||
if not pokemon:
|
||||
raise Exception(f"unexpected end of Pokemon")
|
||||
else:
|
||||
party.append(pokemon)
|
||||
pokemon = None
|
||||
elif m := level_definition.search(line):
|
||||
[level] = m.groups()
|
||||
pokemon.attributes['Level'] = level
|
||||
elif m := species_definition.search(line):
|
||||
[species_] = m.groups()
|
||||
for match, replacement in species_replacements.items():
|
||||
species_ = species_.replace(match, replacement)
|
||||
pokemon.species = species_.replace("_", " ").title()
|
||||
elif m := gender_definition.search(line):
|
||||
[gender_] = m.groups()
|
||||
if gender_ == 'MALE':
|
||||
pokemon.gender = 'M'
|
||||
elif gender_ == 'FEMALE':
|
||||
pokemon.gender = 'F'
|
||||
else:
|
||||
raise Exception(f"unknown gender: '{gender_}'")
|
||||
elif m := nickname_definition.search(line):
|
||||
[nickname] = m.groups()
|
||||
pokemon.nickname = nickname
|
||||
elif m := item_definition.search(line):
|
||||
[item_] = m.groups()
|
||||
pokemon.item = item_.replace("_", " ").title()
|
||||
elif m := ball_definition.search(line):
|
||||
[ball] = m.groups()
|
||||
pokemon.attributes['Ball'] = ball.replace("_", " ").title()
|
||||
elif m := ability_definition.search(line):
|
||||
[ability] = m.groups()
|
||||
pokemon.attributes['Ability'] = ability.replace("_", " ").title()
|
||||
elif m := friendship_definition.search(line):
|
||||
[friendship] = m.groups()
|
||||
pokemon.attributes['Happiness'] = friendship
|
||||
elif m := shiny_definition.search(line):
|
||||
[shiny] = m.groups()
|
||||
if shiny == 'TRUE':
|
||||
pokemon.attributes['Shiny'] = 'Yes'
|
||||
elif shiny == 'FALSE':
|
||||
pokemon.attributes['Shiny'] = 'No'
|
||||
else:
|
||||
raise Exception(f"unknown isShiny: '{shiny}'")
|
||||
elif m := ivs_definition.search(line):
|
||||
[hp, attack, defense, speed, special_attack, special_defense] = [stat.strip() for stat in m.groups()]
|
||||
stats = {"HP": hp, "Atk": attack, "Def": defense, "SpA": special_attack, "SpD": special_defense, "Spe": speed}
|
||||
pokemon.attributes['IVs'] = ' / '.join(f"{value} {key}" for key, value in stats.items())
|
||||
elif m := evs_definition.search(line):
|
||||
[hp, attack, defense, speed, special_attack, special_defense] = [stat.strip() for stat in m.groups()]
|
||||
stats = {"HP": hp, "Atk": attack, "Def": defense, "SpA": special_attack, "SpD": special_defense, "Spe": speed}
|
||||
pokemon.attributes['EVs'] = ' / '.join(f"{value} {key}" for key, value in stats.items() if value != '0')
|
||||
elif m := moves_definition.search(line):
|
||||
[moves_] = m.groups()
|
||||
pokemon.moves = [move.replace("_", " ").title() for move in move_definition.findall(moves_) if move != "NONE"]
|
||||
elif m := nature_definition.search(line):
|
||||
[nature_] = m.groups()
|
||||
pokemon.nature = nature_.replace("_", " ").title()
|
||||
elif is_blank.search(line):
|
||||
pass
|
||||
else:
|
||||
raise Exception(f"could not parse '{line.strip()}'")
|
||||
except Exception as e:
|
||||
print(f"{in_path}:{line_no}: {e}")
|
||||
return parties
|
||||
|
||||
is_trainer_skip = re.compile(r'(const struct Trainer gTrainers\[\] = \{)|(^ \{$)|(\.partySize =)|(\.party = NULL)|(\.mugshotEnabled = TRUE)|(\};)')
|
||||
|
||||
begin_trainer_definition = re.compile(r' \[(TRAINER_\w+)\] =')
|
||||
end_trainer_definition = re.compile(r' }')
|
||||
trainer_class_definition = re.compile(r'\.trainerClass = TRAINER_CLASS_(\w+)')
|
||||
encounter_music_gender_definition = re.compile(r'\.encounterMusic_gender = (F_TRAINER_FEMALE \| )?TRAINER_ENCOUNTER_MUSIC_(\w+)')
|
||||
trainer_pic_definition = re.compile(r'\.trainerPic = TRAINER_PIC_(\w+)')
|
||||
trainer_name_definition = re.compile(r'\.trainerName = _\("([^"]*)"\)')
|
||||
trainer_items_definition = re.compile(r'\.items = \{([^}]*)\}')
|
||||
trainer_item_definition = re.compile(r'ITEM_(\w+)')
|
||||
trainer_double_battle_definition = re.compile(r'\.doubleBattle = (\w+)')
|
||||
trainer_ai_flags_definition = re.compile(r'\.aiFlags = (.*)')
|
||||
trainer_ai_flag_definition = re.compile(r'AI_FLAG_(\w+)')
|
||||
trainer_party_definition = re.compile(r'\.party = TRAINER_PARTY\((\w+)\)')
|
||||
trainer_mugshot_definition = re.compile(r'\.mugshotColor = MUGSHOT_COLOR_(\w+)')
|
||||
trainer_starting_status_definition = re.compile(r'\.startingStatus = STARTING_STATUS_(\w+)')
|
||||
|
||||
class_fixups = {
|
||||
"Rs": "RS",
|
||||
}
|
||||
|
||||
pic_fixups = {
|
||||
"Rs": "RS",
|
||||
}
|
||||
|
||||
class Trainer:
|
||||
def __init__(self, id_):
|
||||
self.id = id_
|
||||
self.class_ = None
|
||||
self.encounter_music = None
|
||||
self.gender = None
|
||||
self.pic = None
|
||||
self.name = None
|
||||
self.items = []
|
||||
self.double_battle = None
|
||||
self.ai_flags = None
|
||||
self.mugshot = None
|
||||
self.starting_status = None
|
||||
self.party = None
|
||||
|
||||
def convert_trainers(in_path, in_h, parties, out_party):
|
||||
newlines = 0
|
||||
trainer = None
|
||||
for line_no, line in enumerate(in_h, 1):
|
||||
try:
|
||||
line = line[:-1]
|
||||
if m := begin_trainer_definition.search(line):
|
||||
if trainer:
|
||||
raise Exception(f"unexpected start of trainer")
|
||||
[id_] = m.groups()
|
||||
trainer = Trainer(id_)
|
||||
elif m := trainer_class_definition.search(line):
|
||||
[class_] = m.groups()
|
||||
class_ = class_.replace("_", " ").title()
|
||||
for match, replacement in class_fixups.items():
|
||||
class_ = class_.replace(match, replacement)
|
||||
trainer.class_ = class_
|
||||
elif m := encounter_music_gender_definition.search(line):
|
||||
[is_female, music] = m.groups()
|
||||
trainer.gender = 'Female' if is_female else 'Male'
|
||||
trainer.encounter_music = music.replace("_", " ").title()
|
||||
elif m := trainer_pic_definition.search(line):
|
||||
[pic] = m.groups()
|
||||
pic = pic.replace("_", " ").title()
|
||||
for match, replacement in pic_fixups.items():
|
||||
pic = pic.replace(match, replacement)
|
||||
trainer.pic = pic
|
||||
elif m := trainer_name_definition.search(line):
|
||||
[name] = m.groups()
|
||||
trainer.name = name
|
||||
elif m := trainer_items_definition.search(line):
|
||||
[items] = m.groups()
|
||||
trainer.items = " / ".join(item.replace("_", " ").title() for item in trainer_item_definition.findall(items) if item != "NONE")
|
||||
elif m := trainer_double_battle_definition.search(line):
|
||||
[double_battle] = m.groups()
|
||||
if double_battle == 'TRUE':
|
||||
trainer.double_battle = "Yes"
|
||||
elif double_battle == 'FALSE':
|
||||
trainer.double_battle = "No"
|
||||
else:
|
||||
raise Exception(f"unknown doubleBattle: '{double_battle}'")
|
||||
elif m := trainer_ai_flags_definition.search(line):
|
||||
[ai_flags] = m.groups()
|
||||
trainer.ai_flags = " / ".join(ai_flag.replace("_", " ").title() for ai_flag in trainer_ai_flag_definition.findall(ai_flags))
|
||||
elif m := trainer_mugshot_definition.search(line):
|
||||
[color] = m.groups()
|
||||
trainer.mugshot = color.title()
|
||||
elif m := trainer_starting_status_definition.search(line):
|
||||
[starting_status] = m.groups()
|
||||
trainer.starting_status = starting_status.replace("_", " ").title()
|
||||
elif m := trainer_party_definition.search(line):
|
||||
[party] = m.groups()
|
||||
trainer.party = parties[party]
|
||||
elif end_trainer_definition.search(line):
|
||||
if not trainer:
|
||||
raise Exception(f"unexpected end of trainer")
|
||||
while newlines > 0:
|
||||
out_party.write(f"\n")
|
||||
newlines -= 1
|
||||
newlines = 1
|
||||
out_party.write(f"=== {trainer.id} ===\n")
|
||||
out_party.write(f"Name: {trainer.name}\n")
|
||||
out_party.write(f"Class: {trainer.class_}\n")
|
||||
out_party.write(f"Pic: {trainer.pic}\n")
|
||||
out_party.write(f"Gender: {trainer.gender}\n")
|
||||
out_party.write(f"Music: {trainer.encounter_music}\n")
|
||||
if trainer.items:
|
||||
out_party.write(f"Items: {trainer.items}\n")
|
||||
out_party.write(f"Double Battle: {trainer.double_battle}\n")
|
||||
if trainer.ai_flags:
|
||||
out_party.write(f"AI: {trainer.ai_flags}\n")
|
||||
if trainer.mugshot:
|
||||
out_party.write(f"Mugshot: {trainer.mugshot}\n")
|
||||
if trainer.starting_status:
|
||||
out_party.write(f"Starting Status: {trainer.starting_status}\n")
|
||||
if trainer.party:
|
||||
for i, pokemon in enumerate(trainer.party):
|
||||
out_party.write(f"\n")
|
||||
if pokemon.nickname:
|
||||
out_party.write(f"{pokemon.nickname} ({pokemon.species})")
|
||||
else:
|
||||
out_party.write(f"{pokemon.species}")
|
||||
if pokemon.gender:
|
||||
out_party.write(f" ({pokemon.gender})")
|
||||
if pokemon.item and pokemon.item != 'None':
|
||||
out_party.write(f" @ {pokemon.item}")
|
||||
out_party.write(f"\n")
|
||||
if pokemon.nature:
|
||||
out_party.write(f"{pokemon.nature} Nature\n")
|
||||
for key in pokemon_attribute_order:
|
||||
if key in pokemon.attributes:
|
||||
out_party.write(f"{key}: {pokemon.attributes[key]}\n")
|
||||
for move in pokemon.moves:
|
||||
out_party.write(f"- {move}\n")
|
||||
trainer = None
|
||||
elif is_blank.search(line) or is_trainer_skip.search(line):
|
||||
pass
|
||||
else:
|
||||
raise Exception(f"could not parse '{line.strip()}'")
|
||||
except Exception as e:
|
||||
print(f"{in_path}:{line_no}: {e}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
[argv0, trainers_in_path, parties_in_path, out_path] = sys.argv
|
||||
except:
|
||||
print(f"usage: python3 {sys.argv[0]} <trainers.h> <trainer_parties.h> <out>")
|
||||
else:
|
||||
with open(trainers_in_path, "r") as trainers_in_h, open(parties_in_path, "r") as parties_in_h, open(out_path, "w") as out_party:
|
||||
parties = convert_parties(parties_in_path, parties_in_h)
|
||||
trainers = convert_trainers(trainers_in_path, trainers_in_h, parties, out_party)
|
||||
|
||||
@ -1,51 +1,51 @@
|
||||
import re
|
||||
import glob
|
||||
|
||||
eggMoveSpecies = []
|
||||
|
||||
exceptions = [ # the following exceptions are hardcoded to streamline the process. you may need to manually check what happens in case you have added forms that work similar to these below
|
||||
["ShellosWestSea", "Shellos"],
|
||||
["OricorioBaile", "Oricorio"]
|
||||
]
|
||||
|
||||
# convert egg_moves.h to the new format
|
||||
with open("src/data/pokemon/egg_moves.h", "r") as f:
|
||||
data = f.read()
|
||||
|
||||
data = re.sub(r"#define(.|\n)*const u16 gEggMoves\[\] = {", "static const u16 sNoneEggMoveLearnset[] = {\n MOVE_UNAVAILABLE,\n};\n", data) # remove and replace header
|
||||
data = re.sub(r"\n EGG_MOVES_TERMINATOR\n};\n\n", "", data) # remove footer
|
||||
|
||||
for mon in re.findall(r"egg_moves\((.*),", data):
|
||||
monname = re.sub(r"_", " ", mon).title().replace(" ", "")
|
||||
for x in exceptions:
|
||||
if monname == x[0]:
|
||||
monname = x[1]
|
||||
# add it to the list for later
|
||||
eggMoveSpecies.append(monname)
|
||||
# regex the egg_moves.h file
|
||||
data = re.sub(r" egg_moves\(" + mon + r",", "static const u16 s%sEggMoveLearnset[] = {" % monname, data)
|
||||
|
||||
data = re.sub(r"\),\n", ",\n MOVE_UNAVAILABLE,\n};\n", data) # add terminator to each old macro
|
||||
|
||||
data = re.sub(r" MOVE_", " MOVE_", data) # fix indentation
|
||||
|
||||
with open("src/data/pokemon/egg_moves.h", "w") as f:
|
||||
f.write(data)
|
||||
|
||||
# update gBaseStats
|
||||
|
||||
for file in glob.glob('./src/data/pokemon/species_info/gen_*_families.h'):
|
||||
with open(file, "r") as f:
|
||||
data = f.read()
|
||||
|
||||
# go through all Pokemon with teachable learnsets that are also in the list, then assign egg moves to them
|
||||
for mon in eggMoveSpecies:
|
||||
# first do the plain replacements outside of macros
|
||||
data = re.sub(r"\.teachableLearnset = s" + mon + r"sTeachableLearnset,\n", ".teachableLearnset = s%sTeachableLearnset,\n .eggMoveLearnset = s%sEggMoveLearnset,\n" % (mon, mon), data)
|
||||
# check for macros (since they require \ at the end of the line and do those manually)
|
||||
macrocheck = re.findall(r"\.teachableLearnset = s" + mon + r"TeachableLearnset,( *)\\\\", data)
|
||||
if len(macrocheck) > 0:
|
||||
data = re.sub(r"\.teachableLearnset = s" + mon + r"TeachableLearnset," + macrocheck[0] + r"\\\\", ".teachableLearnset = s%sTeachableLearnset,%s\\\\\n .eggMoveLearnset = s%sEggMoveLearnset,%s\\\\" % (mon, macrocheck[0], mon, " " * (len(macrocheck[0]) + 4)), data)
|
||||
|
||||
with open(file, "w") as f:
|
||||
f.write(data)
|
||||
import re
|
||||
import glob
|
||||
|
||||
eggMoveSpecies = []
|
||||
|
||||
exceptions = [ # the following exceptions are hardcoded to streamline the process. you may need to manually check what happens in case you have added forms that work similar to these below
|
||||
["ShellosWestSea", "Shellos"],
|
||||
["OricorioBaile", "Oricorio"]
|
||||
]
|
||||
|
||||
# convert egg_moves.h to the new format
|
||||
with open("src/data/pokemon/egg_moves.h", "r") as f:
|
||||
data = f.read()
|
||||
|
||||
data = re.sub(r"#define(.|\n)*const u16 gEggMoves\[\] = {", "static const u16 sNoneEggMoveLearnset[] = {\n MOVE_UNAVAILABLE,\n};\n", data) # remove and replace header
|
||||
data = re.sub(r"\n EGG_MOVES_TERMINATOR\n};\n\n", "", data) # remove footer
|
||||
|
||||
for mon in re.findall(r"egg_moves\((.*),", data):
|
||||
monname = re.sub(r"_", " ", mon).title().replace(" ", "")
|
||||
for x in exceptions:
|
||||
if monname == x[0]:
|
||||
monname = x[1]
|
||||
# add it to the list for later
|
||||
eggMoveSpecies.append(monname)
|
||||
# regex the egg_moves.h file
|
||||
data = re.sub(r" egg_moves\(" + mon + r",", "static const u16 s%sEggMoveLearnset[] = {" % monname, data)
|
||||
|
||||
data = re.sub(r"\),\n", ",\n MOVE_UNAVAILABLE,\n};\n", data) # add terminator to each old macro
|
||||
|
||||
data = re.sub(r" MOVE_", " MOVE_", data) # fix indentation
|
||||
|
||||
with open("src/data/pokemon/egg_moves.h", "w") as f:
|
||||
f.write(data)
|
||||
|
||||
# update gBaseStats
|
||||
|
||||
for file in glob.glob('./src/data/pokemon/species_info/gen_*_families.h'):
|
||||
with open(file, "r") as f:
|
||||
data = f.read()
|
||||
|
||||
# go through all Pokemon with teachable learnsets that are also in the list, then assign egg moves to them
|
||||
for mon in eggMoveSpecies:
|
||||
# first do the plain replacements outside of macros
|
||||
data = re.sub(r"\.teachableLearnset = s" + mon + r"sTeachableLearnset,\n", ".teachableLearnset = s%sTeachableLearnset,\n .eggMoveLearnset = s%sEggMoveLearnset,\n" % (mon, mon), data)
|
||||
# check for macros (since they require \ at the end of the line and do those manually)
|
||||
macrocheck = re.findall(r"\.teachableLearnset = s" + mon + r"TeachableLearnset,( *)\\\\", data)
|
||||
if len(macrocheck) > 0:
|
||||
data = re.sub(r"\.teachableLearnset = s" + mon + r"TeachableLearnset," + macrocheck[0] + r"\\\\", ".teachableLearnset = s%sTeachableLearnset,%s\\\\\n .eggMoveLearnset = s%sEggMoveLearnset,%s\\\\" % (mon, macrocheck[0], mon, " " * (len(macrocheck[0]) + 4)), data)
|
||||
|
||||
with open(file, "w") as f:
|
||||
f.write(data)
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
# 原始字符串
|
||||
text = "全副武装的样子。\n即使是极巨化宝可梦的\n攻击也能轻易抵挡。"
|
||||
|
||||
# 按照\n分割
|
||||
split_text = text.split('\n')
|
||||
|
||||
# 格式化输出为需要的三段,并处理最后一段不加\\n
|
||||
formatted_text = [f'"{part}\\n"' for part in split_text[:-1]] # 所有除最后一段外加\\n
|
||||
formatted_text.append(f'"{split_text[-1]}"') # 最后一段不加\\n
|
||||
|
||||
# 拼接成最终的描述
|
||||
description = '\n'.join(formatted_text)
|
||||
|
||||
# 输出结果
|
||||
print(description)
|
||||
# 原始字符串
|
||||
text = "全副武装的样子。\n即使是极巨化宝可梦的\n攻击也能轻易抵挡。"
|
||||
|
||||
# 按照\n分割
|
||||
split_text = text.split('\n')
|
||||
|
||||
# 格式化输出为需要的三段,并处理最后一段不加\\n
|
||||
formatted_text = [f'"{part}\\n"' for part in split_text[:-1]] # 所有除最后一段外加\\n
|
||||
formatted_text.append(f'"{split_text[-1]}"') # 最后一段不加\\n
|
||||
|
||||
# 拼接成最终的描述
|
||||
description = '\n'.join(formatted_text)
|
||||
|
||||
# 输出结果
|
||||
print(description)
|
||||
|
||||
@ -1,79 +1,79 @@
|
||||
import os
|
||||
import re
|
||||
import pandas as pd
|
||||
import os
|
||||
|
||||
current_folder = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
def convert_description_to_multiline(description):
|
||||
split_text = description.split('\\n')
|
||||
|
||||
# 格式化输出为需要的三段,并处理最后一段不加\\n
|
||||
formatted_text = [f'"{part}\\\\n"' for part in split_text[:-1]] # 所有除最后一段外加\\n
|
||||
formatted_text.append(f'"{split_text[-1]}"') # 最后一段不加\\n
|
||||
|
||||
# 拼接成最终的描述
|
||||
description = '\n\\t\\t\\t'.join(formatted_text)
|
||||
final=r'.description = COMPOUND_STRING(\n\t\t\t' + description+ '),'
|
||||
return final
|
||||
|
||||
def query_pokemon_info(name, df):
|
||||
try:
|
||||
result = df.loc[name]
|
||||
return {
|
||||
'speciesName': result['speciesName'],
|
||||
'categoryName': result['categoryName'],
|
||||
'description': result['description']
|
||||
}
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def replace_species_info(content, df):
|
||||
pattern = r"\[SPECIES_(\w+)\]\s*=\s*\{.*?\n\s*\},?"
|
||||
matches = list(re.finditer(pattern, content, re.DOTALL))
|
||||
|
||||
for match in matches:
|
||||
species = match.group(1)
|
||||
original_block = match.group(0)
|
||||
info = query_pokemon_info("SPECIES_"+species, df)
|
||||
if not info:
|
||||
log(f"❌ 未找到 {'SPECIES_'+species},跳过")
|
||||
continue
|
||||
|
||||
block = original_block
|
||||
|
||||
# 替换 .speciesName
|
||||
block = re.sub(r'\.speciesName\s*=\s*_\(.*?\),', f'.speciesName = _("{info["speciesName"]}"),', block)
|
||||
|
||||
# 替换 .categoryName
|
||||
block = re.sub(r'\.categoryName\s*=\s*_\(.*?\),', f'.categoryName = _("{info["categoryName"]}"),', block)
|
||||
|
||||
# 替换 .description
|
||||
block = re.sub(r'\.description\s*=\s*COMPOUND_STRING\((?:.|\n)*?\),', convert_description_to_multiline(info["description"]), block)
|
||||
|
||||
content = content.replace(original_block, block)
|
||||
|
||||
return content
|
||||
|
||||
def log(message):
|
||||
with open(current_folder+"\log.txt", "a", encoding="utf-8") as log_file:
|
||||
log_file.write(message + "\n")
|
||||
print(message)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
work_folder = current_folder +"\..\src\data\pokemon\species_info"
|
||||
df = pd.read_excel(current_folder +r'\src\图鉴.xlsx')
|
||||
df.set_index('name', inplace=True)
|
||||
|
||||
for filename in os.listdir(work_folder):
|
||||
if re.match(r'^gen_\d+_families\.h$', filename):
|
||||
file_path = os.path.join(work_folder, filename)
|
||||
log(f"✅ 处理文件:{file_path}")
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
new_content = replace_species_info(content, df)
|
||||
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write(new_content)
|
||||
import os
|
||||
import re
|
||||
import pandas as pd
|
||||
import os
|
||||
|
||||
current_folder = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
def convert_description_to_multiline(description):
|
||||
split_text = description.split('\\n')
|
||||
|
||||
# 格式化输出为需要的三段,并处理最后一段不加\\n
|
||||
formatted_text = [f'"{part}\\\\n"' for part in split_text[:-1]] # 所有除最后一段外加\\n
|
||||
formatted_text.append(f'"{split_text[-1]}"') # 最后一段不加\\n
|
||||
|
||||
# 拼接成最终的描述
|
||||
description = '\n\\t\\t\\t'.join(formatted_text)
|
||||
final=r'.description = COMPOUND_STRING(\n\t\t\t' + description+ '),'
|
||||
return final
|
||||
|
||||
def query_pokemon_info(name, df):
|
||||
try:
|
||||
result = df.loc[name]
|
||||
return {
|
||||
'speciesName': result['speciesName'],
|
||||
'categoryName': result['categoryName'],
|
||||
'description': result['description']
|
||||
}
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def replace_species_info(content, df):
|
||||
pattern = r"\[SPECIES_(\w+)\]\s*=\s*\{.*?\n\s*\},?"
|
||||
matches = list(re.finditer(pattern, content, re.DOTALL))
|
||||
|
||||
for match in matches:
|
||||
species = match.group(1)
|
||||
original_block = match.group(0)
|
||||
info = query_pokemon_info("SPECIES_"+species, df)
|
||||
if not info:
|
||||
log(f"❌ 未找到 {'SPECIES_'+species},跳过")
|
||||
continue
|
||||
|
||||
block = original_block
|
||||
|
||||
# 替换 .speciesName
|
||||
block = re.sub(r'\.speciesName\s*=\s*_\(.*?\),', f'.speciesName = _("{info["speciesName"]}"),', block)
|
||||
|
||||
# 替换 .categoryName
|
||||
block = re.sub(r'\.categoryName\s*=\s*_\(.*?\),', f'.categoryName = _("{info["categoryName"]}"),', block)
|
||||
|
||||
# 替换 .description
|
||||
block = re.sub(r'\.description\s*=\s*COMPOUND_STRING\((?:.|\n)*?\),', convert_description_to_multiline(info["description"]), block)
|
||||
|
||||
content = content.replace(original_block, block)
|
||||
|
||||
return content
|
||||
|
||||
def log(message):
|
||||
with open(current_folder+"\log.txt", "a", encoding="utf-8") as log_file:
|
||||
log_file.write(message + "\n")
|
||||
print(message)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
work_folder = current_folder +"\..\src\data\pokemon\species_info"
|
||||
df = pd.read_excel(current_folder +r'\src\图鉴.xlsx')
|
||||
df.set_index('name', inplace=True)
|
||||
|
||||
for filename in os.listdir(work_folder):
|
||||
if re.match(r'^gen_\d+_families\.h$', filename):
|
||||
file_path = os.path.join(work_folder, filename)
|
||||
log(f"✅ 处理文件:{file_path}")
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
new_content = replace_species_info(content, df)
|
||||
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write(new_content)
|
||||
|
||||
@ -1,80 +1,80 @@
|
||||
import os
|
||||
import re
|
||||
import pandas as pd
|
||||
import os
|
||||
|
||||
current_folder = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
def convert_description_to_multiline(description):
|
||||
if not isinstance(description, str):
|
||||
return None
|
||||
# 替换中文字符为英文字符
|
||||
split_text = description.split('\\n')
|
||||
|
||||
# 格式化输出为需要的三段,并处理最后一段不加\\n
|
||||
formatted_text = [f'"{part}\\\\n"' for part in split_text[:-1]] # 所有除最后一段外加\\n
|
||||
formatted_text.append(f'"{split_text[-1]}"') # 最后一段不加\\n
|
||||
|
||||
# 拼接成最终的描述
|
||||
description = '\n\\t\\t\\t'.join(formatted_text)
|
||||
final=r'.description = COMPOUND_STRING(\n\t\t\t' + description+ '),'
|
||||
return final
|
||||
|
||||
def query_pokemon_info(name, df):
|
||||
try:
|
||||
result = df.loc[name]
|
||||
return {
|
||||
'中文名': result['中文名'],
|
||||
'单独技能效果说明': result['单独技能效果说明'],
|
||||
# 'description': result['description']
|
||||
}
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def replace_move_info(content, df):
|
||||
pattern = r"\[MOVE_(\w+)\]\s*=\s*\{.*?\n\s*\},?"
|
||||
matches = list(re.finditer(pattern, content, re.DOTALL))
|
||||
|
||||
for match in matches:
|
||||
move = match.group(1)
|
||||
original_block = match.group(0)
|
||||
info = query_pokemon_info("[MOVE_"+move+"]", df)
|
||||
if not info:
|
||||
log(f"❌ 未找到 {'MOVE_'+move},跳过")
|
||||
continue
|
||||
|
||||
block = original_block
|
||||
|
||||
# 替换 .moveName
|
||||
block = re.sub(r'\.name\s*=\s*COMPOUND_STRING\(.*?\),', f'.name = COMPOUND_STRING("{info["中文名"]}"),', block)
|
||||
|
||||
# block = re.sub(r'\.categoryName\s*=\s*_\(.*?\),', f'.categoryName = _("{info["categoryName"]}"),', block)
|
||||
try:
|
||||
block = re.sub(r'\.description\s*=\s*COMPOUND_STRING\((?:.|\n)*?\),\s+#endif', convert_description_to_multiline(info["单独技能效果说明"]), block)
|
||||
block = re.sub(r'\.description\s*=\s*COMPOUND_STRING\((?:.|\n)*?\),', convert_description_to_multiline(info["单独技能效果说明"]), block)
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
log(f"❌ {'MOVE_'+move} 没有单独技能效果说明,跳过")
|
||||
content = content.replace(original_block, block)
|
||||
|
||||
return content
|
||||
|
||||
def log(message):
|
||||
with open(current_folder+"\log.txt", "a", encoding="utf-8") as log_file:
|
||||
log_file.write(message + "\n")
|
||||
print(message)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
work_file = current_folder +"\..\src\data\moves_info.h"
|
||||
df = pd.read_excel(current_folder +r'\src\技能.xlsx')
|
||||
df.set_index('技能', inplace=True)
|
||||
|
||||
|
||||
with open(work_file, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
new_content = replace_move_info(content, df)
|
||||
|
||||
with open(work_file, "w", encoding="utf-8") as f:
|
||||
f.write(new_content)
|
||||
import os
|
||||
import re
|
||||
import pandas as pd
|
||||
import os
|
||||
|
||||
current_folder = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
def convert_description_to_multiline(description):
|
||||
if not isinstance(description, str):
|
||||
return None
|
||||
# 替换中文字符为英文字符
|
||||
split_text = description.split('\\n')
|
||||
|
||||
# 格式化输出为需要的三段,并处理最后一段不加\\n
|
||||
formatted_text = [f'"{part}\\\\n"' for part in split_text[:-1]] # 所有除最后一段外加\\n
|
||||
formatted_text.append(f'"{split_text[-1]}"') # 最后一段不加\\n
|
||||
|
||||
# 拼接成最终的描述
|
||||
description = '\n\\t\\t\\t'.join(formatted_text)
|
||||
final=r'.description = COMPOUND_STRING(\n\t\t\t' + description+ '),'
|
||||
return final
|
||||
|
||||
def query_pokemon_info(name, df):
|
||||
try:
|
||||
result = df.loc[name]
|
||||
return {
|
||||
'中文名': result['中文名'],
|
||||
'单独技能效果说明': result['单独技能效果说明'],
|
||||
# 'description': result['description']
|
||||
}
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def replace_move_info(content, df):
|
||||
pattern = r"\[MOVE_(\w+)\]\s*=\s*\{.*?\n\s*\},?"
|
||||
matches = list(re.finditer(pattern, content, re.DOTALL))
|
||||
|
||||
for match in matches:
|
||||
move = match.group(1)
|
||||
original_block = match.group(0)
|
||||
info = query_pokemon_info("[MOVE_"+move+"]", df)
|
||||
if not info:
|
||||
log(f"❌ 未找到 {'MOVE_'+move},跳过")
|
||||
continue
|
||||
|
||||
block = original_block
|
||||
|
||||
# 替换 .moveName
|
||||
block = re.sub(r'\.name\s*=\s*COMPOUND_STRING\(.*?\),', f'.name = COMPOUND_STRING("{info["中文名"]}"),', block)
|
||||
|
||||
# block = re.sub(r'\.categoryName\s*=\s*_\(.*?\),', f'.categoryName = _("{info["categoryName"]}"),', block)
|
||||
try:
|
||||
block = re.sub(r'\.description\s*=\s*COMPOUND_STRING\((?:.|\n)*?\),\s+#endif', convert_description_to_multiline(info["单独技能效果说明"]), block)
|
||||
block = re.sub(r'\.description\s*=\s*COMPOUND_STRING\((?:.|\n)*?\),', convert_description_to_multiline(info["单独技能效果说明"]), block)
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
log(f"❌ {'MOVE_'+move} 没有单独技能效果说明,跳过")
|
||||
content = content.replace(original_block, block)
|
||||
|
||||
return content
|
||||
|
||||
def log(message):
|
||||
with open(current_folder+"\log.txt", "a", encoding="utf-8") as log_file:
|
||||
log_file.write(message + "\n")
|
||||
print(message)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
work_file = current_folder +"\..\src\data\moves_info.h"
|
||||
df = pd.read_excel(current_folder +r'\src\技能.xlsx')
|
||||
df.set_index('技能', inplace=True)
|
||||
|
||||
|
||||
with open(work_file, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
new_content = replace_move_info(content, df)
|
||||
|
||||
with open(work_file, "w", encoding="utf-8") as f:
|
||||
f.write(new_content)
|
||||
|
||||
@ -1,420 +1,420 @@
|
||||
mus_abandoned_ship.mid: -E -R50 -G030 -V080
|
||||
mus_abnormal_weather.mid: -E -R50 -G089 -V080
|
||||
mus_aqua_magma_hideout.mid: -E -R50 -G076 -V084
|
||||
mus_awaken_legend.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_b_arena.mid: -E -R50 -G104 -V090
|
||||
mus_b_dome_lobby.mid: -E -R50 -G111 -V056
|
||||
mus_b_dome.mid: -E -R50 -G111 -V090
|
||||
mus_b_factory.mid: -E -R50 -G113 -V100
|
||||
mus_b_frontier.mid: -E -R50 -G103 -V094
|
||||
mus_b_palace.mid: -E -R50 -G108 -V105
|
||||
mus_b_pike.mid: -E -R50 -G112 -V092
|
||||
mus_b_pyramid_top.mid: -E -R50 -G107 -V077
|
||||
mus_b_pyramid.mid: -E -R50 -G106 -V079
|
||||
mus_b_tower_rs.mid: -E -R50 -G035 -V080
|
||||
mus_b_tower.mid: -E -R50 -G110 -V100
|
||||
mus_birch_lab.mid: -E -R50 -G033 -V080
|
||||
mus_c_comm_center.mid: -E -R50 -V080
|
||||
mus_c_vs_legend_beast.mid: -E -R50 -V080
|
||||
mus_cable_car.mid: -E -R50 -G071 -V078
|
||||
mus_caught.mid: -E -R50 -G025 -V080
|
||||
mus_cave_of_origin.mid: -E -R50 -G037 -V080
|
||||
mus_contest_lobby.mid: -E -R50 -G098 -V060
|
||||
mus_contest_results.mid: -E -R50 -G092 -V080
|
||||
mus_contest_winner.mid: -E -R50 -G085 -V100
|
||||
mus_contest.mid: -E -R50 -G086 -V088
|
||||
mus_credits.mid: -E -R50 -G101 -V100
|
||||
mus_cycling.mid: -E -R50 -G049 -V083
|
||||
mus_dewford.mid: -E -R50 -G073 -V078
|
||||
mus_dummy.mid: -E -R40
|
||||
mus_encounter_aqua.mid: -E -R50 -G065 -V086
|
||||
mus_encounter_brendan.mid: -E -R50 -G067 -V078
|
||||
mus_encounter_champion.mid: -E -R50 -G100 -V076
|
||||
mus_encounter_cool.mid: -E -R50 -G063 -V086
|
||||
mus_encounter_elite_four.mid: -E -R50 -G096 -V078
|
||||
mus_encounter_female.mid: -E -R50 -G053 -V072
|
||||
mus_encounter_girl.mid: -E -R50 -G027 -V080
|
||||
mus_encounter_hiker.mid: -E -R50 -G097 -V076
|
||||
mus_encounter_intense.mid: -E -R50 -G062 -V078
|
||||
mus_encounter_interviewer.mid: -E -R50 -G099 -V062
|
||||
mus_encounter_magma.mid: -E -R50 -G087 -V072
|
||||
mus_encounter_male.mid: -E -R50 -G028 -V080
|
||||
mus_encounter_may.mid: -E -R50 -G061 -V078
|
||||
mus_encounter_rich.mid: -E -R50 -G043 -V094
|
||||
mus_encounter_suspicious.mid: -E -R50 -G069 -V078
|
||||
mus_encounter_swimmer.mid: -E -R50 -G036 -V080
|
||||
mus_encounter_twins.mid: -E -R50 -G095 -V075
|
||||
mus_end.mid: -E -R50 -G102 -V036
|
||||
mus_ever_grande.mid: -E -R50 -G068 -V086
|
||||
mus_evolution_intro.mid: -E -R50 -G026 -V080
|
||||
mus_evolution.mid: -E -R50 -G026 -V080
|
||||
mus_evolved.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_fallarbor.mid: -E -R50 -G083 -V100
|
||||
mus_follow_me.mid: -E -R50 -G066 -V074
|
||||
mus_fortree.mid: -E -R50 -G032 -V080
|
||||
mus_game_corner.mid: -E -R50 -G072 -V072
|
||||
mus_gsc_pewter.mid: -E -R50 -V080
|
||||
mus_gsc_route38.mid: -E -R50 -V080
|
||||
mus_gym.mid: -E -R50 -G013 -V080
|
||||
mus_hall_of_fame_room.mid: -E -R50 -G093 -V080
|
||||
mus_hall_of_fame.mid: -E -R50 -G082 -V078
|
||||
mus_heal.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_help.mid: -E -R50 -G056 -V078
|
||||
mus_intro_battle.mid: -E -R50 -G088 -V088
|
||||
mus_intro.mid: -E -R50 -G060 -V090
|
||||
mus_level_up.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_lilycove_museum.mid: -E -R50 -G020 -V080
|
||||
mus_lilycove.mid: -E -R50 -G054 -V085
|
||||
mus_link_contest_p1.mid: -E -R50 -G039 -V079
|
||||
mus_link_contest_p2.mid: -E -R50 -G040 -V090
|
||||
mus_link_contest_p3.mid: -E -R50 -G041 -V075
|
||||
mus_link_contest_p4.mid: -E -R50 -G042 -V090
|
||||
mus_littleroot_test.mid: -E -R50 -G034 -V099
|
||||
mus_littleroot.mid: -E -R50 -G051 -V100
|
||||
mus_move_deleted.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_mt_chimney.mid: -E -R50 -G052 -V078
|
||||
mus_mt_pyre_exterior.mid: -E -R50 -G080 -V080
|
||||
mus_mt_pyre.mid: -E -R50 -G078 -V088
|
||||
mus_obtain_b_points.mid: -E -R50 -G103 -V090 -P5
|
||||
mus_obtain_badge.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_obtain_berry.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_obtain_item.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_obtain_symbol.mid: -E -R50 -G103 -V100 -P5
|
||||
mus_obtain_tmhm.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_oceanic_museum.mid: -E -R50 -G023 -V080
|
||||
mus_oldale.mid: -E -R50 -G019 -V080
|
||||
mus_petalburg_woods.mid: -E -R50 -G018 -V080
|
||||
mus_petalburg.mid: -E -R50 -G015 -V080
|
||||
mus_poke_center.mid: -E -R50 -G046 -V092
|
||||
mus_poke_mart.mid: -E -R50 -G050 -V085
|
||||
mus_rayquaza_appears.mid: -E -R50 -G109 -V090
|
||||
mus_register_match_call.mid: -E -R50 -G105 -V090 -P5
|
||||
mus_rg_berry_pick.mid: -E -R50 -G132 -V090
|
||||
mus_rg_caught_intro.mid: -E -R50 -G179 -V094 -P5
|
||||
mus_rg_caught.mid: -E -R50 -G170 -V100
|
||||
mus_rg_celadon.mid: -E -R50 -G168 -V070
|
||||
mus_rg_cinnabar.mid: -E -R50 -G138 -V090
|
||||
mus_rg_credits.mid: -E -R50 -G149 -V090
|
||||
mus_rg_cycling.mid: -E -R50 -G141 -V090
|
||||
mus_rg_dex_rating.mid: -E -R50 -G175 -V070 -P5
|
||||
mus_rg_encounter_boy.mid: -E -R50 -G144 -V090
|
||||
mus_rg_encounter_deoxys.mid: -E -R50 -G184 -V079
|
||||
mus_rg_encounter_girl.mid: -E -R50 -G143 -V051
|
||||
mus_rg_encounter_gym_leader: -E -R50 -G144 -V090
|
||||
mus_rg_encounter_rival.mid: -E -R50 -G174 -V079
|
||||
mus_rg_encounter_rocket.mid: -E -R50 -G142 -V096
|
||||
mus_rg_follow_me.mid: -E -R50 -G131 -V068
|
||||
mus_rg_fuchsia.mid: -E -R50 -G167 -V090
|
||||
mus_rg_game_corner.mid: -E -R50 -G132 -V090
|
||||
mus_rg_game_freak.mid: -E -R50 -G181 -V075
|
||||
mus_rg_gym.mid: -E -R50 -G134 -V090
|
||||
mus_rg_hall_of_fame.mid: -E -R50 -G145 -V079
|
||||
mus_rg_heal.mid: -E -R50 -G140 -V090
|
||||
mus_rg_intro_fight.mid: -E -R50 -G136 -V090
|
||||
mus_rg_jigglypuff.mid: -E -R50 -G135 -V068 -P5
|
||||
mus_rg_lavender.mid: -E -R50 -G139 -V090
|
||||
mus_rg_mt_moon.mid: -E -R50 -G147 -V090
|
||||
mus_rg_mystery_gift.mid: -E -R50 -G183 -V100
|
||||
mus_rg_net_center.mid: -E -R50 -G162 -V096
|
||||
mus_rg_new_game_exit.mid: -E -R50 -G182 -V088
|
||||
mus_rg_new_game_instruct.mid: -E -R50 -G182 -V085
|
||||
mus_rg_new_game_intro.mid: -E -R50 -G182 -V088
|
||||
mus_rg_oak_lab.mid: -E -R50 -G160 -V075
|
||||
mus_rg_oak.mid: -E -R50 -G161 -V086
|
||||
mus_rg_obtain_key_item.mid: -E -R50 -G178 -V077 -P5
|
||||
mus_rg_pallet.mid: -E -R50 -G159 -V100
|
||||
mus_rg_pewter.mid: -E -R50 -G173 -V084
|
||||
mus_rg_photo.mid: -E -R50 -G180 -V100 -P5
|
||||
mus_rg_poke_center.mid: -E -R50 -G162 -V096
|
||||
mus_rg_poke_flute.mid: -E -R50 -G165 -V048 -P5
|
||||
mus_rg_poke_jump.mid: -E -R50 -G132 -V090
|
||||
mus_rg_poke_mansion.mid: -E -R50 -G148 -V090
|
||||
mus_rg_poke_tower.mid: -E -R50 -G165 -V090
|
||||
mus_rg_rival_exit.mid: -E -R50 -G174 -V079
|
||||
mus_rg_rocket_hideout.mid: -E -R50 -G133 -V090
|
||||
mus_rg_route1.mid: -E -R50 -G150 -V079
|
||||
mus_rg_route3.mid: -E -R50 -G152 -V083
|
||||
mus_rg_route11.mid: -E -R50 -G153 -V090
|
||||
mus_rg_route24.mid: -E -R50 -G151 -V086
|
||||
mus_rg_sevii_45.mid: -E -R50 -G188 -V084
|
||||
mus_rg_sevii_67.mid: -E -R50 -G189 -V084
|
||||
mus_rg_sevii_123.mid: -E -R50 -G173 -V084
|
||||
mus_rg_sevii_cave.mid: -E -R50 -G147 -V090
|
||||
mus_rg_sevii_dungeon.mid: -E -R50 -G146 -V090
|
||||
mus_rg_sevii_route.mid: -E -R50 -G187 -V080
|
||||
mus_rg_silph.mid: -E -R50 -G166 -V076
|
||||
mus_rg_slow_pallet.mid: -E -R50 -G159 -V092
|
||||
mus_rg_ss_anne.mid: -E -R50 -G163 -V090
|
||||
mus_rg_surf.mid: -E -R50 -G164 -V071
|
||||
mus_rg_teachy_tv_menu.mid: -E -R50 -G186 -V059
|
||||
mus_rg_teachy_tv_show.mid: -E -R50 -G131 -V068
|
||||
mus_rg_title.mid: -E -R50 -G137 -V090
|
||||
mus_rg_trainer_tower.mid: -E -R50 -G134 -V090
|
||||
mus_rg_union_room.mid: -E -R50 -G132 -V090
|
||||
mus_rg_vermillion.mid: -E -R50 -G172 -V090
|
||||
mus_rg_victory_gym_leader.mid: -E -R50 -G171 -V090
|
||||
mus_rg_victory_road.mid: -E -R50 -G154 -V090
|
||||
mus_rg_victory_trainer.mid: -E -R50 -G169 -V089
|
||||
mus_rg_victory_wild.mid: -E -R50 -G170 -V090
|
||||
mus_rg_viridian_forest.mid: -E -R50 -G146 -V090
|
||||
mus_rg_vs_champion.mid: -E -R50 -G158 -V090
|
||||
mus_rg_vs_deoxys.mid: -E -R50 -G185 -V080
|
||||
mus_rg_vs_gym_leader.mid: -E -R50 -G155 -V090
|
||||
mus_rg_vs_legend.mid: -E -R50 -G157 -V090
|
||||
mus_rg_vs_mewtwo.mid: -E -R50 -G157 -V090
|
||||
mus_rg_vs_trainer.mid: -E -R50 -G156 -V090
|
||||
mus_rg_vs_wild.mid: -E -R50 -G157 -V090
|
||||
mus_roulette.mid: -E -R50 -G038 -V080
|
||||
mus_route101.mid: -E -R50 -G011 -V080
|
||||
mus_route104.mid: -E -R50 -G047 -V097
|
||||
mus_route110.mid: -E -R50 -G010 -V080
|
||||
mus_route111.mid: -E -R50 -G055 -V076
|
||||
mus_route113.mid: -E -R50 -G064 -V084
|
||||
mus_route119.mid: -E -R50 -G048 -V096
|
||||
mus_route120.mid: -E -R50 -G014 -V080
|
||||
mus_route122.mid: -E -R50 -G021 -V080
|
||||
mus_rustboro.mid: -E -R50 -G045 -V085
|
||||
mus_safari_zone.mid: -E -R50 -G074 -V082
|
||||
mus_sailing.mid: -E -R50 -G077 -V086
|
||||
mus_school.mid: -E -R50 -G081 -V100
|
||||
mus_sealed_chamber.mid: -E -R50 -G084 -V100
|
||||
mus_slateport.mid: -E -R50 -G079 -V070
|
||||
mus_slots_jackpot.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_slots_win.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_sootopolis.mid: -E -R50 -G091 -V062
|
||||
mus_surf.mid: -E -R50 -G017 -V080
|
||||
mus_title.mid: -E -R50 -G059 -V090
|
||||
mus_too_bad.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_trick_house.mid: -E -R50 -G094 -V070
|
||||
mus_underwater.mid: -E -R50 -G057 -V094
|
||||
mus_verdanturf.mid: -E -R50 -G044 -V090
|
||||
mus_victory_aqua_magma.mid: -E -R50 -G070 -V088
|
||||
mus_victory_gym_leader.mid: -E -R50 -G024 -V080
|
||||
mus_victory_league.mid: -E -R50 -G029 -V080
|
||||
mus_victory_road.mid: -E -R50 -G075 -V076
|
||||
mus_victory_trainer.mid: -E -R50 -G058 -V091
|
||||
mus_victory_wild.mid: -E -R50 -G025 -V080
|
||||
mus_vs_aqua_magma_leader.mid: -E -R50 -G126 -V080 -P1
|
||||
mus_vs_aqua_magma.mid: -E -R50 -G118 -V080 -P1
|
||||
mus_vs_champion.mid: -E -R50 -G121 -V080 -P1
|
||||
mus_vs_elite_four.mid: -E -R50 -G125 -V080 -P1
|
||||
mus_vs_frontier_brain.mid: -E -R50 -G115 -V090 -P1
|
||||
mus_vs_gym_leader.mid: -E -R50 -G120 -V080 -P1
|
||||
mus_vs_kyogre_groudon.mid: -E -R50 -G123 -V080 -P1
|
||||
mus_vs_mew.mid: -E -R50 -G116 -V090
|
||||
mus_vs_rayquaza.mid: -E -R50 -G114 -V080 -P1
|
||||
mus_vs_regi.mid: -E -R50 -G122 -V080 -P1
|
||||
mus_vs_rival.mid: -E -R50 -G124 -V080 -P1
|
||||
mus_vs_trainer.mid: -E -R50 -G119 -V080 -P1
|
||||
mus_vs_wild.mid: -E -R50 -G117 -V080 -P1
|
||||
mus_weather_groudon.mid: -E -R50 -G090 -V050
|
||||
ph_choice_blend.mid: -E -G130 -P4
|
||||
ph_choice_held.mid: -E -G130 -P4
|
||||
ph_choice_solo.mid: -E -G130 -P4
|
||||
ph_cloth_blend.mid: -E -G130 -P4
|
||||
ph_cloth_held.mid: -E -G130 -P4
|
||||
ph_cloth_solo.mid: -E -G130 -P4
|
||||
ph_cure_blend.mid: -E -G130 -P4
|
||||
ph_cure_held.mid: -E -G130 -P4
|
||||
ph_cure_solo.mid: -E -G130 -P4
|
||||
ph_dress_blend.mid: -E -G130 -P4
|
||||
ph_dress_held.mid: -E -G130 -P4
|
||||
ph_dress_solo.mid: -E -G130 -P4
|
||||
ph_face_blend.mid: -E -G130 -P4
|
||||
ph_face_held.mid: -E -G130 -P4
|
||||
ph_face_solo.mid: -E -G130 -P4
|
||||
ph_fleece_blend.mid: -E -G130 -P4
|
||||
ph_fleece_held.mid: -E -G130 -P4
|
||||
ph_fleece_solo.mid: -E -G130 -P4
|
||||
ph_foot_blend.mid: -E -G130 -P4
|
||||
ph_foot_held.mid: -E -G130 -P4
|
||||
ph_foot_solo.mid: -E -G130 -P4
|
||||
ph_goat_blend.mid: -E -G130 -P4
|
||||
ph_goat_held.mid: -E -G130 -P4
|
||||
ph_goat_solo.mid: -E -G130 -P4
|
||||
ph_goose_blend.mid: -E -G130 -P4
|
||||
ph_goose_held.mid: -E -G130 -P4
|
||||
ph_goose_solo.mid: -E -G130 -P4
|
||||
ph_kit_blend.mid: -E -G130 -P4
|
||||
ph_kit_held.mid: -E -G130 -P4
|
||||
ph_kit_solo.mid: -E -G130 -P4
|
||||
ph_lot_blend.mid: -E -G130 -P4
|
||||
ph_lot_held.mid: -E -G130 -P4
|
||||
ph_lot_solo.mid: -E -G130 -P4
|
||||
ph_mouth_blend.mid: -E -G130 -P4
|
||||
ph_mouth_held.mid: -E -G130 -P4
|
||||
ph_mouth_solo.mid: -E -G130 -P4
|
||||
ph_nurse_blend.mid: -E -G130 -P4
|
||||
ph_nurse_held.mid: -E -G130 -P4
|
||||
ph_nurse_solo.mid: -E -G130 -P4
|
||||
ph_price_blend.mid: -E -G130 -P4
|
||||
ph_price_held.mid: -E -G130 -P4
|
||||
ph_price_solo.mid: -E -G130 -P4
|
||||
ph_strut_blend.mid: -E -G130 -P4
|
||||
ph_strut_held.mid: -E -G130 -P4
|
||||
ph_strut_solo.mid: -E -G130 -P4
|
||||
ph_thought_blend.mid: -E -G130 -P4
|
||||
ph_thought_held.mid: -E -G130 -P4
|
||||
ph_thought_solo.mid: -E -G130 -P4
|
||||
ph_trap_blend.mid: -E -G130 -P4
|
||||
ph_trap_held.mid: -E -G130 -P4
|
||||
ph_trap_solo.mid: -E -G130 -P4
|
||||
se_a.mid: -E -R50 -G128 -V095 -P4
|
||||
se_applause.mid: -E -R50 -G128 -V100 -P5
|
||||
se_arena_timeup1.mid: -E -R50 -G129 -P5
|
||||
se_arena_timeup2.mid: -E -R50 -G129 -P5
|
||||
se_ball_bounce_1.mid: -E -R50 -G128 -V100 -P4
|
||||
se_ball_bounce_2.mid: -E -R50 -G128 -V100 -P4
|
||||
se_ball_bounce_3.mid: -E -R50 -G128 -V100 -P4
|
||||
se_ball_bounce_4.mid: -E -R50 -G128 -V100 -P4
|
||||
se_ball_open.mid: -E -R50 -G127 -V100 -P5
|
||||
se_ball_throw.mid: -E -R50 -G128 -V120 -P5
|
||||
se_ball_trade.mid: -E -R50 -G127 -V100 -P5
|
||||
se_ball_tray_ball.mid: -E -R50 -G128 -V110 -P5
|
||||
se_ball_tray_enter.mid: -E -R50 -G128 -V110 -P5
|
||||
se_ball_tray_exit.mid: -E -R50 -G127 -V100 -P5
|
||||
se_ball.mid: -E -R50 -G127 -V070 -P4
|
||||
se_balloon_blue.mid: -E -R50 -G128 -V105 -P4
|
||||
se_balloon_red.mid: -E -R50 -G128 -V105 -P4
|
||||
se_balloon_yellow.mid: -E -R50 -G128 -V105 -P4
|
||||
se_bang.mid: -E -R50 -G128 -V110 -P4
|
||||
se_berry_blender.mid: -E -R50 -G128 -V090 -P4
|
||||
se_bike_bell.mid: -E -R50 -G128 -V090 -P4
|
||||
se_bike_hop.mid: -E -R50 -G127 -V090 -P4
|
||||
se_boo.mid: -E -R50 -G127 -V110 -P4
|
||||
se_breakable_door.mid: -E -R50 -G128 -V110 -P4
|
||||
se_bridge_walk.mid: -E -R50 -G128 -V095 -P4
|
||||
se_card.mid: -E -R50 -G127 -V100 -P4
|
||||
se_click.mid: -E -R50 -G127 -V110 -P4
|
||||
se_contest_condition_lose.mid: -E -R50 -G127 -V110 -P4
|
||||
se_contest_curtain_fall.mid: -E -R50 -G128 -V070 -P5
|
||||
se_contest_curtain_rise.mid: -E -R50 -G128 -V070 -P5
|
||||
se_contest_heart.mid: -E -R50 -G128 -V090 -P5
|
||||
se_contest_icon_change.mid: -E -R50 -G128 -V110 -P5
|
||||
se_contest_icon_clear.mid: -E -R50 -G128 -V090 -P5
|
||||
se_contest_mons_turn.mid: -E -R50 -G128 -V090 -P5
|
||||
se_contest_place.mid: -E -R50 -G127 -V110 -P4
|
||||
se_dex_search.mid: -E -R50 -G127 -v100 -P5
|
||||
se_ding_dong.mid: -E -R50 -G127 -V090 -P5
|
||||
se_door.mid: -E -R50 -G127 -V080 -P5
|
||||
se_downpour_stop.mid: -E -R50 -G128 -V100 -P2
|
||||
se_downpour.mid: -E -R50 -G128 -V100 -P2
|
||||
se_e.mid: -E -R50 -G128 -V120 -P4
|
||||
se_effective.mid: -E -R50 -G127 -V110 -P5
|
||||
se_egg_hatch.mid: -E -R50 -G128 -V120 -P5
|
||||
se_elevator.mid: -E -R50 -G128 -V100 -P4
|
||||
se_escalator.mid: -E -R50 -G128 -V100 -P4
|
||||
se_exit.mid: -E -R50 -G127 -V120 -P5
|
||||
se_exp_max.mid: -E -R50 -G128 -V094 -P5
|
||||
se_exp.mid: -E -R50 -G127 -V080 -P5
|
||||
se_failure.mid: -E -R50 -G127 -V120 -P4
|
||||
se_faint.mid: -E -R50 -G127 -V110 -P5
|
||||
se_fall.mid: -E -R50 -G128 -V110 -P4
|
||||
se_field_poison.mid: -E -R50 -G127 -V110 -P5
|
||||
se_flee.mid: -E -R50 -G127 -V090 -P5
|
||||
se_fu_zaku.mid: -E -R50 -G127 -V120 -P4
|
||||
se_glass_flute.mid: -E -R50 -G128 -V105 -P5
|
||||
se_i.mid: -E -R50 -G128 -V120 -P4
|
||||
se_ice_break.mid: -E -R50 -G128 -V100 -P4
|
||||
se_ice_crack.mid: -E -R50 -G127 -V100 -P4
|
||||
se_ice_stairs.mid: -E -R50 -G128 -V090 -P4
|
||||
se_intro_blast.mid: -E -R50 -G127 -V100 -P5
|
||||
se_itemfinder.mid: -E -R50 -G127 -V090 -P5
|
||||
se_lavaridge_fall_warp.mid: -E -R50 -G127 -P4
|
||||
se_ledge.mid: -E -R50 -G127 -V100 -P4
|
||||
se_low_health.mid: -E -R50 -G127 -V100 -P3
|
||||
se_m_bind.mid: -E -R50 -G128 -V100 -P4
|
||||
se_m_comet_punch.mid: -E -R50 -G128 -V120 -P4
|
||||
se_m_cut.mid: -E -R50 -G128 -V120 -P4
|
||||
se_m_double_slap.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_fire_punch.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_fly.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_gust.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_gust2.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_headbutt.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_horn_attack.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_jump_kick.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_leer.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_mega_kick.mid: -E -R50 -G128 -V090 -P4
|
||||
se_m_mega_kick2.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_pay_day.mid: -E -R50 -G128 -V095 -P4
|
||||
se_m_razor_wind.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_razor_wind2.mid: -E -R50 -G128 -V090 -P4
|
||||
se_m_sand_attack.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_scratch.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_swords_dance.mid: -E -R50 -G128 -V100 -P4
|
||||
se_m_tail_whip.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_take_down.mid: -E -R50 -G128 -V105 -P4
|
||||
se_m_vicegrip.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_wing_attack.mid: -E -R50 -G128 -V105 -P4
|
||||
se_mud_ball.mid: -E -R50 -G128 -V110 -P4
|
||||
se_mugshot.mid: -E -R50 -G128 -V090 -P5
|
||||
se_n.mid: -E -R50 -G128 -P4
|
||||
se_not_effective.mid: -E -R50 -G127 -V110 -P5
|
||||
se_note_a.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_b.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_c_high.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_c.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_d.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_e.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_f.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_g.mid: -E -R50 -G128 -V110 -P4
|
||||
se_o.mid: -E -R50 -G128 -V120 -P4
|
||||
se_orb.mid: -E -R50 -G128 -V100 -P5
|
||||
se_pc_login.mid: -E -R50 -G127 -V100 -P5
|
||||
se_pc_off.mid: -E -R50 -G127 -V100 -P5
|
||||
se_pc_on.mid: -E -R50 -G127 -V100 -P5
|
||||
se_pike_curtain_close.mid: -E -R50 -G129 -P5
|
||||
se_pike_curtain_open.mid: -E -R50 -G129 -P5
|
||||
se_pin.mid: -E -R50 -G127 -V060 -P4
|
||||
se_pokenav_call.mid: -E -R50 -G129 -V120 -P5
|
||||
se_pokenav_hang_up.mid: -E -R50 -G129 -V110 -P5
|
||||
se_pokenav_off.mid: -E -R50 -G127 -V100 -P5
|
||||
se_pokenav_on.mid: -E -R50 -G127 -V100 -P5
|
||||
se_puddle.mid: -E -R50 -G128 -V020 -P4
|
||||
se_rain_stop.mid: -E -R50 -G128 -V080 -P2
|
||||
se_rain.mid: -E -R50 -G128 -V080 -P2
|
||||
se_repel.mid: -E -R50 -G127 -V090 -P4
|
||||
se_rg_bag_cursor.mid: -E -R50 -G129 -P5
|
||||
se_rg_bag_pocket.mid: -E -R50 -G129 -P5
|
||||
se_rg_ball_click.mid: -E -R50 -G129 -V100 -P5
|
||||
se_rg_card_flip.mid: -E -R50 -G129 -P5
|
||||
se_rg_card_flipping.mid: -E -R50 -G129 -P5
|
||||
se_rg_card_open.mid: -E -R50 -G129 -V112 -P5
|
||||
se_rg_deoxys_move.mid: -E -R50 -G129 -V080 -P5
|
||||
se_rg_door.mid: -E -R50 -G129 -V100 -P5
|
||||
se_rg_help_close.mid: -E -R50 -G129 -V095 -P5
|
||||
se_rg_help_error.mid: -E -R50 -G129 -V125 -P5
|
||||
se_rg_help_open.mid: -E -R50 -G129 -V096 -P5
|
||||
se_rg_poke_jump_failure.mid: -E -R50 -G127 -P5
|
||||
se_rg_poke_jump_success.mid: -E -R50 -G128 -V110 -P5
|
||||
se_rg_shop.mid: -E -R50 -G129 -V080 -P5
|
||||
se_rg_ss_anne_horn.mid: -E -R50 -G129 -V096 -P5
|
||||
se_rotating_gate.mid: -E -R50 -G128 -V090 -P4
|
||||
se_roulette_ball.mid: -E -R50 -G128 -V110 -P2
|
||||
se_roulette_ball2.mid: -E -R50 -G128 -V110 -P2
|
||||
se_save.mid: -E -R50 -G128 -V080 -P5
|
||||
se_select.mid: -E -R50 -G127 -V080 -P5
|
||||
se_shiny.mid: -E -R50 -G128 -V095 -P5
|
||||
se_ship.mid: -E -R50 -G127 -V075 -P4
|
||||
se_shop.mid: -E -R50 -G127 -V090 -P5
|
||||
se_sliding_door.mid: -E -R50 -G128 -V095 -P4
|
||||
se_success.mid: -E -R50 -G127 -V080 -P4
|
||||
se_sudowoodo_shake.mid: -E -R50 -G129 -V077 -P5
|
||||
se_super_effective.mid: -E -R50 -G127 -V110 -P5
|
||||
se_switch.mid: -E -R50 -G127 -V100 -P4
|
||||
se_taillow_wing_flap.mid: -E -R50 -G128 -V105 -P5
|
||||
se_thunder.mid: -E -R50 -G128 -V110 -P3
|
||||
se_thunder2.mid: -E -R50 -G128 -V110 -P3
|
||||
se_thunderstorm_stop.mid: -E -R50 -G128 -V080 -P2
|
||||
se_thunderstorm.mid: -E -R50 -G128 -V080 -P2
|
||||
se_truck_door.mid: -E -R50 -G128 -V110 -P4
|
||||
se_truck_move.mid: -E -R50 -G128 -P4
|
||||
se_truck_stop.mid: -E -R50 -G128 -P4
|
||||
se_truck_unload.mid: -E -R50 -G127 -P4
|
||||
se_u.mid: -E -R50 -G128 -P4
|
||||
se_unlock.mid: -E -R50 -G128 -V100 -P4
|
||||
se_use_item.mid: -E -R50 -G127 -V100 -P5
|
||||
se_vend.mid: -E -R50 -G128 -V110 -P4
|
||||
se_warp_in.mid: -E -R50 -G127 -V090 -P4
|
||||
se_warp_out.mid: -E -R50 -G127 -V090 -P4
|
||||
mus_abandoned_ship.mid: -E -R50 -G030 -V080
|
||||
mus_abnormal_weather.mid: -E -R50 -G089 -V080
|
||||
mus_aqua_magma_hideout.mid: -E -R50 -G076 -V084
|
||||
mus_awaken_legend.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_b_arena.mid: -E -R50 -G104 -V090
|
||||
mus_b_dome_lobby.mid: -E -R50 -G111 -V056
|
||||
mus_b_dome.mid: -E -R50 -G111 -V090
|
||||
mus_b_factory.mid: -E -R50 -G113 -V100
|
||||
mus_b_frontier.mid: -E -R50 -G103 -V094
|
||||
mus_b_palace.mid: -E -R50 -G108 -V105
|
||||
mus_b_pike.mid: -E -R50 -G112 -V092
|
||||
mus_b_pyramid_top.mid: -E -R50 -G107 -V077
|
||||
mus_b_pyramid.mid: -E -R50 -G106 -V079
|
||||
mus_b_tower_rs.mid: -E -R50 -G035 -V080
|
||||
mus_b_tower.mid: -E -R50 -G110 -V100
|
||||
mus_birch_lab.mid: -E -R50 -G033 -V080
|
||||
mus_c_comm_center.mid: -E -R50 -V080
|
||||
mus_c_vs_legend_beast.mid: -E -R50 -V080
|
||||
mus_cable_car.mid: -E -R50 -G071 -V078
|
||||
mus_caught.mid: -E -R50 -G025 -V080
|
||||
mus_cave_of_origin.mid: -E -R50 -G037 -V080
|
||||
mus_contest_lobby.mid: -E -R50 -G098 -V060
|
||||
mus_contest_results.mid: -E -R50 -G092 -V080
|
||||
mus_contest_winner.mid: -E -R50 -G085 -V100
|
||||
mus_contest.mid: -E -R50 -G086 -V088
|
||||
mus_credits.mid: -E -R50 -G101 -V100
|
||||
mus_cycling.mid: -E -R50 -G049 -V083
|
||||
mus_dewford.mid: -E -R50 -G073 -V078
|
||||
mus_dummy.mid: -E -R40
|
||||
mus_encounter_aqua.mid: -E -R50 -G065 -V086
|
||||
mus_encounter_brendan.mid: -E -R50 -G067 -V078
|
||||
mus_encounter_champion.mid: -E -R50 -G100 -V076
|
||||
mus_encounter_cool.mid: -E -R50 -G063 -V086
|
||||
mus_encounter_elite_four.mid: -E -R50 -G096 -V078
|
||||
mus_encounter_female.mid: -E -R50 -G053 -V072
|
||||
mus_encounter_girl.mid: -E -R50 -G027 -V080
|
||||
mus_encounter_hiker.mid: -E -R50 -G097 -V076
|
||||
mus_encounter_intense.mid: -E -R50 -G062 -V078
|
||||
mus_encounter_interviewer.mid: -E -R50 -G099 -V062
|
||||
mus_encounter_magma.mid: -E -R50 -G087 -V072
|
||||
mus_encounter_male.mid: -E -R50 -G028 -V080
|
||||
mus_encounter_may.mid: -E -R50 -G061 -V078
|
||||
mus_encounter_rich.mid: -E -R50 -G043 -V094
|
||||
mus_encounter_suspicious.mid: -E -R50 -G069 -V078
|
||||
mus_encounter_swimmer.mid: -E -R50 -G036 -V080
|
||||
mus_encounter_twins.mid: -E -R50 -G095 -V075
|
||||
mus_end.mid: -E -R50 -G102 -V036
|
||||
mus_ever_grande.mid: -E -R50 -G068 -V086
|
||||
mus_evolution_intro.mid: -E -R50 -G026 -V080
|
||||
mus_evolution.mid: -E -R50 -G026 -V080
|
||||
mus_evolved.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_fallarbor.mid: -E -R50 -G083 -V100
|
||||
mus_follow_me.mid: -E -R50 -G066 -V074
|
||||
mus_fortree.mid: -E -R50 -G032 -V080
|
||||
mus_game_corner.mid: -E -R50 -G072 -V072
|
||||
mus_gsc_pewter.mid: -E -R50 -V080
|
||||
mus_gsc_route38.mid: -E -R50 -V080
|
||||
mus_gym.mid: -E -R50 -G013 -V080
|
||||
mus_hall_of_fame_room.mid: -E -R50 -G093 -V080
|
||||
mus_hall_of_fame.mid: -E -R50 -G082 -V078
|
||||
mus_heal.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_help.mid: -E -R50 -G056 -V078
|
||||
mus_intro_battle.mid: -E -R50 -G088 -V088
|
||||
mus_intro.mid: -E -R50 -G060 -V090
|
||||
mus_level_up.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_lilycove_museum.mid: -E -R50 -G020 -V080
|
||||
mus_lilycove.mid: -E -R50 -G054 -V085
|
||||
mus_link_contest_p1.mid: -E -R50 -G039 -V079
|
||||
mus_link_contest_p2.mid: -E -R50 -G040 -V090
|
||||
mus_link_contest_p3.mid: -E -R50 -G041 -V075
|
||||
mus_link_contest_p4.mid: -E -R50 -G042 -V090
|
||||
mus_littleroot_test.mid: -E -R50 -G034 -V099
|
||||
mus_littleroot.mid: -E -R50 -G051 -V100
|
||||
mus_move_deleted.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_mt_chimney.mid: -E -R50 -G052 -V078
|
||||
mus_mt_pyre_exterior.mid: -E -R50 -G080 -V080
|
||||
mus_mt_pyre.mid: -E -R50 -G078 -V088
|
||||
mus_obtain_b_points.mid: -E -R50 -G103 -V090 -P5
|
||||
mus_obtain_badge.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_obtain_berry.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_obtain_item.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_obtain_symbol.mid: -E -R50 -G103 -V100 -P5
|
||||
mus_obtain_tmhm.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_oceanic_museum.mid: -E -R50 -G023 -V080
|
||||
mus_oldale.mid: -E -R50 -G019 -V080
|
||||
mus_petalburg_woods.mid: -E -R50 -G018 -V080
|
||||
mus_petalburg.mid: -E -R50 -G015 -V080
|
||||
mus_poke_center.mid: -E -R50 -G046 -V092
|
||||
mus_poke_mart.mid: -E -R50 -G050 -V085
|
||||
mus_rayquaza_appears.mid: -E -R50 -G109 -V090
|
||||
mus_register_match_call.mid: -E -R50 -G105 -V090 -P5
|
||||
mus_rg_berry_pick.mid: -E -R50 -G132 -V090
|
||||
mus_rg_caught_intro.mid: -E -R50 -G179 -V094 -P5
|
||||
mus_rg_caught.mid: -E -R50 -G170 -V100
|
||||
mus_rg_celadon.mid: -E -R50 -G168 -V070
|
||||
mus_rg_cinnabar.mid: -E -R50 -G138 -V090
|
||||
mus_rg_credits.mid: -E -R50 -G149 -V090
|
||||
mus_rg_cycling.mid: -E -R50 -G141 -V090
|
||||
mus_rg_dex_rating.mid: -E -R50 -G175 -V070 -P5
|
||||
mus_rg_encounter_boy.mid: -E -R50 -G144 -V090
|
||||
mus_rg_encounter_deoxys.mid: -E -R50 -G184 -V079
|
||||
mus_rg_encounter_girl.mid: -E -R50 -G143 -V051
|
||||
mus_rg_encounter_gym_leader: -E -R50 -G144 -V090
|
||||
mus_rg_encounter_rival.mid: -E -R50 -G174 -V079
|
||||
mus_rg_encounter_rocket.mid: -E -R50 -G142 -V096
|
||||
mus_rg_follow_me.mid: -E -R50 -G131 -V068
|
||||
mus_rg_fuchsia.mid: -E -R50 -G167 -V090
|
||||
mus_rg_game_corner.mid: -E -R50 -G132 -V090
|
||||
mus_rg_game_freak.mid: -E -R50 -G181 -V075
|
||||
mus_rg_gym.mid: -E -R50 -G134 -V090
|
||||
mus_rg_hall_of_fame.mid: -E -R50 -G145 -V079
|
||||
mus_rg_heal.mid: -E -R50 -G140 -V090
|
||||
mus_rg_intro_fight.mid: -E -R50 -G136 -V090
|
||||
mus_rg_jigglypuff.mid: -E -R50 -G135 -V068 -P5
|
||||
mus_rg_lavender.mid: -E -R50 -G139 -V090
|
||||
mus_rg_mt_moon.mid: -E -R50 -G147 -V090
|
||||
mus_rg_mystery_gift.mid: -E -R50 -G183 -V100
|
||||
mus_rg_net_center.mid: -E -R50 -G162 -V096
|
||||
mus_rg_new_game_exit.mid: -E -R50 -G182 -V088
|
||||
mus_rg_new_game_instruct.mid: -E -R50 -G182 -V085
|
||||
mus_rg_new_game_intro.mid: -E -R50 -G182 -V088
|
||||
mus_rg_oak_lab.mid: -E -R50 -G160 -V075
|
||||
mus_rg_oak.mid: -E -R50 -G161 -V086
|
||||
mus_rg_obtain_key_item.mid: -E -R50 -G178 -V077 -P5
|
||||
mus_rg_pallet.mid: -E -R50 -G159 -V100
|
||||
mus_rg_pewter.mid: -E -R50 -G173 -V084
|
||||
mus_rg_photo.mid: -E -R50 -G180 -V100 -P5
|
||||
mus_rg_poke_center.mid: -E -R50 -G162 -V096
|
||||
mus_rg_poke_flute.mid: -E -R50 -G165 -V048 -P5
|
||||
mus_rg_poke_jump.mid: -E -R50 -G132 -V090
|
||||
mus_rg_poke_mansion.mid: -E -R50 -G148 -V090
|
||||
mus_rg_poke_tower.mid: -E -R50 -G165 -V090
|
||||
mus_rg_rival_exit.mid: -E -R50 -G174 -V079
|
||||
mus_rg_rocket_hideout.mid: -E -R50 -G133 -V090
|
||||
mus_rg_route1.mid: -E -R50 -G150 -V079
|
||||
mus_rg_route3.mid: -E -R50 -G152 -V083
|
||||
mus_rg_route11.mid: -E -R50 -G153 -V090
|
||||
mus_rg_route24.mid: -E -R50 -G151 -V086
|
||||
mus_rg_sevii_45.mid: -E -R50 -G188 -V084
|
||||
mus_rg_sevii_67.mid: -E -R50 -G189 -V084
|
||||
mus_rg_sevii_123.mid: -E -R50 -G173 -V084
|
||||
mus_rg_sevii_cave.mid: -E -R50 -G147 -V090
|
||||
mus_rg_sevii_dungeon.mid: -E -R50 -G146 -V090
|
||||
mus_rg_sevii_route.mid: -E -R50 -G187 -V080
|
||||
mus_rg_silph.mid: -E -R50 -G166 -V076
|
||||
mus_rg_slow_pallet.mid: -E -R50 -G159 -V092
|
||||
mus_rg_ss_anne.mid: -E -R50 -G163 -V090
|
||||
mus_rg_surf.mid: -E -R50 -G164 -V071
|
||||
mus_rg_teachy_tv_menu.mid: -E -R50 -G186 -V059
|
||||
mus_rg_teachy_tv_show.mid: -E -R50 -G131 -V068
|
||||
mus_rg_title.mid: -E -R50 -G137 -V090
|
||||
mus_rg_trainer_tower.mid: -E -R50 -G134 -V090
|
||||
mus_rg_union_room.mid: -E -R50 -G132 -V090
|
||||
mus_rg_vermillion.mid: -E -R50 -G172 -V090
|
||||
mus_rg_victory_gym_leader.mid: -E -R50 -G171 -V090
|
||||
mus_rg_victory_road.mid: -E -R50 -G154 -V090
|
||||
mus_rg_victory_trainer.mid: -E -R50 -G169 -V089
|
||||
mus_rg_victory_wild.mid: -E -R50 -G170 -V090
|
||||
mus_rg_viridian_forest.mid: -E -R50 -G146 -V090
|
||||
mus_rg_vs_champion.mid: -E -R50 -G158 -V090
|
||||
mus_rg_vs_deoxys.mid: -E -R50 -G185 -V080
|
||||
mus_rg_vs_gym_leader.mid: -E -R50 -G155 -V090
|
||||
mus_rg_vs_legend.mid: -E -R50 -G157 -V090
|
||||
mus_rg_vs_mewtwo.mid: -E -R50 -G157 -V090
|
||||
mus_rg_vs_trainer.mid: -E -R50 -G156 -V090
|
||||
mus_rg_vs_wild.mid: -E -R50 -G157 -V090
|
||||
mus_roulette.mid: -E -R50 -G038 -V080
|
||||
mus_route101.mid: -E -R50 -G011 -V080
|
||||
mus_route104.mid: -E -R50 -G047 -V097
|
||||
mus_route110.mid: -E -R50 -G010 -V080
|
||||
mus_route111.mid: -E -R50 -G055 -V076
|
||||
mus_route113.mid: -E -R50 -G064 -V084
|
||||
mus_route119.mid: -E -R50 -G048 -V096
|
||||
mus_route120.mid: -E -R50 -G014 -V080
|
||||
mus_route122.mid: -E -R50 -G021 -V080
|
||||
mus_rustboro.mid: -E -R50 -G045 -V085
|
||||
mus_safari_zone.mid: -E -R50 -G074 -V082
|
||||
mus_sailing.mid: -E -R50 -G077 -V086
|
||||
mus_school.mid: -E -R50 -G081 -V100
|
||||
mus_sealed_chamber.mid: -E -R50 -G084 -V100
|
||||
mus_slateport.mid: -E -R50 -G079 -V070
|
||||
mus_slots_jackpot.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_slots_win.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_sootopolis.mid: -E -R50 -G091 -V062
|
||||
mus_surf.mid: -E -R50 -G017 -V080
|
||||
mus_title.mid: -E -R50 -G059 -V090
|
||||
mus_too_bad.mid: -E -R50 -G012 -V090 -P5
|
||||
mus_trick_house.mid: -E -R50 -G094 -V070
|
||||
mus_underwater.mid: -E -R50 -G057 -V094
|
||||
mus_verdanturf.mid: -E -R50 -G044 -V090
|
||||
mus_victory_aqua_magma.mid: -E -R50 -G070 -V088
|
||||
mus_victory_gym_leader.mid: -E -R50 -G024 -V080
|
||||
mus_victory_league.mid: -E -R50 -G029 -V080
|
||||
mus_victory_road.mid: -E -R50 -G075 -V076
|
||||
mus_victory_trainer.mid: -E -R50 -G058 -V091
|
||||
mus_victory_wild.mid: -E -R50 -G025 -V080
|
||||
mus_vs_aqua_magma_leader.mid: -E -R50 -G126 -V080 -P1
|
||||
mus_vs_aqua_magma.mid: -E -R50 -G118 -V080 -P1
|
||||
mus_vs_champion.mid: -E -R50 -G121 -V080 -P1
|
||||
mus_vs_elite_four.mid: -E -R50 -G125 -V080 -P1
|
||||
mus_vs_frontier_brain.mid: -E -R50 -G115 -V090 -P1
|
||||
mus_vs_gym_leader.mid: -E -R50 -G120 -V080 -P1
|
||||
mus_vs_kyogre_groudon.mid: -E -R50 -G123 -V080 -P1
|
||||
mus_vs_mew.mid: -E -R50 -G116 -V090
|
||||
mus_vs_rayquaza.mid: -E -R50 -G114 -V080 -P1
|
||||
mus_vs_regi.mid: -E -R50 -G122 -V080 -P1
|
||||
mus_vs_rival.mid: -E -R50 -G124 -V080 -P1
|
||||
mus_vs_trainer.mid: -E -R50 -G119 -V080 -P1
|
||||
mus_vs_wild.mid: -E -R50 -G117 -V080 -P1
|
||||
mus_weather_groudon.mid: -E -R50 -G090 -V050
|
||||
ph_choice_blend.mid: -E -G130 -P4
|
||||
ph_choice_held.mid: -E -G130 -P4
|
||||
ph_choice_solo.mid: -E -G130 -P4
|
||||
ph_cloth_blend.mid: -E -G130 -P4
|
||||
ph_cloth_held.mid: -E -G130 -P4
|
||||
ph_cloth_solo.mid: -E -G130 -P4
|
||||
ph_cure_blend.mid: -E -G130 -P4
|
||||
ph_cure_held.mid: -E -G130 -P4
|
||||
ph_cure_solo.mid: -E -G130 -P4
|
||||
ph_dress_blend.mid: -E -G130 -P4
|
||||
ph_dress_held.mid: -E -G130 -P4
|
||||
ph_dress_solo.mid: -E -G130 -P4
|
||||
ph_face_blend.mid: -E -G130 -P4
|
||||
ph_face_held.mid: -E -G130 -P4
|
||||
ph_face_solo.mid: -E -G130 -P4
|
||||
ph_fleece_blend.mid: -E -G130 -P4
|
||||
ph_fleece_held.mid: -E -G130 -P4
|
||||
ph_fleece_solo.mid: -E -G130 -P4
|
||||
ph_foot_blend.mid: -E -G130 -P4
|
||||
ph_foot_held.mid: -E -G130 -P4
|
||||
ph_foot_solo.mid: -E -G130 -P4
|
||||
ph_goat_blend.mid: -E -G130 -P4
|
||||
ph_goat_held.mid: -E -G130 -P4
|
||||
ph_goat_solo.mid: -E -G130 -P4
|
||||
ph_goose_blend.mid: -E -G130 -P4
|
||||
ph_goose_held.mid: -E -G130 -P4
|
||||
ph_goose_solo.mid: -E -G130 -P4
|
||||
ph_kit_blend.mid: -E -G130 -P4
|
||||
ph_kit_held.mid: -E -G130 -P4
|
||||
ph_kit_solo.mid: -E -G130 -P4
|
||||
ph_lot_blend.mid: -E -G130 -P4
|
||||
ph_lot_held.mid: -E -G130 -P4
|
||||
ph_lot_solo.mid: -E -G130 -P4
|
||||
ph_mouth_blend.mid: -E -G130 -P4
|
||||
ph_mouth_held.mid: -E -G130 -P4
|
||||
ph_mouth_solo.mid: -E -G130 -P4
|
||||
ph_nurse_blend.mid: -E -G130 -P4
|
||||
ph_nurse_held.mid: -E -G130 -P4
|
||||
ph_nurse_solo.mid: -E -G130 -P4
|
||||
ph_price_blend.mid: -E -G130 -P4
|
||||
ph_price_held.mid: -E -G130 -P4
|
||||
ph_price_solo.mid: -E -G130 -P4
|
||||
ph_strut_blend.mid: -E -G130 -P4
|
||||
ph_strut_held.mid: -E -G130 -P4
|
||||
ph_strut_solo.mid: -E -G130 -P4
|
||||
ph_thought_blend.mid: -E -G130 -P4
|
||||
ph_thought_held.mid: -E -G130 -P4
|
||||
ph_thought_solo.mid: -E -G130 -P4
|
||||
ph_trap_blend.mid: -E -G130 -P4
|
||||
ph_trap_held.mid: -E -G130 -P4
|
||||
ph_trap_solo.mid: -E -G130 -P4
|
||||
se_a.mid: -E -R50 -G128 -V095 -P4
|
||||
se_applause.mid: -E -R50 -G128 -V100 -P5
|
||||
se_arena_timeup1.mid: -E -R50 -G129 -P5
|
||||
se_arena_timeup2.mid: -E -R50 -G129 -P5
|
||||
se_ball_bounce_1.mid: -E -R50 -G128 -V100 -P4
|
||||
se_ball_bounce_2.mid: -E -R50 -G128 -V100 -P4
|
||||
se_ball_bounce_3.mid: -E -R50 -G128 -V100 -P4
|
||||
se_ball_bounce_4.mid: -E -R50 -G128 -V100 -P4
|
||||
se_ball_open.mid: -E -R50 -G127 -V100 -P5
|
||||
se_ball_throw.mid: -E -R50 -G128 -V120 -P5
|
||||
se_ball_trade.mid: -E -R50 -G127 -V100 -P5
|
||||
se_ball_tray_ball.mid: -E -R50 -G128 -V110 -P5
|
||||
se_ball_tray_enter.mid: -E -R50 -G128 -V110 -P5
|
||||
se_ball_tray_exit.mid: -E -R50 -G127 -V100 -P5
|
||||
se_ball.mid: -E -R50 -G127 -V070 -P4
|
||||
se_balloon_blue.mid: -E -R50 -G128 -V105 -P4
|
||||
se_balloon_red.mid: -E -R50 -G128 -V105 -P4
|
||||
se_balloon_yellow.mid: -E -R50 -G128 -V105 -P4
|
||||
se_bang.mid: -E -R50 -G128 -V110 -P4
|
||||
se_berry_blender.mid: -E -R50 -G128 -V090 -P4
|
||||
se_bike_bell.mid: -E -R50 -G128 -V090 -P4
|
||||
se_bike_hop.mid: -E -R50 -G127 -V090 -P4
|
||||
se_boo.mid: -E -R50 -G127 -V110 -P4
|
||||
se_breakable_door.mid: -E -R50 -G128 -V110 -P4
|
||||
se_bridge_walk.mid: -E -R50 -G128 -V095 -P4
|
||||
se_card.mid: -E -R50 -G127 -V100 -P4
|
||||
se_click.mid: -E -R50 -G127 -V110 -P4
|
||||
se_contest_condition_lose.mid: -E -R50 -G127 -V110 -P4
|
||||
se_contest_curtain_fall.mid: -E -R50 -G128 -V070 -P5
|
||||
se_contest_curtain_rise.mid: -E -R50 -G128 -V070 -P5
|
||||
se_contest_heart.mid: -E -R50 -G128 -V090 -P5
|
||||
se_contest_icon_change.mid: -E -R50 -G128 -V110 -P5
|
||||
se_contest_icon_clear.mid: -E -R50 -G128 -V090 -P5
|
||||
se_contest_mons_turn.mid: -E -R50 -G128 -V090 -P5
|
||||
se_contest_place.mid: -E -R50 -G127 -V110 -P4
|
||||
se_dex_search.mid: -E -R50 -G127 -v100 -P5
|
||||
se_ding_dong.mid: -E -R50 -G127 -V090 -P5
|
||||
se_door.mid: -E -R50 -G127 -V080 -P5
|
||||
se_downpour_stop.mid: -E -R50 -G128 -V100 -P2
|
||||
se_downpour.mid: -E -R50 -G128 -V100 -P2
|
||||
se_e.mid: -E -R50 -G128 -V120 -P4
|
||||
se_effective.mid: -E -R50 -G127 -V110 -P5
|
||||
se_egg_hatch.mid: -E -R50 -G128 -V120 -P5
|
||||
se_elevator.mid: -E -R50 -G128 -V100 -P4
|
||||
se_escalator.mid: -E -R50 -G128 -V100 -P4
|
||||
se_exit.mid: -E -R50 -G127 -V120 -P5
|
||||
se_exp_max.mid: -E -R50 -G128 -V094 -P5
|
||||
se_exp.mid: -E -R50 -G127 -V080 -P5
|
||||
se_failure.mid: -E -R50 -G127 -V120 -P4
|
||||
se_faint.mid: -E -R50 -G127 -V110 -P5
|
||||
se_fall.mid: -E -R50 -G128 -V110 -P4
|
||||
se_field_poison.mid: -E -R50 -G127 -V110 -P5
|
||||
se_flee.mid: -E -R50 -G127 -V090 -P5
|
||||
se_fu_zaku.mid: -E -R50 -G127 -V120 -P4
|
||||
se_glass_flute.mid: -E -R50 -G128 -V105 -P5
|
||||
se_i.mid: -E -R50 -G128 -V120 -P4
|
||||
se_ice_break.mid: -E -R50 -G128 -V100 -P4
|
||||
se_ice_crack.mid: -E -R50 -G127 -V100 -P4
|
||||
se_ice_stairs.mid: -E -R50 -G128 -V090 -P4
|
||||
se_intro_blast.mid: -E -R50 -G127 -V100 -P5
|
||||
se_itemfinder.mid: -E -R50 -G127 -V090 -P5
|
||||
se_lavaridge_fall_warp.mid: -E -R50 -G127 -P4
|
||||
se_ledge.mid: -E -R50 -G127 -V100 -P4
|
||||
se_low_health.mid: -E -R50 -G127 -V100 -P3
|
||||
se_m_bind.mid: -E -R50 -G128 -V100 -P4
|
||||
se_m_comet_punch.mid: -E -R50 -G128 -V120 -P4
|
||||
se_m_cut.mid: -E -R50 -G128 -V120 -P4
|
||||
se_m_double_slap.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_fire_punch.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_fly.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_gust.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_gust2.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_headbutt.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_horn_attack.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_jump_kick.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_leer.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_mega_kick.mid: -E -R50 -G128 -V090 -P4
|
||||
se_m_mega_kick2.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_pay_day.mid: -E -R50 -G128 -V095 -P4
|
||||
se_m_razor_wind.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_razor_wind2.mid: -E -R50 -G128 -V090 -P4
|
||||
se_m_sand_attack.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_scratch.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_swords_dance.mid: -E -R50 -G128 -V100 -P4
|
||||
se_m_tail_whip.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_take_down.mid: -E -R50 -G128 -V105 -P4
|
||||
se_m_vicegrip.mid: -E -R50 -G128 -V110 -P4
|
||||
se_m_wing_attack.mid: -E -R50 -G128 -V105 -P4
|
||||
se_mud_ball.mid: -E -R50 -G128 -V110 -P4
|
||||
se_mugshot.mid: -E -R50 -G128 -V090 -P5
|
||||
se_n.mid: -E -R50 -G128 -P4
|
||||
se_not_effective.mid: -E -R50 -G127 -V110 -P5
|
||||
se_note_a.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_b.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_c_high.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_c.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_d.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_e.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_f.mid: -E -R50 -G128 -V110 -P4
|
||||
se_note_g.mid: -E -R50 -G128 -V110 -P4
|
||||
se_o.mid: -E -R50 -G128 -V120 -P4
|
||||
se_orb.mid: -E -R50 -G128 -V100 -P5
|
||||
se_pc_login.mid: -E -R50 -G127 -V100 -P5
|
||||
se_pc_off.mid: -E -R50 -G127 -V100 -P5
|
||||
se_pc_on.mid: -E -R50 -G127 -V100 -P5
|
||||
se_pike_curtain_close.mid: -E -R50 -G129 -P5
|
||||
se_pike_curtain_open.mid: -E -R50 -G129 -P5
|
||||
se_pin.mid: -E -R50 -G127 -V060 -P4
|
||||
se_pokenav_call.mid: -E -R50 -G129 -V120 -P5
|
||||
se_pokenav_hang_up.mid: -E -R50 -G129 -V110 -P5
|
||||
se_pokenav_off.mid: -E -R50 -G127 -V100 -P5
|
||||
se_pokenav_on.mid: -E -R50 -G127 -V100 -P5
|
||||
se_puddle.mid: -E -R50 -G128 -V020 -P4
|
||||
se_rain_stop.mid: -E -R50 -G128 -V080 -P2
|
||||
se_rain.mid: -E -R50 -G128 -V080 -P2
|
||||
se_repel.mid: -E -R50 -G127 -V090 -P4
|
||||
se_rg_bag_cursor.mid: -E -R50 -G129 -P5
|
||||
se_rg_bag_pocket.mid: -E -R50 -G129 -P5
|
||||
se_rg_ball_click.mid: -E -R50 -G129 -V100 -P5
|
||||
se_rg_card_flip.mid: -E -R50 -G129 -P5
|
||||
se_rg_card_flipping.mid: -E -R50 -G129 -P5
|
||||
se_rg_card_open.mid: -E -R50 -G129 -V112 -P5
|
||||
se_rg_deoxys_move.mid: -E -R50 -G129 -V080 -P5
|
||||
se_rg_door.mid: -E -R50 -G129 -V100 -P5
|
||||
se_rg_help_close.mid: -E -R50 -G129 -V095 -P5
|
||||
se_rg_help_error.mid: -E -R50 -G129 -V125 -P5
|
||||
se_rg_help_open.mid: -E -R50 -G129 -V096 -P5
|
||||
se_rg_poke_jump_failure.mid: -E -R50 -G127 -P5
|
||||
se_rg_poke_jump_success.mid: -E -R50 -G128 -V110 -P5
|
||||
se_rg_shop.mid: -E -R50 -G129 -V080 -P5
|
||||
se_rg_ss_anne_horn.mid: -E -R50 -G129 -V096 -P5
|
||||
se_rotating_gate.mid: -E -R50 -G128 -V090 -P4
|
||||
se_roulette_ball.mid: -E -R50 -G128 -V110 -P2
|
||||
se_roulette_ball2.mid: -E -R50 -G128 -V110 -P2
|
||||
se_save.mid: -E -R50 -G128 -V080 -P5
|
||||
se_select.mid: -E -R50 -G127 -V080 -P5
|
||||
se_shiny.mid: -E -R50 -G128 -V095 -P5
|
||||
se_ship.mid: -E -R50 -G127 -V075 -P4
|
||||
se_shop.mid: -E -R50 -G127 -V090 -P5
|
||||
se_sliding_door.mid: -E -R50 -G128 -V095 -P4
|
||||
se_success.mid: -E -R50 -G127 -V080 -P4
|
||||
se_sudowoodo_shake.mid: -E -R50 -G129 -V077 -P5
|
||||
se_super_effective.mid: -E -R50 -G127 -V110 -P5
|
||||
se_switch.mid: -E -R50 -G127 -V100 -P4
|
||||
se_taillow_wing_flap.mid: -E -R50 -G128 -V105 -P5
|
||||
se_thunder.mid: -E -R50 -G128 -V110 -P3
|
||||
se_thunder2.mid: -E -R50 -G128 -V110 -P3
|
||||
se_thunderstorm_stop.mid: -E -R50 -G128 -V080 -P2
|
||||
se_thunderstorm.mid: -E -R50 -G128 -V080 -P2
|
||||
se_truck_door.mid: -E -R50 -G128 -V110 -P4
|
||||
se_truck_move.mid: -E -R50 -G128 -P4
|
||||
se_truck_stop.mid: -E -R50 -G128 -P4
|
||||
se_truck_unload.mid: -E -R50 -G127 -P4
|
||||
se_u.mid: -E -R50 -G128 -P4
|
||||
se_unlock.mid: -E -R50 -G128 -V100 -P4
|
||||
se_use_item.mid: -E -R50 -G127 -V100 -P5
|
||||
se_vend.mid: -E -R50 -G128 -V110 -P4
|
||||
se_warp_in.mid: -E -R50 -G127 -V090 -P4
|
||||
se_warp_out.mid: -E -R50 -G127 -V090 -P4
|
||||
|
||||
@ -1,43 +1,43 @@
|
||||
=== PARTNER_NONE ===
|
||||
Name:
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Brendan
|
||||
Gender: Male
|
||||
Music: Male
|
||||
|
||||
=== PARTNER_STEVEN ===
|
||||
Name: STEVEN
|
||||
Class: Rival
|
||||
Pic: Steven
|
||||
Gender: Male
|
||||
Music: Male
|
||||
|
||||
Metang
|
||||
Brave Nature
|
||||
Level: 42
|
||||
IVs: 31 HP / 31 Atk / 31 Def / 31 SpA / 31 SpD / 31 Spe
|
||||
EVs: 252 Atk / 252 Def / 6 SpA
|
||||
- Light Screen
|
||||
- Psychic
|
||||
- Reflect
|
||||
- Metal Claw
|
||||
|
||||
Skarmory
|
||||
Impish Nature
|
||||
Level: 43
|
||||
IVs: 31 HP / 31 Atk / 31 Def / 31 SpA / 31 SpD / 31 Spe
|
||||
EVs: 252 HP / 6 SpA / 252 SpD
|
||||
- Toxic
|
||||
- Aerial Ace
|
||||
- Protect
|
||||
- Steel Wing
|
||||
|
||||
Aggron
|
||||
Adamant Nature
|
||||
Level: 44
|
||||
IVs: 31 HP / 31 Atk / 31 Def / 31 SpA / 31 SpD / 31 Spe
|
||||
EVs: 252 Atk / 252 SpA / 6 SpD
|
||||
- Thunder
|
||||
- Protect
|
||||
- Solar Beam
|
||||
- Dragon Claw
|
||||
=== PARTNER_NONE ===
|
||||
Name:
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Brendan
|
||||
Gender: Male
|
||||
Music: Male
|
||||
|
||||
=== PARTNER_STEVEN ===
|
||||
Name: STEVEN
|
||||
Class: Rival
|
||||
Pic: Steven
|
||||
Gender: Male
|
||||
Music: Male
|
||||
|
||||
Metang
|
||||
Brave Nature
|
||||
Level: 42
|
||||
IVs: 31 HP / 31 Atk / 31 Def / 31 SpA / 31 SpD / 31 Spe
|
||||
EVs: 252 Atk / 252 Def / 6 SpA
|
||||
- Light Screen
|
||||
- Psychic
|
||||
- Reflect
|
||||
- Metal Claw
|
||||
|
||||
Skarmory
|
||||
Impish Nature
|
||||
Level: 43
|
||||
IVs: 31 HP / 31 Atk / 31 Def / 31 SpA / 31 SpD / 31 Spe
|
||||
EVs: 252 HP / 6 SpA / 252 SpD
|
||||
- Toxic
|
||||
- Aerial Ace
|
||||
- Protect
|
||||
- Steel Wing
|
||||
|
||||
Aggron
|
||||
Adamant Nature
|
||||
Level: 44
|
||||
IVs: 31 HP / 31 Atk / 31 Def / 31 SpA / 31 SpD / 31 Spe
|
||||
EVs: 252 Atk / 252 SpA / 6 SpD
|
||||
- Thunder
|
||||
- Protect
|
||||
- Solar Beam
|
||||
- Dragon Claw
|
||||
|
||||
33750
src/data/trainers.party
@ -1,215 +1,215 @@
|
||||
=== 0 ===
|
||||
Name: Test1
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
|
||||
Bubbles (Wobbuffet) (F) @ Assault Vest
|
||||
Hasty Nature
|
||||
Level: 67
|
||||
Ability: Telepathy
|
||||
IVs: 25 HP / 26 Atk / 27 Def / 29 SpA / 30 SpD / 28 Spe
|
||||
EVs: 252 HP / 4 SpA / 252 Spe
|
||||
Happiness: 42
|
||||
Shiny: Yes
|
||||
Ball: Master Ball
|
||||
Dynamax Level: 5
|
||||
- Air Slash
|
||||
- Barrier
|
||||
- Solar Beam
|
||||
- Explosion
|
||||
|
||||
Wobbuffet
|
||||
Level: 5
|
||||
Ability: Shadow Tag
|
||||
IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe
|
||||
|
||||
Wynaut
|
||||
Level: 5
|
||||
IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe
|
||||
|
||||
=== 1 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Normal
|
||||
|
||||
Mewtwo
|
||||
Level: 5
|
||||
|
||||
=== 2 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Normal
|
||||
|
||||
Mewtwo
|
||||
Level: 50
|
||||
|
||||
=== 2 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Easy
|
||||
|
||||
Metapod
|
||||
Level: 1
|
||||
|
||||
=== 2 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Hard
|
||||
|
||||
Arceus
|
||||
Level: 99
|
||||
|
||||
=== 3 ===
|
||||
Name: Test3
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Party Size: 1
|
||||
|
||||
Wynaut
|
||||
|
||||
Wobbuffet
|
||||
|
||||
Eevee
|
||||
|
||||
Mew
|
||||
|
||||
=== 4 ===
|
||||
Name: Test4
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Party Size: 3
|
||||
|
||||
Wynaut
|
||||
|
||||
Wobbuffet
|
||||
Tags: Lead
|
||||
|
||||
Eevee
|
||||
Tags: Ace
|
||||
|
||||
Mew
|
||||
|
||||
Oddish
|
||||
Tags: Ace
|
||||
|
||||
Aron
|
||||
Tags: Lead
|
||||
|
||||
=== 5 ===
|
||||
Name: Test5
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: Yes
|
||||
Party Size: 3
|
||||
Pool Rules: Weather Doubles
|
||||
|
||||
Wynaut
|
||||
Tags: Lead
|
||||
|
||||
Wobbuffet
|
||||
Tags: Lead
|
||||
|
||||
Vulpix
|
||||
Tags: Lead / Weather Setter
|
||||
|
||||
Bulbasaur
|
||||
Tags: Lead / Weather Abuser
|
||||
|
||||
Torkoal
|
||||
Tags: Lead / Weather Setter
|
||||
|
||||
Cherrim
|
||||
Tags: Lead / Weather Abuser
|
||||
|
||||
Mew
|
||||
Tags: Lead
|
||||
|
||||
Aron
|
||||
Tags: Lead
|
||||
|
||||
Oddish
|
||||
|
||||
Eevee
|
||||
|
||||
=== 6 ===
|
||||
Name: Test6
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Party Size: 2
|
||||
Pool Rules: Basic
|
||||
|
||||
Wynaut
|
||||
Tags: Lead
|
||||
|
||||
Wobbuffet
|
||||
Tags: Lead
|
||||
|
||||
Eevee
|
||||
Tags: Lead
|
||||
|
||||
=== 7 ===
|
||||
Name: Test1
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Party Size: 2
|
||||
Pool Rules: Basic
|
||||
Pool Prune: Test
|
||||
|
||||
Wynaut
|
||||
|
||||
Wobbuffet
|
||||
Tags: Lead
|
||||
|
||||
Eevee
|
||||
|
||||
=== 8 ===
|
||||
Name: Test1
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Party Size: 2
|
||||
Pool Rules: Basic
|
||||
Pool Pick Functions: Lowest
|
||||
|
||||
Wynaut
|
||||
Tags: Ace
|
||||
|
||||
Wobbuffet
|
||||
|
||||
Eevee
|
||||
Tags: Lead
|
||||
=== 0 ===
|
||||
Name: Test1
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
|
||||
Bubbles (Wobbuffet) (F) @ Assault Vest
|
||||
Hasty Nature
|
||||
Level: 67
|
||||
Ability: Telepathy
|
||||
IVs: 25 HP / 26 Atk / 27 Def / 29 SpA / 30 SpD / 28 Spe
|
||||
EVs: 252 HP / 4 SpA / 252 Spe
|
||||
Happiness: 42
|
||||
Shiny: Yes
|
||||
Ball: Master Ball
|
||||
Dynamax Level: 5
|
||||
- Air Slash
|
||||
- Barrier
|
||||
- Solar Beam
|
||||
- Explosion
|
||||
|
||||
Wobbuffet
|
||||
Level: 5
|
||||
Ability: Shadow Tag
|
||||
IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe
|
||||
|
||||
Wynaut
|
||||
Level: 5
|
||||
IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe
|
||||
|
||||
=== 1 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Normal
|
||||
|
||||
Mewtwo
|
||||
Level: 5
|
||||
|
||||
=== 2 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Normal
|
||||
|
||||
Mewtwo
|
||||
Level: 50
|
||||
|
||||
=== 2 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Easy
|
||||
|
||||
Metapod
|
||||
Level: 1
|
||||
|
||||
=== 2 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Hard
|
||||
|
||||
Arceus
|
||||
Level: 99
|
||||
|
||||
=== 3 ===
|
||||
Name: Test3
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Party Size: 1
|
||||
|
||||
Wynaut
|
||||
|
||||
Wobbuffet
|
||||
|
||||
Eevee
|
||||
|
||||
Mew
|
||||
|
||||
=== 4 ===
|
||||
Name: Test4
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Party Size: 3
|
||||
|
||||
Wynaut
|
||||
|
||||
Wobbuffet
|
||||
Tags: Lead
|
||||
|
||||
Eevee
|
||||
Tags: Ace
|
||||
|
||||
Mew
|
||||
|
||||
Oddish
|
||||
Tags: Ace
|
||||
|
||||
Aron
|
||||
Tags: Lead
|
||||
|
||||
=== 5 ===
|
||||
Name: Test5
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: Yes
|
||||
Party Size: 3
|
||||
Pool Rules: Weather Doubles
|
||||
|
||||
Wynaut
|
||||
Tags: Lead
|
||||
|
||||
Wobbuffet
|
||||
Tags: Lead
|
||||
|
||||
Vulpix
|
||||
Tags: Lead / Weather Setter
|
||||
|
||||
Bulbasaur
|
||||
Tags: Lead / Weather Abuser
|
||||
|
||||
Torkoal
|
||||
Tags: Lead / Weather Setter
|
||||
|
||||
Cherrim
|
||||
Tags: Lead / Weather Abuser
|
||||
|
||||
Mew
|
||||
Tags: Lead
|
||||
|
||||
Aron
|
||||
Tags: Lead
|
||||
|
||||
Oddish
|
||||
|
||||
Eevee
|
||||
|
||||
=== 6 ===
|
||||
Name: Test6
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Party Size: 2
|
||||
Pool Rules: Basic
|
||||
|
||||
Wynaut
|
||||
Tags: Lead
|
||||
|
||||
Wobbuffet
|
||||
Tags: Lead
|
||||
|
||||
Eevee
|
||||
Tags: Lead
|
||||
|
||||
=== 7 ===
|
||||
Name: Test1
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Party Size: 2
|
||||
Pool Rules: Basic
|
||||
Pool Prune: Test
|
||||
|
||||
Wynaut
|
||||
|
||||
Wobbuffet
|
||||
Tags: Lead
|
||||
|
||||
Eevee
|
||||
|
||||
=== 8 ===
|
||||
Name: Test1
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Party Size: 2
|
||||
Pool Rules: Basic
|
||||
Pool Pick Functions: Lowest
|
||||
|
||||
Wynaut
|
||||
Tags: Ace
|
||||
|
||||
Wobbuffet
|
||||
|
||||
Eevee
|
||||
Tags: Lead
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
Copyright (c) 2016 huderlem
|
||||
Copyright (c) 2005, 2006 by Marco Trillo <marcotrillo@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Copyright (c) 2016 huderlem
|
||||
Copyright (c) 2005, 2006 by Marco Trillo <marcotrillo@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
Copyright (c) 2016 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Copyright (c) 2016 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
1348
tools/gbafix/COPYING
@ -1,19 +1,19 @@
|
||||
Copyright (c) 2015 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Copyright (c) 2015 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
@ -1,214 +1,214 @@
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
|
||||
# before all else, abort if the config is off
|
||||
with open("./include/config/pokemon.h", "r") as file:
|
||||
learnset_config = re.findall(r"#define P_LEARNSET_HELPER_TEACHABLE *([^ ]*)", file.read())
|
||||
if len(learnset_config) != 1:
|
||||
quit()
|
||||
if learnset_config[0] != "TRUE":
|
||||
quit()
|
||||
|
||||
def parse_mon_name(name):
|
||||
return re.sub(r'(?!^)([A-Z]+)', r'_\1', name).upper()
|
||||
|
||||
tm_moves = []
|
||||
tutor_moves = []
|
||||
|
||||
# scan incs
|
||||
incs_to_check = glob.glob('./data/scripts/*.inc') # all .incs in the script folder
|
||||
incs_to_check += glob.glob('./data/maps/*/scripts.inc') # all map scripts
|
||||
|
||||
if len(incs_to_check) == 0: # disabled if no jsons present
|
||||
quit()
|
||||
|
||||
for file in incs_to_check:
|
||||
with open(file, 'r') as f2:
|
||||
raw = f2.read()
|
||||
if 'special ChooseMonForMoveTutor' in raw:
|
||||
for x in re.findall(r'setvar VAR_0x8005, (MOVE_.*)', raw):
|
||||
if not x in tutor_moves:
|
||||
tutor_moves.append(x)
|
||||
|
||||
# scan TMs and HMs
|
||||
with open("./include/constants/tms_hms.h", 'r') as file:
|
||||
for x in re.findall(r'F\((.*)\)', file.read()):
|
||||
if not 'MOVE_' + x in tm_moves:
|
||||
tm_moves.append('MOVE_' + x)
|
||||
|
||||
# look up universal moves to exclude them
|
||||
universal_moves = []
|
||||
with open("./src/pokemon.c", "r") as file:
|
||||
for x in re.findall(r"static const u16 sUniversalMoves\[\] =(.|\n)*?{((.|\n)*?)};", file.read())[0]:
|
||||
x = x.replace("\n", "")
|
||||
for y in x.split(","):
|
||||
y = y.strip()
|
||||
if y == "":
|
||||
continue
|
||||
universal_moves.append(y)
|
||||
|
||||
# get compatibility from jsons
|
||||
def construct_compatibility_dict(force_custom_check):
|
||||
dict_out = {}
|
||||
for pth in glob.glob('./tools/learnset_helpers/porymoves_files/*.json'):
|
||||
f = open(pth, 'r')
|
||||
data = json.load(f)
|
||||
for mon in data.keys():
|
||||
if not mon in dict_out:
|
||||
dict_out[mon] = []
|
||||
for move in data[mon]['LevelMoves']:
|
||||
if not move['Move'] in dict_out[mon]:
|
||||
dict_out[mon].append(move['Move'])
|
||||
#for move in data[mon]['PreEvoMoves']:
|
||||
# if not move in dict_out[mon]:
|
||||
# dict_out[mon].append(move)
|
||||
for move in data[mon]['TMMoves']:
|
||||
if not move in dict_out[mon]:
|
||||
dict_out[mon].append(move)
|
||||
for move in data[mon]['EggMoves']:
|
||||
if not move in dict_out[mon]:
|
||||
dict_out[mon].append(move)
|
||||
for move in data[mon]['TutorMoves']:
|
||||
if not move in dict_out[mon]:
|
||||
dict_out[mon].append(move)
|
||||
|
||||
# if the file was not previously generated, check if there is custom data there that needs to be preserved
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", 'r') as file:
|
||||
raw = file.read()
|
||||
if not "// DO NOT MODIFY THIS FILE!" in raw and force_custom_check == True:
|
||||
custom_teachable_compatibilities = {}
|
||||
for entry in re.findall(r"static const u16 s(.*)TeachableLearnset\[\] = {\n((.|\n)*?)\n};", raw):
|
||||
monname = parse_mon_name(entry[0])
|
||||
if monname == "NONE":
|
||||
continue
|
||||
compatibility = entry[1].split("\n")
|
||||
if not monname in custom_teachable_compatibilities:
|
||||
custom_teachable_compatibilities[monname] = []
|
||||
if not monname in dict_out:
|
||||
# this mon is unknown, so all data needs to be preserved
|
||||
for move in compatibility:
|
||||
move = move.replace(",", "").strip()
|
||||
if move == "" or move == "MOVE_UNAVAILABLE":
|
||||
continue
|
||||
custom_teachable_compatibilities[monname].append(move)
|
||||
else:
|
||||
# this mon is known, so check if the moves in the old teachable_learnsets.h are not in the jsons
|
||||
for move in compatibility:
|
||||
move = move.replace(",", "").strip()
|
||||
if move == "" or move == "MOVE_UNAVAILABLE":
|
||||
continue
|
||||
if not move in dict_out[monname]:
|
||||
custom_teachable_compatibilities[monname].append(move)
|
||||
# actually store the data in custom.json
|
||||
if os.path.exists("./tools/learnset_helpers/porymoves_files/custom.json"):
|
||||
f2 = open("./tools/learnset_helpers/porymoves_files/custom.json", "r")
|
||||
custom_json = json.load(f2)
|
||||
f2.close()
|
||||
else:
|
||||
custom_json = {}
|
||||
for x in custom_teachable_compatibilities:
|
||||
if len(custom_teachable_compatibilities[x]) == 0:
|
||||
continue
|
||||
if not x in custom_json:
|
||||
custom_json[x] = {"LevelMoves": [], "PreEvoMoves": [], "TMMoves": [], "EggMoves": [], "TutorMoves": []}
|
||||
for move in custom_teachable_compatibilities[x]:
|
||||
custom_json[x]["TutorMoves"].append(move)
|
||||
f2 = open("./tools/learnset_helpers/porymoves_files/custom.json", "w")
|
||||
f2.write(json.dumps(custom_json, indent=2))
|
||||
f2.close()
|
||||
print("FIRST RUN: Updated custom.json with teachable_learnsets.h's data")
|
||||
# rerun the process
|
||||
dict_out = construct_compatibility_dict(False)
|
||||
return dict_out
|
||||
|
||||
compatibility_dict = construct_compatibility_dict(True)
|
||||
|
||||
# actually prepare the file
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", 'r') as file:
|
||||
out = file.read()
|
||||
list_of_mons = re.findall(r'static const u16 s(.*)TeachableLearnset', out)
|
||||
for mon in list_of_mons:
|
||||
mon_parsed = parse_mon_name(mon)
|
||||
tm_learnset = []
|
||||
tutor_learnset = []
|
||||
if mon_parsed == "NONE" or mon_parsed == "MEW":
|
||||
continue
|
||||
if not mon_parsed in compatibility_dict:
|
||||
print("Unable to find %s in json" % mon)
|
||||
continue
|
||||
for move in tm_moves:
|
||||
if move in universal_moves:
|
||||
continue
|
||||
if move in tm_learnset:
|
||||
continue
|
||||
if move in compatibility_dict[mon_parsed]:
|
||||
tm_learnset.append(move)
|
||||
continue
|
||||
for move in tutor_moves:
|
||||
if move in universal_moves:
|
||||
continue
|
||||
if move in tutor_learnset:
|
||||
continue
|
||||
if move in compatibility_dict[mon_parsed]:
|
||||
tutor_learnset.append(move)
|
||||
continue
|
||||
tm_learnset.sort()
|
||||
tutor_learnset.sort()
|
||||
tm_learnset += tutor_learnset
|
||||
repl = "static const u16 s%sTeachableLearnset[] = {\n " % mon
|
||||
if len(tm_learnset) > 0:
|
||||
repl += ",\n ".join(tm_learnset) + ",\n "
|
||||
repl += "MOVE_UNAVAILABLE,\n};"
|
||||
newout = re.sub(r'static const u16 s%sTeachableLearnset\[\] = {[\s\S]*?};' % mon, repl, out)
|
||||
if newout != out:
|
||||
out = newout
|
||||
print("Updated %s" % mon)
|
||||
|
||||
# add/update header
|
||||
header = "//\n// DO NOT MODIFY THIS FILE! It is auto-generated from tools/learnset_helpers/teachable.py\n//\n\n"
|
||||
longest_move_name = 0
|
||||
for move in tm_moves + tutor_moves:
|
||||
if len(move) > longest_move_name:
|
||||
longest_move_name = len(move)
|
||||
longest_move_name += 2 # + 2 for a hyphen and a space
|
||||
|
||||
universal_title = "Near-universal moves found in sUniversalMoves:"
|
||||
tmhm_title = "TM/HM moves found in \"include/constants/tms_hms.h\":"
|
||||
tutor_title = "Tutor moves found in map scripts:"
|
||||
|
||||
if longest_move_name < len(universal_title):
|
||||
longest_move_name = len(universal_title)
|
||||
if longest_move_name < len(tmhm_title):
|
||||
longest_move_name = len(tmhm_title)
|
||||
if longest_move_name < len(tutor_title):
|
||||
longest_move_name = len(tutor_title)
|
||||
|
||||
def header_print(str):
|
||||
global header
|
||||
header += "// " + str + " " * (longest_move_name - len(str)) + " //\n"
|
||||
|
||||
header += "// " + longest_move_name * "*" + " //\n"
|
||||
header_print(tmhm_title)
|
||||
for move in tm_moves:
|
||||
header_print("- " + move)
|
||||
header += "// " + longest_move_name * "*" + " //\n"
|
||||
header_print(tutor_title)
|
||||
tutor_moves.sort() # alphabetically sort tutor moves for easier referencing
|
||||
for move in tutor_moves:
|
||||
header_print("- " + move)
|
||||
header += "// " + longest_move_name * "*" + " //\n"
|
||||
header_print(universal_title)
|
||||
universal_moves.sort() # alphabetically sort near-universal moves for easier referencing
|
||||
for move in universal_moves:
|
||||
header_print("- " + move)
|
||||
header += "// " + longest_move_name * "*" + " //\n\n"
|
||||
|
||||
if not "// DO NOT MODIFY THIS FILE!" in out:
|
||||
out = header + out
|
||||
else:
|
||||
out = re.sub(r"\/\/\n\/\/ DO NOT MODIFY THIS FILE!(.|\n)*\* \/\/\n\n", header, out)
|
||||
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", 'w') as file:
|
||||
file.write(out)
|
||||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
|
||||
# before all else, abort if the config is off
|
||||
with open("./include/config/pokemon.h", "r") as file:
|
||||
learnset_config = re.findall(r"#define P_LEARNSET_HELPER_TEACHABLE *([^ ]*)", file.read())
|
||||
if len(learnset_config) != 1:
|
||||
quit()
|
||||
if learnset_config[0] != "TRUE":
|
||||
quit()
|
||||
|
||||
def parse_mon_name(name):
|
||||
return re.sub(r'(?!^)([A-Z]+)', r'_\1', name).upper()
|
||||
|
||||
tm_moves = []
|
||||
tutor_moves = []
|
||||
|
||||
# scan incs
|
||||
incs_to_check = glob.glob('./data/scripts/*.inc') # all .incs in the script folder
|
||||
incs_to_check += glob.glob('./data/maps/*/scripts.inc') # all map scripts
|
||||
|
||||
if len(incs_to_check) == 0: # disabled if no jsons present
|
||||
quit()
|
||||
|
||||
for file in incs_to_check:
|
||||
with open(file, 'r') as f2:
|
||||
raw = f2.read()
|
||||
if 'special ChooseMonForMoveTutor' in raw:
|
||||
for x in re.findall(r'setvar VAR_0x8005, (MOVE_.*)', raw):
|
||||
if not x in tutor_moves:
|
||||
tutor_moves.append(x)
|
||||
|
||||
# scan TMs and HMs
|
||||
with open("./include/constants/tms_hms.h", 'r') as file:
|
||||
for x in re.findall(r'F\((.*)\)', file.read()):
|
||||
if not 'MOVE_' + x in tm_moves:
|
||||
tm_moves.append('MOVE_' + x)
|
||||
|
||||
# look up universal moves to exclude them
|
||||
universal_moves = []
|
||||
with open("./src/pokemon.c", "r") as file:
|
||||
for x in re.findall(r"static const u16 sUniversalMoves\[\] =(.|\n)*?{((.|\n)*?)};", file.read())[0]:
|
||||
x = x.replace("\n", "")
|
||||
for y in x.split(","):
|
||||
y = y.strip()
|
||||
if y == "":
|
||||
continue
|
||||
universal_moves.append(y)
|
||||
|
||||
# get compatibility from jsons
|
||||
def construct_compatibility_dict(force_custom_check):
|
||||
dict_out = {}
|
||||
for pth in glob.glob('./tools/learnset_helpers/porymoves_files/*.json'):
|
||||
f = open(pth, 'r')
|
||||
data = json.load(f)
|
||||
for mon in data.keys():
|
||||
if not mon in dict_out:
|
||||
dict_out[mon] = []
|
||||
for move in data[mon]['LevelMoves']:
|
||||
if not move['Move'] in dict_out[mon]:
|
||||
dict_out[mon].append(move['Move'])
|
||||
#for move in data[mon]['PreEvoMoves']:
|
||||
# if not move in dict_out[mon]:
|
||||
# dict_out[mon].append(move)
|
||||
for move in data[mon]['TMMoves']:
|
||||
if not move in dict_out[mon]:
|
||||
dict_out[mon].append(move)
|
||||
for move in data[mon]['EggMoves']:
|
||||
if not move in dict_out[mon]:
|
||||
dict_out[mon].append(move)
|
||||
for move in data[mon]['TutorMoves']:
|
||||
if not move in dict_out[mon]:
|
||||
dict_out[mon].append(move)
|
||||
|
||||
# if the file was not previously generated, check if there is custom data there that needs to be preserved
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", 'r') as file:
|
||||
raw = file.read()
|
||||
if not "// DO NOT MODIFY THIS FILE!" in raw and force_custom_check == True:
|
||||
custom_teachable_compatibilities = {}
|
||||
for entry in re.findall(r"static const u16 s(.*)TeachableLearnset\[\] = {\n((.|\n)*?)\n};", raw):
|
||||
monname = parse_mon_name(entry[0])
|
||||
if monname == "NONE":
|
||||
continue
|
||||
compatibility = entry[1].split("\n")
|
||||
if not monname in custom_teachable_compatibilities:
|
||||
custom_teachable_compatibilities[monname] = []
|
||||
if not monname in dict_out:
|
||||
# this mon is unknown, so all data needs to be preserved
|
||||
for move in compatibility:
|
||||
move = move.replace(",", "").strip()
|
||||
if move == "" or move == "MOVE_UNAVAILABLE":
|
||||
continue
|
||||
custom_teachable_compatibilities[monname].append(move)
|
||||
else:
|
||||
# this mon is known, so check if the moves in the old teachable_learnsets.h are not in the jsons
|
||||
for move in compatibility:
|
||||
move = move.replace(",", "").strip()
|
||||
if move == "" or move == "MOVE_UNAVAILABLE":
|
||||
continue
|
||||
if not move in dict_out[monname]:
|
||||
custom_teachable_compatibilities[monname].append(move)
|
||||
# actually store the data in custom.json
|
||||
if os.path.exists("./tools/learnset_helpers/porymoves_files/custom.json"):
|
||||
f2 = open("./tools/learnset_helpers/porymoves_files/custom.json", "r")
|
||||
custom_json = json.load(f2)
|
||||
f2.close()
|
||||
else:
|
||||
custom_json = {}
|
||||
for x in custom_teachable_compatibilities:
|
||||
if len(custom_teachable_compatibilities[x]) == 0:
|
||||
continue
|
||||
if not x in custom_json:
|
||||
custom_json[x] = {"LevelMoves": [], "PreEvoMoves": [], "TMMoves": [], "EggMoves": [], "TutorMoves": []}
|
||||
for move in custom_teachable_compatibilities[x]:
|
||||
custom_json[x]["TutorMoves"].append(move)
|
||||
f2 = open("./tools/learnset_helpers/porymoves_files/custom.json", "w")
|
||||
f2.write(json.dumps(custom_json, indent=2))
|
||||
f2.close()
|
||||
print("FIRST RUN: Updated custom.json with teachable_learnsets.h's data")
|
||||
# rerun the process
|
||||
dict_out = construct_compatibility_dict(False)
|
||||
return dict_out
|
||||
|
||||
compatibility_dict = construct_compatibility_dict(True)
|
||||
|
||||
# actually prepare the file
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", 'r') as file:
|
||||
out = file.read()
|
||||
list_of_mons = re.findall(r'static const u16 s(.*)TeachableLearnset', out)
|
||||
for mon in list_of_mons:
|
||||
mon_parsed = parse_mon_name(mon)
|
||||
tm_learnset = []
|
||||
tutor_learnset = []
|
||||
if mon_parsed == "NONE" or mon_parsed == "MEW":
|
||||
continue
|
||||
if not mon_parsed in compatibility_dict:
|
||||
print("Unable to find %s in json" % mon)
|
||||
continue
|
||||
for move in tm_moves:
|
||||
if move in universal_moves:
|
||||
continue
|
||||
if move in tm_learnset:
|
||||
continue
|
||||
if move in compatibility_dict[mon_parsed]:
|
||||
tm_learnset.append(move)
|
||||
continue
|
||||
for move in tutor_moves:
|
||||
if move in universal_moves:
|
||||
continue
|
||||
if move in tutor_learnset:
|
||||
continue
|
||||
if move in compatibility_dict[mon_parsed]:
|
||||
tutor_learnset.append(move)
|
||||
continue
|
||||
tm_learnset.sort()
|
||||
tutor_learnset.sort()
|
||||
tm_learnset += tutor_learnset
|
||||
repl = "static const u16 s%sTeachableLearnset[] = {\n " % mon
|
||||
if len(tm_learnset) > 0:
|
||||
repl += ",\n ".join(tm_learnset) + ",\n "
|
||||
repl += "MOVE_UNAVAILABLE,\n};"
|
||||
newout = re.sub(r'static const u16 s%sTeachableLearnset\[\] = {[\s\S]*?};' % mon, repl, out)
|
||||
if newout != out:
|
||||
out = newout
|
||||
print("Updated %s" % mon)
|
||||
|
||||
# add/update header
|
||||
header = "//\n// DO NOT MODIFY THIS FILE! It is auto-generated from tools/learnset_helpers/teachable.py\n//\n\n"
|
||||
longest_move_name = 0
|
||||
for move in tm_moves + tutor_moves:
|
||||
if len(move) > longest_move_name:
|
||||
longest_move_name = len(move)
|
||||
longest_move_name += 2 # + 2 for a hyphen and a space
|
||||
|
||||
universal_title = "Near-universal moves found in sUniversalMoves:"
|
||||
tmhm_title = "TM/HM moves found in \"include/constants/tms_hms.h\":"
|
||||
tutor_title = "Tutor moves found in map scripts:"
|
||||
|
||||
if longest_move_name < len(universal_title):
|
||||
longest_move_name = len(universal_title)
|
||||
if longest_move_name < len(tmhm_title):
|
||||
longest_move_name = len(tmhm_title)
|
||||
if longest_move_name < len(tutor_title):
|
||||
longest_move_name = len(tutor_title)
|
||||
|
||||
def header_print(str):
|
||||
global header
|
||||
header += "// " + str + " " * (longest_move_name - len(str)) + " //\n"
|
||||
|
||||
header += "// " + longest_move_name * "*" + " //\n"
|
||||
header_print(tmhm_title)
|
||||
for move in tm_moves:
|
||||
header_print("- " + move)
|
||||
header += "// " + longest_move_name * "*" + " //\n"
|
||||
header_print(tutor_title)
|
||||
tutor_moves.sort() # alphabetically sort tutor moves for easier referencing
|
||||
for move in tutor_moves:
|
||||
header_print("- " + move)
|
||||
header += "// " + longest_move_name * "*" + " //\n"
|
||||
header_print(universal_title)
|
||||
universal_moves.sort() # alphabetically sort near-universal moves for easier referencing
|
||||
for move in universal_moves:
|
||||
header_print("- " + move)
|
||||
header += "// " + longest_move_name * "*" + " //\n\n"
|
||||
|
||||
if not "// DO NOT MODIFY THIS FILE!" in out:
|
||||
out = header + out
|
||||
else:
|
||||
out = re.sub(r"\/\/\n\/\/ DO NOT MODIFY THIS FILE!(.|\n)*\* \/\/\n\n", header, out)
|
||||
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", 'w') as file:
|
||||
file.write(out)
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
Copyright (c) 2016 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Copyright (c) 2016 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
Copyright (c) 2016 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Copyright (c) 2016 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
Copyright (c) 2016 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Copyright (c) 2016 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
Copyright (c) 2015-2016 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Copyright (c) 2015-2016 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
Copyright (c) 2015 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Copyright (c) 2015 YamaArashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||