Skip to content

Instantly share code, notes, and snippets.

@Grayfox96
Last active June 26, 2021 13:10
Show Gist options
  • Save Grayfox96/fe50cabfd264caeefdabe34507b86bce to your computer and use it in GitHub Desktop.
Save Grayfox96/fe50cabfd264caeefdabe34507b86bce to your computer and use it in GitHub Desktop.
import csv
import tkinter as tk
from tkinter import font
def get_condition(raw_rng, initiative=False):
condition_rng = raw_rng & 255
condition = 2
if initiative:
condition_rng += -32 -1
if condition_rng < (255 - 32):
condition = 1 if condition_rng < 32 else 0
if condition == 0:
output = ''
elif condition == 1:
output = 'Preemptive'
elif condition == 2:
output = 'Ambush'
return output
def print_notes(unused=None):
def encounter_counter():
i = 0
while True:
i += 1
yield i
text = ''
e = encounter_counter()
rng_position = 0
max_lines = 500
def get_formation(raw_rng, zone):
global formations_list
formation_number = raw_rng % len(formations_list[zone])
return formations_list[zone][formation_number]
def add_random_encounters(zone, initiative=False):
nonlocal text, rng_position
encounters = encounters_sliders[zone]['scale'].get()
for number in range(encounters):
if encounters_sliders[zone]['checkbutton_state'].get():
formation = get_formation(int(current_seed[rng_position + 6]), zone)
condition = get_condition(int(current_seed[rng_position + 6 + 1]), initiative)
text += f'{next(e):3}: {zone} [{number + 1}]\n `-{formation:28}{condition}\n'
else: next(e)
rng_position += 2
def add_forced_encounters(encounter_names, show=True, initiative=False):
nonlocal text, rng_position
for encounter_name in encounter_names:
if show:
condition = get_condition(int(current_seed[rng_position + 6]), initiative)
text += f'{next(e):3}: {encounter_name:28}{condition}\n'
else: next(e)
rng_position += 1
def add_optional_forced_encounters(encounter_name, initiative=False):
nonlocal text, rng_position
encounters = encounters_sliders[encounter_name]['scale'].get()
for number in range(encounters):
if encounters_sliders[encounter_name]['checkbutton_state'].get():
number = ' ' + str(number + 1)
condition = get_condition(int(current_seed[rng_position + 6]), initiative)
text += f'{next(e):3}: {encounter_name + number:28}{condition}\n'
else: next(e)
rng_position += 1
# prints 2 encounters from different zones
def add_cave_encounters(initiative=False):
nonlocal text, rng_position
encounters = encounters_sliders['Cave']['scale'].get()
for number in range(encounters):
if encounters_sliders['Cave']['checkbutton_state'].get():
formation_white = get_formation(int(current_seed[rng_position + 6]), 'Cave (White Zone)')
formation_green = get_formation(int(current_seed[rng_position + 6]), 'Cave (Green Zone)')
formation = formation_white + '/' + formation_green
condition = get_condition(int(current_seed[rng_position + 6 + 1]), initiative)
text += f'{next(e):3}: Cave [{number + 1}]\n `-{formation:28}{condition}\n'
else: next(e)
rng_position += 2
def highlight_pattern(text, pattern, tag, start='1.0', end='end'):
start = text.index(start)
end = text.index(end)
text.mark_set('matchStart', start)
text.mark_set('matchEnd', start)
text.mark_set('searchLimit', end)
count = tk.IntVar()
while True:
index = text.search(pattern, 'matchEnd','searchLimit', count=count)
if index == '': break
if count.get() == 0: break # degenerate pattern which matches zero-length strings
text.mark_set('matchStart', index)
text.mark_set('matchEnd', f'{index}+{count.get()}c')
text.tag_add(tag, 'matchStart', 'matchEnd')
add_forced_encounters(('Sinscales', 'Ammes', 'Tanker', 'Sahagins', 'Geosgaeno', 'Klikk 1', 'Klikk 2'), show=encounters_sliders['Underwater Ruins']['checkbutton_state'].get())
add_random_encounters('Underwater Ruins')
add_forced_encounters(('Piranhas', 'Tros'), show=encounters_sliders['Besaid Lagoon']['checkbutton_state'].get())
add_random_encounters('Besaid Lagoon')
add_forced_encounters(('Dingo/Condor', 'Water Flan', 'Kimahri', 'Garuda 1', 'Garuda 2', 'Condor/Dingo/Water Flan'), show=encounters_sliders['Besaid']['checkbutton_state'].get())
add_random_encounters('Besaid')
add_forced_encounters(('Sin Fin', 'Echuilles', 'Lancet tutorial'), show=encounters_sliders['Lord Ochu (Way In)']['checkbutton_state'].get())
add_optional_forced_encounters('Lord Ochu (Way In)')
add_random_encounters('Kilika Woods (Way In)')
add_forced_encounters(('Geneaux',), show=encounters_sliders['Lord Ochu (Way Out)']['checkbutton_state'].get())
add_optional_forced_encounters('Lord Ochu (Way Out)')
add_random_encounters('Kilika Woods (Way Out)')
add_forced_encounters(('Machina 1', 'Machina 2', 'Machina 3', 'Oblitzerator', 'Sahagin Chiefs', 'Vouivre', 'Garuda', 'Pierce tutorial'), show=encounters_sliders['Miihen Screen 1']['checkbutton_state'].get())
add_random_encounters('Miihen Screen 1')
add_random_encounters('Miihen Screen 2/3')
add_forced_encounters(('Chocobo Eater',), show=encounters_sliders['Old Road']['checkbutton_state'].get())
add_random_encounters('Old Road')
add_random_encounters('Clasko Skip Screen')
add_random_encounters('MRR - Valley')
add_random_encounters('MRR - Precipice')
add_forced_encounters(('Sinspawn Gui 1', 'Sinspawn Gui 2'), show=encounters_sliders['Djose Highroad (Front Half)']['checkbutton_state'].get())
add_random_encounters('Djose Highroad (Front Half)', initiative=True)
add_random_encounters('Djose Highroad (Back Half)', initiative=True)
add_random_encounters('Moonflow (South)', initiative=True)
add_forced_encounters(('Extractor', 'Rikku tutorial'), show=encounters_sliders['Moonflow (North)']['checkbutton_state'].get())
add_random_encounters('Moonflow (North)', initiative=True)
add_random_encounters('Thunder Plains (South)', initiative=True)
add_random_encounters('Thunder Plains (North)', initiative=True)
add_random_encounters('Macalania Woods')
add_forced_encounters(('Spherimorph',), show=encounters_sliders['Lake Macalania']['checkbutton_state'].get())
add_random_encounters('Lake Macalania')
add_forced_encounters(('Crawler', 'Seymour'), show=encounters_sliders['Guado Encounter']['checkbutton_state'].get())
add_optional_forced_encounters('Guado Encounter')
add_random_encounters('Crevasse')
add_forced_encounters(('Wendigo', 'Zu'), show=encounters_sliders['Bikanel (Pre Machina)']['checkbutton_state'].get())
add_random_encounters('Bikanel (Pre Machina)', initiative=True)
add_forced_encounters(('Machina Steal tutorial',), show=encounters_sliders['Bikanel (Post Machina)']['checkbutton_state'].get())
add_random_encounters('Bikanel (Post Machina)', initiative=True)
add_random_encounters('Bikanel (Central)', initiative=True)
add_random_encounters('Bikanel (Ruins)', initiative=True)
add_random_encounters('Bikanel (Pre Sandragora)', initiative=True)
add_forced_encounters(('Sandragora 1',), show=encounters_sliders['Sandragora 1 refight']['checkbutton_state'].get())
add_optional_forced_encounters('Sandragora 1 refight', initiative=True)
add_random_encounters('Bikanel (Post Sandragora)', initiative=True)
add_forced_encounters(('Sandragora 2', 'Guado + 3 Bombs', 'Guado + 2 Dual Horn 1', 'Guado + 2 Chimera', 'Evrae', 'Bevelle Guards 1', 'Bevelle Guards 2', 'Bevelle Guards 3', 'Bevelle Guards 4', 'Bevelle Guards 5'), show=encounters_sliders['Via Purifico']['checkbutton_state'].get())
add_random_encounters('Via Purifico', initiative=True)
add_forced_encounters(('Isaaru Grothia', 'Isaaru Pterya', 'Isaaru Spathi'), show=encounters_sliders['Via Purifico Underwater']['checkbutton_state'].get())
add_random_encounters('Via Purifico Underwater')
add_forced_encounters(('Evrae Altana',), show=encounters_sliders['Highbridge']['checkbutton_state'].get())
add_random_encounters('Highbridge', initiative=True)
add_forced_encounters(('Seymour Natus',), show=encounters_sliders['Calm Lands']['checkbutton_state'].get())
add_random_encounters('Calm Lands', initiative=True)
add_forced_encounters(('Defender X',), show=encounters_sliders['Cave']['checkbutton_state'].get())
add_cave_encounters(initiative=True)
# padding
for number in range(max_lines):
text += '\n'
notes.config(state='normal')
notes.delete(1.0,'end')
notes.insert(1.0, text)
# if notes has more lines than raw_data delete the last lines
if int(notes.index('end-1c').split('.')[0]) > int(raw_data_text.index('end-1c').split('.')[0]):
notes.delete(float(raw_data_text.index('end-1c').split('.')[0]), 'end')
highlight_pattern(notes, 'Preemptive', 'preemptive')
highlight_pattern(notes, 'Ambush', 'ambush')
highlight_pattern(notes, 'Ghost', 'ghost')
notes.config(state='disabled')
damage_rolls = {}
damage_rolls['auron'] = {}
damage_rolls['tidus'] = {}
damage_rolls['possible_rolls'] = {}
damage_rolls['possible_rolls']['tidus'] = (125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141)
damage_rolls['possible_rolls']['auron'] = (260, 261, 262, 263, 264, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 278,
279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 291, 292, 293, 294)
damage_rolls_input = input('Damage rolls (Auron1 Tidus1 A2 T2 A3 T3): ')
damage_rolls_input = damage_rolls_input.replace(',', ' ')
damage_rolls_input = damage_rolls_input.replace('-', ' ')
damage_rolls_input = damage_rolls_input.replace('/', ' ')
damage_rolls_input = damage_rolls_input.replace('\\', ' ')
damage_rolls['auron'][1], damage_rolls['tidus'][1], damage_rolls['auron'][2], damage_rolls['tidus'][2], damage_rolls['auron'][3], \
damage_rolls['tidus'][3] = [int(roll) for roll in damage_rolls_input.split()]
for key, roll in damage_rolls['auron'].items():
if roll not in damage_rolls['possible_rolls']['auron']:
if roll / 2 not in damage_rolls['possible_rolls']['auron']:
print(f'Invalid damage roll: {roll}')
else:
damage_rolls['auron'][key] = roll // 2
for key, roll in damage_rolls['tidus'].items():
if roll not in damage_rolls['possible_rolls']['tidus']:
if roll / 2 not in damage_rolls['possible_rolls']['tidus']:
print(f'Invalid damage roll: {roll}')
else:
damage_rolls['tidus'][key] = roll // 2
def get_current_seed(rng_file, damage_rolls_dict):
rng_file_reader = csv.reader(open(rng_file), delimiter=',')
line_count = 0
for line in rng_file_reader:
if line_count == 0:
pass
else:
if all([damage_rolls['auron'][1] == int(line[0]), damage_rolls['auron'][2] == int(line[2]), damage_rolls['auron'][3] == int(line[4]),
damage_rolls['tidus'][1] == int(line[1]), damage_rolls['tidus'][2] == int(line[3]), damage_rolls['tidus'][3] == int(line[5])]):
print('Seed found!')
print(f'Seed number is {line_count}')
return line, True
line_count += 1
current_seed, seed_found = get_current_seed('ffxhd-raw-encounter-values.csv', damage_rolls)
if seed_found == False:
print('Seed not found!')
quit()
def get_formation_list(formations_file):
formations_file_reader = csv.reader(open(formations_file), delimiter=',')
formations_list = {}
for line in formations_file_reader:
cell_counter = 0
for formation in line:
if cell_counter == 0:
zone = formation
formations_list[zone] = []
else:
formations_list[zone].append(formation)
cell_counter += 1
return formations_list
formations_list = get_formation_list('ffxhd-formations.csv')
def get_raw_data():
max_lines = 500
data = ''
for counter in range(max_lines):
f_e_condition = get_condition(int(current_seed[counter + 6]))
r_e_condition = get_condition(int(current_seed[counter + 6 + 1]))
data += f'Seed roll {(counter + 1):3} | Forced: {f_e_condition:10} | Random: {r_e_condition:10}\n'
counter += 1
return data
raw_data = get_raw_data()
# GUI
#--------------------------------------------------------------------------------------------------------------------------------------------------------------
root = tk.Tk()
def on_ui_close():
global root
root.quit()
quit()
root.protocol('WM_DELETE_WINDOW', on_ui_close)
root.title('ffx_seed_finder')
root.geometry('1000x800')
# Texts
#--------------------------------------------------------------------------------------------------------------------------------------------------------------
canvas = tk.Canvas(root)
canvas.pack(expand=True, fill='both', side='left')
font = font.Font(family='Courier New', size=9)
raw_data_text = tk.Text(canvas, font=font, width=55)
raw_data_text.pack(expand=True, fill='both', side='left')
raw_data_text.insert('end', raw_data)
notes = tk.Text(canvas, font=font, width=43)
notes.tag_configure('ambush', foreground='#ff0000')
notes.tag_configure('preemptive', foreground='#00ff00')
notes.tag_configure('ghost', foreground='#ff0000')
notes.pack(expand=True, fill='both', side='right')
def on_raw_data_text_scroll(*args):
notes.yview('moveto', args[0])
def on_notes_scroll(*args):
raw_data_text.yview('moveto', args[0])
raw_data_text.configure(yscrollcommand=on_raw_data_text_scroll)
notes.configure(yscrollcommand=on_notes_scroll)
encounters_outer_frame = tk.Frame(root)
encounters_outer_frame.pack(fill='y', side='right')
encounters_canvas = tk.Canvas(encounters_outer_frame, width=280)
encounters_canvas.pack(side='left', fill='both', expand=True)
encounters_scrollbar = tk.Scrollbar(encounters_outer_frame, orient='vertical', command=encounters_canvas.yview)
encounters_scrollbar.pack(side='right', fill='y')
encounters_canvas.configure(yscrollcommand=encounters_scrollbar.set)
def encounters_canvas_on_mousewheel(event):
encounters_canvas.yview_scroll(int(-1*(event.delta/120)), 'units')
encounters_inner_frame = tk.Frame(encounters_canvas)
encounters_inner_frame.bind('<Configure>', lambda e: encounters_canvas.configure(scrollregion=encounters_canvas.bbox('all')))
encounters_canvas.create_window((0, 0), window=encounters_inner_frame, anchor='nw')
# these make it possible to scroll the canvas with the mousewheel only when the mouse hovers the canvas
encounters_canvas.bind('<Enter>', lambda _: encounters_canvas.bind_all('<MouseWheel>', encounters_canvas_on_mousewheel))
encounters_canvas.bind('<Leave>', lambda _: encounters_canvas.unbind_all('<MouseWheel>'))
# Labels and Scales
#--------------------------------------------------------------------------------------------------------------------------------------------------------------
sliders_dict = {'Underwater Ruins': {'min_encounters': 0, 'default_encounters': 1, 'max_encounters': 1},
'Besaid Lagoon': {'min_encounters': 1, 'default_encounters': 2, 'max_encounters': 4},
'Besaid': {'min_encounters': 0, 'default_encounters': 0, 'max_encounters': 1},
'Lord Ochu (Way In)': {'min_encounters': 0, 'default_encounters': 0, 'max_encounters': 1},
'Kilika Woods (Way In)': {'min_encounters': 0, 'default_encounters': 2, 'max_encounters': 6},
'Lord Ochu (Way Out)': {'min_encounters': 0, 'default_encounters': 0, 'max_encounters': 1},
'Kilika Woods (Way Out)': {'min_encounters': 0, 'default_encounters': 4, 'max_encounters': 6},
'Miihen Screen 1': {'min_encounters': 0, 'default_encounters': 3, 'max_encounters': 6},
'Miihen Screen 2/3': {'min_encounters': 0, 'default_encounters': 6, 'max_encounters': 10},
'Old Road': {'min_encounters': 0, 'default_encounters': 3, 'max_encounters': 8},
'Clasko Skip Screen': {'min_encounters': 0, 'default_encounters': 2, 'max_encounters': 3},
'MRR - Valley': {'min_encounters': 0, 'default_encounters': 5, 'max_encounters': 10},
'MRR - Precipice': {'min_encounters': 0, 'default_encounters': 1, 'max_encounters': 3},
'Djose Highroad (Front Half)': {'min_encounters': 0, 'default_encounters': 1, 'max_encounters': 3},
'Djose Highroad (Back Half)': {'min_encounters': 0, 'default_encounters': 4, 'max_encounters': 6},
'Moonflow (South)': {'min_encounters': 0, 'default_encounters': 5, 'max_encounters': 10},
'Moonflow (North)': {'min_encounters': 0, 'default_encounters': 5, 'max_encounters': 10},
'Thunder Plains (South)': {'min_encounters': 0, 'default_encounters': 7, 'max_encounters': 11},
'Thunder Plains (North)': {'min_encounters': 0, 'default_encounters': 7, 'max_encounters': 11},
'Macalania Woods': {'min_encounters': 0, 'default_encounters': 7, 'max_encounters': 10},
'Lake Macalania': {'min_encounters': 0, 'default_encounters': 1, 'max_encounters': 1},
'Guado Encounter': {'min_encounters': 0, 'default_encounters': 0, 'max_encounters': 2},
'Crevasse': {'min_encounters': 0, 'default_encounters': 2, 'max_encounters': 5},
'Bikanel (Pre Machina)': {'min_encounters': 0, 'default_encounters': 3, 'max_encounters': 5},
'Bikanel (Post Machina)': {'min_encounters': 0, 'default_encounters': 1, 'max_encounters': 5},
'Bikanel (Central)': {'min_encounters': 0, 'default_encounters': 3, 'max_encounters': 5},
'Bikanel (Ruins)': {'min_encounters': 0, 'default_encounters': 0, 'max_encounters': 5},
'Bikanel (Pre Sandragora)': {'min_encounters': 0, 'default_encounters': 1, 'max_encounters': 2},
'Sandragora 1 refight': {'min_encounters': 0, 'default_encounters': 0, 'max_encounters': 1},
'Bikanel (Post Sandragora)': {'min_encounters': 0, 'default_encounters': 0, 'max_encounters': 2},
'Via Purifico': {'min_encounters': 1, 'default_encounters': 2, 'max_encounters': 4},
'Via Purifico Underwater': {'min_encounters': 0, 'default_encounters': 1, 'max_encounters': 3},
'Highbridge': {'min_encounters': 0, 'default_encounters': 2, 'max_encounters': 5},
'Calm Lands': {'min_encounters': 6, 'default_encounters': 10, 'max_encounters': 12},
'Cave': {'min_encounters': 0, 'default_encounters': 50, 'max_encounters': 100},
}
def make_sliders(zones_dict, parent, scale_command):
encounters_dict = {}
row = 0
labels_column = 2
labels_sticky = 'sw'
scales_column = 0
checkbutton_column = 1
checkbutton_sticky = 'sw'
for zone_name, encounters_info in zones_dict.items():
min_encounters = encounters_info['min_encounters']
default_encounters = encounters_info['default_encounters']
max_encounters = encounters_info['max_encounters']
encounters_dict[zone_name] = {}
encounters_dict[zone_name]['checkbutton_state'] = tk.BooleanVar()
encounters_dict[zone_name]['checkbutton_state'].set(True)
encounters_dict[zone_name]['checkbutton'] = tk.Checkbutton(parent, text=zone_name, command=scale_command,
variable=encounters_dict[zone_name]['checkbutton_state'], onvalue=True, offvalue=False)
encounters_dict[zone_name]['checkbutton'].grid(row=row, column=checkbutton_column, sticky=checkbutton_sticky)
encounters_dict[zone_name]['scale'] = tk.Scale(parent, orient='horizontal', from_=min_encounters, to=max_encounters, command=scale_command)
encounters_dict[zone_name]['scale'].grid(row=row, column=scales_column)
encounters_dict[zone_name]['scale'].set(default_encounters)
row += 1
return encounters_dict
encounters_sliders = make_sliders(zones_dict=sliders_dict, parent=encounters_inner_frame, scale_command=print_notes)
#--------------------------------------------------------------------------------------------------------------------------------------------------------------
print_notes()
if int(notes.index('end-1c').split('.')[0]) > int(raw_data_text.index('end-1c').split('.')[0]):
notes.delete(float(raw_data_text.index('end-1c').split('.')[0]), 'end')
raw_data_text.config(state='disabled')
notes.config(state='disabled')
root.mainloop()
We can make this file beautiful and searchable if this error is corrected: It looks like row 2 should actually have 5 columns, instead of 3. in line 1.
Credits,to,CrimsonInferno9,https://www.twitch.tv/crimsoninferno9,VoHiYo
Underwater Ruins,2 Piranhas,1 Piranha
Besaid Lagoon,2 Piranhas,2 Piranhas,3 Piranhas,4 Piranhas
Besaid Road,No Encounters Data
Kilika Woods (Way In),Lizard+Element,Lizard+Element,Lizard+Bee,Lizard+Bee,Element+Bee,Element+Bee,Lizard+Element+Bee,Lizard+Element+Bee,Ragora,Ragora,Ragora,Ragora+Ragora,Ragora+Bee+Bee
Kilika Woods (Way Out),Lizard+Element,Lizard+Element,Lizard+Bee,Lizard+Bee,Element+Bee,Element+Bee,Lizard+Element+Bee,Lizard+Element+Bee,Ragora,Ragora,Ragora,Ragora+Ragora,Ragora+Bee+Bee
Miihen Screen 1,Wolf+Element+Eye,Wolf+Element+Boulder,Eye+Wolf+Boulder,Boulder+Element+Eye,Bomb,Dual Horn
Miihen Screen 2/3,Element+Wolf+Eye,Element+Wolf+Eye,Element+Wolf+Eye,Wolf+Element+Boulder,Wolf+Element+Boulder,Wolf+Element+Boulder,Wolf+Boulder+Eye,Wolf+Boulder+Eye,Wolf+Boulder+Eye,Boulder+Element+Eye,Boulder+Element+Eye,Boulder+Element+Eye,Dual Horn+Wolf,Dual Horn+Wolf,Bomb+Bomb+Dual Horn,Eye+Bomb+Eye,Eye+Bomb+Eye,Bomb+Bomb+Bomb
Old Road,Drake+Lizard+Flan,Drake+Lizard+Flan,Drake+Lizard+Flan,Lizard+Drake+Eye,Lizard+Drake+Eye,Lizard+Drake+Eye,Drake+Eye+Flan,Drake+Eye+Flan,Drake+Eye+Flan,Drake+Flan,Drake+Flan,Drake+Flan,Flan+Bomb+Bomb,Flan+Bomb+Bomb,Dual Horn+Flan,Dual Horn+Flan,Drake+Dual Horn+Dual Horn,Drake+Dual Horn+Dual Horn,Bomb+Dual Horn+Bomb,Bomb+Dual Horn+Bomb
Clasko Skip Screen,Drake+Lizard+Flan,Drake+Lizard+Eye,Flan+Eye+Drake,Bomb+Bomb+Flan,Bomb+Bomb+Dual Horn,Dual Horn+Drake+Dual Horn
MRR - Valley,Lamashtu+Lizard+Element,Lamashtu+Gandarewa+Element,Lizard+Element+Gandarewa,Lizard+Funguar+Element,Funguar+Element+Gandarewa,Garuda
MRR - Precipice,Lizard+Funguar+Funguar,Lizard+Funguar+Funguar,Lizard+Funguar+Element,Lizard+Funguar+Element,Funguar+Element+Gandarewa,Funguar+Element+Gandarewa,Garuda,Garuda,Garuda+Funguar+Funguar
Djose Highroad (Front Half),Bee+Bee+Funguar,Bee+Basilisk+Bee,Basilisk+Basilisk,Lamashtu+Lizard+Funguar,Lamashtu+Lizard+Funguar
Djose Highroad (Back Half),Wolf+Boulder+Flan,Wolf+Boulder+Flan,Wolf+Boulder+Flan,Wolf+Boulder+Flan,Wolf+Boulder+Simurgh,Wolf+Boulder+Simurgh,Ganderewa+Funguar+Gandarewa,Gandarewa+Gandarewa+Flan,Basilisk+Funguar+Funguar,Basilisk+Funguar+Funguar,Basilisk+Funguar+Funguar,Bee+Bee+Simurgh,Basilisk+Basilisk,Basilisk+Basilisk,Basilisk+Basilisk
Moonflow (South),Boulder+Wolf+Bee,Bee+Bee+Ochu,Bee+Bee+Ochu,Wolf+Ochu,Wolf+Ochu,Ochu,Ochu,Wolf+Boulder+Flan,Wolf+Boulder+Flan,Wolf+Boulder+Flan,Wolf+Boulder+Flan,Gandarewa+Funguar+Gandarewa
Moonflow (North),Boulder+Wolf+Chest,Bee+Bee+Chest,Bee+Bee+Boulder+Chest,Wolf+Ochu,Wolf+Boulder+Flan
Thunder Plains (South),Larva+Element,Lizard+Kusariqu+Aerouge,Element+Buer+Lizard,Aerouge+Aerouge+Larva,Aerouge+Buer+Element
Thunder Plains (North),Iron Giant,Iron Giant+Buer+Buer,Larva+Larva,Lizard+Kusariqu+Aerouge,Element+Buer+Kusariqu
Macalania Woods,Lizard+Boulder+Bee,Lizard+Boulder+Element,Bee+Element+Element,Xiphos,Xiphos+Bee+Bee,Chimera,Chimera
Lake Macalania,1?,2?,3?
Crevasse,Eye+Wolf+Flan,Boulder+Wolf+Flan,Eye+Eye+Boulder
Bikanel (Pre Machina),Wolf+Dragon+Bird,Wolf+Dragon+Bird,Wolf+Dragon+Bird,Wolf+Dragon+Bird,Wolf+Bird+Bird,Wolf+Bird+Bird,Wolf+Bird+Bird,Machina+Machina,Machina+Machina,Machina+Machina,Zu,Sand Worm,Cactuar
Bikanel (Post Machina),Wolf+Dragon+Bird,Wolf+Dragon+Bird,Wolf+Dragon+Bird,Wolf+Dragon+Bird,Wolf+Bird+Bird,Wolf+Bird+Bird,Wolf+Bird+Bird,Machina+Machina,Machina+Machina,Machina+Machina,Zu,Sand Worm,Cactuar
Bikanel (Central),Wolf+Dragon+Bird,Wolf+Dragon+Bird,Wolf+Dragon+Bird,Wolf+Dragon+Bird,Wolf+Bird+Bird,Wolf+Bird+Bird,Wolf+Bird+Bird,Machina+Machina,Machina+Machina,Machina+Machina,Zu,Sand Worm,Cactuar
Bikanel (Ruins),Sand Worm,Sand Worm,Sand Worm/Zu?,Zu+Chest,Zu+Chest,Zu+Chest+Chest,Zu+Chest+Chest,Wolf+Wolf+Wolf+Chest,Wolf+Wolf+Wolf+Chest,Cactuar
Bikanel (Pre Sandragora),No Encounters Data
Bikanel (Post Sandragora),No Encounters Data
Via Purifico,No Encounters Data
Via Purifico Underwater,No Encounters Data
Highbridge,No Encounters Data
Calm Lands,No Encounters Data
Cave (White Zone),Yowie x3,Yowie x3,Nidhogg+Dark Element x2,Nidhogg+Dark Element x2,Imp+Mech Hunter+Epaaj,Imp+Mech Hunter+Epaaj,Thorn x3,Thorn x3,Ghost,Valaha+Epaaj,Magic Urn,Magic Urn,Magic Urn
Cave (Green Zone),Ghost,Valaha+Epaaj,Malboro,Defender,Tonberry,Coeurl x2,Magic Urn,Magic Urn,Magic Urn,Magic Urn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment