@@ -160,6 +160,14 @@ class CommandListFlags(Flag):
160160 disable_falling_damage = auto ()
161161 manual_bsp_index = auto ()
162162
163+ class LightFlags (Flag ):
164+ dynamic = auto ()
165+ no_specular = auto ()
166+ dont_light_own_object = auto ()
167+ supersize_in_first_person = auto ()
168+ first_person_flashlight = auto ()
169+ dont_fade_active_camouflage = auto ()
170+
163171def get_rotation_euler (yaw = 0 , pitch = 0 , roll = 0 ):
164172 yaw = - radians (yaw )
165173 pitch = radians (pitch )
@@ -681,6 +689,8 @@ def generate_object_elements(context, level_root, collection_name, scnr_data, as
681689 for element_idx , element in enumerate (tag_block ):
682690 tag_path = ""
683691 mesh_data = None
692+ marker_data = None
693+ palette_asset = None
684694 tag_path_no_ext = ""
685695 if element ["type" ] >= 0 and element ["type" ] < palette_count :
686696 pallete_item = tag_palette [element ["type" ]]["name" ]
@@ -689,6 +699,7 @@ def generate_object_elements(context, level_root, collection_name, scnr_data, as
689699 palette_asset = tag_interface .get_disk_asset (pallete_item ["path" ], h1_tag_groups .get (pallete_item ["group name" ]))
690700 if palette_asset is not None and len (palette_asset ["Data" ]["model" ]["path" ]) > 0 :
691701 mesh_data = asset_cache [palette_asset ["Data" ]["model" ]["group name" ]][palette_asset ["Data" ]["model" ]["path" ]]["blender_assets" ].get ("blender_asset" )
702+ marker_data = asset_cache [palette_asset ["Data" ]["model" ]["group name" ]][palette_asset ["Data" ]["model" ]["path" ]].get ("marker_positions" )
692703
693704 tag_name = "NONE"
694705 if not global_functions .string_empty_check (tag_path_no_ext ):
@@ -717,6 +728,49 @@ def generate_object_elements(context, level_root, collection_name, scnr_data, as
717728 root .hide_set (True )
718729 root .hide_render = True
719730
731+ if collection_name == "Scenery" or collection_name == "Light Fixtures" :
732+ if palette_asset is not None and marker_data is not None :
733+ palette_data = palette_asset ["Data" ]
734+ for attachment in palette_data ["attachments" ]:
735+ type_field = attachment .get ("type" )
736+ marker_field = attachment .get ("marker" , "" )
737+ if type_field is not None :
738+ group_name_value = type_field .get ("group name" )
739+ if group_name_value == "ligh" :
740+ light_asset = tag_interface .get_disk_asset (type_field ["path" ], h1_tag_groups .get (type_field ["group name" ]))
741+ if light_asset is not None :
742+ light_dict = light_asset ["Data" ]
743+ marker_entry = marker_data .get (marker_field , [None ])
744+ for marker_idx , marker_positions in enumerate (marker_entry ):
745+ # We are just taking the index that the collection comes up in our if else check at the start of this function.
746+ # Kinda to mirror the H2 object type enum. - Gen
747+ collection_index = 0
748+ if not collection_name == "Scenery" :
749+ collection_index = 7
750+
751+ marker_name = "%s_%s%s%s" % (marker_field , collection_index , element_idx , marker_idx )
752+ light_data = asset_cache [type_field ["group name" ]][type_field ["path" ]]["blender_assets" ].get ("blender_asset" )
753+ if not light_data :
754+ light_data = asset_cache [type_field ["group name" ]][type_field ["path" ]]["blender_assets" ]["blender_asset" ] = bpy .data .lights .new (marker_name , "POINT" )
755+ light_data .energy = 0
756+ light_data .shadow_soft_size = 0
757+ light_data .color = (0 , 0 , 0 )
758+
759+ if not LightFlags .dynamic in LightFlags (light_dict ["flags" ]):
760+ # The multiplication values here are made up and just look good to me in Blender. - Gen
761+ light_data .energy = light_dict ["intensity" ] * 6000000
762+ light_data .shadow_soft_size = light_dict ["radius" ] * 10
763+ light_data .color = convert_to_blender_color (light_dict ["color" ], False )
764+
765+ light_ob = bpy .data .objects .new (marker_name , light_data )
766+ asset_collection .objects .link (light_ob )
767+
768+ light_ob .parent = root
769+ if marker_positions is not None :
770+ light_ob .matrix_basis = marker_positions
771+
772+
773+
720774def generate_netgame_equipment_elements (context , level_root , scnr_data , asset_cache , fix_rotations , report , random_color_gen ):
721775 asset_collection = global_functions .get_referenced_collection ("Netgame Equipment" , context .scene .collection , True )
722776 for element_idx , element in enumerate (scnr_data ["netgame equipment" ]):
@@ -993,7 +1047,60 @@ def generate_decals(context, level_root, scnr_data):
9931047
9941048 get_data_type (ob , asset_collection , element , scnr_data , tag_path )
9951049
1050+ def generate_marker_positions (parsed_asset ):
1051+ asset_data = parsed_asset ["Data" ]
1052+ marker_positions = {}
1053+
1054+ absolute_frame = [None for node in asset_data ["nodes" ]]
1055+ for node_idx , node in enumerate (asset_data ["nodes" ]):
1056+ parent_idx = node ["parent node" ]
1057+ matrix_rotation = global_functions .convert_quaternion (node ["default rotation" ]).inverted ().to_matrix ().to_4x4 ()
1058+ matrix_translation = Matrix .Translation (Vector (node ["default translation" ]) * 100 )
1059+
1060+ transform_matrix = matrix_translation @ matrix_rotation
1061+ if parent_idx != - 1 :
1062+ absolute_matrix = absolute_frame [parent_idx ] @ transform_matrix
1063+ else :
1064+ absolute_matrix = transform_matrix
1065+ absolute_frame [node_idx ] = absolute_matrix
1066+
1067+ for region in asset_data ["regions" ]:
1068+ permutation_element = None
1069+ for permutation in region ["permutations" ]:
1070+ if "base" in permutation ["name" ].lower ():
1071+ permutation_element = permutation
1072+ break
1073+
1074+ if permutation_element is None :
1075+ for permutation in region ["permutations" ]:
1076+ permutation_element = permutation
1077+ break
1078+
1079+ if permutation_element is not None :
1080+ for marker in permutation ["markers" ]:
1081+ marker_entry = marker_positions .get (marker ["name" ])
1082+ if marker_entry is None :
1083+ marker_entry = marker_positions [marker ["name" ]] = []
1084+
1085+ matrix_rotation = global_functions .convert_quaternion (marker ["rotation" ]).inverted ().to_matrix ().to_4x4 ()
1086+ matrix_translation = Matrix .Translation (Vector (marker ["translation" ]) * 100 )
1087+
1088+ transform_matrix = matrix_translation @ matrix_rotation
1089+
1090+ marker_entry .append (transform_matrix )
1091+
1092+ return marker_positions
1093+
9961094def generate_scenario_scene (context , tag_ref , asset_cache , game_title , fix_rotations , empty_markers , report ):
1095+ mod2_group = asset_cache .get ("mod2" )
1096+ if mod2_group is not None :
1097+ for tag_path in asset_cache ["mod2" ]:
1098+ mod2_asset = tag_interface .get_disk_asset (tag_path , h1_tag_groups .get ("mod2" ))
1099+ if mod2_asset is not None :
1100+ marker_positions = asset_cache ["mod2" ][tag_path ].get ("marker_positions" )
1101+ if marker_positions is None :
1102+ mod2_group [tag_path ]["marker_positions" ] = generate_marker_positions (mod2_asset )
1103+
9971104 scnr_asset = tag_interface .get_disk_asset (tag_ref ["path" ], h1_tag_groups .get (tag_ref ["group name" ]))
9981105 scnr_data = scnr_asset ["Data" ]
9991106
0 commit comments