Exemple #1
0
def load(data: ScnDataReader) -> List[Effect]:
    """
    Read all effects from here
    """
    data.mark("effects")
    num_effects = data.uint32()
    return [Effect.read(data) for _ in range(0, num_effects)]
Exemple #2
0
def load(data: ScnDataReader) -> List[ColorTable]:
    """
    Read in all of the colors
    """
    data.mark(name='colors')
    num_color_tables = data.uint16(debug='num_color_tables')
    return [ColorTable.read(data) for _ in range(0, num_color_tables)]
Exemple #3
0
def load(data: ScnDataReader) -> List[Technology]:
    """
    Read all technologies from here
    """
    data.mark('technologies')
    num_techs = data.int16(debug='num_techs')
    return [Technology.read(data) for _ in range(0, num_techs)]
Exemple #4
0
def load(data: ScnDataReader) -> List[Civilization]:
    """
    Read all civilizations from here
    """
    data.mark("civilizations")
    num_civs = data.int16(debug='num_civs')
    for i in range(0, num_civs):
        data.uint8(debug='civ_type {}'.format(i))
        data.string_fixed(size=20, debug='civ_name {}'.format(i))
        civ_num_attributes = data.uint16(
            debug='civ_num_attributes {}'.format(i))
        civ_effect = data.int16(debug='civ_effect {}'.format(i))
        # civ_bonus_effect = data.int16(debug='civ_bonus_effect {}'.format(i)) # Might not exist in AOE1 dat.
        civ_attributes = [
            data.float32(debug='civ_attribute {} {}'.format(i, x))
            for x in range(0, civ_num_attributes)
        ]
        civ_icon_set = data.uint8(debug='civ_icon_set {}'.format(i))
        civ_num_units = data.uint16(debug='civ_num_units {}'.format(i))
        civ_unit_available = [
            data.boolean32(debug='civ_unit_available {} {}'.format(i, x))
            for x in range(0, civ_num_units)
        ]
        for j in range(0, civ_num_units):
            if not civ_unit_available[j]:
                continue
            read_unit(data)
    return []
Exemple #5
0
def discard_extra_map_stuff(data: ScnDataReader):
    data.mark("Extra map stuff")
    # NB: Values from genie-rs skip way past random map data in AOE1 files.
    # data.int32(debug='_map_row_offset')
    # data.float32(debug='_map_min_x')
    # data.float32(debug='_map_min_y')
    # data.float32(debug='_map_max_x')
    # data.float32(debug='_map_max_y')
    # data.float32(debug='_map_max_x')
    # data.float32(debug='_map_max_y')
    # data.uint16(debug='_additional_terrain_count')
    # data.uint16(debug='_borders_used')
    # data.uint16(debug='_max_terrain')
    # data.uint16(debug='_tile_width')
    # data.uint16(debug='_tile_height')
    # data.uint16(debug='_tile_half_width')
    # data.uint16(debug='_tile_half_height')
    # data.uint16(debug='_elev_height')
    # data.uint16(debug='_current_row')
    # data.uint16(debug='_current_column')
    # data.uint16(debug='_block_begin_row')
    # data.uint16(debug='_block_end_row')
    # data.uint16(debug='_block_begin_column')
    # data.uint16(debug='_block_end_column')
    # data.int32(debug='_seach_map_pointer')
    # data.int32(debug='_seach_map_rows_pointer')
    # data.uint8(debug='_any_frame_change')
    # data.uint8(debug='_map_visible')
    # data.uint8(debug='_map_fog_of_war')
    # data.read(21 + 157 * 4)
    data.read(68)
