def store_terrain(self): # index mesh_index = self.terrain.get_mesh_index() mesh_index = { Hex.parse('0x{:03X}{:05X}'.format(self.data.mesh_range, mesh_guid)): mesh_name for mesh_guid, mesh_name in mesh_index.items() } self.gas_dir.create_subdir( 'index', { 'node_mesh_index': Gas([ Section('node_mesh_index', [ Attribute(str(mesh_guid), mesh_name) for mesh_guid, mesh_name in mesh_index.items() ]) ]), 'streamer_node_index': Gas([ Section('streamer_node_index', [ Attribute('*', node.guid) for node in self.terrain.nodes ]) ]) }) # terrain_nodes nodes_gas = NodesGas() nodes_gas.ambient_color = self.terrain.ambient_light.terrain_color nodes_gas.ambient_intensity = self.terrain.ambient_light.terrain_intensity nodes_gas.object_ambient_color = self.terrain.ambient_light.object_color nodes_gas.object_ambient_intensity = self.terrain.ambient_light.object_intensity nodes_gas.actor_ambient_color = self.terrain.ambient_light.actor_color nodes_gas.actor_ambient_intensity = self.terrain.ambient_light.actor_intensity nodes_gas.targetnode = self.terrain.target_node.guid snodes = list() for node in self.terrain.nodes: mesh_guid = Terrain.mesh_index_lookup[node.mesh_name] mesh_guid = Hex.parse('0x{:03X}{:05X}'.format( self.data.mesh_range, mesh_guid)) doors = [ Door(door_id, far_node.guid, far_door) for door_id, (far_node, far_door) in node.doors.items() ] nodesection = Hex( node.section if node.section != -1 else 0xffffffff) nodelevel = Hex(node.section if node.section != -1 else 0xffffffff) nodeobject = Hex( node.section if node.section != -1 else 0xffffffff) snode = SNode(node.guid, mesh_guid, node.texture_set, True, False, False, True, nodesection, nodelevel, nodeobject, doors) snodes.append(snode) nodes_gas.nodes = snodes self.gas_dir.create_subdir('terrain_nodes', {'nodes': nodes_gas.write_gas()})
def store_objects(self): assert self.objects_non_interactive is not None objects_dir = self.gas_dir.get_or_create_subdir('objects') object_sections = [go.section for go in self.objects_non_interactive] if self.objects_loaded: objects_dir.get_gas_file('non_interactive').gas = Gas( object_sections) else: # if the objects weren't loaded and you try to override the file, this will fail, because it was most probably not intentional objects_dir.create_gas_file('non_interactive', Gas(object_sections))
def to_gas(self) -> Gas: map_section = Section('t:map,n:map', [ Attribute('name', self.name), Attribute('screen_name', self.screen_name), Attribute('description', self.description), Attribute('dev_only', self.dev_only), Attribute('timeofday', self.timeofday), Attribute('use_node_mesh_index', self.use_node_mesh_index), Attribute('use_player_journal', self.use_player_journal), Section('camera', [ Attribute('azimuth', self.camera.azimuth), Attribute('distance', self.camera.distance), Attribute('position', self.camera.position) ]) ]) if self.worlds is not None: world_sections: list[Section] = [] for name, world in self.worlds.items(): world_sections.append(Section(name, [ Attribute('screen_name', world.screen_name), Attribute('description', world.description), Attribute('required_level', str(world.required_level)) ])) map_section.items.append(Section('worlds', world_sections)) map_main_gas = Gas([map_section]) return map_main_gas
def store_start_positions(self): assert self.start_positions is not None info_dir = self.gas_dir.get_or_create_subdir('info') start_group_sections = [] gas_file = info_dir.get_or_create_gas_file('start_positions') gas_file.gas = Gas([ Section('start_positions', start_group_sections) ]) for sg_name, sg in self.start_positions.start_groups.items(): sp_sections: list = [ Section('start_position', [ Attribute('id', sp.id), Attribute('position', str(sp.position)), Section('camera', [ Attribute('azimuth', float(sp.camera.azimuth)), Attribute('distance', float(sp.camera.distance)), Attribute('orbit', float(sp.camera.orbit)), Attribute('position', str(sp.camera.position)) ]) ]) for sp in sg.start_positions ] start_group_sections.append(Section('t:start_group,n:' + sg_name, [ Attribute('default', self.start_positions.default == sg_name), Attribute('description', sg.description), Attribute('dev_only', sg.dev_only), Attribute('id', sg.id), Attribute('screen_name', sg.screen_name) ] + sp_sections))
def from_gas(cls, map_main_gas: Gas): map_section = map_main_gas.get_section('t:map,n:map') data = Map.Data() data.name = map_section.get_attr_value('name') data.screen_name = map_section.get_attr_value('screen_name') data.description = map_section.get_attr_value('description') data.dev_only = map_section.get_attr_value('dev_only') data.timeofday = map_section.get_attr_value('timeofday') data.use_node_mesh_index = map_section.get_attr_value('use_node_mesh_index') data.use_player_journal = map_section.get_attr_value('use_player_journal') camera_section = map_section.get_section('camera') data.camera.azimuth = camera_section.get_attr_value('azimuth') data.camera.distance = camera_section.get_attr_value('distance') data.camera.position = camera_section.get_attr_value('position') worlds_section = map_section.get_section('worlds') if worlds_section is not None: worlds = dict() for world_section in worlds_section.get_sections(): name = world_section.header screen_name = world_section.get_attr_value('screen_name') description = world_section.get_attr_value('description') required_level = int(world_section.get_attr_value('required_level')) worlds[name] = Map.Data.World(screen_name, description, required_level) data.worlds = worlds return data
def write_gas(self) -> Gas: node_sections = [Section('t:snode,n:' + snode.guid.to_str_lower(), [ Attribute('bounds_camera', snode.bounds_camera), Attribute('camera_fade', snode.camera_fade), Attribute('guid', snode.guid), Attribute('mesh_guid', Hex(snode.mesh_guid)), Attribute('nodelevel', snode.nodelevel), Attribute('nodeobject', snode.nodeobject), Attribute('nodesection', snode.nodesection), Attribute('occludes_camera', snode.occludes_camera), Attribute('occludes_light', snode.occludes_light), Attribute('texsetabbr', snode.texsetabbr), ] + [Section('door*', [ Attribute('fardoor', door.fardoor), Attribute('farguid', door.farguid), Attribute('id', door.id), ]) for door in snode.doors]) for snode in self.nodes] return Gas([ Section('t:terrain_nodes,n:siege_node_list', [ Attribute('ambient_color', Hex(self.ambient_color)), Attribute('ambient_intensity', float(self.ambient_intensity)), Attribute('object_ambient_color', Hex(self.object_ambient_color)), Attribute('object_ambient_intensity', float(self.object_ambient_intensity)), Attribute('actor_ambient_color', Hex(self.actor_ambient_color)), Attribute('actor_ambient_intensity', float(self.actor_ambient_intensity)), Attribute('targetnode', self.targetnode) ] + node_sections) ])
def ensure_north_vector(self): editor_subdir = self.gas_dir.get_or_create_subdir('editor') if not editor_subdir.has_gas_file('hotpoints'): hotpoints_gas = Gas([ Section('hotpoints', [ Section('t:hotpoint_directional,n:' + str(Hex(1)), [ Attribute('direction', '0,0,-1'), Attribute('id', Hex(1)) ]) ]) ]) editor_subdir.create_gas_file('hotpoints', hotpoints_gas)
def store_lights(self): # Note: storing directional / point / spot lights; ambient light is part of terrain. # prepare if self.terrain is not None: target_node = self.terrain.target_node for light in self.lights: if isinstance(light, DirectionalLight): if light.direction.node_guid is None: light.direction.node_guid = target_node.guid # store lights_dir = self.gas_dir.get_or_create_subdir('lights', False) lights_dir.get_or_create_gas_file('lights').gas = Gas([ Section('lights', [light.to_gas_section() for light in self.lights]) ])
def write_gas(self) -> Gas: se_sections = [ Section(f't:stitch_editor,n:{se.dest_region}', [ Attribute('dest_region', se.dest_region), Section('node_ids', [ Attribute( Hex(stitch_id).to_str_lower(), f'{node_guid},{door}') for stitch_id, (node_guid, door) in se.node_ids.items() ]) ]) for se in self.stitch_editors ] return Gas([ Section('stitch_helper_data', [ Attribute('source_region_guid', Hex(self.source_region_guid)), Attribute('source_region_name', self.source_region_name), ] + se_sections) ])
def load_gas(cls, gas: Gas) -> Progression: ppp_section = gas.get_section('perlin_plant_progression') direction = ppp_section.get_attr_value('direction') assert direction in ['sw2ne', 'nw2se'] perlin_name = ppp_section.get_attr_value('perlin').strip() perlin_curve_factor = float( ppp_section.get_attr_value('perlin_curve_factor')) tx_factor = float(ppp_section.get_attr_value('tx_factor')) steps_section = ppp_section.get_section('steps') steps = [] for step_section in steps_section.get_sections(): step_value = float(step_section.header) sub_progression_section = step_section.get_section( 'perlin_plant_progression') if sub_progression_section is not None: step = cls.load_gas(step_section) else: step = ProgressionStep.load_gas(step_section) steps.append((step_value, step)) return Progression(steps, direction, perlin_name, perlin_curve_factor, tx_factor)
def convert_region(region: Region, nmg: NodeMeshGuids): index_dir = region.gas_dir.get_subdir('index') if index_dir.has_gas_file('node_mesh_index'): return nodes_file = region.gas_dir.get_subdir('terrain_nodes').get_gas_file( 'nodes') node_gas = nodes_file.get_gas() nodes_section: Section = node_gas.items[0] node_sections = nodes_section.get_sections() mesh_guid_attrs = [ns.get_attr('mesh_guid') for ns in node_sections] node_mesh_index = {} node_mesh_guids = nmg.get_node_mesh_guids() for mesh_guid_attr in mesh_guid_attrs: mesh_guid = mesh_guid_attr.value.to_str_lower() assert mesh_guid in node_mesh_guids, str( mesh_guid) + ' is not in ' + str(node_mesh_guids) if mesh_guid not in node_mesh_index: node_mesh_index[mesh_guid] = Hex(len(node_mesh_index) + 1) mesh_id = node_mesh_index[mesh_guid] mesh_guid_attr.value = mesh_id nodes_file.save() node_mesh_index_attrs = [ Attribute(mesh_id, node_mesh_guids[mesh_guid]) for mesh_guid, mesh_id in node_mesh_index.items() ] index_dir.create_gas_file( 'node_mesh_index', Gas([Section('node_mesh_index', node_mesh_index_attrs)])).save() region_data = region.get_data() if region_data.mesh_range == 0: if 0 < region_data.scid_range < Hex.parse('0x00001000'): region_data.mesh_range = region_data.scid_range elif 0 < region_data.id < Hex.parse('0x00001000'): region_data.mesh_range = region_data.id if region_data.mesh_range != 0: region.save() print(f'Converted region {region.get_name()} to NMI')
def write_gas(self) -> Gas: return Gas( [Section('decals', [decal.to_gas() for decal in self.decals])])