|
| 1 | +"""Creates the subset of assets needed for an input FGD to work. |
| 2 | +""" |
| 3 | +from __future__ import annotations |
| 4 | +from pathlib import Path |
| 5 | +import argparse |
| 6 | +import sys |
| 7 | +import os |
| 8 | + |
| 9 | +from srctools.fgd import ( |
| 10 | + FGD, AutoVisgroup, EntAttribute, EntityDef, EntityTypes, Helper, HelperExtAppliesTo, |
| 11 | + HelperTypes, KVDef, Snippet, ValueTypes, match_tags, validate_tags, |
| 12 | +) |
| 13 | +from srctools.filesys import File, RawFileSystem |
| 14 | +from srctools.packlist import PackList |
| 15 | + |
| 16 | + |
| 17 | +def action_build(input_path: Path, output_path: Path, asset_path: Path) -> None: |
| 18 | + |
| 19 | + # Import the FGD |
| 20 | + fgd_fsys = RawFileSystem(str(input_path.parent)) |
| 21 | + asset_fsys = RawFileSystem(str(asset_path)) |
| 22 | + fgd = FGD() |
| 23 | + fgd.parse_file(fgd_fsys, fgd_fsys[str(input_path)], eval_bases=False, eval_extensions=False, encoding='iso-8859-1') |
| 24 | + pack = PackList(asset_fsys) |
| 25 | + |
| 26 | + # Iterate over all entries, build a list of assets |
| 27 | + for classname in fgd.entities: |
| 28 | + ent = fgd.entities[classname] |
| 29 | + for helper in ent.helpers: |
| 30 | + for resource in helper.get_resources(ent): |
| 31 | + pack.pack_file(resource) |
| 32 | + |
| 33 | + # Evaluate everything we needed for these helper's resources |
| 34 | + pack.eval_dependencies() |
| 35 | + |
| 36 | + # Output all the files we can to our new output |
| 37 | + for file in pack._files.values(): |
| 38 | + try: |
| 39 | + sys_file = asset_fsys[file.filename] |
| 40 | + except FileNotFoundError: |
| 41 | + print(f'WARNING: "{file.filename}" not packed!') |
| 42 | + continue |
| 43 | + |
| 44 | + print(file.filename) |
| 45 | + with sys_file.open_bin() as f: |
| 46 | + data = f.read() |
| 47 | + new_path = Path(os.path.join(str(output_path), file.filename)) |
| 48 | + new_path.parent.mkdir(parents=True, exist_ok=True) |
| 49 | + with open(new_path, "wb") as out: |
| 50 | + out.write(data) |
| 51 | + |
| 52 | + |
| 53 | +def main(args: list[str] | None = None) -> None: |
| 54 | + """Entry point.""" |
| 55 | + parser = argparse.ArgumentParser( |
| 56 | + description="Build a set of assets from an input FGD.", |
| 57 | + ) |
| 58 | + |
| 59 | + parser.add_argument( |
| 60 | + "-i", "--input", |
| 61 | + help="The FGD to read from." |
| 62 | + ) |
| 63 | + parser.add_argument( |
| 64 | + "-o", "--output", |
| 65 | + help="Output folder", |
| 66 | + ) |
| 67 | + parser.add_argument( |
| 68 | + "-a", "--assets", |
| 69 | + help="Assets folder", |
| 70 | + ) |
| 71 | + result = parser.parse_args(args) |
| 72 | + |
| 73 | + if result.input is None or result.output is None or result.assets is None: |
| 74 | + parser.print_help() |
| 75 | + return |
| 76 | + |
| 77 | + input_path = Path(result.input).resolve() |
| 78 | + output_path = Path(result.output).resolve() |
| 79 | + output_path.mkdir(parents=True, exist_ok=True) |
| 80 | + asset_path = Path(result.assets).resolve() |
| 81 | + |
| 82 | + action_build(input_path, output_path, asset_path) |
| 83 | + |
| 84 | +if __name__ == '__main__': |
| 85 | + main(sys.argv[1:]) |
0 commit comments