From 4518675915eb9579cc22f465bcd12bb786035217 Mon Sep 17 00:00:00 2001 From: Steven Garcia Date: Mon, 21 Oct 2024 08:12:02 -0500 Subject: [PATCH] Lightmap tag writer/parser work and fix split string error Also start importing scenario resources --- .../file_tag/build_scene/build_lightmap.py | 5 +- .../build_scene/generate_h2_scenario.py | 264 +++++++++- .../file_scenario_ai_resource/process_file.py | 136 ++++++ .../file_scenario_bipeds_resource/format.py | 36 ++ .../process_file.py | 108 +++++ .../process_file.py | 74 +++ .../process_file.py | 78 +++ .../process_file.py | 70 +++ .../file_scenario_creature_resource/format.py | 36 ++ .../process_file.py | 103 ++++ .../process_file.py | 72 +++ .../process_file.py | 72 +++ .../file_scenario_devices_resource/format.py | 38 ++ .../process_file.py | 91 ++++ .../format.py | 36 ++ .../process_file.py | 106 ++++ .../file_scenario_lights_resource/format.py | 36 ++ .../process_file.py | 107 +++++ .../file_scenario_scenery_resource/format.py | 207 +------- .../process_file.py | 315 ++---------- .../format.py | 36 ++ .../process_file.py | 106 ++++ .../process_file.py | 69 +++ .../build_asset.py | 453 ++++++++++++------ .../format.py | 12 +- .../process_file.py | 48 +- .../process_file.py | 72 +++ .../file_scenario_vehicles_resource/format.py | 36 ++ .../process_file.py | 110 +++++ .../file_scenario_weapons_resource/format.py | 36 ++ .../process_file.py | 110 +++++ io_scene_halo/global_functions/parse_tags.py | 129 +++++ io_scene_halo/global_functions/tag_format.py | 40 +- 33 files changed, 2570 insertions(+), 677 deletions(-) create mode 100644 io_scene_halo/file_tag/h2/file_scenario_ai_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_bipeds_resource/format.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_bipeds_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_cinematics_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_cluster_data_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_comments_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_creature_resource/format.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_creature_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_decals_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_decorators_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_devices_resource/format.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_devices_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_equipment_resource/format.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_equipment_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_lights_resource/format.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_lights_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_sound_scenery_resource/format.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_sound_scenery_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_structure_lighting_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_trigger_volumes_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_vehicles_resource/format.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_vehicles_resource/process_file.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_weapons_resource/format.py create mode 100644 io_scene_halo/file_tag/h2/file_scenario_weapons_resource/process_file.py diff --git a/io_scene_halo/file_tag/build_scene/build_lightmap.py b/io_scene_halo/file_tag/build_scene/build_lightmap.py index c01a8dc05..8abae1910 100644 --- a/io_scene_halo/file_tag/build_scene/build_lightmap.py +++ b/io_scene_halo/file_tag/build_scene/build_lightmap.py @@ -153,12 +153,11 @@ def process_mesh(SBSP_ASSET, random_color_gen, tag_block, poop_name, material_co if mat is None: mat = bpy.data.materials.new(name=material_name) - if not material_name in mesh.materials.keys(): + if not mat in mesh.materials.values(): mesh.materials.append(mat) mat.diffuse_color = random_color_gen.next() - material_index = mesh.materials.keys().index(material_name) - + material_index = mesh.materials.values().index(mat) for triangle_idx in range(triangle_length): mesh.polygons[triangle_start + triangle_idx].material_index = material_index diff --git a/io_scene_halo/file_tag/build_scene/generate_h2_scenario.py b/io_scene_halo/file_tag/build_scene/generate_h2_scenario.py index eb43adae5..ef938f25c 100644 --- a/io_scene_halo/file_tag/build_scene/generate_h2_scenario.py +++ b/io_scene_halo/file_tag/build_scene/generate_h2_scenario.py @@ -436,6 +436,251 @@ def generate_trigger_volumes(context, level_root, collection_name, tag_block): asset_collection.objects.link(ob) +def scenario_get_resources(H2_ASSET, report): + ai_resource = None + bipeds_resource = None + cinematics_resource = None + cluster_data_resource = None + comments_resource = None + creature_resource = None + decals_resource = None + decorators_resource = None + devices_resource = None + equipment_resource = None + lights_resource = None + scenery_resource = None + sound_scenery_resource = None + structure_lighting_resource = None + trigger_volumes_resource = None + vehicles_resource = None + weapons_resource = None + for scenario_reference in H2_ASSET.scenario_resources: + for reference in scenario_reference.references: + if reference.tag_group == "ai**": + ai_resource = reference + elif reference.tag_group == "*ipd": + bipeds_resource = reference + elif reference.tag_group == "cin*": + cinematics_resource = reference + elif reference.tag_group == "clu*": + cluster_data_resource = reference + elif reference.tag_group == "/**/": + comments_resource = reference + elif reference.tag_group == "*rea": + creature_resource = reference + elif reference.tag_group == "dec*": + decals_resource = reference + elif reference.tag_group == "dc*s": + decorators_resource = reference + elif reference.tag_group == "dgr*": + devices_resource = reference + elif reference.tag_group == "*qip": + equipment_resource = reference + elif reference.tag_group == "*igh": + lights_resource = reference + elif reference.tag_group == "*cen": + scenery_resource = reference + elif reference.tag_group == "*sce": + sound_scenery_resource = reference + elif reference.tag_group == "sslt": + structure_lighting_resource = reference + elif reference.tag_group == "trg*": + trigger_volumes_resource = reference + elif reference.tag_group == "*ehi": + vehicles_resource = reference + elif reference.tag_group == "*eap": + weapons_resource = reference + for reference in scenario_reference.ai_resources: + if reference.tag_group == "ai**": + ai_resource = reference + elif reference.tag_group == "*ipd": + bipeds_resource = reference + elif reference.tag_group == "cin*": + cinematics_resource = reference + elif reference.tag_group == "clu*": + cluster_data_resource = reference + elif reference.tag_group == "/**/": + comments_resource = reference + elif reference.tag_group == "*rea": + creature_resource = reference + elif reference.tag_group == "dec*": + decals_resource = reference + elif reference.tag_group == "dc*s": + decorators_resource = reference + elif reference.tag_group == "dgr*": + devices_resource = reference + elif reference.tag_group == "*qip": + equipment_resource = reference + elif reference.tag_group == "*igh": + lights_resource = reference + elif reference.tag_group == "*cen": + scenery_resource = reference + elif reference.tag_group == "*sce": + sound_scenery_resource = reference + elif reference.tag_group == "sslt": + structure_lighting_resource = reference + elif reference.tag_group == "trg*": + trigger_volumes_resource = reference + elif reference.tag_group == "*ehi": + vehicles_resource = reference + elif reference.tag_group == "*eap": + weapons_resource = reference + + if ai_resource: + RESOURCE_ASSET = parse_tag(ai_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.style_palette = RESOURCE_ASSET.style_palette + H2_ASSET.squad_groups = RESOURCE_ASSET.squad_groups + H2_ASSET.squads = RESOURCE_ASSET.squads + H2_ASSET.zones = RESOURCE_ASSET.zones + H2_ASSET.character_palette = RESOURCE_ASSET.character_palette + H2_ASSET.ai_animation_references = RESOURCE_ASSET.ai_animation_references + H2_ASSET.ai_script_references = RESOURCE_ASSET.ai_script_references + H2_ASSET.ai_recording_references = RESOURCE_ASSET.ai_recording_references + H2_ASSET.ai_conversations = RESOURCE_ASSET.ai_conversations + H2_ASSET.scripting_data = RESOURCE_ASSET.scripting_data + H2_ASSET.orders = RESOURCE_ASSET.orders + H2_ASSET.triggers = RESOURCE_ASSET.triggers + H2_ASSET.structure_bsps = RESOURCE_ASSET.structure_bsps + H2_ASSET.weapon_palette = RESOURCE_ASSET.weapon_palette + H2_ASSET.vehicle_palette = RESOURCE_ASSET.vehicle_palette + H2_ASSET.vehicles = RESOURCE_ASSET.vehicles + H2_ASSET.mission_scenes = RESOURCE_ASSET.mission_scenes + H2_ASSET.flocks = RESOURCE_ASSET.flocks + H2_ASSET.trigger_volumes = RESOURCE_ASSET.trigger_volumes + + if bipeds_resource: + RESOURCE_ASSET = parse_tag(bipeds_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.object_names = RESOURCE_ASSET.object_names + H2_ASSET.structure_bsps = RESOURCE_ASSET.structure_bsps + H2_ASSET.biped_palette = RESOURCE_ASSET.biped_palette + H2_ASSET.bipeds = RESOURCE_ASSET.bipeds + H2_ASSET.editor_folders = RESOURCE_ASSET.editor_folders + + if cinematics_resource: + RESOURCE_ASSET = parse_tag(cinematics_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.cutscene_flags = RESOURCE_ASSET.cutscene_flags + H2_ASSET.cutscene_camera_points = RESOURCE_ASSET.cutscene_camera_points + H2_ASSET.recorded_animations = RESOURCE_ASSET.recorded_animations + + if cluster_data_resource: + RESOURCE_ASSET = parse_tag(cluster_data_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.scenario_cluster_data = RESOURCE_ASSET.scenario_cluster_data + H2_ASSET.background_sound_palette = RESOURCE_ASSET.background_sound_palette + H2_ASSET.sound_environment_palette = RESOURCE_ASSET.sound_environment_palette + H2_ASSET.weather_palette = RESOURCE_ASSET.weather_palette + H2_ASSET.atmospheric_fog_palette = RESOURCE_ASSET.atmospheric_fog_palette + + if comments_resource: + RESOURCE_ASSET = parse_tag(comments_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.comments = RESOURCE_ASSET.comments + + if creature_resource: + RESOURCE_ASSET = parse_tag(creature_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.object_names = RESOURCE_ASSET.object_names + H2_ASSET.structure_bsps = RESOURCE_ASSET.structure_bsps + H2_ASSET.creatures_palette = RESOURCE_ASSET.creatures_palette + H2_ASSET.creatures = RESOURCE_ASSET.creatures + H2_ASSET.editor_folders = RESOURCE_ASSET.editor_folders + + if decals_resource: + RESOURCE_ASSET = parse_tag(decals_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.decal_palette = RESOURCE_ASSET.decal_palette + H2_ASSET.decals = RESOURCE_ASSET.decals + + if decorators_resource: + RESOURCE_ASSET = parse_tag(decorators_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.decorators = RESOURCE_ASSET.decorators + H2_ASSET.decorator_palette = RESOURCE_ASSET.decorator_palette + + if devices_resource: + RESOURCE_ASSET = parse_tag(devices_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.object_names = RESOURCE_ASSET.object_names + H2_ASSET.structure_bsps = RESOURCE_ASSET.structure_bsps + H2_ASSET.device_groups = RESOURCE_ASSET.device_groups + H2_ASSET.device_machines = RESOURCE_ASSET.device_machines + H2_ASSET.device_machine_palette = RESOURCE_ASSET.device_machine_palette + H2_ASSET.device_controls = RESOURCE_ASSET.device_controls + H2_ASSET.device_control_palette = RESOURCE_ASSET.device_control_palette + H2_ASSET.device_light_fixtures = RESOURCE_ASSET.device_light_fixtures + H2_ASSET.device_light_fixtures_palette = RESOURCE_ASSET.device_light_fixtures_palette + H2_ASSET.editor_folders = RESOURCE_ASSET.editor_folders + + if equipment_resource: + RESOURCE_ASSET = parse_tag(equipment_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.object_names = RESOURCE_ASSET.object_names + H2_ASSET.structure_bsps = RESOURCE_ASSET.structure_bsps + H2_ASSET.equipment_palette = RESOURCE_ASSET.equipment_palette + H2_ASSET.equipment = RESOURCE_ASSET.equipment + H2_ASSET.editor_folders = RESOURCE_ASSET.editor_folders + + if lights_resource: + RESOURCE_ASSET = parse_tag(lights_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.object_names = RESOURCE_ASSET.object_names + H2_ASSET.structure_bsps = RESOURCE_ASSET.structure_bsps + H2_ASSET.light_volume_palette = RESOURCE_ASSET.light_volume_palette + H2_ASSET.light_volumes = RESOURCE_ASSET.light_volumes + H2_ASSET.editor_folders = RESOURCE_ASSET.editor_folders + + if scenery_resource: + RESOURCE_ASSET = parse_tag(lights_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.object_names = RESOURCE_ASSET.object_names + H2_ASSET.structure_bsps = RESOURCE_ASSET.structure_bsps + H2_ASSET.scenery_palette = RESOURCE_ASSET.scenery_palette + H2_ASSET.scenery = RESOURCE_ASSET.scenery + H2_ASSET.crates_palette = RESOURCE_ASSET.crates_palette + H2_ASSET.crates = RESOURCE_ASSET.crates + H2_ASSET.editor_folders = RESOURCE_ASSET.editor_folders + + if sound_scenery_resource: + RESOURCE_ASSET = parse_tag(sound_scenery_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.object_names = RESOURCE_ASSET.object_names + H2_ASSET.structure_bsps = RESOURCE_ASSET.structure_bsps + H2_ASSET.sound_scenery_palette = RESOURCE_ASSET.sound_scenery_palette + H2_ASSET.sound_scenery = RESOURCE_ASSET.sound_scenery + H2_ASSET.editor_folders = RESOURCE_ASSET.editor_folders + + if structure_lighting_resource: + RESOURCE_ASSET = parse_tag(structure_lighting_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.structure_bsp_lighting = RESOURCE_ASSET.structure_bsp_lighting + + if trigger_volumes_resource: + RESOURCE_ASSET = parse_tag(trigger_volumes_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.trigger_volumes = RESOURCE_ASSET.trigger_volumes + H2_ASSET.object_names = RESOURCE_ASSET.object_names + + if vehicles_resource: + RESOURCE_ASSET = parse_tag(vehicles_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.object_names = RESOURCE_ASSET.object_names + H2_ASSET.structure_bsps = RESOURCE_ASSET.structure_bsps + H2_ASSET.vehicle_palette = RESOURCE_ASSET.vehicle_palette + H2_ASSET.vehicles = RESOURCE_ASSET.vehicles + H2_ASSET.editor_folders = RESOURCE_ASSET.editor_folders + + if weapons_resource: + RESOURCE_ASSET = parse_tag(weapons_resource, report, "halo2", "retail") + if not RESOURCE_ASSET == None: + H2_ASSET.object_names = RESOURCE_ASSET.object_names + H2_ASSET.structure_bsps = RESOURCE_ASSET.structure_bsps + H2_ASSET.weapon_palette = RESOURCE_ASSET.weapon_palette + H2_ASSET.weapons = RESOURCE_ASSET.weapons + H2_ASSET.editor_folders = RESOURCE_ASSET.editor_folders + def generate_scenario_scene(context, H2_ASSET, game_version, game_title, file_version, fix_rotations, empty_markers, report): random_color_gen = global_functions.RandomColorGenerator() # generates a random sequence of colors levels_collection = bpy.data.collections.get("BSPs") @@ -480,26 +725,13 @@ def generate_scenario_scene(context, H2_ASSET, game_version, game_title, file_ve level_root = bpy.data.objects.new("frame_root", level_mesh) context.collection.objects.link(level_root) - scenery_resource = None - for scenario_reference in H2_ASSET.scenario_resources: - for reference in scenario_reference.references: - if reference.tag_group == "*cen": - scenery_resource = reference - + scenario_get_resources(H2_ASSET, report) if len(H2_ASSET.skies) > 0: generate_skies(context, level_root, H2_ASSET.skies, report) if len(H2_ASSET.comments) > 0: generate_comments(context, level_root, H2_ASSET.comments) if len(H2_ASSET.scenery) > 0: - scenery_palette = H2_ASSET.scenery_palette - scenery = H2_ASSET.scenery - if scenery_resource: - SCENERY_RESOURCE_ASSET = parse_tag(scenery_resource, report, "halo2", "retail") - if not SCENERY_RESOURCE_ASSET == None: - scenery_palette = SCENERY_RESOURCE_ASSET.scenery_palette - scenery = SCENERY_RESOURCE_ASSET.scenery - - generate_object_elements(level_root, "Scenery", scenery_palette, scenery, context, game_version, file_version, fix_rotations, report, random_color_gen) + generate_object_elements(level_root, "Scenery", H2_ASSET.scenery_palette, H2_ASSET.scenery, context, game_version, file_version, fix_rotations, report, random_color_gen) if len(H2_ASSET.bipeds) > 0: generate_object_elements(level_root, "Biped", H2_ASSET.biped_palette, H2_ASSET.bipeds, context, game_version, file_version, fix_rotations, report, random_color_gen) if len(H2_ASSET.vehicles) > 0: @@ -518,6 +750,8 @@ def generate_scenario_scene(context, H2_ASSET, game_version, game_title, file_ve generate_object_elements(level_root, "Sound Scenery", H2_ASSET.sound_scenery_palette, H2_ASSET.sound_scenery, context, game_version, file_version, fix_rotations, report, random_color_gen) if len(H2_ASSET.crates) > 0: generate_object_elements(level_root, "Crates", H2_ASSET.crates_palette, H2_ASSET.crates, context, game_version, file_version, fix_rotations, report, random_color_gen) + if len(H2_ASSET.creatures) > 0: + generate_object_elements(level_root, "Creatures", H2_ASSET.creatures_palette, H2_ASSET.creatures, context, game_version, file_version, fix_rotations, report, random_color_gen) if len(H2_ASSET.player_starting_locations) > 0: generate_empties(context, level_root, "Player Starting Locations", H2_ASSET.player_starting_locations) if len(H2_ASSET.netgame_flags) > 0: diff --git a/io_scene_halo/file_tag/h2/file_scenario_ai_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_ai_resource/process_file.py new file mode 100644 index 000000000..3e251e4a7 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_ai_resource/process_file.py @@ -0,0 +1,136 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from ..file_scenario.format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.skies_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.editor_folders_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.scenario_kill_triggers_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.style_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "style palette")) + SCENARIO.scenario_body.squad_groups_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "squad groups")) + SCENARIO.scenario_body.squads_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "squads")) + SCENARIO.scenario_body.zones_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "zones")) + SCENARIO.scenario_body.character_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "character palette")) + SCENARIO.scenario_body.ai_animation_references_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "ai animation references")) + SCENARIO.scenario_body.ai_script_references_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "ai script references")) + SCENARIO.scenario_body.ai_recording_references_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "ai recording references")) + SCENARIO.scenario_body.ai_conversations_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "ai conversations")) + SCENARIO.scenario_body.scripting_data_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "scripting data")) + SCENARIO.scenario_body.orders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "orders")) + SCENARIO.scenario_body.triggers_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "triggers")) + SCENARIO.scenario_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) + SCENARIO.scenario_body.weapon_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "weapon palette")) + SCENARIO.scenario_body.vehicle_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "vehicles palette")) + SCENARIO.scenario_body.vehicles_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "vehicles")) + SCENARIO.scenario_body.mission_scenes_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "mission scenes")) + SCENARIO.scenario_body.flocks_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "flocks")) + SCENARIO.scenario_body.trigger_volumes_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "trigger volumes")) + +def read_vehicles(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.vehicle_palette_tag_block.count, "vehicles palette", SCENARIO.vehicle_palette_header, SCENARIO.vehicle_palette, tag_node, TAG) + if SCENARIO.scenario_body.vehicles_tag_block.count > 0: + SCENARIO.vehicles_header = TAG.TagBlockHeader().read(input_stream, TAG) + vehicle_node = tag_format.get_xml_node(XML_OUTPUT, SCENARIO.scenario_body.vehicles_tag_block.count, tag_node, "name", "vehicles") + for vehicle_idx in range(SCENARIO.scenario_body.vehicles_tag_block.count): + vehicle_element_node = None + if XML_OUTPUT: + vehicle_element_node = TAG.xml_doc.createElement('element') + vehicle_element_node.setAttribute('index', str(vehicle_idx)) + vehicle_node.appendChild(vehicle_element_node) + + SCENARIO.vehicles.append(process_scenario.get_units(input_stream, SCENARIO, TAG, vehicle_element_node, SCENARIO.scenario_body.vehicle_palette_tag_block.count, "scenario_vehicle_palette_block")) + + for vehicle_idx, vehicle in enumerate(SCENARIO.vehicles): + vehicle_element_node = None + if XML_OUTPUT: + vehicle_element_node = vehicle_node.childNodes[vehicle_idx] + + vehicle.sobj_header = TAG.TagBlockHeader().read(input_stream, TAG) + vehicle.obj0_header = TAG.TagBlockHeader().read(input_stream, TAG) + vehicle.sper_header = TAG.TagBlockHeader().read(input_stream, TAG) + if vehicle.variant_name_length > 0: + vehicle.variant_name = TAG.read_variable_string_no_terminator(input_stream, vehicle.variant_name_length, TAG, tag_format.XMLData(vehicle_element_node, "variant name")) + + vehicle.sunt_header = TAG.TagBlockHeader().read(input_stream, TAG) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_style_palette(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_squad_groups(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_squads(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_zones(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_character_palette(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_ai_animation_references(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_ai_script_references(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_ai_recording_references(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_ai_conversations(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_scripting_data(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_orders(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_triggers(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsps(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.weapon_palette_tag_block.count, "weapon palette", SCENARIO.weapon_palette_header, SCENARIO.weapon_palette, tag_node, TAG) + read_vehicles(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_mission_scenes(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_flocks(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_trigger_volumes(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_bipeds_resource/format.py b/io_scene_halo/file_tag/h2/file_scenario_bipeds_resource/format.py new file mode 100644 index 000000000..64b4acba2 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_bipeds_resource/format.py @@ -0,0 +1,36 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from ..file_scenario.format import ScenarioAsset + +class ScenarioAsset(ScenarioAsset): + def __init__(self): + super().__init__() + + class ScenarioBody(ScenarioAsset.ScenarioBody): + def __init__(self, next_object_id_salt=0): + super().__init__() + self.next_object_id_salt = next_object_id_salt diff --git a/io_scene_halo/file_tag/h2/file_scenario_bipeds_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_bipeds_resource/process_file.py new file mode 100644 index 000000000..7e98a1ccd --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_bipeds_resource/process_file.py @@ -0,0 +1,108 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from .format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.skies_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) + SCENARIO.scenario_body.environment_objects_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "environment objects")) + SCENARIO.scenario_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) + SCENARIO.scenario_body.biped_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "bipeds palette")) + SCENARIO.scenario_body.bipeds_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "bipeds")) + SCENARIO.scenario_body.next_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next object id salt")) + SCENARIO.scenario_body.editor_folders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "editor folders")) + +def read_bipeds(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.biped_palette_tag_block.count, "bipeds palette", SCENARIO.biped_palette_header, SCENARIO.biped_palette, tag_node, TAG) + if SCENARIO.scenario_body.bipeds_tag_block.count > 0: + SCENARIO.bipeds_header = TAG.TagBlockHeader().read(input_stream, TAG) + biped_node = tag_format.get_xml_node(XML_OUTPUT, SCENARIO.scenario_body.bipeds_tag_block.count, tag_node, "name", "bipeds") + for biped_idx in range(SCENARIO.scenario_body.bipeds_tag_block.count): + biped_element_node = None + if XML_OUTPUT: + biped_element_node = TAG.xml_doc.createElement('element') + biped_element_node.setAttribute('index', str(biped_idx)) + biped_node.appendChild(biped_element_node) + + SCENARIO.bipeds.append(process_scenario.get_units(input_stream, SCENARIO, TAG, biped_element_node, SCENARIO.scenario_body.biped_palette_tag_block.count, "scenario_biped_palette_block")) + + for biped_idx, biped in enumerate(SCENARIO.bipeds): + biped_element_node = None + if XML_OUTPUT: + biped_element_node = biped_node.childNodes[biped_idx] + + biped.sobj_header = TAG.TagBlockHeader().read(input_stream, TAG) + biped.obj0_header = TAG.TagBlockHeader().read(input_stream, TAG) + biped.sper_header = TAG.TagBlockHeader().read(input_stream, TAG) + if biped.variant_name_length > 0: + biped.variant_name = TAG.read_variable_string_no_terminator(input_stream, biped.variant_name_length, TAG, tag_format.XMLData(biped_element_node, "variant name")) + + biped.sunt_header = TAG.TagBlockHeader().read(input_stream, TAG) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_environment_objects(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_object_names(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsps(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + read_bipeds(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_editor_folders(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_cinematics_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_cinematics_resource/process_file.py new file mode 100644 index 000000000..85d192d15 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_cinematics_resource/process_file.py @@ -0,0 +1,74 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from ..file_scenario.format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.cutscene_flags_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "cutscene flags")) + SCENARIO.scenario_body.cutscene_camera_points_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "cutscene camera points")) + SCENARIO.scenario_body.recorded_animations_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "recorded animations")) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_cutscene_flags(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_cutscene_camera_points(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_recorded_animations(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_cluster_data_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_cluster_data_resource/process_file.py new file mode 100644 index 000000000..f12df7b05 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_cluster_data_resource/process_file.py @@ -0,0 +1,78 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from ..file_scenario.format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.scenario_cluster_data_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "scenario cluster data")) + SCENARIO.scenario_body.background_sound_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "background sound palette")) + SCENARIO.scenario_body.sound_environment_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "sound environment palette")) + SCENARIO.scenario_body.weather_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "weather palette")) + SCENARIO.scenario_body.atmospheric_fog_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "atmospheric fog palette")) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_scenario_cluster_data(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_background_sound_palette(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_sound_environment_palette(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_weather_palette(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_atmospheric_fog_palette(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_comments_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_comments_resource/process_file.py new file mode 100644 index 000000000..0790bef3e --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_comments_resource/process_file.py @@ -0,0 +1,70 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from ..file_scenario.format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.comments_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "comments")) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_comments(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_creature_resource/format.py b/io_scene_halo/file_tag/h2/file_scenario_creature_resource/format.py new file mode 100644 index 000000000..64b4acba2 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_creature_resource/format.py @@ -0,0 +1,36 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from ..file_scenario.format import ScenarioAsset + +class ScenarioAsset(ScenarioAsset): + def __init__(self): + super().__init__() + + class ScenarioBody(ScenarioAsset.ScenarioBody): + def __init__(self, next_object_id_salt=0): + super().__init__() + self.next_object_id_salt = next_object_id_salt diff --git a/io_scene_halo/file_tag/h2/file_scenario_creature_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_creature_resource/process_file.py new file mode 100644 index 000000000..ecac81e95 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_creature_resource/process_file.py @@ -0,0 +1,103 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from .format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.skies_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) + SCENARIO.scenario_body.environment_objects_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "environment objects")) + SCENARIO.scenario_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) + SCENARIO.scenario_body.creature_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "creatures palette")) + SCENARIO.scenario_body.creatures_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "creatures")) + SCENARIO.scenario_body.next_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next object id salt")) + SCENARIO.scenario_body.editor_folders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "editor folders")) + +def read_creatures(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.creature_palette_tag_block.count, "creatures palette", SCENARIO.creatures_palette_header, SCENARIO.creatures_palette, tag_node, TAG) + if SCENARIO.scenario_body.creatures_tag_block.count > 0: + SCENARIO.creatures_header = TAG.TagBlockHeader().read(input_stream, TAG) + creatures_node = tag_format.get_xml_node(XML_OUTPUT, SCENARIO.scenario_body.creatures_tag_block.count, tag_node, "name", "creatures") + for creature_idx in range(SCENARIO.scenario_body.creatures_tag_block.count): + creature_element_node = None + if XML_OUTPUT: + creature_element_node = TAG.xml_doc.createElement('element') + creature_element_node.setAttribute('index', str(creature_idx)) + creatures_node.appendChild(creature_element_node) + + SCENARIO.creatures.append(process_scenario.get_creature(input_stream, SCENARIO, TAG, creature_element_node)) + + for creature_idx, creature in enumerate(SCENARIO.creatures): + creature_element_node = None + if XML_OUTPUT: + creature_element_node = creatures_node.childNodes[creature_idx] + + creature.sobj_header = TAG.TagBlockHeader().read(input_stream, TAG) + creature.obj0_header = TAG.TagBlockHeader().read(input_stream, TAG) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_environment_objects(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_object_names(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsps(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + read_creatures(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_editor_folders(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_decals_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_decals_resource/process_file.py new file mode 100644 index 000000000..ade4cc0a1 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_decals_resource/process_file.py @@ -0,0 +1,72 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from ..file_scenario.format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.decal_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "decal palette")) + SCENARIO.scenario_body.decals_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "decals")) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_decal_palette(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_decals(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_decorators_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_decorators_resource/process_file.py new file mode 100644 index 000000000..6b45e1231 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_decorators_resource/process_file.py @@ -0,0 +1,72 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from ..file_scenario.format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.decorators_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "decorators")) + SCENARIO.scenario_body.decorator_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "decorator palette")) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_decorators(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_decorator_palette(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_devices_resource/format.py b/io_scene_halo/file_tag/h2/file_scenario_devices_resource/format.py new file mode 100644 index 000000000..0fb96a570 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_devices_resource/format.py @@ -0,0 +1,38 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from ..file_scenario.format import ScenarioAsset + +class ScenarioAsset(ScenarioAsset): + def __init__(self): + super().__init__() + + class ScenarioBody(ScenarioAsset.ScenarioBody): + def __init__(self, next_machine_id_salt=0, next_control_id_salt=0, next_light_fixture_id_salt=0): + super().__init__() + self.next_machine_id_salt = next_machine_id_salt + self.next_control_id_salt = next_control_id_salt + self.next_light_fixture_id_salt = next_light_fixture_id_salt diff --git a/io_scene_halo/file_tag/h2/file_scenario_devices_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_devices_resource/process_file.py new file mode 100644 index 000000000..1eb230192 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_devices_resource/process_file.py @@ -0,0 +1,91 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from .format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.skies_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) + SCENARIO.scenario_body.environment_objects_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "environment objects")) + SCENARIO.scenario_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) + SCENARIO.scenario_body.device_groups_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "device groups")) + SCENARIO.scenario_body.machines_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "machines")) + SCENARIO.scenario_body.machine_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "machine palette")) + SCENARIO.scenario_body.controls_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "controls")) + SCENARIO.scenario_body.control_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "control palette")) + SCENARIO.scenario_body.light_fixtures_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "light fixtures")) + SCENARIO.scenario_body.light_fixtures_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "light fixtures palette")) + SCENARIO.scenario_body.next_machine_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next machine id salt")) + SCENARIO.scenario_body.next_control_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next control id salt")) + SCENARIO.scenario_body.next_light_fixture_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next light fixture id salt")) + SCENARIO.scenario_body.editor_folders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "editor folders")) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_environment_objects(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_object_names(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsps(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_device_groups(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_machines(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_controls(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_light_fixtures(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_editor_folders(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_equipment_resource/format.py b/io_scene_halo/file_tag/h2/file_scenario_equipment_resource/format.py new file mode 100644 index 000000000..64b4acba2 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_equipment_resource/format.py @@ -0,0 +1,36 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from ..file_scenario.format import ScenarioAsset + +class ScenarioAsset(ScenarioAsset): + def __init__(self): + super().__init__() + + class ScenarioBody(ScenarioAsset.ScenarioBody): + def __init__(self, next_object_id_salt=0): + super().__init__() + self.next_object_id_salt = next_object_id_salt diff --git a/io_scene_halo/file_tag/h2/file_scenario_equipment_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_equipment_resource/process_file.py new file mode 100644 index 000000000..2074a2e0b --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_equipment_resource/process_file.py @@ -0,0 +1,106 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from .format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.skies_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.device_groups_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) + SCENARIO.scenario_body.environment_objects_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "environment objects")) + SCENARIO.scenario_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) + SCENARIO.scenario_body.equipment_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "equipment palette")) + SCENARIO.scenario_body.equipment_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "equipment")) + SCENARIO.scenario_body.next_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next object id salt")) + SCENARIO.scenario_body.editor_folders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "editor folders")) + +def read_equipment(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.equipment_palette_tag_block.count, "equipment palette", SCENARIO.equipment_palette_header, SCENARIO.equipment_palette, tag_node, TAG) + + if SCENARIO.scenario_body.equipment_tag_block.count > 0: + SCENARIO.equipment_header = TAG.TagBlockHeader().read(input_stream, TAG) + equipment_node = tag_format.get_xml_node(XML_OUTPUT, SCENARIO.scenario_body.equipment_tag_block.count, tag_node, "name", "equipment") + for equipment_idx in range(SCENARIO.scenario_body.equipment_tag_block.count): + equipment_element_node = None + if XML_OUTPUT: + equipment_element_node = TAG.xml_doc.createElement('element') + equipment_element_node.setAttribute('index', str(equipment_idx)) + equipment_node.appendChild(equipment_element_node) + + SCENARIO.equipment.append(process_scenario.get_equipment(input_stream, SCENARIO, TAG, equipment_element_node)) + + for equipment_idx, equipment in enumerate(SCENARIO.equipment): + equipment_element_node = None + if XML_OUTPUT: + equipment_element_node = equipment_node.childNodes[equipment_idx] + + equipment.sobj_header = TAG.TagBlockHeader().read(input_stream, TAG) + equipment.obj0_header = TAG.TagBlockHeader().read(input_stream, TAG) + equipment.seqt_header = TAG.TagBlockHeader().read(input_stream, TAG) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_environment_objects(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_object_names(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsps(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + read_equipment(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_editor_folders(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_lights_resource/format.py b/io_scene_halo/file_tag/h2/file_scenario_lights_resource/format.py new file mode 100644 index 000000000..64b4acba2 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_lights_resource/format.py @@ -0,0 +1,36 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from ..file_scenario.format import ScenarioAsset + +class ScenarioAsset(ScenarioAsset): + def __init__(self): + super().__init__() + + class ScenarioBody(ScenarioAsset.ScenarioBody): + def __init__(self, next_object_id_salt=0): + super().__init__() + self.next_object_id_salt = next_object_id_salt diff --git a/io_scene_halo/file_tag/h2/file_scenario_lights_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_lights_resource/process_file.py new file mode 100644 index 000000000..a0df0893b --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_lights_resource/process_file.py @@ -0,0 +1,107 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from .format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.skies_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.device_groups_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) + SCENARIO.scenario_body.environment_objects_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "environment objects")) + SCENARIO.scenario_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) + SCENARIO.scenario_body.light_volume_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "light volume palette")) + SCENARIO.scenario_body.light_volumes_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "light volumes")) + SCENARIO.scenario_body.next_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next object id salt")) + SCENARIO.scenario_body.editor_folders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "editor folders")) + +def read_light_volumes(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.light_volume_palette_tag_block.count, "light volume palette", SCENARIO.light_volume_palette_header, SCENARIO.light_volume_palette, tag_node, TAG) + + if SCENARIO.scenario_body.light_volumes_tag_block.count > 0: + SCENARIO.light_volume_header = TAG.TagBlockHeader().read(input_stream, TAG) + light_volume_node = tag_format.get_xml_node(XML_OUTPUT, SCENARIO.scenario_body.light_volumes_tag_block.count, tag_node, "name", "light volumes") + for light_volume_idx in range(SCENARIO.scenario_body.light_volumes_tag_block.count): + light_volume_element_node = None + if XML_OUTPUT: + light_volume_element_node = TAG.xml_doc.createElement('element') + light_volume_element_node.setAttribute('index', str(light_volume_idx)) + light_volume_node.appendChild(light_volume_element_node) + + SCENARIO.light_volumes.append(process_scenario.get_light_volumes(input_stream, SCENARIO, TAG, light_volume_element_node)) + + for light_volume_idx, light_volume in enumerate(SCENARIO.light_volumes): + light_volume_element_node = None + if XML_OUTPUT: + light_volume_element_node = light_volume_node.childNodes[light_volume_idx] + + light_volume.sobj_header = TAG.TagBlockHeader().read(input_stream, TAG) + light_volume.obj0_header = TAG.TagBlockHeader().read(input_stream, TAG) + light_volume.sdvt_header = TAG.TagBlockHeader().read(input_stream, TAG) + light_volume.slit_header = TAG.TagBlockHeader().read(input_stream, TAG) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_environment_objects(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_object_names(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsps(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + read_light_volumes(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_editor_folders(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_scenery_resource/format.py b/io_scene_halo/file_tag/h2/file_scenario_scenery_resource/format.py index 0ad9e7c6e..64b4acba2 100644 --- a/io_scene_halo/file_tag/h2/file_scenario_scenery_resource/format.py +++ b/io_scene_halo/file_tag/h2/file_scenario_scenery_resource/format.py @@ -24,208 +24,13 @@ # # ##### END MIT LICENSE BLOCK ##### -from mathutils import Vector, Euler -from enum import Flag, Enum, auto +from ..file_scenario.format import ScenarioAsset -class StructureBSPFlags(Flag): - default_sky_enabled = auto() - -class ObjectFlags(Flag): - not_automatically = auto() - unused_0 = auto() - unused_1 = auto() - unused_2 = auto() - lock_type_to_env_object = auto() - lock_transform_to_env_object = auto() - never_placed = auto() - lock_name_to_env_object = auto() - create_at_rest = auto() - -class TransformFlags(Flag): - mirrored = auto() - -class ObjectTypeFlags(Enum): - biped = 0 - vehicle = auto() - weapon = auto() - equipment = auto() - garbage = auto() - projectile = auto() - scenery = auto() - machine = auto() - control = auto() - light_fixture = auto() - sound_scenery = auto() - crate = auto() - creature = auto() - -class ObjectSourceFlags(Enum): - structure = 0 - editor = auto() - dynamic = auto() - legacy = auto() - -class ObjectBSPPolicyFlags(Enum): - default = 0 - always_placed = auto() - manual_bsp_placement = auto() - -class ObjectColorChangeFlags(Flag): - primary = auto() - secondary = auto() - tertiary = auto() - quaternary = auto() - -class PathfindingPolicyEnum(Enum): - tag_default = 0 - pathfinding_dynamic = auto() - pathfinding_cut_out = auto() - pathfinding_static = auto() - pathfinding_none = auto() - -class LightmappingPolicyEnum(Enum): - tag_default = 0 - dynamic = auto() - per_vertex = auto() - -class ObjectGametypeEnum(Flag): - ctf = auto() - slayer = auto() - oddball = auto() - king = auto() - juggernaut = auto() - territories = auto() - assault = auto() - medic = auto() - vip = auto() - infection = auto() - headhunter = auto() - -class SceneryResourceAsset(): +class ScenarioAsset(ScenarioAsset): def __init__(self): - self.header = None - self.resource_body_header = None - self.resource_body = None - self.object_names_header = None - self.object_names = None - self.environment_objects_header = None - self.environment_objects = None - self.structure_bsps_header = None - self.structure_bsps = None - self.scenery_palette_header = None - self.scenery_palette = None - self.scenery_header = None - self.scenery = None - self.crate_palette_header = None - self.crate_palette = None - self.crates_header = None - self.crates = None - self.editor_folders_header = None - self.editor_folders = None + super().__init__() - class ResourceBody: - def __init__(self, object_names_tag_block=None, environment_objects_tag_block=None, structure_bsps_tag_block=None, scenery_palette_tag_block=None, scenery_tag_block=None, - next_scenery_object_id_salt=0, crate_palette_tag_block=None, crates_tag_block=None, next_block_object_id_salt=0, editor_folders_tag_block=None): - self.object_names_tag_block = object_names_tag_block - self.environment_objects_tag_block = environment_objects_tag_block - self.structure_bsps_tag_block = structure_bsps_tag_block - self.scenery_palette_tag_block = scenery_palette_tag_block - self.scenery_tag_block = scenery_tag_block - self.next_scenery_object_id_salt = next_scenery_object_id_salt - self.crate_palette_tag_block = crate_palette_tag_block - self.crates_tag_block = crates_tag_block - self.next_block_object_id_salt = next_block_object_id_salt - self.editor_folders_tag_block = editor_folders_tag_block - - class ObjectName: - def __init__(self, name="", object_type=0, placement_index=0): - self.name = name - self.object_type = object_type - self.placement_index = placement_index - - class EnvironmentObject: - def __init__(self, bsp_index=0, runtime_object_type=0, unique_id=0, object_definition_tag=0, environment_object=0): - self.bsp_index = bsp_index - self.runtime_object_type = runtime_object_type - self.unique_id = unique_id - self.object_definition_tag = object_definition_tag - self.environment_object = environment_object - - class StructureBSP(): - def __init__(self, structure_bsp=None, structure_lightmap=None, unused_radiance_estimated_search_distance=0.0, unused_luminels_per_world_unit=0.0, - unused_output_white_reference=0.0, flags=0, default_sky=0): - self.structure_bsp = structure_bsp - self.structure_lightmap = structure_lightmap - self.unused_radiance_estimated_search_distance = unused_radiance_estimated_search_distance - self.unused_luminels_per_world_unit = unused_luminels_per_world_unit - self.unused_output_white_reference = unused_output_white_reference - self.flags = flags - self.default_sky = default_sky - - class Object: - def __init__(self, palette_index=0, name_index=0, placement_flags=0, position=Vector(), rotation=Euler(), scale=0.0, transform_flags=0, manual_bsp_flags=0, unique_id=0, - origin_bsp_index=0, object_type=0, source=0, bsp_policy=0, editor_folder_index=0): - self.palette_index = palette_index - self.name_index = name_index - self.placement_flags = placement_flags - self.position = position - self.rotation = rotation - self.scale = scale - self.transform_flags = transform_flags - self.manual_bsp_flags = manual_bsp_flags - self.unique_id = unique_id - self.origin_bsp_index = origin_bsp_index - self.object_type = object_type - self.source = source - self.bsp_policy = bsp_policy - self.editor_folder_index = editor_folder_index - - class Scenery(Object): - def __init__(self, sobj_header=None, obj0_header=None, sper_header=None, sct3_header=None, variant_name="", variant_name_length=0, active_change_colors=0, - primary_color_BGRA=(0, 0, 0, 255), secondary_color_BGRA=(0, 0, 0, 255), tertiary_color_BGRA=(0, 0, 0, 255), - quaternary_color_BGRA=(0, 0, 0, 255), pathfinding_policy=0, lightmap_policy=0, pathfinding_references_header=None, pathfinding_references_tag_block=None, - valid_multiplayer_games=0, pathfinding_references=None): + class ScenarioBody(ScenarioAsset.ScenarioBody): + def __init__(self, next_object_id_salt=0): super().__init__() - self.sobj_header = sobj_header - self.obj0_header = obj0_header - self.sper_header = sper_header - self.sct3_header = sct3_header - self.variant_name = variant_name - self.variant_name_length = variant_name_length - self.active_change_colors = active_change_colors - self.primary_color_BGRA = primary_color_BGRA - self.secondary_color_BGRA = secondary_color_BGRA - self.tertiary_color_BGRA = tertiary_color_BGRA - self.quaternary_color_BGRA = quaternary_color_BGRA - self.pathfinding_policy = pathfinding_policy - self.lightmap_policy = lightmap_policy - self.pathfinding_references_header = pathfinding_references_header - self.pathfinding_references_tag_block = pathfinding_references_tag_block - self.valid_multiplayer_games = valid_multiplayer_games - self.pathfinding_references = pathfinding_references - - class PathfindingReference: - def __init__(self, bsp_index=0, pathfinding_object_index=0): - self.bsp_index = bsp_index - self.pathfinding_object_index = pathfinding_object_index - - class Crate(Object): - def __init__(self, sobj_header=None, obj0_header=None, sper_header=None, variant_name="", variant_name_length=0, active_change_colors=0, - primary_color_BGRA=(0, 0, 0, 255), secondary_color_BGRA=(0, 0, 0, 255), tertiary_color_BGRA=(0, 0, 0, 255), - quaternary_color_BGRA=(0, 0, 0, 255)): - super().__init__() - self.sobj_header = sobj_header - self.obj0_header = obj0_header - self.sper_header = sper_header - self.variant_name = variant_name - self.variant_name_length = variant_name_length - self.active_change_colors = active_change_colors - self.primary_color_BGRA = primary_color_BGRA - self.secondary_color_BGRA = secondary_color_BGRA - self.tertiary_color_BGRA = tertiary_color_BGRA - self.quaternary_color_BGRA = quaternary_color_BGRA - - class EditorFolder: - def __init__(self, parent_folder=0, name=""): - self.parent_folder = parent_folder - self.name = name + self.next_object_id_salt = next_object_id_salt diff --git a/io_scene_halo/file_tag/h2/file_scenario_scenery_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_scenery_resource/process_file.py index 4dce651d2..d11e85bcf 100644 --- a/io_scene_halo/file_tag/h2/file_scenario_scenery_resource/process_file.py +++ b/io_scene_halo/file_tag/h2/file_scenario_scenery_resource/process_file.py @@ -26,240 +26,42 @@ from xml.dom import minidom from ....global_functions import tag_format -from .format import ( - SceneryResourceAsset, - StructureBSPFlags, - ObjectFlags, - TransformFlags, - ObjectTypeFlags, - ObjectSourceFlags, - ObjectBSPPolicyFlags, - ObjectColorChangeFlags, - PathfindingPolicyEnum, - LightmappingPolicyEnum, - ObjectGametypeEnum - ) - -XML_OUTPUT = True - -def initilize_resource(RESOURCE): - RESOURCE.object_names = [] - RESOURCE.environment_objects = [] - RESOURCE.structure_bsps = [] - RESOURCE.scenery_palette = [] - RESOURCE.scenery = [] - RESOURCE.crate_palette = [] - RESOURCE.crates = [] - RESOURCE.editor_folders = [] - -def read_resource_body(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT): - RESOURCE.resource_body_header = TAG.TagBlockHeader().read(input_stream, TAG) - RESOURCE.resource_body = RESOURCE.ResourceBody() - RESOURCE.resource_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) - RESOURCE.resource_body.environment_objects_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "environment objects")) - RESOURCE.resource_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) - RESOURCE.resource_body.scenery_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "scenery palette")) - RESOURCE.resource_body.scenery_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "scenery")) - RESOURCE.resource_body.next_scenery_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next scenery object id salt")) - RESOURCE.resource_body.crate_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "crate palette")) - RESOURCE.resource_body.crates_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "crates")) - RESOURCE.resource_body.next_block_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next block object id salt")) - RESOURCE.resource_body.editor_folders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "editor folders")) - -def get_object_names(input_stream, RESOURCE, TAG, node_element): - object_name = RESOURCE.ObjectName() - object_name.name = TAG.read_string32(input_stream, TAG, tag_format.XMLData(node_element, "name")) - object_name.object_type = TAG.read_block_index_signed_short(input_stream, TAG, tag_format.XMLData(node_element, "object type", None, 1, "")) - object_name.placement_index = TAG.read_block_index_signed_short(input_stream, TAG, tag_format.XMLData(node_element, "placement index", None, 1, "")) - - return object_name - -def get_environment_objects(input_stream, RESOURCE, TAG, node_element): - environment_object = RESOURCE.EnvironmentObject() - environment_object.bsp_index = TAG.read_block_index_signed_short(input_stream, TAG, tag_format.XMLData(node_element, "bsp", None, RESOURCE.resource_body.structure_bsps_tag_block.count, "scenario_bsp_block")) - environment_object.runtime_object_type = TAG.read_signed_short(input_stream, TAG, tag_format.XMLData(node_element, "runtime object type")) - environment_object.unique_id = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(node_element, "unique id")) - input_stream.read(4) # Padding? - environment_object.object_definition_tag = TAG.read_variable_string_no_terminator_reversed(input_stream, 4, TAG, tag_format.XMLData(node_element, "object definition tag")) - environment_object.environment_object = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(node_element, "object")) - input_stream.read(44) # Padding? - - return environment_object - -def get_structure_bsp(input_stream, RESOURCE, TAG, node_element): - structure_bsp = RESOURCE.StructureBSP() - - input_stream.read(16) # Padding? - structure_bsp.structure_bsp = TAG.TagRef().read(input_stream, TAG, tag_format.XMLData(node_element, "structure bsp")) - structure_bsp.structure_lightmap = TAG.TagRef().read(input_stream, TAG, tag_format.XMLData(node_element, "structure lightmap")) - input_stream.read(4) # Padding - structure_bsp.unused_radiance_estimated_search_distance = TAG.read_float(input_stream, TAG, tag_format.XMLData(node_element, "radiance estimated search distance")) - input_stream.read(4) # Padding - structure_bsp.unused_luminels_per_world_unit = TAG.read_float(input_stream, TAG, tag_format.XMLData(node_element, "luminels per world unit")) - structure_bsp.unused_output_white_reference = TAG.read_float(input_stream, TAG, tag_format.XMLData(node_element, "output white reference")) - input_stream.read(8) # Padding - structure_bsp.flags = TAG.read_flag_unsigned_integer(input_stream, TAG, tag_format.XMLData(node_element, "flags", StructureBSPFlags)) - structure_bsp.default_sky = TAG.read_block_index_signed_short(input_stream, TAG, tag_format.XMLData(node_element, "default sky", None, 1, "scenario_skies_block")) - input_stream.read(2) # Padding - - return structure_bsp - -def object_helper(tag_element, TAG, input_stream, RESOURCE, node_element, palette_count, palette_name): - tag_element.palette_index = TAG.read_block_index_signed_short(input_stream, TAG, tag_format.XMLData(node_element, "type", None, palette_count, palette_name)) - tag_element.name_index = TAG.read_block_index_signed_short(input_stream, TAG, tag_format.XMLData(node_element, "name", None, RESOURCE.resource_body.object_names_tag_block.count, "scenario_object_names_block")) - tag_element.placement_flags = TAG.read_flag_unsigned_integer(input_stream, TAG, tag_format.XMLData(node_element, "placement flags", ObjectFlags)) - tag_element.position = TAG.read_point_3d(input_stream, TAG, tag_format.XMLData(node_element, "position")) - tag_element.rotation = TAG.read_euler_angles(input_stream, TAG, tag_format.XMLData(node_element, "rotation")) - tag_element.scale = TAG.read_float(input_stream, TAG, tag_format.XMLData(node_element, "scale")) - tag_element.transform_flags = TAG.read_flag_unsigned_short(input_stream, TAG, tag_format.XMLData(node_element, "transform flags", TransformFlags)) - tag_element.manual_bsp_flags = TAG.read_signed_short(input_stream, TAG, tag_format.XMLData(node_element, "manual bsp flags")) - tag_element.unique_id = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(node_element, "unique id")) - tag_element.origin_bsp_index = TAG.read_block_index_signed_short(input_stream, TAG, tag_format.XMLData(node_element, "origin bsp index", None, RESOURCE.resource_body.structure_bsps_tag_block.count, "scenario_bsp_block")) - tag_element.object_type = TAG.read_enum_unsigned_byte(input_stream, TAG, tag_format.XMLData(node_element, "object type", ObjectTypeFlags)) - tag_element.source = TAG.read_enum_unsigned_byte(input_stream, TAG, tag_format.XMLData(node_element, "source", ObjectSourceFlags)) - tag_element.bsp_policy = TAG.read_enum_unsigned_byte(input_stream, TAG, tag_format.XMLData(node_element, "bsp policy", ObjectBSPPolicyFlags)) - input_stream.read(1) # Padding? - tag_element.editor_folder_index = TAG.read_block_index_signed_short(input_stream, TAG, tag_format.XMLData(node_element, "editor folder", None, RESOURCE.resource_body.editor_folders_tag_block.count, "scenario_editor_folder_block")) - -def get_scenery(input_stream, RESOURCE, TAG, node_element): - scenery = RESOURCE.Scenery() - object_helper(scenery, TAG, input_stream, RESOURCE, node_element, RESOURCE.resource_body.scenery_palette_tag_block.count, "scenario_scenery_palette_block") - - TAG.big_endian = True - input_stream.read(2) # Padding? - scenery.variant_name_length = TAG.read_signed_short(input_stream, TAG) - TAG.big_endian = False - - scenery.active_change_colors = TAG.read_flag_unsigned_integer(input_stream, TAG, tag_format.XMLData(node_element, "active change colors", ObjectColorChangeFlags)) - scenery.primary_color_BGRA = TAG.read_bgr_byte(input_stream, TAG, tag_format.XMLData(node_element, "primary color")) - scenery.secondary_color_BGRA = TAG.read_bgr_byte(input_stream, TAG, tag_format.XMLData(node_element, "secondary color")) - scenery.tertiary_color_BGRA = TAG.read_bgr_byte(input_stream, TAG, tag_format.XMLData(node_element, "tertiary color")) - scenery.quaternary_color_BGRA = TAG.read_bgr_byte(input_stream, TAG, tag_format.XMLData(node_element, "quaternary color")) - scenery.pathfinding_policy = TAG.read_enum_unsigned_short(input_stream, TAG, tag_format.XMLData(node_element, "pathfinding policy", PathfindingPolicyEnum)) - scenery.lightmap_policy = TAG.read_enum_unsigned_short(input_stream, TAG, tag_format.XMLData(node_element, "lightmap policy", LightmappingPolicyEnum)) - scenery.pathfinding_references_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(node_element, "pathfinding references")) - input_stream.read(2) # Padding? - scenery.valid_multiplayer_games = TAG.read_flag_unsigned_short(input_stream, TAG, tag_format.XMLData(node_element, "valid multiplayer games", ObjectGametypeEnum)) - - return scenery - -def get_crates(input_stream, RESOURCE, TAG, node_element): - crate = RESOURCE.Crate() - object_helper(crate, TAG, input_stream, RESOURCE, node_element, RESOURCE.resource_body.crate_palette_tag_block.count, "scenario_scenery_palette_block") - - TAG.big_endian = True - input_stream.read(2) # Padding? - crate.variant_name_length = TAG.read_signed_short(input_stream, TAG) - TAG.big_endian = False - - crate.active_change_colors = TAG.read_flag_unsigned_integer(input_stream, TAG, tag_format.XMLData(node_element, "active change colors", ObjectColorChangeFlags)) - crate.primary_color_BGRA = TAG.read_bgr_byte(input_stream, TAG, tag_format.XMLData(node_element, "primary color")) - crate.secondary_color_BGRA = TAG.read_bgr_byte(input_stream, TAG, tag_format.XMLData(node_element, "secondary color")) - crate.tertiary_color_BGRA = TAG.read_bgr_byte(input_stream, TAG, tag_format.XMLData(node_element, "tertiary color")) - crate.quaternary_color_BGRA = TAG.read_bgr_byte(input_stream, TAG, tag_format.XMLData(node_element, "quaternary color")) - - return crate - -def get_palette(input_stream, TAG, node_element, padding=32): - tag_reference = TAG.TagRef().read(input_stream, TAG, tag_format.XMLData(node_element, "name")) - input_stream.read(padding) # Padding? - - return tag_reference - -def palette_helper(input_stream, palette_count, palette_name, palette_header, palette, node, TAG, padding=32): - if palette_count > 0: - palette_header = TAG.TagBlockHeader().read(input_stream, TAG) - palette_node = tag_format.get_xml_node(XML_OUTPUT, palette_count, node, "name", palette_name) - for palette_idx in range(palette_count): - palette_element_node = None - if XML_OUTPUT: - palette_element_node = TAG.xml_doc.createElement('element') - palette_element_node.setAttribute('index', str(palette_idx)) - palette_node.appendChild(palette_element_node) - - palette.append(get_palette(input_stream, TAG, palette_element_node, padding)) - - for palette_idx, palette_element in enumerate(palette): - palette_name_length = palette_element.name_length - if palette_name_length > 0: - palette_element.name = TAG.read_variable_string(input_stream, palette_name_length, TAG) - - if XML_OUTPUT: - palette_element_node = palette_node.childNodes[palette_idx] - palette_tag_ref_node = tag_format.get_xml_node(XML_OUTPUT, 1, palette_element_node, "name", "name") - palette_element.append_xml_attributes(palette_tag_ref_node) - -def read_object_names(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT): - if RESOURCE.resource_body.object_names_tag_block.count > 0: - RESOURCE.object_name_header = TAG.TagBlockHeader().read(input_stream, TAG) - object_name_node = tag_format.get_xml_node(XML_OUTPUT, RESOURCE.resource_body.object_names_tag_block.count, tag_node, "name", "object names") - for object_name_idx in range(RESOURCE.resource_body.object_names_tag_block.count): - object_name_element_node = None - if XML_OUTPUT: - object_name_element_node = TAG.xml_doc.createElement('element') - object_name_element_node.setAttribute('index', str(object_name_idx)) - object_name_node.appendChild(object_name_element_node) - - RESOURCE.object_names.append(get_object_names(input_stream, RESOURCE, TAG, object_name_element_node)) - -def read_environment_objects(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT): - if RESOURCE.resource_body.environment_objects_tag_block.count > 0: - RESOURCE.environment_objects_header = TAG.TagBlockHeader().read(input_stream, TAG) - environment_objects_node = tag_format.get_xml_node(XML_OUTPUT, RESOURCE.resource_body.environment_objects_tag_block.count, tag_node, "name", "environment objects") - for environment_object_idx in range(RESOURCE.resource_body.environment_objects_tag_block.count): - environment_object_element_node = None - if XML_OUTPUT: - environment_object_element_node = TAG.xml_doc.createElement('element') - environment_object_element_node.setAttribute('index', str(environment_object_idx)) - environment_objects_node.appendChild(environment_object_element_node) - - RESOURCE.environment_objects.append(get_environment_objects(input_stream, RESOURCE, TAG, environment_object_element_node)) - -def read_structure_bsps(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT): - if RESOURCE.resource_body.structure_bsps_tag_block.count > 0: - RESOURCE.structure_bsps_header = TAG.TagBlockHeader().read(input_stream, TAG) - structure_bsp_node = tag_format.get_xml_node(XML_OUTPUT, RESOURCE.resource_body.structure_bsps_tag_block.count, tag_node, "name", "structure bsps") - for structure_bsp_idx in range(RESOURCE.resource_body.structure_bsps_tag_block.count): - structure_bsp_element_node = None - if XML_OUTPUT: - structure_bsp_element_node = TAG.xml_doc.createElement('element') - structure_bsp_element_node.setAttribute('index', str(structure_bsp_idx)) - structure_bsp_node.appendChild(structure_bsp_element_node) - - RESOURCE.structure_bsps.append(get_structure_bsp(input_stream, RESOURCE, TAG, structure_bsp_element_node)) - - for structure_bsp_idx, structure_bsp in enumerate(RESOURCE.structure_bsps): - structure_bsp_name_length = structure_bsp.structure_bsp.name_length - structure_lightmap_name_length = structure_bsp.structure_lightmap.name_length - if structure_bsp_name_length > 0: - structure_bsp.structure_bsp.name = TAG.read_variable_string(input_stream, structure_bsp_name_length, TAG) - - if structure_lightmap_name_length > 0: - structure_bsp.structure_lightmap.name = TAG.read_variable_string(input_stream, structure_lightmap_name_length, TAG) - - if XML_OUTPUT: - structure_bsp_element_node = structure_bsp_node.childNodes[structure_bsp_idx] - structure_bsp_tag_ref_node = tag_format.get_xml_node(XML_OUTPUT, 1, structure_bsp_element_node, "name", "structure bsp") - structure_lightmap_tag_ref_node = tag_format.get_xml_node(XML_OUTPUT, 1, structure_bsp_element_node, "name", "structure lightmap") - structure_bsp.structure_bsp.append_xml_attributes(structure_bsp_tag_ref_node) - structure_bsp.structure_lightmap.append_xml_attributes(structure_lightmap_tag_ref_node) - -def read_scenery(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT): - palette_helper(input_stream, RESOURCE.resource_body.scenery_palette_tag_block.count, "scenery palette", RESOURCE.scenery_palette_header, RESOURCE.scenery_palette, tag_node, TAG) - - if RESOURCE.resource_body.scenery_tag_block.count > 0: - RESOURCE.scenery_header = TAG.TagBlockHeader().read(input_stream, TAG) - scenery_node = tag_format.get_xml_node(XML_OUTPUT, RESOURCE.resource_body.scenery_tag_block.count, tag_node, "name", "scenery") - for scenery_idx in range(RESOURCE.resource_body.scenery_tag_block.count): +from ..file_scenario import process_file as process_scenario +from .format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.skies_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) + SCENARIO.scenario_body.environment_objects_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "environment objects")) + SCENARIO.scenario_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) + SCENARIO.scenario_body.scenery_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "scenery palette")) + SCENARIO.scenario_body.scenery_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "scenery")) + SCENARIO.scenario_body.next_scenery_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next scenery object id salt")) + SCENARIO.scenario_body.crate_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "crate palette")) + SCENARIO.scenario_body.crates_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "crates")) + SCENARIO.scenario_body.next_block_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next block object id salt")) + SCENARIO.scenario_body.editor_folders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "editor folders")) + +def read_scenery(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.scenery_palette_tag_block.count, "scenery palette", SCENARIO.scenery_palette_header, SCENARIO.scenery_palette, tag_node, TAG) + + if SCENARIO.scenario_body.scenery_tag_block.count > 0: + SCENARIO.scenery_header = TAG.TagBlockHeader().read(input_stream, TAG) + scenery_node = tag_format.get_xml_node(XML_OUTPUT, SCENARIO.scenario_body.scenery_tag_block.count, tag_node, "name", "scenery") + for scenery_idx in range(SCENARIO.scenario_body.scenery_tag_block.count): scenery_element_node = None if XML_OUTPUT: scenery_element_node = TAG.xml_doc.createElement('element') scenery_element_node.setAttribute('index', str(scenery_idx)) scenery_node.appendChild(scenery_element_node) - RESOURCE.scenery.append(get_scenery(input_stream, RESOURCE, TAG, scenery_element_node)) + SCENARIO.scenery.append(process_scenario.get_scenery(input_stream, SCENARIO, TAG, scenery_element_node)) - for scenery_idx, scenery in enumerate(RESOURCE.scenery): + for scenery_idx, scenery in enumerate(SCENARIO.scenery): scenery_element_node = None if XML_OUTPUT: scenery_element_node = scenery_node.childNodes[scenery_idx] @@ -283,28 +85,28 @@ def read_scenery(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT): pathfinding_reference_element_node.setAttribute('index', str(pathfinding_reference_idx)) pathfinding_reference_node.appendChild(pathfinding_reference_element_node) - pathfinding_reference = RESOURCE.PathfindingReference() + pathfinding_reference = SCENARIO.PathfindingReference() pathfinding_reference.bsp_index = TAG.read_signed_short(input_stream, TAG, tag_format.XMLData(pathfinding_reference_element_node, "bsp index")) pathfinding_reference.pathfinding_object_index = TAG.read_signed_short(input_stream, TAG, tag_format.XMLData(pathfinding_reference_element_node, "pathfinding object index")) scenery.pathfinding_references.append(pathfinding_reference) -def read_crates(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT): - palette_helper(input_stream, RESOURCE.resource_body.crate_palette_tag_block.count, "crate palette", RESOURCE.crate_palette_header, RESOURCE.crate_palette, tag_node, TAG) +def read_crates(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.crate_palette_tag_block.count, "crate palette", SCENARIO.crates_palette_header, SCENARIO.crates_palette, tag_node, TAG) - if RESOURCE.resource_body.crates_tag_block.count > 0: - RESOURCE.crate_header = TAG.TagBlockHeader().read(input_stream, TAG) - crates_node = tag_format.get_xml_node(XML_OUTPUT, RESOURCE.resource_body.crates_tag_block.count, tag_node, "name", "crates") - for crate_idx in range(RESOURCE.resource_body.crates_tag_block.count): + if SCENARIO.scenario_body.crates_tag_block.count > 0: + SCENARIO.crates_header = TAG.TagBlockHeader().read(input_stream, TAG) + crates_node = tag_format.get_xml_node(XML_OUTPUT, SCENARIO.scenario_body.crates_tag_block.count, tag_node, "name", "crates") + for crate_idx in range(SCENARIO.scenario_body.crates_tag_block.count): crate_element_node = None if XML_OUTPUT: crate_element_node = TAG.xml_doc.createElement('element') crate_element_node.setAttribute('index', str(crate_idx)) crates_node.appendChild(crate_element_node) - RESOURCE.crates.append(get_crates(input_stream, RESOURCE, TAG, crate_element_node)) + SCENARIO.crates.append(process_scenario.get_crate(input_stream, SCENARIO, TAG, crate_element_node)) - for crate_idx, crate in enumerate(RESOURCE.crates): + for crate_idx, crate in enumerate(SCENARIO.crates): crate_element_node = None if XML_OUTPUT: crate_element_node = crates_node.childNodes[crate_idx] @@ -315,45 +117,28 @@ def read_crates(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT): if crate.variant_name_length > 0: crate.variant_name = TAG.read_variable_string_no_terminator(input_stream, crate.variant_name_length, TAG, tag_format.XMLData(crate_element_node, "variant name")) -def read_editor_folders(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT): - if RESOURCE.resource_body.editor_folders_tag_block.count > 0: - RESOURCE.editor_folders_header = TAG.TagBlockHeader().read(input_stream, TAG) - editor_folders_node = tag_format.get_xml_node(XML_OUTPUT, RESOURCE.resource_body.editor_folders_tag_block.count, tag_node, "name", "editor folders") - for editor_folder_idx in range(RESOURCE.resource_body.editor_folders_tag_block.count): - editor_folder_element_node = None - if XML_OUTPUT: - editor_folder_element_node = TAG.xml_doc.createElement('element') - editor_folder_element_node.setAttribute('index', str(editor_folder_idx)) - editor_folders_node.appendChild(editor_folder_element_node) - - editor_folder = RESOURCE.EditorFolder() - editor_folder.parent_folder = TAG.read_block_index_signed_integer(input_stream, TAG, tag_format.XMLData(editor_folder_element_node, "parent folder", None, 1, "")) - editor_folder.name = TAG.read_string256(input_stream, TAG, tag_format.XMLData(editor_folder_element_node, "name")) - - RESOURCE.editor_folders.append(editor_folder) - def process_file(input_stream, report): TAG = tag_format.TagAsset() - RESOURCE = SceneryResourceAsset() + SCENARIO = ScenarioAsset() TAG.is_legacy = False TAG.big_endian = False if XML_OUTPUT: TAG.xml_doc = minidom.Document() - RESOURCE.header = TAG.Header().read(input_stream, TAG) + SCENARIO.header = TAG.Header().read(input_stream, TAG) tag_node = None if XML_OUTPUT: tag_node = TAG.xml_doc.childNodes[0] - initilize_resource(RESOURCE) - read_resource_body(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT) - read_object_names(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT) - read_environment_objects(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT) - read_structure_bsps(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT) - read_scenery(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT) - read_crates(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT) - read_editor_folders(RESOURCE, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_object_names(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_environment_objects(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsps(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + read_scenery(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + read_crates(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_editor_folders(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) current_position = input_stream.tell() EOF = input_stream.seek(0, 2) @@ -363,9 +148,9 @@ def process_file(input_stream, report): if XML_OUTPUT: xml_str = TAG.xml_doc.toprettyxml(indent ="\t") - save_path_file = tag_format.get_xml_path(input_stream.name, RESOURCE.header.tag_group, TAG.is_legacy) + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) with open(save_path_file, "w") as f: f.write(xml_str) - return RESOURCE + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_sound_scenery_resource/format.py b/io_scene_halo/file_tag/h2/file_scenario_sound_scenery_resource/format.py new file mode 100644 index 000000000..64b4acba2 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_sound_scenery_resource/format.py @@ -0,0 +1,36 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from ..file_scenario.format import ScenarioAsset + +class ScenarioAsset(ScenarioAsset): + def __init__(self): + super().__init__() + + class ScenarioBody(ScenarioAsset.ScenarioBody): + def __init__(self, next_object_id_salt=0): + super().__init__() + self.next_object_id_salt = next_object_id_salt diff --git a/io_scene_halo/file_tag/h2/file_scenario_sound_scenery_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_sound_scenery_resource/process_file.py new file mode 100644 index 000000000..e2b782d78 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_sound_scenery_resource/process_file.py @@ -0,0 +1,106 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from .format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.skies_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) + SCENARIO.scenario_body.environment_objects_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "environment objects")) + SCENARIO.scenario_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) + SCENARIO.scenario_body.sound_scenery_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "sound scenery palette")) + SCENARIO.scenario_body.sound_scenery_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "sound scenery")) + SCENARIO.scenario_body.next_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next object id salt")) + SCENARIO.scenario_body.editor_folders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "editor folders")) + +def read_sound_scenery(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.sound_scenery_palette_tag_block.count, "sound scenery palette", SCENARIO.sound_scenery_palette_header, SCENARIO.sound_scenery_palette, tag_node, TAG) + + if SCENARIO.scenario_body.sound_scenery_tag_block.count > 0: + SCENARIO.sound_scenery_header = TAG.TagBlockHeader().read(input_stream, TAG) + sound_scenery_node = tag_format.get_xml_node(XML_OUTPUT, SCENARIO.scenario_body.sound_scenery_tag_block.count, tag_node, "name", "sound scenery") + for sound_scenery_idx in range(SCENARIO.scenario_body.sound_scenery_tag_block.count): + sound_scenery_element_node = None + if XML_OUTPUT: + sound_scenery_element_node = TAG.xml_doc.createElement('element') + sound_scenery_element_node.setAttribute('index', str(sound_scenery_idx)) + sound_scenery_node.appendChild(sound_scenery_element_node) + + SCENARIO.sound_scenery.append(process_scenario.get_sound_scenery(input_stream, SCENARIO, TAG, sound_scenery_element_node)) + + for sound_scenery_idx, device_light_fixture in enumerate(SCENARIO.sound_scenery): + sound_scenery_element_node = None + if XML_OUTPUT: + sound_scenery_element_node = sound_scenery_node.childNodes[sound_scenery_idx] + + device_light_fixture.sobj_header = TAG.TagBlockHeader().read(input_stream, TAG) + device_light_fixture.obj0_header = TAG.TagBlockHeader().read(input_stream, TAG) + device_light_fixture._sc__header = TAG.TagBlockHeader().read(input_stream, TAG) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_environment_objects(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_object_names(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsps(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + read_sound_scenery(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_editor_folders(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_structure_lighting_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_structure_lighting_resource/process_file.py new file mode 100644 index 000000000..e9a48f179 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_structure_lighting_resource/process_file.py @@ -0,0 +1,69 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from ..file_scenario.format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.structure_bsp_lighting_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsp lighting")) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsp_lighting(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_structure_lightmap/build_asset.py b/io_scene_halo/file_tag/h2/file_scenario_structure_lightmap/build_asset.py index 8f89c519d..7effcab36 100644 --- a/io_scene_halo/file_tag/h2/file_scenario_structure_lightmap/build_asset.py +++ b/io_scene_halo/file_tag/h2/file_scenario_structure_lightmap/build_asset.py @@ -49,6 +49,166 @@ def write_body(output_stream, LIGHTMAP, TAG): LIGHTMAP.lightmap_body.errors_tag_block.write(output_stream, False) output_stream.write(struct.pack('<104x')) +def write_clusters(output_stream, clusters, clusters_header, TAG): + if len(clusters) > 0: + clusters_header.write(output_stream, TAG, True) + for cluster_element in clusters: + output_stream.write(struct.pack(' 0: + cluster_element.compression_info_header.write(output_stream, TAG, True) + for compression_info_element in cluster_element.compression_info: + output_stream.write(struct.pack(' 0: + cluster_element.resources_header.write(output_stream, TAG, True) + for resource_element in cluster_element.resources: + output_stream.write(struct.pack(' 0: + cluster_element.cache_data_header.write(output_stream, TAG, True) + for cache_data_element in cluster_element.cache_data: + cache_data_element.parts_tag_block.write(output_stream, False) + cache_data_element.subparts_tag_block.write(output_stream, False) + cache_data_element.visibility_bounds_tag_block.write(output_stream, False) + cache_data_element.raw_vertices_tag_block.write(output_stream, False) + cache_data_element.strip_indices_tag_block.write(output_stream, False) + cache_data_element.visibility_mopp_code_tag_data.write(output_stream, False) + cache_data_element.mopp_reorder_table_tag_block.write(output_stream, False) + cache_data_element.vertex_buffers_tag_block.write(output_stream, False) + output_stream.write(struct.pack('<4x')) + + for cache_data_element in cluster_element.cache_data: + cache_data_element.sect_header.write(output_stream, TAG, True) + if len(cache_data_element.parts) > 0: + cache_data_element.parts_header.write(output_stream, TAG, True) + for part_element in cache_data_element.parts: + output_stream.write(struct.pack(' 0: + cache_data_element.subparts_header.write(output_stream, TAG, True) + for subpart_element in cache_data_element.subparts: + output_stream.write(struct.pack(' 0: + cache_data_element.visibility_bounds_header.write(output_stream, TAG, True) + for visibility_bound_element in cache_data_element.visibility_bounds: + output_stream.write(struct.pack(' 0: + cache_data_element.raw_vertices_header.write(output_stream, TAG, True) + for raw_vertex_element in cache_data_element.raw_vertices: + output_stream.write(struct.pack(' 0: + cache_data_element.strip_indices_header.write(output_stream, TAG, True) + for strip_index_element in cache_data_element.strip_indices: + output_stream.write(struct.pack(' 0: + cache_data_element.mopp_reorder_table_header.write(output_stream, TAG, True) + for mopp_reorder_table_element in cache_data_element.mopp_reorder_table: + output_stream.write(struct.pack(' 0: + cache_data_element.vertex_buffers_header.write(output_stream, TAG, True) + for vertex_buffer_element in cache_data_element.vertex_buffers: + output_stream.write(vertex_buffer_element) + def write_lightmap_groups(output_stream, LIGHTMAP, TAG): if len(LIGHTMAP.lightmap_groups) > 0: LIGHTMAP.lightmap_groups_header.write(output_stream, TAG, True) @@ -86,164 +246,7 @@ def write_lightmap_groups(output_stream, LIGHTMAP, TAG): if bitmap_group_name_length > 0: output_stream.write(struct.pack('<%ssx' % bitmap_group_name_length, tag_format.string_to_bytes(lightmap_group_element.bitmap_group_tag_ref.name, False))) - if len(lightmap_group_element.clusters) > 0: - lightmap_group_element.clusters_header.write(output_stream, TAG, True) - for cluster_element in lightmap_group_element.clusters: - output_stream.write(struct.pack(' 0: - cluster_element.compression_info_header.write(output_stream, TAG, True) - for compression_info_element in cluster_element.compression_info: - output_stream.write(struct.pack(' 0: - cluster_element.resources_header.write(output_stream, TAG, True) - for resource_element in cluster_element.resources: - output_stream.write(struct.pack(' 0: - cluster_element.cache_data_header.write(output_stream, TAG, True) - for cache_data_element in cluster_element.cache_data: - cache_data_element.parts_tag_block.write(output_stream, False) - cache_data_element.subparts_tag_block.write(output_stream, False) - cache_data_element.visibility_bounds_tag_block.write(output_stream, False) - cache_data_element.raw_vertices_tag_block.write(output_stream, False) - cache_data_element.strip_indices_tag_block.write(output_stream, False) - cache_data_element.visibility_mopp_code_tag_data.write(output_stream, False) - cache_data_element.mopp_reorder_table_tag_block.write(output_stream, False) - cache_data_element.vertex_buffers_tag_block.write(output_stream, False) - output_stream.write(struct.pack('<4x')) - - for cache_data_element in cluster_element.cache_data: - cache_data_element.sect_header.write(output_stream, TAG, True) - if len(cache_data_element.parts) > 0: - cache_data_element.parts_header.write(output_stream, TAG, True) - for part_element in cache_data_element.parts: - output_stream.write(struct.pack(' 0: - cache_data_element.subparts_header.write(output_stream, TAG, True) - for subpart_element in cache_data_element.subparts: - output_stream.write(struct.pack(' 0: - cache_data_element.visibility_bounds_header.write(output_stream, TAG, True) - for visibility_bound_element in cache_data_element.visibility_bounds: - output_stream.write(struct.pack(' 0: - cache_data_element.raw_vertices_header.write(output_stream, TAG, True) - for raw_vertex_element in cache_data_element.raw_vertices: - output_stream.write(struct.pack(' 0: - cache_data_element.strip_indices_header.write(output_stream, TAG, True) - for strip_index_element in cache_data_element.strip_indices: - output_stream.write(struct.pack(' 0: - cache_data_element.mopp_reorder_table_header.write(output_stream, TAG, True) - for mopp_reorder_table_element in cache_data_element.mopp_reorder_table: - output_stream.write(struct.pack(' 0: - cache_data_element.vertex_buffers_header.write(output_stream, TAG, True) - for vertex_buffer_element in cache_data_element.vertex_buffers: - output_stream.write(vertex_buffer_element) + write_clusters(output_stream, lightmap_group_element.clusters, lightmap_group_element.clusters_header, TAG) if len(lightmap_group_element.cluster_render_info) > 0: lightmap_group_element.cluster_render_info_header.write(output_stream, TAG, True) @@ -251,6 +254,140 @@ def write_lightmap_groups(output_stream, LIGHTMAP, TAG): output_stream.write(struct.pack(' 0: + lightmap_group_element.lighting_environments_header.write(output_stream, TAG, True) + for lighting_environment_element in lightmap_group_element.lighting_environments: + output_stream.write(struct.pack(' 0: + lightmap_group_element.geometry_buckets_header.write(output_stream, TAG, True) + for geometry_bucket_element in lightmap_group_element.geometry_buckets: + output_stream.write(struct.pack(' 0: + geometry_bucket_element.raw_vertices_header.write(output_stream, TAG, True) + for raw_vertex in geometry_bucket_element.raw_vertices: + R, G, B, A = raw_vertex.primary_lightmap_color_RGBA + output_stream.write(struct.pack(' 0: + geometry_bucket_element.resources_header.write(output_stream, TAG, True) + for resource in geometry_bucket_element.resources: + output_stream.write(struct.pack(' 0: + geometry_bucket_element.cache_data_header.write(output_stream, TAG, True) + for cache_data in geometry_bucket_element.cache_data: + cache_data.vertex_buffers_tag_block.write(output_stream, False) + + for cache_data in geometry_bucket_element.cache_data: + if len(cache_data.vertex_buffers) > 0: + cache_data.vertex_buffers_header.write(output_stream, TAG, True) + for vertex_buffer in cache_data.vertex_buffers: + output_stream.write(vertex_buffer) + + if len(lightmap_group_element.instance_render_info) > 0: + lightmap_group_element.instance_render_info_header.write(output_stream, TAG, True) + for instance_render_info in lightmap_group_element.instance_render_info: + output_stream.write(struct.pack(' 0: + lightmap_group_element.instance_bucket_refs_header.write(output_stream, TAG, True) + for instance_bucket_ref in lightmap_group_element.instance_bucket_refs: + output_stream.write(struct.pack(' 0: + instance_bucket_ref.section_offsets_header.write(output_stream, TAG, True) + for section_offset in instance_bucket_ref.section_offsets: + output_stream.write(struct.pack(' 0: + lightmap_group_element.scenery_object_info_header.write(output_stream, TAG, True) + for scenery_object_info in lightmap_group_element.scenery_object_info: + output_stream.write(struct.pack(' 0: + lightmap_group_element.scenery_object_bucket_refs_header.write(output_stream, TAG, True) + for scenery_object_bucket_ref in lightmap_group_element.scenery_object_bucket_refs: + output_stream.write(struct.pack(' 0: + scenery_object_bucket_ref.section_offsets_header.write(output_stream, TAG, True) + for section_offset in scenery_object_bucket_ref.section_offsets: + output_stream.write(struct.pack(' 0: compression_info_node = tag_format.get_xml_node(XML_OUTPUT, compression_info_count, poop_definition_element_node, "name", "compression info") - compression_info_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + poop_definition.compression_info_header = TAG.TagBlockHeader().read(input_stream, TAG) for compression_info_idx in range(compression_info_count): compression_info_element_node = None if XML_OUTPUT: @@ -528,11 +528,11 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): poop_definition.compression_info.append(compression_info) - blok_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + poop_definition.blok_header = TAG.TagBlockHeader().read(input_stream, TAG) if resources_count > 0: resources_node = tag_format.get_xml_node(XML_OUTPUT, resources_count, poop_definition_element_node, "name", "resources") - resources_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + poop_definition.resources_header = TAG.TagBlockHeader().read(input_stream, TAG) for resource_idx in range(resources_count): resource_element_node = None if XML_OUTPUT: @@ -552,7 +552,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if cache_data_count > 0: cache_data_node = tag_format.get_xml_node(XML_OUTPUT, cache_data_count, poop_definition_element_node, "name", "cache data") - cache_data_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + poop_definition.cache_data_header = TAG.TagBlockHeader().read(input_stream, TAG) for cache_data_idx in range(cache_data_count): cache_data_element_node = None if XML_OUTPUT: @@ -593,11 +593,11 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): mopp_reorder_table_count = cache_data.mopp_reorder_table_tag_block.count vertex_buffers_count = cache_data.vertex_buffers_tag_block.count - sect_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + cache_data.sect_header = TAG.TagBlockHeader().read(input_stream, TAG) if parts_count > 0: parts_node = tag_format.get_xml_node(XML_OUTPUT, parts_count, cache_data_element_node, "name", "parts") - parts_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + cache_data.parts_header = TAG.TagBlockHeader().read(input_stream, TAG) for parts_idx in range(parts_count): parts_element_node = None if XML_OUTPUT: @@ -630,7 +630,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if subparts_count > 0: subparts_node = tag_format.get_xml_node(XML_OUTPUT, subparts_count, cache_data_element_node, "name", "subparts") - subparts_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + cache_data.subparts_header = TAG.TagBlockHeader().read(input_stream, TAG) for subparts_idx in range(subparts_count): subparts_element_node = None if XML_OUTPUT: @@ -648,7 +648,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if visibility_bounds_count > 0: visibility_bounds_node = tag_format.get_xml_node(XML_OUTPUT, visibility_bounds_count, cache_data_element_node, "name", "visibility bounds") - visibility_bounds_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + cache_data.visibility_bounds_header = TAG.TagBlockHeader().read(input_stream, TAG) for visibility_bounds_idx in range(visibility_bounds_count): visibility_bounds_element_node = None if XML_OUTPUT: @@ -666,7 +666,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if raw_vertices_count > 0: raw_vertices_node = tag_format.get_xml_node(XML_OUTPUT, raw_vertices_count, cache_data_element_node, "name", "raw vertices") - raw_vertices_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + cache_data.raw_vertices_header = TAG.TagBlockHeader().read(input_stream, TAG) for raw_vertex_idx in range(raw_vertices_count): raw_vertex_element_node = None if XML_OUTPUT: @@ -705,7 +705,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if strip_indices_count > 0: strip_indices_node = tag_format.get_xml_node(XML_OUTPUT, strip_indices_count, cache_data_element_node, "name", "strip indices") - strip_indices_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + cache_data.strip_indices_header = TAG.TagBlockHeader().read(input_stream, TAG) for strip_index_idx in range(strip_indices_count): strip_index_element_node = None if XML_OUTPUT: @@ -717,11 +717,11 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): cache_data.strip_indices.append(strip_index) - mopp_data = input_stream.read(cache_data.visibility_mopp_code_tag_data.size) + cache_data.visibility_mopp_code_tag_data.data = input_stream.read(cache_data.visibility_mopp_code_tag_data.size) if mopp_reorder_table_count > 0: mopp_reorder_table_node = tag_format.get_xml_node(XML_OUTPUT, mopp_reorder_table_count, cache_data_element_node, "name", "mopp reorder table") - mopp_reorder_table_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + cache_data.mopp_reorder_table_header = TAG.TagBlockHeader().read(input_stream, TAG) for mopp_reorder_table_idx in range(mopp_reorder_table_count): mopp_reorder_table_element_node = None if XML_OUTPUT: @@ -735,7 +735,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if vertex_buffers_count > 0: vertex_buffers_node = tag_format.get_xml_node(XML_OUTPUT, vertex_buffers_count, cache_data_element_node, "name", "vertex buffers") - vertex_buffers_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + cache_data.vertex_buffers_header = TAG.TagBlockHeader().read(input_stream, TAG) for vertex_buffer_idx in range(vertex_buffers_count): vertex_buffer_element_node = None if XML_OUTPUT: @@ -743,7 +743,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): vertex_buffer_element_node.setAttribute('index', str(vertex_buffer_idx)) vertex_buffers_node.appendChild(vertex_buffer_element_node) - input_stream.read(32) # Padding? + cache_data.vertex_buffers.append(input_stream.read(32)) # Padding? lightmap_group.lighting_environments = [] lighting_environments_count = lightmap_group.lighting_environments_tag_block.count @@ -843,7 +843,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if raw_vertices_count > 0: raw_vertices_node = tag_format.get_xml_node(XML_OUTPUT, raw_vertices_count, geometry_bucket_element_node, "name", "raw vertices") - raw_vertices_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + geometry_bucket.raw_vertices_header = TAG.TagBlockHeader().read(input_stream, TAG) for raw_vertex_idx in range(raw_vertices_count): raw_vertex_element_node = None if XML_OUTPUT: @@ -857,12 +857,10 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): geometry_bucket.raw_vertices.append(raw_vertex) - - blok_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) - + geometry_bucket.blok_header = TAG.TagBlockHeader().read(input_stream, TAG) if resources_count > 0: resources_node = tag_format.get_xml_node(XML_OUTPUT, resources_count, geometry_bucket_element_node, "name", "resources") - resources_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + geometry_bucket.resources_header = TAG.TagBlockHeader().read(input_stream, TAG) for resource_idx in range(resources_count): resource_element_node = None if XML_OUTPUT: @@ -882,7 +880,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if cache_data_count > 0: cache_data_node = tag_format.get_xml_node(XML_OUTPUT, cache_data_count, geometry_bucket_element_node, "name", "cache data") - cache_data_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + geometry_bucket.cache_data_header = TAG.TagBlockHeader().read(input_stream, TAG) for cache_data_idx in range(cache_data_count): cache_data_element_node = None if XML_OUTPUT: @@ -905,7 +903,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if vertex_buffers_count > 0: vertex_buffers_node = tag_format.get_xml_node(XML_OUTPUT, vertex_buffers_count, cache_data_element_node, "name", "vertex buffers") - vertex_buffers_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + cache_data.vertex_buffers_header = TAG.TagBlockHeader().read(input_stream, TAG) for vertex_buffer_idx in range(vertex_buffers_count): vertex_buffer_element_node = None if XML_OUTPUT: @@ -913,7 +911,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): vertex_buffer_element_node.setAttribute('index', str(vertex_buffer_idx)) vertex_buffers_node.appendChild(vertex_buffer_element_node) - input_stream.read(32) # Padding? + cache_data.vertex_buffers.append(input_stream.read(32)) # Padding? lightmap_group.instance_render_info = [] instance_render_info_count = lightmap_group.instance_render_info_tag_block.count @@ -962,7 +960,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if section_offsets_count > 0: section_offsets_node = tag_format.get_xml_node(XML_OUTPUT, section_offsets_count, instance_bucket_ref_element_node, "name", "section offsets") - section_offsets_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + instance_bucket_ref.section_offsets_header = TAG.TagBlockHeader().read(input_stream, TAG) for section_offset_idx in range(section_offsets_count): section_offset_element_node = None if XML_OUTPUT: @@ -1024,7 +1022,7 @@ def read_lightmap_groups(LIGHTMAP, TAG, input_stream, tag_node, XML_OUTPUT): if section_offsets_count > 0: section_offsets_node = tag_format.get_xml_node(XML_OUTPUT, section_offsets_count, scenery_object_bucket_ref_element_node, "name", "section offsets") - section_offsets_tag_block_header = TAG.TagBlockHeader().read(input_stream, TAG) + scenery_object_bucket_ref.section_offsets_header = TAG.TagBlockHeader().read(input_stream, TAG) for section_offset_idx in range(section_offsets_count): section_offset_element_node = None if XML_OUTPUT: diff --git a/io_scene_halo/file_tag/h2/file_scenario_trigger_volumes_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_trigger_volumes_resource/process_file.py new file mode 100644 index 000000000..b7e152a6e --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_trigger_volumes_resource/process_file.py @@ -0,0 +1,72 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from ..file_scenario.format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.scenario_kill_triggers_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.trigger_volumes_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "trigger volumes")) + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_trigger_volumes(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_object_names(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_vehicles_resource/format.py b/io_scene_halo/file_tag/h2/file_scenario_vehicles_resource/format.py new file mode 100644 index 000000000..64b4acba2 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_vehicles_resource/format.py @@ -0,0 +1,36 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from ..file_scenario.format import ScenarioAsset + +class ScenarioAsset(ScenarioAsset): + def __init__(self): + super().__init__() + + class ScenarioBody(ScenarioAsset.ScenarioBody): + def __init__(self, next_object_id_salt=0): + super().__init__() + self.next_object_id_salt = next_object_id_salt diff --git a/io_scene_halo/file_tag/h2/file_scenario_vehicles_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_vehicles_resource/process_file.py new file mode 100644 index 000000000..ade93733a --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_vehicles_resource/process_file.py @@ -0,0 +1,110 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from .format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.skies_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) + SCENARIO.scenario_body.environment_objects_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "environment objects")) + SCENARIO.scenario_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) + SCENARIO.scenario_body.vehicle_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "vehicles palette")) + SCENARIO.scenario_body.vehicles_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "vehicles")) + SCENARIO.scenario_body.next_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next object id salt")) + SCENARIO.scenario_body.editor_folders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "editor folders")) + +def read_vehicles(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.vehicle_palette_tag_block.count, "vehicles palette", SCENARIO.vehicle_palette_header, SCENARIO.vehicle_palette, tag_node, TAG) + + if SCENARIO.scenario_body.vehicles_tag_block.count > 0: + SCENARIO.vehicles_header = TAG.TagBlockHeader().read(input_stream, TAG) + vehicle_node = tag_format.get_xml_node(XML_OUTPUT, SCENARIO.scenario_body.vehicles_tag_block.count, tag_node, "name", "vehicles") + for vehicle_idx in range(SCENARIO.scenario_body.vehicles_tag_block.count): + vehicle_element_node = None + if XML_OUTPUT: + vehicle_element_node = TAG.xml_doc.createElement('element') + vehicle_element_node.setAttribute('index', str(vehicle_idx)) + vehicle_node.appendChild(vehicle_element_node) + + SCENARIO.vehicles.append(process_scenario.get_units(input_stream, SCENARIO, TAG, vehicle_element_node, SCENARIO.scenario_body.vehicle_palette_tag_block.count, "scenario_vehicle_palette_block")) + + for vehicle_idx, vehicle in enumerate(SCENARIO.vehicles): + vehicle_element_node = None + if XML_OUTPUT: + vehicle_element_node = vehicle_node.childNodes[vehicle_idx] + + vehicle.sobj_header = TAG.TagBlockHeader().read(input_stream, TAG) + vehicle.obj0_header = TAG.TagBlockHeader().read(input_stream, TAG) + vehicle.sper_header = TAG.TagBlockHeader().read(input_stream, TAG) + if vehicle.variant_name_length > 0: + vehicle.variant_name = TAG.read_variable_string_no_terminator(input_stream, vehicle.variant_name_length, TAG, tag_format.XMLData(vehicle_element_node, "variant name")) + + vehicle.sunt_header = TAG.TagBlockHeader().read(input_stream, TAG) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_environment_objects(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_object_names(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsps(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + read_vehicles(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_editor_folders(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/file_tag/h2/file_scenario_weapons_resource/format.py b/io_scene_halo/file_tag/h2/file_scenario_weapons_resource/format.py new file mode 100644 index 000000000..64b4acba2 --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_weapons_resource/format.py @@ -0,0 +1,36 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from ..file_scenario.format import ScenarioAsset + +class ScenarioAsset(ScenarioAsset): + def __init__(self): + super().__init__() + + class ScenarioBody(ScenarioAsset.ScenarioBody): + def __init__(self, next_object_id_salt=0): + super().__init__() + self.next_object_id_salt = next_object_id_salt diff --git a/io_scene_halo/file_tag/h2/file_scenario_weapons_resource/process_file.py b/io_scene_halo/file_tag/h2/file_scenario_weapons_resource/process_file.py new file mode 100644 index 000000000..8afc4b3cf --- /dev/null +++ b/io_scene_halo/file_tag/h2/file_scenario_weapons_resource/process_file.py @@ -0,0 +1,110 @@ +# ##### BEGIN MIT LICENSE BLOCK ##### +# +# MIT License +# +# Copyright (c) 2023 Steven Garcia +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ##### END MIT LICENSE BLOCK ##### + +from xml.dom import minidom +from ....global_functions import tag_format +from ..file_scenario import process_file as process_scenario +from ..file_scenario.format import ScenarioAsset + +XML_OUTPUT = False + +def read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + SCENARIO.scenario_body_header = TAG.TagBlockHeader().read(input_stream, TAG) + SCENARIO.scenario_body = SCENARIO.ScenarioBody() + SCENARIO.scenario_body.skies_tag_block = TAG.TagBlock() + SCENARIO.scenario_body.object_names_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "object names")) + SCENARIO.scenario_body.environment_objects_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "environment objects")) + SCENARIO.scenario_body.structure_bsps_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "structure bsps")) + SCENARIO.scenario_body.weapon_palette_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "weapon palette")) + SCENARIO.scenario_body.weapons_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "weapons")) + SCENARIO.scenario_body.next_object_id_salt = TAG.read_signed_integer(input_stream, TAG, tag_format.XMLData(tag_node, "next object id salt")) + SCENARIO.scenario_body.editor_folders_tag_block = TAG.TagBlock().read(input_stream, TAG, tag_format.XMLData(tag_node, "editor folders")) + +def read_weapon(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT): + process_scenario.palette_helper(input_stream, SCENARIO.scenario_body.weapon_palette_tag_block.count, "weapon palette", SCENARIO.weapon_palette_header, SCENARIO.weapon_palette, tag_node, TAG) + + if SCENARIO.scenario_body.weapons_tag_block.count > 0: + SCENARIO.weapon_header = TAG.TagBlockHeader().read(input_stream, TAG) + weapon_node = tag_format.get_xml_node(XML_OUTPUT, SCENARIO.scenario_body.weapons_tag_block.count, tag_node, "name", "weapons") + for weapon_idx in range(SCENARIO.scenario_body.weapons_tag_block.count): + weapon_element_node = None + if XML_OUTPUT: + weapon_element_node = TAG.xml_doc.createElement('element') + weapon_element_node.setAttribute('index', str(weapon_idx)) + weapon_node.appendChild(weapon_element_node) + + SCENARIO.weapons.append(process_scenario.get_weapons(input_stream, SCENARIO, TAG, weapon_element_node)) + + for weapon_idx, weapon in enumerate(SCENARIO.weapons): + weapon_element_node = None + if XML_OUTPUT: + weapon_element_node = weapon_node.childNodes[weapon_idx] + + weapon.sobj_header = TAG.TagBlockHeader().read(input_stream, TAG) + weapon.obj0_header = TAG.TagBlockHeader().read(input_stream, TAG) + weapon.sper_header = TAG.TagBlockHeader().read(input_stream, TAG) + if weapon.variant_name_length > 0: + weapon.variant_name = TAG.read_variable_string_no_terminator(input_stream, weapon.variant_name_length, TAG, tag_format.XMLData(weapon_element_node, "variant name")) + + weapon.swpt_header = TAG.TagBlockHeader().read(input_stream, TAG) + +def process_file(input_stream, report): + TAG = tag_format.TagAsset() + SCENARIO = ScenarioAsset() + TAG.is_legacy = False + TAG.big_endian = False + tag_node = None + if XML_OUTPUT: + TAG.xml_doc = minidom.Document() + + SCENARIO.header = TAG.Header().read(input_stream, TAG) + if XML_OUTPUT: + tag_node = TAG.xml_doc.childNodes[0] + + process_scenario.initilize_scenario(SCENARIO) + read_scenario_body(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + process_scenario.read_environment_objects(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_object_names(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_structure_bsps(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + read_weapon(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + process_scenario.read_editor_folders(SCENARIO, TAG, input_stream, tag_node, XML_OUTPUT) + + + current_position = input_stream.tell() + EOF = input_stream.seek(0, 2) + if not EOF - current_position == 0: # is something wrong with the parser? + report({'WARNING'}, "%s elements left after parse end" % (EOF - current_position)) + + if XML_OUTPUT: + xml_str = TAG.xml_doc.toprettyxml(indent ="\t") + + save_path_file = tag_format.get_xml_path(input_stream.name, SCENARIO.header.tag_group, TAG.is_legacy) + + with open(save_path_file, "w") as f: + f.write(xml_str) + + return SCENARIO diff --git a/io_scene_halo/global_functions/parse_tags.py b/io_scene_halo/global_functions/parse_tags.py index a2991a16b..343eee325 100644 --- a/io_scene_halo/global_functions/parse_tags.py +++ b/io_scene_halo/global_functions/parse_tags.py @@ -73,7 +73,24 @@ from ..file_tag.h2.file_sound_scenery.process_file import process_file as process_h2_sound_scenery from ..file_tag.h2.file_item_collection.process_file import process_file as process_h2_item_collection from ..file_tag.h2.file_vehicle_collection.process_file import process_file as process_h2_vehicle_collection + +from ..file_tag.h2.file_scenario_ai_resource.process_file import process_file as process_h2_scenario_ai_resource +from ..file_tag.h2.file_scenario_bipeds_resource.process_file import process_file as process_h2_scenario_bipeds_resource +from ..file_tag.h2.file_scenario_cinematics_resource.process_file import process_file as process_h2_scenario_cinematics_resource +from ..file_tag.h2.file_scenario_cluster_data_resource.process_file import process_file as process_h2_scenario_cluster_data_resource +from ..file_tag.h2.file_scenario_comments_resource.process_file import process_file as process_h2_scenario_comments_resource +from ..file_tag.h2.file_scenario_creature_resource.process_file import process_file as process_h2_scenario_creature_resource +from ..file_tag.h2.file_scenario_decals_resource.process_file import process_file as process_h2_scenario_decals_resource +from ..file_tag.h2.file_scenario_decorators_resource.process_file import process_file as process_h2_scenario_decorators_resource +from ..file_tag.h2.file_scenario_devices_resource.process_file import process_file as process_h2_scenario_devices_resource +from ..file_tag.h2.file_scenario_equipment_resource.process_file import process_file as process_h2_scenario_equipment_resource +from ..file_tag.h2.file_scenario_lights_resource.process_file import process_file as process_h2_scenario_lights_resource from ..file_tag.h2.file_scenario_scenery_resource.process_file import process_file as process_h2_scenario_scenery_resource +from ..file_tag.h2.file_scenario_sound_scenery_resource.process_file import process_file as process_h2_scenario_sound_scenery_resource +from ..file_tag.h2.file_scenario_structure_lighting_resource.process_file import process_file as process_h2_scenario_structure_lighting_resource +from ..file_tag.h2.file_scenario_trigger_volumes_resource.process_file import process_file as process_h2_scenario_trigger_volumes_resource +from ..file_tag.h2.file_scenario_vehicles_resource.process_file import process_file as process_h2_scenario_vehicles_resource +from ..file_tag.h2.file_scenario_weapons_resource.process_file import process_file as process_h2_scenario_weapons_resource def parse_tag(tagref, report, game_title, game_version): ASSET = None @@ -386,6 +403,83 @@ def parse_tag(tagref, report, game_title, game_version): ASSET = process_h2_vehicle_collection(input_stream, report) input_stream.close() + elif tagref.tag_group == "ai**": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_ai_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_ai_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "*ipd": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_bipeds_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_bipeds_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "cin*": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_cinematics_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_cinematics_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "clu*": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_cluster_data_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_cluster_data_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "/**/": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_comments_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_comments_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "*rea": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_creature_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_creature_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "dec*": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_decals_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_decals_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "dc*s": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_decorators_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_decorators_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "dgr*": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_devices_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_devices_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "*qip": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_equipment_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_equipment_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "*igh": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_lights_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_lights_resource(input_stream, report) + input_stream.close() + elif tagref.tag_group == "*cen": input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_scenery_resource" % tagref.name) if os.path.exists(input_file): @@ -393,4 +487,39 @@ def parse_tag(tagref, report, game_title, game_version): ASSET = process_h2_scenario_scenery_resource(input_stream, report) input_stream.close() + elif tagref.tag_group == "*sce": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_sound_scenery_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_sound_scenery_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "sslt": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_structure_lighting_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_structure_lighting_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "trg*": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_trigger_volumes_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_trigger_volumes_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "*ehi": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_vehicles_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_vehicles_resource(input_stream, report) + input_stream.close() + + elif tagref.tag_group == "*eap": + input_file = os.path.join(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path, "%s.scenario_weapons_resource" % tagref.name) + if os.path.exists(input_file): + input_stream = open(input_file, 'rb') + ASSET = process_h2_scenario_weapons_resource(input_stream, report) + input_stream.close() + return ASSET diff --git a/io_scene_halo/global_functions/tag_format.py b/io_scene_halo/global_functions/tag_format.py index 82448bd1c..bb9b54a42 100644 --- a/io_scene_halo/global_functions/tag_format.py +++ b/io_scene_halo/global_functions/tag_format.py @@ -288,10 +288,11 @@ def get_xml_path(input_path, tag_group, is_legacy, is_reversed=False): if is_reversed: tag_group = tag_group[::-1] - xml_path = os.path.join(os.path.dirname(input_path), "%s_%s.XML" % (tag_name, tag_group)) - special_characters=['@','#','$','*','&'] + special_characters=['@','#','$','*','&',"/",os.sep] for i in special_characters: - xml_path = xml_path.replace(i, " ") + tag_group = tag_group.replace(i, "_") + + xml_path = os.path.join(os.path.dirname(input_path), "%s_%s.XML" % (tag_name, tag_group)) return xml_path @@ -301,6 +302,13 @@ def string_to_bytes(string, reverse): return bytes(string, 'utf-8') +def string_empty_check(string): + is_empty = False + if not string == None and (len(string) == 0 or string.isspace()): + is_empty = True + + return is_empty + class TagAsset(): def __init__(self): self.big_endian = True @@ -869,10 +877,28 @@ def __init__(self, local_path="", unk1=0, flags=0, type=0, name="", tag_group="" self.engine_tag = engine_tag def read(self, input_stream, tag): - if bpy.context.preferences.addons["io_scene_halo"].preferences.halo_1_tag_path in input_stream.name: - self.local_path = input_stream.name.split(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_1_tag_path)[1].rsplit(".", 1)[0] - elif bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path in input_stream.name: - self.local_path = input_stream.name.split(bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path)[1].rsplit(".", 1)[0] + h1_path = bpy.context.preferences.addons["io_scene_halo"].preferences.halo_1_tag_path + h2_path = bpy.context.preferences.addons["io_scene_halo"].preferences.halo_2_tag_path + if not string_empty_check(h1_path) and h1_path in input_stream.name: + result = input_stream.name.split(h1_path) + if len(result) > 1: + result = result[1].rsplit(".", 1)[0] + + else: + result = result[0].rsplit(".", 1)[0] + + self.local_path = result + + elif not string_empty_check(h2_path) and h2_path in input_stream.name: + result = input_stream.name.split(h2_path) + if len(result) > 1: + result = result[1].rsplit(".", 1)[0] + + else: + result = result[0].rsplit(".", 1)[0] + + self.local_path = result + else: self.local_path = input_stream.name.rsplit(".", 1)[0]