def _parse_object(parsed_data, **kwargs) -> TriggersObject: # Expected {} display_order = parser.listify( find_retriever(parsed_data['TriggerPiece'].retrievers, "Trigger display order array").data) trigger_data = parser.listify( find_retriever(parsed_data['TriggerPiece'].retrievers, "Trigger data").data) var_data = parser.listify( find_retriever(parsed_data['TriggerPiece'].retrievers, "Variables").data) triggers = [] for index, trigger in enumerate(trigger_data): triggers.append( TriggerObject._parse_object(parsed_data, trigger=trigger, trigger_id=index)) variables = [] for var in var_data: variables.append( VariableObject._parse_object(parsed_data, variable=var)) return TriggersObject(triggers=triggers, trigger_display_order=display_order, variables=variables)
def __init__(self, triggers, trigger_display_order, variables): self.triggers: List[TriggerObject] = parser.listify(triggers) self.trigger_display_order: List[int] = parser.listify( trigger_display_order) self.variables: List[VariableObject] = parser.listify(variables) super().__init__()
def get_content_as_string(self) -> str: return_string = "Triggers:\n" triggers = parser.listify(self.trigger_data) display_order = parser.listify(self.trigger_display_order) if len(triggers) == 0: return return_string + "\t<<No triggers>>" for trigger_id in display_order: return_string += self.get_trigger_as_string(trigger_id) + "\n" return return_string
def _reconstruct_object(parsed_header, parsed_data, objects, **kwargs): # Expected {trigger=triggerStruct} trigger_data_retriever = find_retriever( parsed_data['TriggerPiece'].retrievers, "Trigger data") trigger = kwargs['trigger'] trigger.effect_order = parser.listify(trigger.effect_order) trigger.condition_order = parser.listify(trigger.condition_order) effects_list = [] for effect_obj in trigger.effects: EffectObject._reconstruct_object(parsed_header, parsed_data, objects, effect=effect_obj, effects=effects_list) helper.update_order_array(trigger.effect_order, len(trigger.effects)) conditions_list = [] for condition_obj in trigger.conditions: ConditionObject._reconstruct_object(parsed_header, parsed_data, objects, condition=condition_obj, conditions=conditions_list) helper.update_order_array(trigger.condition_order, len(trigger.conditions)) trigger_data_retriever.data.append( TriggerStruct(data=[ trigger.enabled, trigger.looping, trigger.description_stid, trigger.display_as_objective, trigger.description_order, trigger.header, trigger.short_description_stid, trigger.display_on_screen, b'\x00\x00\x00\x00\x00', # Unknown trigger.mute_objectives, trigger.description, trigger.name, trigger.short_description, len(trigger.effects), effects_list, trigger.effect_order, len(trigger.conditions), conditions_list, trigger.condition_order, ]))
def _parse_object( parsed_data, **kwargs): # Expected {trigger=triggerStruct, trigger_id=id} trigger = kwargs['trigger'] effects_list = [] effect_structs = parser.listify( find_retriever(trigger.retrievers, "Effect data").data) for effect_struct in effect_structs: effects_list.append( EffectObject._parse_object(parsed_data, effect=effect_struct)) conditions_list = [] condition_structs = parser.listify( find_retriever(trigger.retrievers, "Condition data").data) for condition_struct in condition_structs: conditions_list.append( ConditionObject._parse_object(parsed_data, condition=condition_struct)) return TriggerObject( name=find_retriever(trigger.retrievers, "Trigger name").data, description=find_retriever(trigger.retrievers, "Trigger description").data, description_stid=find_retriever( trigger.retrievers, "Description string Table ID").data, display_as_objective=find_retriever(trigger.retrievers, "Act as objective").data, short_description=find_retriever(trigger.retrievers, "Short description").data, short_description_stid=find_retriever( trigger.retrievers, "Short description string Table ID").data, display_on_screen=find_retriever(trigger.retrievers, "Display on screen").data, description_order=find_retriever( trigger.retrievers, "Description order (in objectives)").data, enabled=find_retriever(trigger.retrievers, "Enabled").data, looping=find_retriever(trigger.retrievers, "Looping").data, header=find_retriever(trigger.retrievers, "Make header").data, mute_objectives=find_retriever(trigger.retrievers, "Mute objectives").data, conditions_list=conditions_list, condition_order=parser.listify( find_retriever(trigger.retrievers, "Condition display order array").data), effects_list=effects_list, effect_order=parser.listify( find_retriever(trigger.retrievers, "Effect display order array").data), trigger_id=kwargs['trigger_id'], )
def get_trigger(self, trigger_id=None, display_index=None) -> TriggerObject: _evaluate_index_params(trigger_id, display_index) if trigger_id is None: trigger_id = self._get_trigger_id_by_display_index(display_index) return parser.listify(self.trigger_data)[trigger_id]
def get_summary_as_string(self) -> str: return_string = "\nTrigger Summary:\n" triggers = parser.listify(self.triggers) display_order = parser.listify(self.trigger_display_order) if len(display_order) == 0: return_string += "\t<< No Triggers >>" longest_trigger_name = -1 for trigger_id in display_order: trigger_name = helper.del_str_trail(triggers[trigger_id].name) longest_trigger_name = max(longest_trigger_name, len(trigger_name)) longest_trigger_name += 3 for display, trigger_id in enumerate(display_order): trigger = triggers[trigger_id] trigger_name = helper.del_str_trail(trigger.name) buffer = longest_trigger_name - len(trigger_name) return_string += "\t" + trigger_name + (" " * buffer) return_string += " [Index: " + str( trigger_id) + ", Display: " + str(display) + "]" return_string += "\t(conditions: " + str( len(parser.listify(trigger.conditions))) + ", " return_string += " effects: " + str( len(parser.listify(trigger.effects))) + ")\n" variables = parser.listify(self.variables) return_string += "\nVariables Summary:\n" if len(variables) == 0: return_string += "\t<< No Variables >>" longest_variable_name = -1 for variable in variables: longest_variable_name = max(longest_variable_name, len(variable.name)) longest_variable_name += 3 for index, variable in enumerate(variables): var_name = variable.name buffer = " " * (longest_variable_name - len(var_name)) return_string += f"\t{var_name}{buffer}[Index: {variable.variable_id}]\n" return return_string
def get_trigger_as_string(self, trigger_id=None, display_index=None) -> str: _evaluate_index_params(trigger_id, display_index) if trigger_id is None: trigger_id = self._get_trigger_id_by_display_index(display_index) trigger = parser.listify(self.trigger_data)[trigger_id] display = parser.listify(self.trigger_display_order).index(trigger_id) return_string = "" return_string += "\t'" + helper.del_str_trail(trigger.name) + "'" return_string += " [Index: " + str(trigger_id) + ", Display: " + str(display) + "]" + ":\n" return_string += trigger.get_content_as_string() return return_string
def get_byte_structure_as_string(self, pieces, skip_retrievers=None): if skip_retrievers is None: skip_retrievers = [] byte_structure = "\n" + self.get_header_string() for retriever in self.retrievers: if retriever.name in skip_retrievers: continue byte_structure += "\n" listed_retriever_data = parser.listify(retriever.data) struct_header_set = False for struct in listed_retriever_data: if isinstance(struct, AoE2Piece): if not struct_header_set: byte_structure += f"\n{'#' * 27} {retriever.name} ({retriever.datatype.to_simple_string()})" struct_header_set = True byte_structure += struct.get_byte_structure_as_string(pieces) # Struct Header was set. Retriever was struct, data retrieved using recursion. Next retriever. if struct_header_set: byte_structure += f"{'#' * 27} End of: {retriever.name} ({retriever.datatype.to_simple_string()})\n" continue retriever_data_bytes = parser.retriever_to_bytes(retriever, pieces) if retriever_data_bytes is None: return byte_structure else: retriever_data_bytes = retriever_data_bytes.hex() retriever_short_string: str = retriever.get_short_str() retriever_hex = helper.create_textual_hex( retriever_data_bytes, space_distance=2, enter_distance=24 ) split_hex = retriever_hex.split("\n") split_hex_length = len(split_hex) split_data_string = retriever_short_string.replace('\x00', ' ').splitlines() data_lines = [] for x in split_data_string: if len(x) > 120: data_lines += [f'\t{x}' for x in helper.insert_char(x, '\r\n', 120).splitlines()] else: data_lines.append(x) split_data_length = len(data_lines) lines = max(split_hex_length, split_data_length) combined_strings = [] for i in range(0, lines): hex_part = split_hex[i] if i < split_hex_length else "" data_part = data_lines[i] if i < split_data_length else "" combined_strings.append(helper.add_suffix_chars(hex_part, " ", 28) + data_part) byte_structure += "\n".join(combined_strings) return byte_structure + "\n"
def get_content_as_string(self) -> str: return_string = "Triggers:\n" triggers = parser.listify(self.triggers) display_order = parser.listify(self.trigger_display_order) if len(triggers) == 0: return_string += "\t<<No triggers>>" for trigger_id in display_order: return_string += self.get_trigger_as_string(trigger_id) + "\n" return_string += "Variables:\n" if len(triggers) == 0: return_string += "\t<<No Variables>>" for variable in parser.listify(self.variables): return_string += f"\t'{variable.name}' [Index: {variable.variable_id}]\n" return return_string
def get_summary_as_string(self) -> str: return_string = "Trigger Summary:\n" triggers = parser.listify(self.trigger_data) display_order = parser.listify(self.trigger_display_order) longest_trigger_name = -1 for trigger_id in display_order: trigger_name = helper.del_str_trail(triggers[trigger_id].name) longest_trigger_name = max(longest_trigger_name, len(trigger_name)) longest_trigger_name += 3 for display, trigger_id in enumerate(display_order): trigger = triggers[trigger_id] trigger_name = helper.del_str_trail(trigger.name) buffer = longest_trigger_name - len(trigger_name) return_string += "\t" + trigger_name + (" " * buffer) return_string += " [Index: " + str(trigger_id) + ", Display: " + str(display) + "]" return_string += "\t(conditions: " + str(len(parser.listify(trigger.conditions))) + ", " return_string += " effects: " + str(len(parser.listify(trigger.effects))) + ")\n" return return_string
def _debug_log_condition_dataset(self): """ Used for debugging - Only reads One Trigger. """ trigger_data = find_retriever(self._parsed_data['TriggerPiece'].retrievers, "Trigger data").data conditions = parser.listify(find_retriever(trigger_data.retrievers, "Condition data").data) for condition in conditions: for retriever in condition.retrievers: if retriever.data != -1 and \ retriever.data != [] and \ retriever.data != "" and \ retriever.data != " " and \ retriever.name != "static_value_21": if retriever.name == "condition_type": print("],\n" + str(retriever.data) + ": [") print("\t\"" + retriever.name + "\",") print("]\n")
def _reconstruct_object(parsed_data, objects, **kwargs) -> None: # Expected {} number_of_triggers_retriever = find_retriever(parsed_data['TriggerPiece'].retrievers, "Number of triggers") trigger_data_retriever = find_retriever(parsed_data['TriggerPiece'].retrievers, "Trigger data") display_order_retriever = find_retriever(parsed_data['TriggerPiece'].retrievers, "Trigger display order array") trigger_data_retriever.data = [] for trigger in objects["TriggersObject"].trigger_data: TriggerObject._reconstruct_object(parsed_data, objects, trigger=trigger) assert len(trigger_data_retriever.data) == len(objects["TriggersObject"].trigger_data) trigger_count = len(trigger_data_retriever.data) number_of_triggers_retriever.data = trigger_count # Currently not necessary due to the parser changing the 'repeated' value equal to the len(list) # trigger_data_retriever.datatype.repeat = trigger_count # display_order_retriever.datatype.repeat = trigger_count helper.update_order_array(parser.listify(display_order_retriever.data), trigger_count)
def _debug_log_effect_dataset(self): """ Used for debugging - Only reads One Trigger. """ trigger_data = find_retriever(self._parsed_data['TriggerPiece'].retrievers, "Trigger data").data effects = parser.listify(find_retriever(trigger_data.retrievers, "Effect data").data) for effect in effects: for retriever in effect.retrievers: if retriever.data != -1 and \ retriever.data != [] and \ retriever.data != "" and \ retriever.data != " " and \ retriever.name != "static_value_46": if retriever.name == "effect_type": print("],\n" + str(retriever.data) + ": [") print("\t\"" + retriever.name + "\",") print("]\n")
def _reconstruct_object(parsed_header, parsed_data, objects, **kwargs) -> None: # Expected {} number_of_triggers_retriever = find_retriever( parsed_data['TriggerPiece'].retrievers, "Number of triggers") trigger_data_retriever = find_retriever( parsed_data['TriggerPiece'].retrievers, "Trigger data") display_order_retriever = find_retriever( parsed_data['TriggerPiece'].retrievers, "Trigger display order array") display_order_retriever.data = parser.listify( display_order_retriever.data) file_header_trigger_count_retriever = find_retriever( parsed_header['FileHeaderPiece'].retrievers, "Trigger count") number_of_variable_retriever = find_retriever( parsed_data['TriggerPiece'].retrievers, "Number of variables") variable_data_retriever = find_retriever( parsed_data['TriggerPiece'].retrievers, "Variables") trigger_data_retriever.data = [] for trigger in objects["TriggersObject"].triggers: TriggerObject._reconstruct_object(parsed_header, parsed_data, objects, trigger=trigger) variable_data_retriever.data = [] for variable in objects["TriggersObject"].variables: VariableObject._reconstruct_object( parsed_header, parsed_data, objects, variable=variable, variables=variable_data_retriever.data) assert len(trigger_data_retriever.data) == len( objects["TriggersObject"].triggers) trigger_count = len(trigger_data_retriever.data) number_of_triggers_retriever.data = trigger_count file_header_trigger_count_retriever.data = trigger_count number_of_variable_retriever.data = len(variable_data_retriever.data) # Currently not necessary due to the parser changing the 'repeated' value equal to the len(list) # trigger_data_retriever.datatype.repeat = trigger_count # display_order_retriever.datatype.repeat = trigger_count helper.update_order_array(display_order_retriever.data, trigger_count)
def _parse_object(parsed_data, **kwargs) -> UnitsObject: object_piece = parsed_data['UnitsPiece'] units_per_player = find_retriever(object_piece.retrievers, "Player Units").data player_units = [] for player_id in range(0, 9): # 0 Gaia & 1-8 Players: player_units.append([]) units = parser.listify( find_retriever(units_per_player[player_id].retrievers, "Units").data) for unit in units: player_units[player_id].append( UnitObject._parse_object(parsed_data, unit=unit, player=Player(player_id))) return UnitsObject(units=player_units)
def selected_object_ids(self, val: List[int]): val = parser.listify(val) self._selected_object_ids = val
def get_byte_structure_as_string(self, skip_retrievers=None): if skip_retrievers is None: skip_retrievers = [] byte_structure = "\n" + self.get_header_string() for retriever in self.retrievers: if retriever.name in skip_retrievers: continue byte_structure += "\n" listed_retriever_data = parser.listify(retriever.data) struct_header_set = False for struct in listed_retriever_data: if isinstance(struct, AoE2Piece): if not struct_header_set: byte_structure += f"\n{'#' * 27} {retriever.name} ({retriever.datatype.to_simple_string()})" struct_header_set = True byte_structure += struct.get_byte_structure_as_string() # Struct Header was set. Retriever was struct, data retrieved using recursion. Next retriever. if struct_header_set: byte_structure += f"{'#' * 27} End of: {retriever.name} ({retriever.datatype.to_simple_string()})\n" continue retriever_data_bytes = parser.retriever_to_bytes(retriever) if retriever_data_bytes is None: return byte_structure else: retriever_data_bytes = retriever_data_bytes.hex() retriever_short_string = retriever.get_short_str() retriever_data_hex = helper.create_textual_hex( retriever_data_bytes, space_distance=2, enter_distance=24) if "\n" in retriever_data_hex: split_hex = retriever_data_hex.split("\n") if "\r\n" in retriever_short_string: split_data_string = retriever_short_string.split("\r\n") split_hex_length = len(split_hex) split_data_string_length = len(split_data_string) lines = max(split_hex_length, split_data_string_length) combined_strings = [] for i in range(0, lines): combined_strings.append( helper.add_suffix_chars( split_hex[i] if i < split_hex_length else "", " ", 28) + (split_data_string[i] if i < split_data_string_length else "")) byte_structure += "\n".join(combined_strings) else: split_hex[0] = helper.add_suffix_chars( split_hex[0], " ", 28) + retriever_short_string byte_structure += "\n".join(split_hex) else: byte_structure += helper.add_suffix_chars( retriever_data_hex, " ", 28) + retriever_short_string return byte_structure + "\n"
def get_triggers(self) -> List[TriggerObject]: return parser.listify(self.trigger_data)
def __init__( self, effect_type: int, ai_script_goal: int, aa_quantity: int, aa_armor_or_attack_type: int, quantity: int, tribute_list: int, diplomacy: int, number_of_units_selected: int, object_list_unit_id: int, source_player: IntEnum, target_player: IntEnum, technology: IntEnum, string_id: int, display_time: int, trigger_id: int, location_x: int, location_y: int, location_object_reference: int, area_1_x: int, area_1_y: int, area_2_x: int, area_2_y: int, object_group: int, object_type: int, instruction_panel_position: int, attack_stance: int, time_unit: int, enabled_or_victory: int, food: int, wood: int, stone: int, gold: int, item_id: int, flash_object: int, force_research_technology: int, visibility_state: int, scroll: int, operation: int, object_list_unit_id_2: IntEnum, button_location: int, ai_signal_value: int, object_attributes: int, from_variable: int, variable_or_timer: int, facet: int, play_sound: int, message: str = "", sound_name: str = "", selected_object_ids: List[int] = None, ): if selected_object_ids is None: selected_object_ids = [] else: selected_object_ids = parser.listify(selected_object_ids) self.effect_type: int = effect_type self.ai_script_goal: int = ai_script_goal self.aa_quantity: int = aa_quantity self.aa_armor_or_attack_type: int = aa_armor_or_attack_type self.quantity: int = quantity self.tribute_list: int = tribute_list self.diplomacy: int = diplomacy self.number_of_units_selected: int = number_of_units_selected self.object_list_unit_id: int = object_list_unit_id self.source_player: IntEnum = source_player self.target_player: IntEnum = target_player self.technology: IntEnum = technology self.string_id: int = string_id self.display_time: int = display_time self.trigger_id: int = trigger_id self.location_x: int = location_x self.location_y: int = location_y self.location_object_reference: int = location_object_reference self.area_1_x: int = area_1_x self.area_1_y: int = area_1_y self.area_2_x: int = area_2_x self.area_2_y: int = area_2_y self.object_group: int = object_group self.object_type: int = object_type self.instruction_panel_position: int = instruction_panel_position self.attack_stance: int = attack_stance self.time_unit: int = time_unit self.enabled_or_victory: int = enabled_or_victory self.food: int = food self.wood: int = wood self.stone: int = stone self.gold: int = gold self.item_id: int = item_id self.flash_object: int = flash_object self.force_research_technology: int = force_research_technology self.visibility_state: int = visibility_state self.scroll: int = scroll self.operation: int = operation self.object_list_unit_id_2: IntEnum = object_list_unit_id_2 self.button_location: int = button_location self.ai_signal_value: int = ai_signal_value self.object_attributes: int = object_attributes self.from_variable: int = from_variable self.variable_or_timer: int = variable_or_timer self.facet: int = facet self.play_sound: int = play_sound self.message: str = message self.sound_name: str = sound_name self.selected_object_ids: List[int] = selected_object_ids super().__init__()
def selected_object_ids(self, val: List[int]): val = parser.listify(val) self._selected_object_ids = val self.number_of_units_selected = len(val)