Example #1
0
    def store_generated_objects(self):
        snci_section = self.gas_dir.get_or_create_subdir(
            'index').get_or_create_gas_file(
                'streamer_node_content_index').get_gas().get_or_create_section(
                    'streamer_node_content_index')
        all_ioids = [
            Hex.parse('0x' + str(attr.value)[5:])
            for attr in snci_section.get_attrs()
        ]  # all internal object ids (internal meaning without scid range)
        streamer_node_content_index = {}
        object_sections = []
        last_ioid = 0
        for go_data in self.generated_objects_non_interactive:
            assert isinstance(go_data, GameObjectData)
            assert go_data.scid is None
            ioid = last_ioid + 1
            while ioid in all_ioids:  # find free oid
                ioid += 1
            last_ioid = ioid
            go_data.scid = Hex.parse('0x{:03X}{:05X}'.format(
                self.data.scid_range, ioid))

            object_sections.append(go_data.make_gas())
            node_guid = go_data.placement.position.node_guid
            if node_guid not in streamer_node_content_index:
                streamer_node_content_index[node_guid] = []
            streamer_node_content_index[node_guid].append(go_data.scid)
        objects_dir = self.gas_dir.get_or_create_subdir('objects')
        objects_dir.get_or_create_gas_file(
            'non_interactive').get_gas().items.extend(object_sections)
        snci_attrs = []
        for node_guid, oids in streamer_node_content_index.items():
            snci_attrs.extend([Attribute(node_guid, oid) for oid in oids])
        snci_section.items.extend(snci_attrs)
Example #2
0
def edit_region_mesh_range(region: Region, new_mesh_range: Hex):
    new_mesh_range_str = str(new_mesh_range)
    assert new_mesh_range_str.startswith(
        '0x00000')  # only last 3 digits may be used
    old_mesh_range: Hex = region.get_data().mesh_range
    if new_mesh_range == old_mesh_range:
        print('no change in mesh range')
        return

    print('edit mesh range: ' + str(old_mesh_range) + ' -> ' +
          str(new_mesh_range))
    region.get_data().mesh_range = new_mesh_range
    region.save()

    new_mesh_prefix = new_mesh_range_str[7:]
    assert len(new_mesh_prefix) == 3, new_mesh_prefix
    # replace & collect in node_mesh_index
    node_mesh_index_file = region.gas_dir.get_subdir('index').get_gas_file(
        'node_mesh_index')
    mesh_replacements = list()
    for node_mesh_attr in node_mesh_index_file.get_gas().get_section(
            'node_mesh_index').items:
        assert isinstance(node_mesh_attr, Attribute)
        old_hex = Hex.parse(node_mesh_attr.name)
        new_hex = Hex.parse('0x' + new_mesh_prefix + node_mesh_attr.name[5:])
        mesh_replacements.append((old_hex, new_hex))
        node_mesh_attr.name = new_hex.to_str_lower()
    node_mesh_index_file.save()
    # replace mesh references in terrain nodes
    replace_hexes_in_file(
        region.gas_dir.get_subdir('terrain_nodes').get_gas_file('nodes').path,
        mesh_replacements)
Example #3
0
    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()})
Example #4
0
def main(argv):
    path = argv[0]
    hexes = [(Hex.parse(hex_hex.split(',')[0]), Hex.parse(hex_hex.split(',')[1])) for hex_hex in argv[1].split(';')]
    if os.path.isdir(path):
        replace_hexes_in_dir(path, hexes)
    elif os.path.isfile(path):
        replace_hexes_in_file(path, hexes)
    else:
        assert False, f'{path} does not exist'
    return 0
Example #5
0
def get_stitch_id(rx: int, rz: int, hv: bool, xz: int):
    assert 0 <= rx < 100
    assert 0 <= rz < 100
    assert 0 <= xz < 0x1000
    rx = str(rx).zfill(2)
    rz = str(rz).zfill(2)
    hv = '0' if hv else '1'
    stitch_range = f'0x{rx}{rz}{hv}000'
    return Hex.parse(stitch_range) + xz
Example #6
0
def edit_region_ids(map_name,
                    region_name,
                    mesh_range=None,
                    scid_range=None,
                    guid=None):
    bits = Bits()
    assert map_name in bits.maps, map_name
    _map = bits.maps[map_name]
    regions = _map.get_regions()
    assert region_name in regions, region_name
    region = regions[region_name]
    if mesh_range is not None:
        edit_region_mesh_range(region, Hex.parse(mesh_range))
    region.gas_dir.clear_cache()
    region.load_data()
    if scid_range is not None:
        edit_region_scid_range(region, Hex.parse(scid_range))
    region.gas_dir.clear_cache()
    region.load_data()
    if guid is not None:
        edit_region_guid(region, Hex.parse(guid))
