====== WEM Mapper ====== Authors: WindShadowRuins ===== Preamble ===== Put this inside python script inside your soundbank folder where the soundbank.json is located and it will generate a csv file that will tell you what Play_c and Play_s ID plays Wem files. ===== Script ===== #!/usr/bin/env python3 import json import os import csv def extract_wem_mappings(json_file): print("Starting extraction...") # Load JSON data try: with open(json_file, 'r', encoding='utf-8') as f: data = json.load(f) except json.JSONDecodeError as e: print(f"Error loading JSON: {e}") input("Press Enter to exit...") return # Extract all HIRC objects from all sections hirc_objects = [] for section in data.get("sections", []): body = section.get("body", {}) hirc = body.get("HIRC", {}) objects = hirc.get("objects", []) hirc_objects.extend(objects) print(f"Extracted {len(hirc_objects)} HIRC objects.") # Build mapping from Sound objects: # Mapping: direct_parent_id -> list of WEM source_ids parent_to_wems = {} sound_count = 0 for obj in hirc_objects: if not isinstance(obj, dict): continue sound = obj.get("body", {}).get("Sound", {}) if not isinstance(sound, dict): continue bank_source = sound.get("bank_source_data", {}) if bank_source.get("plugin") == "VORBIS": source_id = bank_source.get("media_information", {}).get("source_id") node_params = sound.get("node_base_params", {}) direct_parent_id = node_params.get("direct_parent_id") if isinstance(source_id, int) and isinstance(direct_parent_id, int): parent_to_wems.setdefault(direct_parent_id, []).append(source_id) sound_count += 1 print(f"Found {sound_count} WEM sound entries. Parent-to-WEM mapping has {len(parent_to_wems)} keys.") # Build mapping for Action objects: # Mapping: action object's id (Hash) -> external_id action_id_to_external = {} action_count = 0 for obj in hirc_objects: if not isinstance(obj, dict): continue action = obj.get("body", {}).get("Action") if isinstance(action, dict): act_hash = obj.get("id", {}).get("Hash") external_id = action.get("external_id") if isinstance(act_hash, int) and isinstance(external_id, int): action_id_to_external[act_hash] = external_id action_count += 1 print(f"Found {action_count} Action objects with external IDs.") # Extract play events (Play_c and Play_s) and determine their external_id. play_to_external = {} play_count = 0 for obj in hirc_objects: if not isinstance(obj, dict): continue play_name = obj.get("id", {}).get("String") if play_name and (play_name.startswith("Play_c") or play_name.startswith("Play_s")): event = obj.get("body", {}).get("Event") if isinstance(event, dict): actions = event.get("actions", []) found_external = None for act in actions: if isinstance(act, dict): # If action is a dict, try to get external_id directly. ext = act.get("external_id") if isinstance(ext, int): found_external = ext break elif isinstance(act, int): # If action is an integer, use it as key in our Action mapping. if act in action_id_to_external: found_external = action_id_to_external[act] break if found_external is not None: play_to_external[play_name] = found_external play_count += 1 print(f"Found {play_count} play events with external IDs.") # Build the final mapping: for each play event, match its external_id with the Sound's direct_parent_id final_mappings = [] for play, external_id in play_to_external.items(): wem_ids = parent_to_wems.get(external_id, []) wem_str = ", ".join(map(str, wem_ids)) if wem_ids else "N/A" final_mappings.append((play, external_id, wem_str)) print(f"Built final mapping for {len(final_mappings)} play events.") # Write the output to a CSV file output_file = "wem_mappings.csv" try: with open(output_file, "w", encoding="utf-8", newline="") as csvfile: writer = csv.writer(csvfile) writer.writerow(["Play Name", "External ID", "WEM Source IDs"]) for row in final_mappings: writer.writerow(row) print(f"Extraction complete! Output saved to {output_file}") except Exception as e: print(f"Error writing to file: {e}") input("Press Enter to exit...") if __name__ == "__main__": json_file = "soundbank.json" if os.path.exists(json_file): extract_wem_mappings(json_file) else: print(f"Error: {json_file} not found in the current directory.") input("Press Enter to exit...")