Exemple #6
0
def load(data: ScnDataReader):
    # Terrain
    data.mark(name='terrain')
    # num_terrains_override = num_terrains
    num_terrains_override = 32
    for i in range(0, num_terrains_override):
        data.boolean8(debug='terrain_enabled {}'.format(i))
        data.uint8(debug='terrain_random {}'.format(i))  # always 0?
        data.string_fixed(size=13, debug='terrain_name {}'.format(i))
        data.string_fixed(size=13, debug='terrain_texture_name {}'.format(
            i))  # Maybe read as int and test agains -1?
        data.int32(debug='terrain_slp_id {}'.format(i))
        data.int32(debug='terrain_slp_pointer {}'.format(i))
        data.int32(debug='terrain_sound_id {}'.format(i))
        data.uint8(debug='terrain_minimap_color_high {}'.format(
            i))  #  These colors are off-by-one compared with AGE.
        data.uint8(debug='terrain_minimap_color_medium {}'.format(i))
        data.uint8(debug='terrain_minimap_color_low {}'.format(i))
        data.uint8(debug='terrain_minimap_color_cliff_lt {}'.format(i))
        data.uint8(debug='terrain_minimap_color_cliff_rt {}'.format(i))
        data.int8(debug='terrain_passable_id {}'.format(i))
        data.int8(debug='terrain_impassable_id {}'.format(i))
        # Animation
        data.boolean8(debug='terrain_animation_enabled {}'.format(i))
        data.int16(debug='terrain_anim_num_frames {}'.format(i))
        data.int16(debug='terrain_anim_num_pause_frames {}'.format(i))
        data.float32(debug='terrain_anim_frame_interval {}'.format(i))
        data.float32(debug='terrain_anim_replay_delay {}'.format(i))
        data.int16(debug='terrain_anim_frame {}'.format(i))
        data.int16(debug='terrain_anim_draw_frame {}'.format(i))
        data.float32(debug='terrain_anim_animate_last {}'.format(i))
        data.boolean8(debug='terrain_anim_frame_changed {}'.format(i))
        data.boolean8(debug='terrain_anim_drawn {}'.format(i))
        # Elevation sprites
        for j in range(0, 19):
            data.uint16(debug="terrain_elevation_sprite_frames {} {}".format(
                i, j))  # frames
            data.uint16(debug="terrain_elevation_sprite_facets {} {}".format(
                i, j))  # facets
            data.uint16(debug="terrain_elevation_sprite_frame_id {} {}".format(
                i, j))  # frame_id
        data.int16(debug="terrain_to_draw {}".format(i))
        data.uint16(debug="terrain_rows {}".format(i))
        data.uint16(debug="terrain_cols {}".format(i))
        # Borders
        for j in range(0, num_terrains_override):
            data.uint16(debug="terrain_border {} {}".format(i, j))

        # Objects
        for j in range(0, 30):
            data.uint16(debug="terrain_object_id {} {}".format(i, j))
        for j in range(0, 30):
            data.int16(debug="terrain_density {} {}".format(i, j))
        for j in range(0, 30):
            data.int8(debug="terrain_placement_flag {} {}".format(
                i, j))  # 0 for random, 1 for central

        data.uint16(debug="terrain_object_count {}".format(i))
        data.uint16(debug="padding {}".format(i))
    return []
Exemple #7
0
 def read(data: ScnDataReader):
     data.mark('random maps')
     num_random_maps = data.uint32(debug='num_random_maps')
     random_maps_pointer = data.uint32(debug='random_maps_pointer')  # 39845000 in empires_up.dat
     random_map_meta = [RandomMapMeta.read(data) for _ in range(0, num_random_maps)]
     # Data from random_map_meta repeats here
     random_maps = [RandomMap.read(data) for _ in range(0, num_random_maps)]
     return RandomMapListWrapper(
         num_random_maps,
         random_maps_pointer,
         random_map_meta,
         random_maps
     )
Exemple #8
0
def load(data: ScnDataReader) -> List[Sprite]:
    """
    Read all the sprites
    """
    data.mark(name='sprites')
    num_sprites = data.uint16(debug='num_sprites')
    sprites_exist = [data.uint32() for _ in range(0, num_sprites)]
    sprites = []
    for sprite_id in range(0, num_sprites):
        if sprites_exist[sprite_id] == 0:
            continue
        sprite = Sprite.read(data, sprite_id)
        sprites.append(sprite)
    return sprites
Exemple #9
0
def discard_first_map_stuff(data: ScnDataReader):
    data.mark(name='map tiles')
    data.uint32(debug='__vfptr')
    data.uint32(debug='map_pointer')
    data.uint32(debug='map_width')
    data.uint32(debug='map_height')
    data.uint32(debug='world_width')
    data.uint32(debug='world_height')
    # Advanced Genie Editor describes these as "19 x (Width, Height, Delta Y) 1st is flat tile, then 2x8 elevation ties, then 2 1:1 tiles"
    for i in range(0, 19):
        data.int16(debug='tile width {}'.format(i))
        data.int16(debug='tile height {}'.format(i))
        data.int16(debug='tile delta_y {}'.format(i))
    data.uint16(debug="padding?")