Example #7
0
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')
Example #8
0
def edit_region_scid_range(region: Region, new_scid_range: Hex):
    new_scid_range_str = str(new_scid_range)
    assert new_scid_range_str.startswith(
        '0x00000')  # only last 3 digits may be used
    old_scid_range: Hex = region.get_data().scid_range
    if new_scid_range == old_scid_range:
        print('no change in scid range')
        return
    # check that no region already uses the new scid range
    other_regions: list[Region] = [
        r for r in region.map.get_regions().values()
        if r.get_name() != region.get_name()
    ]
    other_regions_using_new_scid_range = [
        r for r in other_regions if r.get_data().scid_range == new_scid_range
    ]
    assert len(
        other_regions_using_new_scid_range
    ) == 0, f'new scid range is already used by {[r.get_name() for r in other_regions_using_new_scid_range]}'
    # check that target region is the only one with the old scid range
    other_regions_using_old_scid_range = [
        r for r in other_regions if r.get_data().scid_range == old_scid_range
    ]
    assert len(
        other_regions_using_old_scid_range
    ) == 0, f'old scid range is also used by {[r.get_name() for r in other_regions_using_old_scid_range]}'

    print('edit scid range: ' + str(old_scid_range) + ' -> ' +
          new_scid_range_str)
    region.get_data().scid_range = new_scid_range
    region.save()

    new_scid_prefix = new_scid_range_str[7:]
    assert len(new_scid_prefix) == 3, new_scid_prefix
    old_scids = region.get_scids()
    scid_replacements = [
        (old_scid, Hex.parse('0x' + new_scid_prefix + str(old_scid)[5:]))
        for old_scid in old_scids
    ]
    # replace in all files of target region
    replace_hexes_in_dir(region.gas_dir.path, scid_replacements)
    # replace in referencing files of all regions
    replace_hexes_in_dir(region.map.gas_dir.path, scid_replacements,
                         'elevator.gas')
    replace_hexes_in_dir(region.map.gas_dir.path, scid_replacements,
                         'interactive.gas')
    replace_hexes_in_dir(region.map.gas_dir.path, scid_replacements,
                         'special.gas')
Example #9
0
    def load_terrain(self):
        node_mesh_index_file = self.gas_dir.get_subdir('index').get_gas_file(
            'node_mesh_index')
        nmi = {
            Hex.parse(attr.name): attr.value
            for attr in node_mesh_index_file.get_gas().get_section(
                'node_mesh_index').get_attrs()
        }

        nodes_gas_file = self.gas_dir.get_subdir('terrain_nodes').get_gas_file(
            'nodes')
        nodes_gas = NodesGas.load(nodes_gas_file)

        # ambient light
        ambient_light = AmbientLight(nodes_gas.ambient_color,
                                     nodes_gas.ambient_intensity,
                                     nodes_gas.object_ambient_color,
                                     nodes_gas.object_ambient_intensity,
                                     nodes_gas.actor_ambient_color,
                                     nodes_gas.actor_ambient_intensity)

        # nodes
        nodes = list()
        nodes_dict = dict()
        for snode in nodes_gas.nodes:
            assert snode.mesh_guid in nmi, 'unknown mesh_guid: ' + str(
                snode.mesh_guid)
            mesh_name = nmi[snode.mesh_guid]
            node = TerrainNode(snode.guid, mesh_name, snode.texsetabbr)
            node.section = snode.nodesection if snode.nodesection != 0xffffffff else -1
            node.level = snode.nodelevel if snode.nodelevel != 0xffffffff else -1
            node.object = snode.nodeobject if snode.nodeobject != 0xffffffff else -1
            nodes_dict[snode.guid] = node
            nodes.append(node)
        for snode in nodes_gas.nodes:
            node = nodes_dict[snode.guid]
            for door in snode.doors:
                far_node = nodes_dict[door.farguid]
                node.doors[door.id] = (far_node, door.fardoor)

        target_node = nodes_dict[nodes_gas.targetnode]

        terrain = Terrain()
        terrain.nodes = nodes
        terrain.target_node = target_node
        terrain.ambient_light = ambient_light
        self.terrain = terrain