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 []
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
def read_classic(data: ScnDataReader): base = ScnEngineProperties.read_classic(data) version = base.rge_version if version <= 1.13: for i in range(0, 16): # skip past player names player_name = data.string_fixed(size=256) raise Exception( "Not implemented: Don't know how to read player base properties from <1.13 file" ) else: player_start_resources = [] for i in range(0, 16): # Ignoring at the moment this_player_start_resources = ScnPlayerStartResources.read( data, version) player_start_resources.append(this_player_start_resources) if version >= 1.02: check5 = data.int32() if check5 != -99: raise Exception( "Check value did not match in scenario data, giving up") victory_conquest = data.uint32() victory_ruins = data.uint32() victory_artifacts = data.uint32() victory_discoveries = data.uint32() victory_exploration = data.uint32() victory_gold = data.uint32() victory_all_flag = data.boolean32() if version >= 1.13: mp_victory_type = data.uint32() victory_score = data.uint32() victory_time = data.uint32() for i in range(0, 16): for j in range(0, 16): stance = data.uint32() logging.debug("Diplomacy from=%d to=%d stance=%d", i, j, stance) # 12 victory conditions for each player for i in range(0, 16): for j in range(0, 12): # TODO read these ??? individual_victory_blob = data.read(60) if version >= 1.02: check5 = data.int32() if check5 != -99: raise Exception( "Check value did not match in scenario data, giving up") # Allied victory for i in range(0, 16): allied_victory = data.uint32() if version >= 1.24: raise Exception( "Not implemented: Don't know how to read team information from >=1.24 file" ) if version >= 1.18: # Also has disabled units and building, where are they in older versions? raise Exception( "Not implemented: Don't know how to read tech tree from >=1.18 file" ) elif version > 1.03: for i in range(0, 16): for j in range(0, 20): disabled_tech_id = data.uint32() logging.debug("Disabled tech player %d, position %d: %d", i, j, disabled_tech_id) if version > 1.04: data.uint32() # No idea if version >= 1.12: data.uint32() # No idea full_tech_tree = data.boolean32() if version > 1.05: for i in range(0, 16): player_start_age = data.uint32() if version >= 1.02: check6 = data.int32() if check6 != -99: raise Exception( "Check value did not match in scenario data, giving up") if version >= 1.19: # 'view'?? data.uint32() data.uint32() if version >= 1.21: raise Exception( "Not implemented: Don't know how to read map type from >=1.21 file" ) if version >= 1.21: raise Exception( "Not implemented: Don't know how to read base priorities from >=1.21 file" ) game_properties = ScnGameProperties(base) logging.debug(game_properties) return game_properties
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