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))