Exemple #10
0
    def read(data: ScnDataReader):
        # Load header
        file_version = data.string_fixed(size=4)
        file_version_float = float(file_version)
        header_size = data.uint32()
        data.mark(name='SCN header', limit=header_size)  # header size
        header_version = data.uint32(debug='header_version')

        if header_version >= 3:
            # DE scenario a bit different
            timestamp = data.uint32(debug='Timestamp maybe')
            string_marker = data.uint16(debug='string_marker')  # always 2656
            description = data.string16(debug='description')
            # Data sometimes here sometimes not. Need to check remaining bytes in header size to see if we can read it.
            if header_size - data.bytes_read_since_mark >= 8:
                # might not account for all possibilities for these fields
                has_single_player_victory_condition = data.boolean32()
                player_count = data.uint32()
            else:
                has_single_player_victory_condition = False
                player_count = -1
            scenario_header = ScnHeader(file_version=file_version_float,
                                        header_version=header_version,
                                        timestamp=timestamp,
                                        description=description,
                                        has_singleplayer_victory_condition=
                                        has_single_player_victory_condition,
                                        player_count=player_count)
        else:
            timestamp = data.uint32(debug='timestamp')
            scenario_header = ScnHeader(
                file_version=file_version_float,
                header_version=header_version,
                timestamp=timestamp,
                description=data.string32(),
                has_singleplayer_victory_condition=data.boolean32(),
                player_count=data.uint32())
        logging.debug(scenario_header)
        data.unmark()
        data.decompress()

        return scenario_header
Exemple #11
0
def load(data: ScnDataReader) -> List[TerrainTable]:
    # Read the terrain tables
    data.mark(name='terrain tables')
    num_terrain_tables = data.uint16(debug='num_terrain_tables')
    num_terrains = data.uint16(debug='num_terrains')
    unknown_values = []
    for terrain_table_id in range(0, num_terrain_tables):
        unknown_value = data.uint32(
            debug="terrain table {} unknown value".format(terrain_table_id))
        unknown_values.append(unknown_value)
    terrain_tables = []
    for terrain_table_id in range(0, num_terrain_tables):
        passable = [
            data.float32("passability table={} terrain={}".format(
                terrain_table_id, terrain_id))
            for terrain_id in range(0, num_terrains)
        ]
        terrain_tables.append(
            TerrainTable(unknown_values[terrain_table_id], passable))
    return terrain_tables
Exemple #12
0
def load(file_name: str):
    if not (file_name.endswith(".slp")):
        raise Exception("SLP file must end with .slp")

    with open(file_name, 'rb') as f:
        all_data = f.read()
        data = ScnDataReader(all_data)

    header = SlpHeader.read(data)
    frames = []
    for i in range(0, header.frames):
        data.mark('frame {}'.format(i))
        frame_info = SlpFrameInfo.read(data)
        # Sub-reader for outline data (identified by offset)
        outline_region_start = frame_info.outline_table_offset
        outline_region_end = outline_region_start + frame_info.height * 4
        outline_reader = ScnDataReader(
            all_data[outline_region_start:outline_region_end])
        frame_outline = SlpOutline.read(outline_reader, frame_info.height)
        # Sub-reader for pixel offsets
        command_offset_region_start = frame_info.command_table_offset
        command_offset_region_end = command_offset_region_start + frame_info.height * 4
        command_offset_reader = ScnDataReader(
            all_data[command_offset_region_start:command_offset_region_end])
        command_offset = SlpCommandOffset.read(command_offset_reader,
                                               frame_info.height)
        # Sub-reader for pixel data (very inefficient..)
        command_data_reader = ScnDataReader(all_data)
        command_data_reader.read(
            command_offset.row[0]
        )  # read and discard so that we don't need to do maths to find in-file offset
        rows = []
        for y in range(0, frame_info.height):
            row = SlpRow.read(command_data_reader, frame_outline.row[y])
            rows.append(row)
        frames.append(SlpFrame(frame_info, rows))
    return SlpFile(header, frames)
Exemple #13
0
def load(data: ScnDataReader) -> List[TerrainBorder]:
    """
    Read all of the terrain borders
    """
    data.mark(name='terrain borders')
    return [TerrainBorder.read(data) for _ in range(0, 16)]
    def read_de(data: ScnDataReader):
        version = data.float32(debug='version')

        for i in range(0, 16):
            data.uint16(debug='some number here')  # 2656
            data.string16(debug='player tribe name')

        if version >= 3.13:
            # These 16 bytes are not present in some DE scenarios bundled w/ the game, labelled version 3.125.
            for i in range(0, 16):
                # Guessing its a string ref, have not checked
                data.int32(debug="unknown_string_ref for player {}".format(i))

        for i in range(0, 16):
            player_base_props = ScnPlayerBaseProperties.read(data)
            logging.debug(player_base_props)

        data.boolean32(debug='conquest maybe')
        data.float32(debug='probable check field')

        data.uint8(debug='unknown field')

        data.uint16(debug='some number here')  # 2656
        data.string16(debug='scenario_name')

        data.uint16(debug='some number here')  # 2656
        data.string16(debug='scenario_instructions')

        data.uint16(debug='some number here')  # 2656
        data.string16(debug='history_string')

        data.uint16(debug='some number here')  # 2656
        data.string16(debug='victory_string')

        data.uint16(debug='some number here')  # 2656
        data.string16(debug='loss_string')

        data.uint16(debug='some number here')  # 2656
        data.string16(debug='history_string')

        data.int32(debug='instructions_string_reference')
        data.uint16(debug='some_number_here')  # 2656
        data.string16(debug='instructions_vox')

        data.int32(debug='hints_string_reference')
        data.uint16(debug='some_number_here')  # 2656
        data.string16(debug='hints_vox')

        data.int32(debug='victory_string_reference')
        data.uint16(debug='some_number_here')  # 2656
        data.string16(debug='victory_vox')

        data.int32(debug='loss_string_reference')
        data.uint16(debug='some_number_here')  # 2656
        data.string16(debug='loss_vox')

        data.int32(debug='history_string_reference')
        data.uint16(debug='some_number_here')  # 2656
        data.string16(debug='history_vox')

        # Not sure if cinematics or per-player personality, AI, city plans etc

        data.uint16(debug='some_number_here')  # 2656
        data.string16(debug='unidentified_string 1')  # ' <None> '

        data.uint16(debug='some_number_here')  # 2656
        data.string16(debug='unidentified_string 2')  # ' <None> '

        data.uint16(debug='some_number_here')  # 2656
        data.string16(debug='unidentified_string 3')  # ' <None> '

        data.uint16(debug='some_number_here')  # 2656
        data.string16(debug='unidentified_string 4')  # ' <None> '

        data.uint32(debug='unidentified number 1')  # 0
        data.uint32(debug='unidentified number 2')  # 0
        data.uint32(debug='unidentified number 3')  # 0
        data.uint16(debug='unidentified number 4')  # 1

        for i in range(0, 16):
            data.string16(debug="ai player {}".format(i))

        for i in range(0, 16):
            data.string16(debug="city plan player {}".format(i))

        for i in range(0, 16):
            data.string16(debug="personality player {}".format(i))

        for i in range(0, 16):
            some_length1 = data.uint32(debug='some length maybe')
            some_length2 = data.uint32(debug='some length maybe')
            some_length3 = data.uint32(debug='some length maybe')
            data.string_fixed(some_length1, debug='some string 1')
            data.string_fixed(some_length2, debug='some string 2')
            data.string_fixed(some_length3, debug='some string 3')

        check1 = data.int32(debug='check value 1')
        if check1 != -99:
            raise Exception("Check value did not match in scenario data, giving up")

        if version < 3.13:
            data.mark('extra data observed in 3.125 version')
            for i in range(0, 32):
                data.int32(debug='unknown value 1 {}'.format(i))  # 500
            for i in range(0, 32):
                data.int32(debug='unknown value 2 {}'.format(i))  # 0

        check2 = data.int32(debug='check value 2')
        if check2 != -99:
            raise Exception("Check value did not match in scenario data, giving up")

        rge_scen = ScnEngineProperties(
            version
        )
        logging.debug(rge_scen)
        return rge_scen
Exemple #15
0
def load(data: ScnDataReader) -> List[Sound]:
    data.mark(name='sounds')
    num_sounds = data.uint16(debug='num_sounds')
    return [Sound.read(data) for _ in range(0, num_sounds)]
