Last active
April 8, 2023 12:11
-
-
Save swablueme/8e0f525ac2b8d4b215d31340ec390f85 to your computer and use it in GitHub Desktop.
Quick python script to generate dragon class entries in the person.xml file in the person.xml.bundle for the Fire Emblem Engage games
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from lxml import etree | |
import sys | |
import copy | |
# enables utf-8 printing | |
sys.stdout.reconfigure(encoding='utf-8') | |
class CONSTANTS: | |
# Units to make able to transform into a fell dragon | |
# see https://docs.google.com/spreadsheets/d/1qFcABi455ZzLh0Drz1yZAxat5i_GWxIv3SPEDdlcZRE/edit#gid=248980928 for unit list | |
CHARACTER_SET = { | |
"Alear": "PID_リュール", | |
"Vander": "PID_ヴァンドレ", | |
"Clanne": "PID_クラン", | |
"Framme": "PID_フラン", | |
"Alfred": "PID_アルフレッド", | |
"Etie": "PID_エーティエ", | |
"Boucheron": "PID_ブシュロン", | |
"Céline": "PID_セリーヌ", | |
"Chloé": "PID_クロエ", | |
"Louis": "PID_ルイ", | |
"Yunaka": "PID_ユナカ", | |
"Alcryst": "PID_スタルーク", | |
"Citrinne": "PID_シトリニカ", | |
"Lapis": "PID_ラピス", | |
"Diamant": "PID_ディアマンド", | |
"Amber": "PID_アンバー", | |
"Jade": "PID_ジェーデ", | |
"Ivy": "PID_アイビー", | |
"Kagetsu": "PID_カゲツ", | |
"Zelkov": "PID_ゼルコバ", | |
"Fogado": "PID_フォガート", | |
"Pandreo": "PID_パンドロ", | |
"Bunet": "PID_ボネ", | |
"Timerra": "PID_ミスティラ", | |
"Panette": "PID_パネトネ", | |
"Merrin": "PID_メリン", | |
"Hortensia": "PID_オルテンシア", | |
"Seadall": "PID_セアダス", | |
"Rosado": "PID_ロサード", | |
"Goldmary": "PID_ゴルドマリー", | |
"Lindon": "PID_リンデン", | |
"Saphir": "PID_ザフィーア", | |
"Hyacinth": "PID_ハイアシンス", | |
"Veyle": "PID_ヴェイル", | |
"Zephia": "PID_セピア", | |
"Griss": "PID_グリ", | |
"Mauvier": "PID_モーヴ", | |
"Marni": "PID_マロン", | |
"Anna": "PID_アンナ", | |
"Jean": "PID_ジャン", | |
"Zelestia": "PID_セレスティア", | |
"Gregory": "PID_グレゴリー", | |
"Madeline": "PID_マデリーン" | |
} | |
FELL_DRAGON_CLASSES = {"Nel": {"Jid": "JID_裏邪竜ノ娘", "AID": "AID_エル竜化"}, | |
"Nil": {"Jid": "JID_裏邪竜ノ子", "AID": "AID_ラファール竜化"} | |
} | |
def open_file(file: str) -> object: | |
# Opens up an xml file | |
with open(file, 'r', encoding='utf-8') as xml_file: | |
xml_tree = etree.parse(xml_file) | |
return xml_tree.getroot() | |
def create_parameter(character: object) -> object: | |
TRANSFORMED = "竜化" | |
dragonified_character = etree.Element("Param") | |
for attribute in character: | |
if attribute in ["Pid", "Fid"]: | |
# add the transformed pids | |
dragonified_character.set( | |
attribute, character[attribute] + "_" + TRANSFORMED) | |
elif attribute == "Aid": | |
# add a transformed AID | |
# set to El aka Nel's dragon asset ID (the blue dragon) | |
dragonified_character.set( | |
attribute, CONSTANTS.FELL_DRAGON_CLASSES["Nel"]["AID"]) | |
elif attribute == "Jid": | |
# sets the job id to a dragon class. in testing, this | |
# had no specific impact | |
dragonified_character.set( | |
attribute, CONSTANTS.FELL_DRAGON_CLASSES["Nel"]["Jid"]) | |
else: | |
# otherwise we want to clone a copy of the non dragonified attribute | |
dragonified_character.set(attribute, character[attribute]) | |
return dragonified_character | |
if __name__ == "__main__": | |
# person.xml refers to a 2.0.0 person xml extracted from a person.xml.bundle | |
# file via UABE | |
root = open_file( | |
"person.xml") | |
# select every Param in Data in the Person.xml | |
data_load = root.findall('./Sheet/Data//Param') | |
NUMBER_PARAM_ELEMENTS_IN_DATA_TOTAL = len(data_load) | |
# add characters that we want to be able to transform | |
# into a dictionary called found_character_parameters | |
found_character_parameters = {} | |
for child in data_load: | |
pid = child.attrib["Pid"] | |
if pid in CONSTANTS.CHARACTER_SET.values(): | |
if pid not in found_character_parameters: | |
found_character_parameters[pid] = copy.deepcopy(child.attrib) | |
# The entries that are found in the xml should match | |
if len(CONSTANTS.CHARACTER_SET) != len(found_character_parameters): | |
raise Exception( | |
"Person.xml is missing characters that we expect to see!") | |
# insert dragon forms after the last element, preventing potential issues | |
# if like the asset table it cares about the order | |
last_ele = root.findall("./Sheet/Data//Param")[-1] | |
for character_pid, param_details in found_character_parameters.items(): | |
last_ele.addnext(create_parameter(param_details)) | |
NUMBER_PARAM_ELEMENTS_AFTER_EDIT = root.findall('./Sheet/Data//Param') | |
# ensure that the correct number of elements have been inserted into the xml | |
if len(CONSTANTS.CHARACTER_SET) + NUMBER_PARAM_ELEMENTS_IN_DATA_TOTAL != len(NUMBER_PARAM_ELEMENTS_AFTER_EDIT): | |
raise Exception( | |
"Person.xml (generated) is missing elements that should be there!") | |
# makes the new entries line up nicely | |
etree.indent(root) | |
# creates the output xml with the changed dragon entries that needs to be inserted into the person.xml.bundle in UABE | |
FILENAME = "personxml_edited.xml" | |
if os.path.exists(FILENAME): | |
os.remove(FILENAME) | |
with open(FILENAME, 'wb') as file: | |
file.write(etree.tostring(root, encoding='UTF-8', pretty_print=True)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment