You've already forked Gamedata
mirror of
https://github.com/TeamLumi/Gamedata.git
synced 2026-03-30 10:09:42 -07:00
350 lines
14 KiB
Python
350 lines
14 KiB
Python
import json
|
|
import math
|
|
import os
|
|
import re
|
|
import time
|
|
|
|
import constants
|
|
from convert_lmpt_data import getTrainerData, find_zone_id
|
|
from data_checks import get_average_time, check_for_valid_ability
|
|
from load_files import load_data
|
|
from pokemonUtils import get_pokemon_from_trainer_info, get_pokemon_name
|
|
from trainerUtils import parse_ev_script_file, process_files, get_map_info, get_area_display_name
|
|
|
|
repo_file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
output_file_path = os.path.join(repo_file_path, "Python_tasks", constants.OUTPUT_NAME)
|
|
trainer_doc_data_file_path = os.path.join(repo_file_path, constants.TRAINER_DOC_PATH, "trainer_doc_output.txt")
|
|
|
|
first_excecution_time_list = []
|
|
second_execution_time_list = []
|
|
|
|
def get_trainer_pokemon(trainerId, output_format):
|
|
'''
|
|
Using the get_pokemon_from_trainer_info from pokemonUtils
|
|
Requires the trainerId and the output_format being either "Scripted" or "Place Data"
|
|
Those are referenced in Constants.py
|
|
'''
|
|
TRAINER_TABLE = full_data['raw_trainer_data']
|
|
|
|
pokemon_list = []
|
|
trainer = None
|
|
for t in TRAINER_TABLE["TrainerPoke"]:
|
|
if t["ID"] == trainerId:
|
|
trainer = t
|
|
break
|
|
pokemon_list = get_pokemon_from_trainer_info(trainer, output_format, check_for_valid_ability)
|
|
|
|
return pokemon_list
|
|
|
|
def sort_dicts_by_key(dicts_list, sort_key1, sort_key2, sort_key1_order):
|
|
"""
|
|
Sorts a list of dictionaries by two given keys in ascending order
|
|
The sorting order of the first key is specified by DOCS_ZONE_ORDER in Constants.py
|
|
"""
|
|
return sorted(dicts_list, key=lambda x: (sort_key1_order.index(x[sort_key1]), x[sort_key2]))
|
|
|
|
def get_avg_trainer_level(trainer_team):
|
|
'''
|
|
Requires the full trainer's team
|
|
This function counts the mons, add the levels of those mons together and returns the average
|
|
'''
|
|
mon_count = len(trainer_team)
|
|
if len(trainer_team) == 0:
|
|
print("Trainer does not have a team")
|
|
return 0
|
|
total_levels = 0
|
|
for mon in trainer_team:
|
|
total_levels += mon['level']
|
|
trainer_avg = math.ceil(total_levels / mon_count)
|
|
return trainer_avg
|
|
|
|
def sort_trainers_by_level(trainer_info):
|
|
'''
|
|
Requires the trainer_info from the process_files function or trainer_info.json
|
|
Adds the trainer's team and average level to trainer_info
|
|
Calls the sort_dicts_by_key function and sorts the trainers by zoneName then average level
|
|
'''
|
|
for trainer in trainer_info:
|
|
trainerId = trainer['trainerId']
|
|
trainer['team'] = get_trainer_pokemon(trainerId, constants.DOCS_METHOD)
|
|
trainer['avg_lvl'] = get_avg_trainer_level(trainer['team'])
|
|
sorted_trainers_by_level = sort_dicts_by_key(trainer_info, 'zoneName', 'avg_lvl', constants.DOCS_ZONE_ORDER)
|
|
return sorted_trainers_by_level
|
|
|
|
def sort_trainers_by_route(trainer_info):
|
|
'''
|
|
Requires the trainer_info from the process_files function or trainer_info.json
|
|
Calls the sort_dicts_by_key function and sorts the trainers by zoneName then trainerId
|
|
Adds the trainer's team to trainer_info
|
|
Adds each trainer to an `areaName: trainer_info` dictionary for use later
|
|
'''
|
|
sorted_trainers_by_key = sort_dicts_by_key(trainer_info, 'zoneName', 'trainerId', constants.DOCS_ZONE_ORDER)
|
|
sorted_trainers_by_route = {}
|
|
for trainer in sorted_trainers_by_key:
|
|
areaName = trainer['areaName']
|
|
trainerId = trainer['trainerId']
|
|
trainer['team'] = get_trainer_pokemon(trainerId, constants.TRACKER_METHOD)
|
|
if areaName not in sorted_trainers_by_route.keys():
|
|
sorted_trainers_by_route[areaName] = [trainer]
|
|
else:
|
|
sorted_trainers_by_route[areaName].append(trainer)
|
|
return sorted_trainers_by_route
|
|
|
|
def get_trainer_name(trainer_name, zone_name, TRAINER_INDEX=0, rematch=0):
|
|
'''
|
|
Requires trainer's name, zone name with optional trainer index
|
|
Finds if there is team already in the trainer's name and adds zone_name in the middle
|
|
If there is a TRAINER_INDEX, then it adds that value to the end of the name
|
|
If there isn't any of those, it returns the trainer name with zone name
|
|
'''
|
|
if re.findall(constants.TEAM_REGEX, trainer_name):
|
|
split_name = trainer_name.split()
|
|
altered_trainer_name = ' '.join(split_name[:-2])
|
|
if rematch == 1:
|
|
altered_trainer_name += ' Rematch'
|
|
team_name = ' '.join(split_name[-2:])
|
|
updated_name = f"{altered_trainer_name} ({zone_name}) [{team_name}]"
|
|
return [trainer_name, updated_name]
|
|
if TRAINER_INDEX != 0:
|
|
if rematch == 1:
|
|
trainer_name += ' Rematch'
|
|
updated_name = f"{trainer_name} {TRAINER_INDEX} ({zone_name})"
|
|
name = f"{trainer_name} {TRAINER_INDEX}"
|
|
return [name, updated_name]
|
|
if rematch == 1:
|
|
trainer_name += ' Rematch'
|
|
updated_name = f"{trainer_name} ({zone_name})"
|
|
return [trainer_name, updated_name]
|
|
|
|
def get_trainer_doc_moves(moves, index):
|
|
'''
|
|
Requires the full list of moves per pokemon and the index of each move
|
|
'''
|
|
if index < len(moves):
|
|
return f"{moves[index]}\n"
|
|
return f"(No Move)\n"
|
|
|
|
def write_trainer_docs_team_format(pokemon):
|
|
'''
|
|
Requires each pokemon from a trainer's team in write_to_trainer_docs_file function
|
|
Returns the format for the header, ivs and evs of each pokemon
|
|
'''
|
|
pokemon_header = f"\n{get_pokemon_name(pokemon['id'])}\n{pokemon['level']}\n{pokemon['nature']}\n{pokemon['ability']}\n\n{pokemon['item']}\n"
|
|
pokemon_ivs = f"{pokemon['ivhp']}/{pokemon['ivatk']}/{pokemon['ivdef']}/{pokemon['ivspatk']}/{pokemon['ivspdef']}/{pokemon['ivspeed']}\n"
|
|
pokemon_evs = f"{pokemon['evhp']}/{pokemon['evatk']}/{pokemon['evdef']}/{pokemon['evspatk']}/{pokemon['evspdef']}/{pokemon['evspeed']}\n"
|
|
|
|
return pokemon_header, pokemon_ivs, pokemon_evs
|
|
|
|
def write_to_trainer_docs_file(trainer, trainer_name):
|
|
'''
|
|
Requires the trainer info and trainer's full name from get_trainer_name
|
|
Writes lines to trainer_doc_output.txt for Solarnce to c/p into the Trainer Docs Google Sheet
|
|
'''
|
|
trainerId = trainer['trainerId']
|
|
rematch = trainer['rematch']
|
|
battle_format = f"Format: {trainer['format']}"
|
|
link = trainer['link']
|
|
team = trainer['team']
|
|
level_cap = "Level Cap:"
|
|
if rematch == 1:
|
|
trainer_name += " Rematch"
|
|
with open(trainer_doc_data_file_path, "a") as f:
|
|
f.write(f"{trainerId}\n{trainer_name}\n{level_cap}\n{battle_format}\n")
|
|
for mon in team:
|
|
mon_header, mon_ivs, mon_evs = write_trainer_docs_team_format(mon)
|
|
moves = mon['moves']
|
|
|
|
f.write(mon_header)
|
|
for index in range(0, 4):
|
|
f.write(get_trainer_doc_moves(moves, index))
|
|
f.write(mon_ivs)
|
|
f.write(mon_evs)
|
|
if link != '':
|
|
f.write(f"Paired with {link}\n\n")
|
|
else:
|
|
f.write(f"{link}\n\n")
|
|
|
|
def write_trainer_docs(trainer_list):
|
|
'''
|
|
Requires the full list of trainers from trainer_info.json or process_files
|
|
This opens the trainer_doc_output.txt and deletes anything there first.
|
|
This will then write every trainer to the trainer_doc_output.txt
|
|
'''
|
|
with open(trainer_doc_data_file_path, "w") as f:
|
|
f.write("Trainer Documentation\n")
|
|
for trainer in trainer_list:
|
|
|
|
zone_name = trainer['zoneName']
|
|
name = f"{trainer['type']} {trainer['name']}"
|
|
full_trainer_name = get_trainer_name(name, zone_name)[0]
|
|
|
|
write_to_trainer_docs_file(trainer, full_trainer_name)
|
|
|
|
def generate_repeat_trainer_name(trainer, index_dict):
|
|
zone_name = f"{trainer['zoneName']} Trainers"
|
|
name = f"{trainer['type']} {trainer['name']}"
|
|
|
|
if constants.REPEAT_TRAINERS_LIST[0] in name:
|
|
index_dict['Grunt'] += 1
|
|
return get_trainer_name(name, zone_name, index_dict['Grunt'])
|
|
elif constants.REPEAT_TRAINERS_LIST[1] in name:
|
|
if index_dict['Lucas'] < 3:
|
|
STARTER_INDEX = constants.STARTERS[index_dict['Lucas']].capitalize()
|
|
else:
|
|
STARTER_INDEX = f"End Game {constants.STARTERS[index_dict['Lucas'] - 3].capitalize()}"
|
|
index_dict['Lucas'] += 1
|
|
return get_trainer_name(name, zone_name, STARTER_INDEX)
|
|
elif constants.REPEAT_TRAINERS_LIST[2] in name:
|
|
if index_dict['Dawn'] < 3:
|
|
STARTER_INDEX = constants.STARTERS[index_dict['Dawn']].capitalize()
|
|
else:
|
|
STARTER_INDEX = f"End Game {constants.STARTERS[index_dict['Dawn'] - 3].capitalize()}"
|
|
index_dict['Dawn'] += 1
|
|
return get_trainer_name(name, zone_name, STARTER_INDEX)
|
|
elif constants.REPEAT_TRAINERS_LIST[3] in name:
|
|
if index_dict['Barry'] < 3:
|
|
STARTER_INDEX = constants.STARTERS[index_dict['Barry']].capitalize()
|
|
else:
|
|
STARTER_INDEX = f"End Game {constants.STARTERS[index_dict['Barry'] - 3].capitalize()}"
|
|
index_dict['Barry'] += 1
|
|
return get_trainer_name(name, zone_name, STARTER_INDEX)
|
|
|
|
def write_tracker_docs(trainers_list):
|
|
'''
|
|
Requires the trainers sorted for the Nuzlocke Tracker
|
|
This formats all of the trainers for use in the Tracker
|
|
'''
|
|
all_trainers = []
|
|
|
|
for zone in trainers_list.keys():
|
|
zone_trainers = []
|
|
index_dict = {
|
|
"Grunt": 0,
|
|
"Lucas": 0,
|
|
"Dawn": 0,
|
|
"Barry": 0,
|
|
}
|
|
for trainer in trainers_list[zone]:
|
|
zone_trainer = {}
|
|
zone_name = f"{trainer['zoneName']} Trainers"
|
|
zone_id = trainer['zoneId']
|
|
person_name = trainer['name']
|
|
if person_name == constants.CEDRIC:
|
|
trainer['name'] = constants.BARRY.capitalize()
|
|
name = f"{trainer['type']} {trainer['name']}"
|
|
rematch = trainer['rematch']
|
|
is_repeat_trainer = any(substring in name for substring in constants.REPEAT_TRAINERS_LIST) and not re.findall(constants.TEAM_REGEX, name)
|
|
if is_repeat_trainer:
|
|
full_trainer_name = generate_repeat_trainer_name(trainer, index_dict)
|
|
else:
|
|
full_trainer_name = get_trainer_name(name, zone_name, 0, rematch)
|
|
trainer_name = full_trainer_name[0]
|
|
team_name = full_trainer_name[1]
|
|
trainer_team = trainer['team']
|
|
trainer_type = trainer['format']
|
|
zone_trainer = {
|
|
"content": trainer_team,
|
|
"game": team_name,
|
|
"name": trainer_name,
|
|
"type": "Trainer",
|
|
"route": zone_name,
|
|
"zoneId": zone_id,
|
|
"trainerType": trainer_type
|
|
}
|
|
zone_trainers.append(zone_trainer)
|
|
all_trainers.append(zone_trainers)
|
|
return all_trainers
|
|
|
|
def write_mapper_docs(trainers_list):
|
|
'''
|
|
Requires the trainers sorted for the Nuzlocke Tracker
|
|
This formats all of the trainers for use in the Tracker
|
|
'''
|
|
all_trainers = {}
|
|
|
|
for zone in trainers_list.keys():
|
|
index_dict = {
|
|
"Grunt": 0,
|
|
"Lucas": 0,
|
|
"Dawn": 0,
|
|
"Barry": 0,
|
|
}
|
|
for trainer in trainers_list[zone]:
|
|
zone_trainer = {}
|
|
zone_name = trainer['zoneName']
|
|
zone_id = trainer['zoneId']
|
|
name = f"{trainer['type']} {trainer['name']}"
|
|
rematch = trainer['rematch']
|
|
is_repeat_trainer = any(substring in name for substring in constants.REPEAT_TRAINERS_LIST) and not re.findall(constants.TEAM_REGEX, name)
|
|
if is_repeat_trainer:
|
|
full_trainer_name = generate_repeat_trainer_name(trainer, index_dict)
|
|
else:
|
|
full_trainer_name = get_trainer_name(name, zone_name, 0, rematch)
|
|
trainer_name = full_trainer_name[0]
|
|
team_name = full_trainer_name[1]
|
|
trainer_team = trainer['team']
|
|
trainer_type = trainer['format']
|
|
zone_trainer = {
|
|
"team": trainer_team,
|
|
"team_name": team_name,
|
|
"name": trainer_name,
|
|
"route": zone_name,
|
|
"zoneId": zone_id,
|
|
"trainerType": trainer_type,
|
|
"trainer_id": trainer["trainerId"]
|
|
}
|
|
if zone_id not in constants.EXCLUSIVE_ZONE_IDS:
|
|
areaName, _ = get_map_info(zone_id)
|
|
generalized_zone_id = find_zone_id(areaName)
|
|
if generalized_zone_id not in all_trainers.keys():
|
|
all_trainers[generalized_zone_id] = [zone_trainer]
|
|
else:
|
|
all_trainers[generalized_zone_id].append(zone_trainer)
|
|
else:
|
|
if zone_id not in all_trainers.keys():
|
|
all_trainers[zone_id] = [zone_trainer]
|
|
else:
|
|
all_trainers[zone_id].append(zone_trainer)
|
|
|
|
return all_trainers
|
|
|
|
def get_trainer_doc_data():
|
|
'''
|
|
This gets the trainer documentation for Solarnce's Trainer Docs in the Google Sheets
|
|
'''
|
|
trainer_info = process_files(os.path.join(repo_file_path, constants.SCRIPT_DATA), parse_ev_script_file)
|
|
print("Start trainer sorting by level")
|
|
sorted_trainers = sort_trainers_by_level(trainer_info)
|
|
print("Trainers have been sorted")
|
|
write_trainer_docs(sorted_trainers)
|
|
print("Done")
|
|
|
|
def get_tracker_trainer_data():
|
|
'''
|
|
This gets all of the trainer data for the tracker sorted by routes
|
|
'''
|
|
gym_leader_data = full_data['gym_leaders']
|
|
|
|
original_teams = getTrainerData(gym_leader_data)
|
|
trainer_info = process_files(os.path.join(repo_file_path, constants.SCRIPT_DATA), parse_ev_script_file)
|
|
|
|
print("Start sorting trainers by zone")
|
|
sorted_tracker_trainers = sort_trainers_by_route(trainer_info)
|
|
print("Trainers have been sorted")
|
|
new_trainers = write_tracker_docs(sorted_tracker_trainers)
|
|
mapper_trainers = write_mapper_docs(sorted_tracker_trainers)
|
|
for route in new_trainers:
|
|
original_teams["1"].append(route)
|
|
with open(os.path.join(output_file_path, 'Trainer_output.json'), 'w', encoding='utf-8') as f:
|
|
json.dump(original_teams, f, indent=2)
|
|
with open(os.path.join(output_file_path, "Mapper_Trainer_Output.json"), "w", encoding='utf-8') as f:
|
|
json.dump(mapper_trainers, f, indent=2)
|
|
|
|
if __name__ == "__main__":
|
|
start_time = time.time()
|
|
full_data = load_data()
|
|
get_trainer_doc_data()
|
|
get_tracker_trainer_data()
|
|
end_time = time.time()
|
|
print("This is how long it took to run this file:", end_time - start_time, "seconds")
|