Skip to content

Instantly share code, notes, and snippets.

@Infernio
Last active April 22, 2023 21:33
Show Gist options
  • Save Infernio/1a1970a37588f782a6746ffac3e89f75 to your computer and use it in GitHub Desktop.
Save Infernio/1a1970a37588f782a6746ffac3e89f75 to your computer and use it in GitHub Desktop.
Linux/Proton alternative to 'DLC Transfer To Awakening Patch (UPDATED)' for Dragon Age: Origins by silencer711
#!/bin/python
# fix_dao_dlc.py
# License: MIT
#
# Linux/Proton alternative to 'DLC Transfer To Awakening Patch (UPDATED)' for Dragon Age: Origins by silencer711, written in Python.
# See https://www.nexusmods.com/dragonage/mods/5354 for the original.
# Original license: 'THIS MOD IS FREELY DISTRIBUTED, AND I GIVE PERMISSION TO ANYONE TO DO ANYTHING WITH IT :)', which I'm interpreting as basically CC0.
#
# WARNING: I tested this on my game and it seems to work, with the exception that some of my imported DLC items are now missing their name.
# They work fine, appear correctly on the character and give the right stats, but their names are blank when equipped and become the internal IDs when unequipped.
#
# To use it, run fix_dao_dlc.py with the path to your Steam library
# (e.g. python fix_dao_dlc.py ~/Games).
import os
import shutil
import sys
from itertools import chain
from pathlib import Path
# If True, don't perform any actual filesystem writes
DRY_RUN = False
all_dlcs = sorted(chain(
(f'dao_prc_{x}' for x in ('cp_1', 'cp_2', 'cp_3', 'cp_7', 'nrx_1')),
(f'dao_prc_promo_{x}' for x in ('1', '2', '3', '4', '5', 'c2', 'edg', 'emb', 'hod', 'lks', 'lnp', 'me', 'vgl', 'war', 'wkd', 'btk', 'pan', 'gbk')),
))
# DLCs that do not need special handling for their talktables
regular_dlcs = {f'dao_prc_{x}' for x in ('cp_1', 'cp_2', 'promo_1', 'promo_btk', 'promo_pan', 'promo_gbk')}
def main():
if len(sys.argv) < 2:
printerr('Usage: fix_dao_dlc.py <steam library>')
sys.exit(1)
steam_lib = Path(sys.argv[1]).resolve(strict=True)
all_addins = (steam_lib / 'steamapps' / 'common' / 'Dragon Age Ultimate Edition' / 'Addins',
steam_lib / 'steamapps' / 'compatdata' / '47810' / 'pfx' / 'drive_c' / 'users' / 'steamuser' / 'Documents' / 'BioWare' / 'Dragon Age' / 'AddIns')
for addin in all_addins:
for dlc in all_dlcs:
dlc_path = addin / dlc
if dlc_path.is_dir():
fix_dlc(dlc_path)
def fix_dlc(dlc_path: Path):
dlc_rel = dlc_path.name
print(f'Fixing {dlc_rel}...')
core_path = dlc_path / 'core'
module_path = dlc_path / 'module'
if not core_path.is_dir():
printerr('Error: There is no "core" folder in the AddIn?')
return
if not module_path.is_dir():
printerr('Error: There is no "module" folder in the AddIn?')
return
# Create the destination folder
dest_path = core_path / 'override' / 'DLC_FIX'
mkdir(dest_path)
# Copy over the module/data files (not dirs!)
data_path = module_path / 'data'
for data_file in data_path.iterdir():
if data_file.is_file():
cp(data_file, dest_path / data_file.name)
# Copy over all talktables files
is_regular_dlc = dlc_rel in regular_dlcs
all_tlks = list(module_path.glob('**/*.tlk'))
dest_talktables = dest_path / 'talktables'
if all_tlks:
mkdir(dest_talktables)
for source_tlk in all_tlks:
rel_tlk = source_tlk.name
if is_regular_dlc:
cp(source_tlk, dest_talktables / rel_tlk)
else:
# Mangle the filenames - no clue why, that's what the batch script did
cp(source_tlk, dest_talktables / f'{dlc_rel}_c_{rel_tlk}')
# Copy over all files (not dirs!) from audio/sound, if the DLC has such a folder
sound_path = module_path / 'audio' / 'sound'
if sound_path.is_dir():
dest_sound = dest_path / 'sound'
mkdir(dest_sound)
for sound_file in sound_path.iterdir():
if sound_file.is_file():
cp(sound_file, dest_sound / sound_file.name)
print('Fixed.')
# Some utilities
def printerr(s: str):
print(s, file=sys.stderr)
def mkdir(p: os.PathLike | str):
if DRY_RUN:
print(f'mkdir -p "{p}"')
else:
os.makedirs(p, exist_ok=True)
def cp(s: os.PathLike | str, d: os.PathLike | str):
if DRY_RUN:
print(f'cp "{s}" "{d}"')
else:
shutil.copyfile(s, d)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment