Skip to content

Instantly share code, notes, and snippets.

@swablueme
Last active April 8, 2023 12:11
Show Gist options
  • Save swablueme/8e0f525ac2b8d4b215d31340ec390f85 to your computer and use it in GitHub Desktop.
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
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