class PlayerUnitsStruct(AoE2Struct): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { "unit_count": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("self", "units"), DependencyEval("len(x)")) }, "units": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "unit_count")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "unit_count")) }, } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever("unit_count", DataType("u32")), Retriever("units", DataType(UnitStruct)) ] super().__init__("Player Units", retrievers, parser_obj, data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'unit_count': 0, 'units': [], } return defaults
def _fill_dependencies(dependencies): for disabled_type in ["tech", "building", "unit"]: dependencies[f"per_player_number_of_disabled_{disabled_type}s"] = { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget(["self"] * 8, [ f"disabled_{disabled_type}_ids_player_{p}" for p in range(1, 9) ]), DependencyEval( "[len(x) for x in [p1, p2, p3, p4, p5, p6, p7, p8]]", values_as_variable=[ 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8' ])) } for player in range(1, 9): dependencies[f"disabled_{disabled_type}_ids_player_{player}"] = { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget( "self", f"per_player_number_of_disabled_{disabled_type}s"), DependencyEval(f"x[{player - 1}]")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget( "self", f"per_player_number_of_disabled_{disabled_type}s")) if player == 1 else None }
class BackgroundImagePiece(aoe2_piece.AoE2Piece): dependencies = { 'bitmap_info': { "on_construct": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "picture_orientation"), DependencyEval("1 if x in [-1, 2] else 0") ) }, } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever("ascii_filename", DataType("str16")), Retriever("picture_version", DataType("u32")), Retriever("bitmap_width", DataType("u32")), Retriever("bitmap_height", DataType("s32")), Retriever("picture_orientation", DataType("s16")), Retriever("bitmap_info", DataType(BitMapInfoStruct), possibly_list=False), ] super().__init__("Background Image", retrievers, parser_obj, data=data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'ascii_filename': '', 'picture_version': 3, 'bitmap_width': 0, 'bitmap_height': 0, 'picture_orientation': 1, 'bitmap_info': [] } return defaults
class OptionsPiece(aoe2_piece.AoE2Piece): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { 'number_of_triggers': { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("TriggerPiece", "trigger_data"), DependencyEval("len(x)") ) } } _fill_dependencies(dependencies) def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [] for disabled_type in ["tech", "building", "unit"]: retrievers.append(Retriever(f"per_player_number_of_disabled_{disabled_type}s", DataType("u32", repeat=16))) for player in range(1, 9): retrievers.append(Retriever(f"disabled_{disabled_type}_ids_player_{player}", DataType("u32"))) # Unused: Players 9 - 16 can't have {disabled_type} technologies retrievers.append(Retriever(f"disabled_{disabled_type}_ids_player9-16", DataType("u32", repeat=0))) retrievers += [ Retriever("combat_mode", DataType("u32")), Retriever("naval_mode", DataType("u32")), Retriever("all_techs", DataType("u32")), Retriever("per_player_starting_age", DataType("u32", repeat=16)), # 2: Dark 6 = Post | 1-8 players 9 GAIA Retriever("unknown", DataType("32")), Retriever("number_of_triggers", DataType("u32")), ] super().__init__("Options", retrievers, parser_obj, data=data, pieces=pieces) @staticmethod def defaults(pieces): defaults = {} for disabled_type in ["tech", "building", "unit"]: defaults[f'per_player_number_of_disabled_{disabled_type}s'] = [0] * 16 for player in range(1, 9): defaults[f'disabled_{disabled_type}_ids_player_{player}'] = [] defaults[f'disabled_{disabled_type}_ids_player9-16'] = [] defaults = dict(**defaults, **{ 'combat_mode': 0, 'naval_mode': 0, 'all_techs': 0, 'per_player_starting_age': [2] * 16, # 'unknown': b'\x9d\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00', # 'unknown': b'\x9d\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # b'\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'unknown': b'\x9d\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'number_of_triggers': 0, }) return defaults
class UnitsPiece(aoe2_piece.AoE2Piece): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { "number_of_unit_sections": { "on_refresh": RetrieverDependency(DependencyAction.SET_VALUE, DependencyTarget("self", "players_units"), DependencyEval('len(x)')) }, "players_units": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_unit_sections")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "number_of_unit_sections")) } } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever("number_of_unit_sections", DataType("u32")), Retriever("player_data_4", DataType(PlayerDataFourStruct, repeat=8)), Retriever("number_of_players", DataType("u32")), # Also always 9 (Gaia + 8Plyrs) Retriever("player_data_3", DataType(PlayerDataThreeStruct, repeat=8)), Retriever("players_units", DataType(PlayerUnitsStruct)), ] super().__init__("Units", retrievers, parser_obj, data=data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'number_of_unit_sections': 9, 'player_data_4': [ PlayerDataFourStruct( data=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 200.0], pieces=pieces) for _ in range(8) ], 'number_of_players': 9, 'player_data_3': UnitsPiece._get_player_data_three_default(pieces), 'players_units': [PlayerUnitsStruct(data=[0, []], pieces=pieces) for _ in range(9)], } return defaults @staticmethod def _get_player_data_three_default(pieces): data = [ list(PlayerDataThreeStruct.defaults(pieces).values()) for _ in range(8) ] for i in range(len(data)): # diplomacy_for_interaction data[i][7] = [3] + ([3] * i) + [0] + ([3] * (7 - i)) # diplomacy_for_ai_system data[i][8] = [0] + ([4] * i) + [1] + ([4] * (7 - i)) # Color data[i][9] = i return [PlayerDataThreeStruct(data=d, pieces=pieces) for d in data]
class PlayerDataThreeStruct(AoE2Struct): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { "player_count_for_diplomacy": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("self", "diplomacy_for_interaction"), DependencyEval("len(x)")) }, "diplomacy_for_interaction": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "player_count_for_diplomacy")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "player_count_for_diplomacy")) }, "victory_version": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("self", "unknown_2"), DependencyEval("2 if len(x) == 7 else 0")) }, "unknown": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("self", "unknown_structure_grand_theft_empires"), DependencyEval("len(x)")) }, "unknown_2": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "victory_version"), DependencyEval("7 if x == 2 else 0")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "victory_version")) }, "unknown_5": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "victory_version"), DependencyEval("1 if x == 2 else 0")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) }, "unknown_structure_grand_theft_empires": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "unknown") ), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "unknown")) }, "unknown_structure_ww_campaign_2": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "unknown_5")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) }, } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever("constant_name", DataType("str16")), Retriever("initial_camera_x", DataType("f32")), Retriever("initial_camera_y", DataType("f32")), Retriever("unknown_similar_to_camera_x", DataType("s16")), Retriever("unknown_similar_to_camera_y", DataType("s16")), Retriever("aok_allied_victory", DataType("u8")), Retriever("player_count_for_diplomacy", DataType("u16")), Retriever("diplomacy_for_interaction", DataType("u8")), Retriever("diplomacy_for_ai_system", DataType("u32", repeat=9)), Retriever("color", DataType("u32")), Retriever("victory_version", DataType("f32")), Retriever("unknown", DataType("u16")), Retriever("unknown_2", DataType("u8")), Retriever("unknown_structure_grand_theft_empires", DataType("44")), Retriever("unknown_5", DataType("u8"), possibly_list=False), Retriever("unknown_3", DataType("u8", repeat=7)), # Todo: Has to change value of unknown_5. But currently not supported Retriever("unknown_structure_ww_campaign_2", DataType("32")), Retriever("unknown_4", DataType("s32")), ] super().__init__("Player Data #3", retrievers, parser_obj, data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'constant_name': 'Scenario Editor Phantom', 'initial_camera_x': 72.0, 'initial_camera_y': 72.0, 'unknown_similar_to_camera_x': 72, 'unknown_similar_to_camera_y': 72, 'aok_allied_victory': 0, 'player_count_for_diplomacy': 9, 'diplomacy_for_interaction': [3, 0, 3, 3, 3, 3, 3, 3, 3], 'diplomacy_for_ai_system': [0, 1, 4, 4, 4, 4, 4, 4, 4], 'color': 0, 'victory_version': 2.0, 'unknown': 0, 'unknown_2': [0, 0, 0, 0, 0, 0, 0], 'unknown_5': 0, 'unknown_structure_grand_theft_empires': [], 'unknown_3': [0, 0, 0, 0, 0, 0, 0], 'unknown_structure_ww_campaign_2': [], 'unknown_4': -1, } return defaults
class EffectStruct(AoE2Struct): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { "effect_type": { "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget(['self', 'self', 'self'], ['aa_quantity', 'aa_armor_or_attack_type', 'quantity']) ) }, "aa_quantity": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget('self', 'effect_type'), DependencyEval('1 if x in [28, 31] else 0') ), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) }, "aa_armor_or_attack_type": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget('self', 'effect_type'), DependencyEval('1 if x in [28, 31] else 0') ), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) }, "quantity": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget('self', 'effect_type'), DependencyEval('1 if x not in [28, 31] else 0') ), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) }, "number_of_units_selected": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget('self', 'selected_object_ids'), DependencyEval('len(x) if len(x) != 0 else -1') ) }, "selected_object_ids": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_units_selected"), ), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "number_of_units_selected") ) }, # "player_color": { # "on_refresh": RetrieverDependency( # DependencyAction.SET_REPEAT, # DependencyTarget('FileHeaderPiece', 'version'), # DependencyEval('1 if x in [\'1.40\'] else 0') # ), # "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) # }, } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever("effect_type", DataType("s32")), Retriever("static_value_46", DataType("s32")), # always 0x17, now 0x30 (48)? Retriever("ai_script_goal", DataType("s32")), Retriever("aa_quantity", DataType("u8")), Retriever("aa_armor_or_attack_type", DataType("s24")), Retriever("quantity", DataType("s32")), Retriever("tribute_list", DataType("s32")), Retriever("diplomacy", DataType("s32")), Retriever("number_of_units_selected", DataType("s32")), Retriever("unknown", DataType("s32")), Retriever("object_list_unit_id", DataType("s32")), Retriever("source_player", DataType("s32")), Retriever("target_player", DataType("s32")), Retriever("technology", DataType("s32")), Retriever("string_id", DataType("s32")), Retriever("unknown_2", DataType("s32")), Retriever("display_time", DataType("s32")), Retriever("trigger_id", DataType("s32")), Retriever("location_x", DataType("s32")), Retriever("location_y", DataType("s32")), Retriever("area_1_x", DataType("s32")), Retriever("area_1_y", DataType("s32")), Retriever("area_2_x", DataType("s32")), Retriever("area_2_y", DataType("s32")), Retriever("object_group", DataType("s32")), Retriever("object_type", DataType("s32")), Retriever("instruction_panel_position", DataType("s32")), Retriever("attack_stance", DataType("s32")), Retriever("time_unit", DataType("s32")), Retriever("enabled_or_victory", DataType("s32")), Retriever("food", DataType("s32")), Retriever("wood", DataType("s32")), Retriever("stone", DataType("s32")), Retriever("gold", DataType("s32")), Retriever("item_id", DataType("s32")), Retriever("flash_object", DataType("s32")), Retriever("force_research_technology", DataType("s32")), Retriever("visibility_state", DataType("s32")), Retriever("scroll", DataType("s32")), Retriever("operation", DataType("s32")), Retriever("object_list_unit_id_2", DataType("s32")), Retriever("button_location", DataType("s32")), Retriever("ai_signal_value", DataType("s32")), Retriever("unknown_3", DataType("s32")), Retriever("object_attributes", DataType("s32")), Retriever("from_variable", DataType("s32")), Retriever("variable_or_timer", DataType("s32")), Retriever("facet", DataType("s32")), Retriever("location_object_reference", DataType("s32")), Retriever("play_sound", DataType("s32")), Retriever("player_color", DataType("s32")), Retriever("unknown_4", DataType("s32")), Retriever("message", DataType("str32")), Retriever("sound_name", DataType("str32")), Retriever("selected_object_ids", DataType("s32")), ] super().__init__("Effect", retrievers, parser_obj, data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'effect_type': 0, 'static_value_46': 48, 'ai_script_goal': -1, 'quantity': -1, 'aa_quantity': -1, 'aa_armor_or_attack_type': -1, 'tribute_list': -1, 'diplomacy': -1, 'number_of_units_selected': -1, 'unknown': -1, 'object_list_unit_id': -1, 'source_player': -1, 'target_player': -1, 'technology': -1, 'string_id': -1, 'unknown_2': -1, 'display_time': -1, 'trigger_id': -1, 'location_x': -1, 'location_y': -1, 'area_1_x': -1, 'area_1_y': -1, 'area_2_x': -1, 'area_2_y': -1, 'object_group': -1, 'object_type': -1, 'instruction_panel_position': -1, 'attack_stance': -1, 'time_unit': -1, 'enabled_or_victory': -1, 'food': -1, 'wood': -1, 'stone': -1, 'gold': -1, 'item_id': -1, 'flash_object': -1, 'force_research_technology': -1, 'visibility_state': -1, 'scroll': -1, 'operation': -1, 'object_list_unit_id_2': -1, 'button_location': -1, 'ai_signal_value': -1, 'unknown_3': -1, 'object_attributes': -1, 'from_variable': -1, 'variable_or_timer': -1, 'facet': -1, 'location_object_reference': -1, 'play_sound': -1, 'player_color': -1, 'unknown_4': -1, 'message': '', 'sound_name': '', 'selected_object_ids': [], } return defaults
class FilesPiece(aoe2_piece.AoE2Piece): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { "script_file_path": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("MapPiece", "script_name"), DependencyEval("x + ('.xs' if len(x) > 0 else '')") ), }, "ai_files_present": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("self", "number_of_ai_files"), DependencyEval('0 if x == 0 else 1') ), }, "number_of_ai_files": { "on_construct": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "ai_files_present"), ), "on_refresh": [ # RetrieverDependency( # DependencyAction.SET_VALUE, DependencyTarget("self", "ai_files"), DependencyEval('len(x)') # ), RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "ai_files"), DependencyEval('1 if len(x) > 0 else 0') ), ], "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "ai_files_present") ) }, "ai_files": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_ai_files"), DependencyEval('0 if x == [] else x') # x is a list because of the SET_REPEAT present ), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "number_of_ai_files") ) }, } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever("unknown_2", DataType("4")), Retriever("script_file_path", DataType("str16")), Retriever("unknown_3", DataType("4")), Retriever("ai_files_present", DataType("u32")), Retriever("unknown_4", DataType("4")), Retriever("number_of_ai_files", DataType("u32"), possibly_list=False), Retriever("ai_files", DataType(AI2Struct)), Retriever("__END_OF_FILE_MARK__", DataType("1")), ] super().__init__("Files", retrievers, parser_obj, data=data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'unknown_2': b'\x00' * 4, 'script_name': "", 'unknown_3': b'\x00' * 4, 'ai_files_present': 0, 'unknown_4': b'\x00' * 4, 'number_of_ai_files': [], 'ai_files': [], '__END_OF_FILE_MARK__': b'', } return defaults
class DataHeaderPiece(aoe2_piece.AoE2Piece): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { "mission_items_counter": { "on_refresh": RetrieverDependency(DependencyAction.SET_VALUE, DependencyTarget("self", "mission_item"), DependencyEval("len(x)")) }, "mission_item": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "mission_items_counter")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "mission_items_counter")) }, "unknown2": { "on_refresh": RetrieverDependency(DependencyAction.SET_REPEAT, DependencyTarget("FileHeaderPiece", "version"), DependencyEval("1 if x == '1.40' else 0")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) }, } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever("next_unit_id_to_place", DataType("u32")), Retriever("version", DataType("f32")), Retriever("player_names", DataType("c256", repeat=16)), Retriever("string_table_player_names", DataType("u32", repeat=16)), Retriever("player_data_1", DataType(PlayerDataOneStruct, repeat=16)), Retriever("conquest_mode", DataType("u8")), Retriever("mission_items_counter", DataType("u16")), Retriever("mission_available", DataType("u16")), Retriever("mission_timeline", DataType("f32")), Retriever("mission_item", DataType("30")), Retriever("unknown", DataType("64")), Retriever("filename", DataType("str16")), ] super().__init__("Data Header", retrievers, parser_obj, data=data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'next_unit_id_to_place': 0, 'version': 1.399999976158142, 'player_names': ['\x00' * 256] * 16, 'string_table_player_names': [4294967294] * 16, 'player_data_1': DataHeaderPiece._get_player_data_1_default(pieces), 'conquest_mode': 0, 'mission_items_counter': 0, 'mission_available': 0, 'mission_timeline': 0.0, 'mission_item': [], 'unknown': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00', 'filename': 'CreatedUsingAoE2ScenarioParser.aoe2scenario', } return defaults @staticmethod def _get_player_data_1_default(pieces): # active, human, civilization, cty_mode data = [ list(PlayerDataOneStruct.defaults(pieces).values()) for _ in range(2) ] data[0][0] = 1 # P1 Active data[0][1] = 1 # P1 Human data[1][0] = 1 # P2 Active data += [ list(PlayerDataOneStruct.defaults(pieces).values()) for _ in range(14) ] return [PlayerDataOneStruct(data=x, pieces=pieces) for x in data]
class MapPiece(aoe2_piece.AoE2Piece): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { "villager_force_drop": { "on_refresh": RetrieverDependency(DependencyAction.SET_REPEAT, DependencyTarget('FileHeaderPiece', 'version'), DependencyEval('1 if x == \'1.37\' else 0')), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) }, "map_width": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("self", "terrain_data"), DependencyEval("int(sqrt(len(x)))", {'sqrt': math.sqrt})) }, "map_height": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("self", "terrain_data"), DependencyEval("int(sqrt(len(x)))", {'sqrt': math.sqrt})) }, "terrain_data": { "on_refresh": RetrieverDependency(DependencyAction.SET_REPEAT, DependencyTarget("self", "map_width"), DependencyEval("pow(x, 2)")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget(["self", "self"], ["map_width", "map_height"])) } } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever('separator_1', DataType("2")), Retriever('unknown_string', DataType("str16")), Retriever('separator_2', DataType("2")), Retriever('map_color_mood', DataType("str16")), Retriever('collide_and_correct', DataType("u8")), # [VERSION CHANGE] ADDED in 1.36 > 1.37 Retriever('villager_force_drop', DataType("u8")), Retriever('player_1_camera_y', DataType("s32")), Retriever('player_1_camera_x', DataType("s32")), Retriever('ai_type', DataType("s8")), Retriever('map_width', DataType("s32")), Retriever('map_height', DataType("s32")), Retriever('terrain_data', DataType(TerrainStruct)) ] super().__init__("Map", retrievers, parser_obj, data=data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'separator_1': b'`\n', 'unknown_string': 'Preset_Main', 'separator_2': b'`\n', 'map_color_mood': 'Empty', 'collide_and_correct': 0, 'villager_force_drop': [0], 'player_1_camera_y': -559026163, 'player_1_camera_x': 2, 'ai_type': 1, 'map_width': 120, 'map_height': 120, 'terrain_data': [ TerrainStruct(data=list( TerrainStruct.defaults(pieces).values()), pieces=pieces) for _ in range(120 * 120) ], } return defaults
class UnitsPiece(aoe2_piece.AoE2Piece): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { "number_of_unit_sections": { "on_refresh": RetrieverDependency(DependencyAction.SET_VALUE, DependencyTarget("self", "players_units"), DependencyEval('len(x)')) }, "players_units": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_unit_sections")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "number_of_unit_sections")) } } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever("number_of_unit_sections", DataType("u32")), Retriever("player_data_4", DataType(PlayerDataFourStruct, repeat=8)), Retriever("number_of_players", DataType("u32")), # Also always 9 (Gaia + 8Plyrs) Retriever("player_data_3", DataType(PlayerDataThreeStruct, repeat=8)), Retriever("players_units", DataType(PlayerUnitsStruct)), ] super().__init__("Units", retrievers, parser_obj, data=data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'number_of_unit_sections': 9, 'player_data_4': [ PlayerDataFourStruct( data=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 200.0], pieces=pieces) for _ in range(8) ], 'number_of_players': 9, 'player_data_3': [ PlayerDataThreeStruct(data=list( PlayerDataThreeStruct.defaults(pieces).values()), pieces=pieces) for _ in range(8) ], 'players_units': [PlayerUnitsStruct(data=[0, []], pieces=pieces) for _ in range(9)], } return defaults
class TriggerStruct(AoE2Struct): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { "number_of_effects": { "on_refresh": RetrieverDependency(DependencyAction.SET_VALUE, DependencyTarget("self", "effect_data"), DependencyEval("len(x)")) }, "effect_data": { "on_refresh": RetrieverDependency(DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_effects")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency(DependencyAction.REFRESH, DependencyTarget("self", "number_of_effects")) }, "effect_display_order_array": { "on_refresh": RetrieverDependency(DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_effects")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) }, "number_of_conditions": { "on_refresh": RetrieverDependency(DependencyAction.SET_VALUE, DependencyTarget("self", "condition_data"), DependencyEval("len(x)")) }, "condition_data": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_conditions")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "number_of_conditions")) }, "condition_display_order_array": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_conditions")), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) }, } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever("enabled", DataType("u32")), Retriever("looping", DataType("s8")), Retriever("description_string_table_id", DataType("s32")), Retriever("display_as_objective", DataType("u8")), Retriever("objective_description_order", DataType("u32")), Retriever("make_header", DataType("u8")), Retriever("short_description_string_table_id", DataType("s32")), Retriever("display_on_screen", DataType("u8")), Retriever("unknown", DataType("5")), Retriever("mute_objectives", DataType("u8")), # Retriever("Trigger starting time", DataType("u32")), Retriever("trigger_description", DataType("str32")), Retriever("trigger_name", DataType("str32")), # (max 44 characters in UI) Retriever("short_description", DataType("str32")), Retriever("number_of_effects", DataType("s32")), Retriever("effect_data", DataType(EffectStruct)), Retriever("effect_display_order_array", DataType("s32")), Retriever("number_of_conditions", DataType("s32")), Retriever("condition_data", DataType(ConditionStruct)), Retriever("condition_display_order_array", DataType("s32")) ] super().__init__("Trigger", retrievers, parser_obj, data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'enabled': 1, 'looping': 0, 'description_string_table_id': -1, 'display_as_objective': 0, 'objective_description_order': 0, 'make_header': 0, 'short_description_string_table_id': -1, 'display_on_screen': 0, 'unknown': b'\x00\x00\x00\x00\x00', 'mute_objectives': 0, 'trigger_description': '', 'trigger_name': 'Trigger 0', 'short_description': '', 'number_of_effects': 0, 'effect_data': [], 'effect_display_order_array': [], 'number_of_conditions': 0, 'condition_data': [], 'condition_display_order_array': [], } return defaults
class TriggerPiece(aoe2_piece.AoE2Piece): dependencies: Dict[str, Dict[str, RetrieverDependency]] = { "number_of_triggers": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("self", "trigger_data"), DependencyEval("len(x)") ) }, "trigger_data": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_triggers") ), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget( [ "self", "FileHeaderPiece", "OptionsPiece", ], [ "number_of_triggers", "trigger_count", "number_of_triggers", ] ) ) }, "trigger_display_order_array": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_triggers") ), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF) }, "number_of_variables": { "on_refresh": RetrieverDependency( DependencyAction.SET_VALUE, DependencyTarget("self", "variable_data"), DependencyEval("len(x)") ) }, "variable_data": { "on_refresh": RetrieverDependency( DependencyAction.SET_REPEAT, DependencyTarget("self", "number_of_variables") ), "on_construct": RetrieverDependency(DependencyAction.REFRESH_SELF), "on_commit": RetrieverDependency( DependencyAction.REFRESH, DependencyTarget("self", "number_of_variables") ) }, } def __init__(self, parser_obj=None, data=None, pieces=None): retrievers = [ Retriever("trigger_version", DataType("f64")), Retriever("trigger_instruction_start", DataType("s8")), Retriever("number_of_triggers", DataType("s32")), Retriever("trigger_data", DataType(TriggerStruct)), Retriever("trigger_display_order_array", DataType("u32")), Retriever("unknown", DataType("1028")), Retriever("number_of_variables", DataType("u32")), Retriever("variable_data", DataType(VariableStruct)), ] super().__init__("Triggers", retrievers, parser_obj, data=data, pieces=pieces) @staticmethod def defaults(pieces): defaults = { 'trigger_version': 2.4, 'trigger_instruction_start': 0, 'number_of_triggers': 0, 'trigger_data': [], 'trigger_display_order_array': [], 'unknown': b'\x00' * 1028, 'number_of_variables': 0, 'variable_data': [], } return defaults