#!/usr/bin/env python3 """ scan_scenes.py -- inventory the .SCN files in sda4\HPDAVE: search paths, entities, spline/event refs, and how many of the referenced objects resolve against surviving files (checked with the shipped loader's extensions: .BGF/.BMF/.BSL/.TGA/.VTX, plus .B2Z which staging exposes as .BGF). python scan_scenes.py """ import os, re, glob SRC = r"s:\OneDrive\Tesla III\DaveMcCoy\sda4" HP = os.path.join(SRC, "HPDAVE") LOAD_EXTS = ('.BGF', '.B2Z', '.BMF', '.BSL', '.VTX') def build_index(dirs): idx = {} for d in dirs: if not os.path.isdir(d): continue for f in os.listdir(d): base, ext = os.path.splitext(f.upper()) if ext in LOAD_EXTS: idx.setdefault(base, set()).add(ext) return idx def main(): for scn in sorted(glob.glob(os.path.join(HP, "*.SCN"))): try: text = open(scn, encoding='latin1').read() except OSError: continue lines = [l.split('//')[0].strip() for l in text.splitlines()] geo_paths, statics, dynamics, spls, other = [], [], [], [], [] for l in lines: if not l: continue t = l.split() kw = t[0].upper() if kw == 'GEOMETRY' and len(t) > 1: geo_paths.append(t[1]) elif kw == 'STATIC' and len(t) > 1: statics.append(t[1].lower()) elif kw in ('DYNAMIC', 'PATH') and len(t) > 1: dynamics.append(t[1].lower()) for x in t[2:]: if x.lower().endswith('.spl'): spls.append(x.lower()) elif kw in ('SPECIALFX', 'SCROLL', 'NOVIEWMATRIX'): if kw == 'NOVIEWMATRIX' and len(t) > 1: statics.append(t[1].lower()) # resolve search dirs relative to HPDAVE dirs = [os.path.normpath(os.path.join(HP, p.replace('\\', os.sep))) for p in geo_paths] idx = build_index(dirs) names = statics + dynamics uniq = sorted(set(names)) found = [n for n in uniq if n.upper().split(':')[-1] in idx] missing = [n for n in uniq if n.upper().split(':')[-1] not in idx] spl_ok = sum(1 for s in set(spls) if os.path.exists(os.path.join(HP, s))) size = os.path.getsize(scn) pct = (100 * len(found) // len(uniq)) if uniq else 0 print(f"{os.path.basename(scn):14} {size:6}B paths={','.join(geo_paths) or '-'}") print(f" entities: {len(names):3} ({len(uniq)} unique) resolvable: {len(found)}/{len(uniq)} ({pct}%)" f" splines: {spl_ok}/{len(set(spls))}") if missing: print(f" missing: {', '.join(missing[:12])}{' ...' if len(missing) > 12 else ''}") print() print("note: resolvable = name found (any loadable ext) in the scene's own GEOMETRY search") print(" dirs on the archive drive; staging exposes .B2Z as .BGF the same way.") if __name__ == '__main__': main()