Exemple #16
0
def read_base_unit_props(data: ScnDataReader):
    data.mark("base unit")
    unit_name_len = data.uint16(debug='unit_name_len')
    unit_id = data.int16(debug='unit_id')
    unit_name_string_id = data.int16(debug='unit_name_string_id')
    unit_creation_string_id = data.int16(debug='unit_creation_string_id')
    unit_class = data.int16(debug='unit_class')
    standing_sprite = data.int16(
        debug='standing_sprite')  # no standing sprite #2 here.. ?
    dying_sprite = data.int16(debug='dying_sprite')
    undead_sprite = data.int16(debug='undead_sprite')
    undead_flag = data.int8(debug='undead_flag')
    hp = data.uint16(debug='hp')
    los = data.float32(debug='los')
    garrison_capacity = data.uint8(debug='garrison_capacity')
    collision_radius = (data.float32(debug='collision_radius1'),
                        data.float32(debug='collision_radius2'),
                        data.float32(debug='collision_radius3'))
    unit_train_sound = data.int16(debug='train_sound')
    # unit_damage_sound = data.int16(debug='damage_sound')
    unit_death_spawn = data.int16(
        debug='unit_death_spawn')  # no unit_damage_sound here ??
    unit_sort_number = data.uint8(debug='unit_sort_number')
    unit_can_be_built_on = data.uint8(debug='unit_can_be_built_on')
    unit_button_picture = data.int16(debug='unit_button_picture')
    unit_hide_in_scenario_editor = data.boolean8(
        debug='unit_hide_in_scenario_editor')
    unit_portrait_picture = data.int16(debug='unit_portrait_picture')
    unit_enabled = data.boolean8(
        debug='unit_enabled')  # no unit_disabled here ??
    unit_tile_req = (data.int16(debug='unit_tile_req1'),
                     data.int16(debug='unit_tile_req2')
                     )  # "Placement side terrains"
    unit_center_tile_req = (data.int16(debug='unit_center_tile_req1'),
                            data.int16(debug='unit_center_tile_req1'))
    unit_construction_radius = (data.float32(
        debug='unit_construction_radius1'),
                                data.float32(
                                    debug='unit_construction_radius2'))
    unit_elevation_flag = data.boolean8(debug='unit_elevation_flag')
    unit_fog_flag = data.boolean8(debug='unit_fog_flag')
    unit_terrain_restriction_id = data.uint16(
        debug='unit_terrain_restriction_id')  # "terrain tables"
    unit_movement_type = data.uint8(debug='unit_movement_type')
    unit_attribute_max_amount = data.uint16(
        debug='unit_attribute_max_amount')  # resource capacity
    unit_attribute_rot = data.float32(debug='unit_attribute_rot')  # decay
    unit_area_effect_level = data.uint8(debug='unit_area_effect_level')
    unit_combat_level = data.uint8(debug='unit_combat_level')
    unit_select_level = data.uint8(debug='unit_select_level')
    unit_map_draw_level = data.uint8(debug='unit_map_draw_level')
    unit_level = data.uint8(debug='unit_level')
    unit_multiple_attribute_mod = data.float32(
        debug='unit_multiple_attribute_mod')
    unit_map_color = data.uint8(debug='unit_map_color')
    unit_help_string_id = data.uint32('unit_help_string_id')
    unit_help_page_id = data.uint32(debug='unit_help_page_id')
    unit_hotkey_id = data.uint32(debug='unit_hotkey_id')
    unit_recyclable = data.boolean8(debug='unit_recyclable')
    unit_track_as_resource = data.boolean8(debug='unit_track_as_resource')
    unit_create_doppleganger = data.boolean8(debug='unit_create_doppleganger')
    unit_resource_group = data.uint8(
        debug='unit_resource_group')  # tree/stone/gold etc
    unit_occlusion_mask = data.uint8(
        debug='unit_occlusion_mask')  # "hill mode" in AGE
    unit_obstruction_type = data.uint8(
        debug='unit_obstruction_type'
    )  # dropped unit_selection_shape, unit_civilization, unit_attribute_piece
    # # object flags go here in later versions
    selection_outline_radius = (
        data.float32(debug='selection_outline_radius1'),
        data.float32(debug='selection_outline_radius2'),
        data.float32(debug='selection_outline_radius3'))
    for i in range(0, 3):
        attribute_res = data.int16(debug='attribute_res {}'.format(i))
        attribute_amount = data.float32(debug='attribute_amount {}'.format(i))
        attribute_store_mode = data.int8(
            debug='attribute_store_mode {}'.format(i))
    num_damage_sprites = data.uint8(debug='num_damage_sprites')
    for i in range(0, num_damage_sprites):
        damage_sprite = data.uint16(debug='damage_sprite {}'.format(i))
        damage_percent = data.uint8(debug='damage_percent {}'.format(i))
        damage_apply_mode = data.uint8(debug='damage_apply_mode {}'.format(i))
        damage_unused = data.uint8(debug='damage_unused {}'.format(i))
    unit_selected_sound = data.int16(debug='unit_selected_sound')
    unit_death_sound = data.int16(debug='unit_death_sound')
    unit_attack_reaction = data.uint8(debug='unit_attack_reaction')
    unit_convert_terrain_flag = data.uint8(debug='unit_convert_terrain_flag')
    unit_name = data.string_fixed(size=unit_name_len, debug='unit_name')
    data.uint16(debug='unit_copy_id')  # dropped unit_copy_id, unit_group
    return unit_name