Exemplo n.º 1
0
    def replace_player(self,
                       trigger_select,
                       to_player,
                       only_change_from=None,
                       include_player_source=True,
                       include_player_target=False,
                       trigger_ce_lock=None) -> TriggerObject:
        """
        Replaces player attributes. Specifically useful if multiple players are used in the same trigger.

        Args:
            trigger_select (TriggerSelect): An object used to identify which trigger to select.
            to_player (Player): The player the attributes are changed to.
            only_change_from (Player): Can only change player attributes if the player is equal to the given value
            include_player_source (bool): If set to True, allow player source attributes to be changed while replacing.
                Player source attributes are attributes where a player is defined to perform an action such as create an
                object. If set to False these attributes will remain unchanged.
            include_player_target (bool): If set to True, allow player target attributes to be changed while replacing.
                Player target attributes are attributes where a player is defined as the target such as change ownership
                or sending resources. If set to False these attributes will remain unchanged.
            trigger_ce_lock (TriggerCELock): The TriggerCELock object. Used to lock certain (types) of conditions or
                effects from being changed.

        Returns:
            The given trigger with the proper player attributes changed
        """
        trigger_index, display_index, trigger = self._validate_and_retrieve_trigger_info(
            trigger_select)
        alter_conditions, alter_effects = TriggersObject._find_alterable_ce(
            trigger, trigger_ce_lock)

        for cond_x in alter_conditions:
            cond = trigger.conditions[cond_x]
            if not cond.source_player == -1 and include_player_source:
                if only_change_from is not None and only_change_from != cond.source_player:
                    continue
                cond.source_player = Player(to_player)
            if not cond.target_player == -1 and include_player_target:
                if only_change_from is not None and only_change_from != cond.target_player:
                    continue
                cond.target_player = Player(to_player)
        for effect_x in alter_effects:
            effect = trigger.effects[effect_x]
            if not effect.source_player == -1 and include_player_source:
                if only_change_from is not None and only_change_from != effect.source_player:
                    continue
                effect.source_player = Player(to_player)
            if not effect.target_player == -1 and include_player_target:
                if only_change_from is not None and only_change_from != effect.target_player:
                    continue
                effect.target_player = Player(to_player)

        return trigger
Exemplo n.º 2
0
def get_units_array(scn: AoE2Scenario, player: int) -> List[UnitStruct]:
    """
    Returns the array of units in scenario for the given player.

    Raises a ValueError if player is not in 0, ..., 8.
    """
    return scn.object_manager.unit_manager.get_player_units(Player(player))
Exemplo n.º 3
0
    def __init__(self, player: Player, x: float, y: float, z: float,
                 reference_id: int, unit_const: int, status: int,
                 rotation: float, initial_animation_frame: int,
                 garrisoned_in_id: int):

        self._player: Player = Player(player)
        """
        PLEASE NOTE: This is an internal (read-only) value for ease of access. It accurately represent the actual 
        player controlling the unit but is not directly connected to it. Changing this value will have no impact to your
        scenario.
        To change which player controls this unit, use:
            unit_manager.change_ownership(UnitObject, to_player)
        """
        self.x: float = x
        self.y: float = y
        self.z: float = z
        self.reference_id: int = reference_id
        self.unit_const: int = unit_const
        self.status: int = status
        self.rotation: float = rotation % math.tau
        # Mods by tau because the scenario editor seems to place units at radian angles not strictly less than tau.
        self.initial_animation_frame: int = initial_animation_frame
        self.garrisoned_in_id: int = garrisoned_in_id

        super().__init__()
Exemplo n.º 4
0
 def unit_edit_commit_handle():
     unit_info = t_Unitedit.get(1.0, tk.END)
     while True:
         try:
             info_text, info_temp = unit_info.split("单位ID:", 1)
             arg_id, info_temp = info_temp.split("\n", 1)
             info_text, info_temp = info_temp.split("种类ID:", 1)
             arg_cns, info_temp = info_temp.split("\n", 1)
             info_text, info_temp = info_temp.split("属于:玩家 ", 1)
             arg_ply, info_temp = info_temp.split("\n", 1)
             info_text, info_temp = info_temp.split("位置:", 1)
             arg_loc, info_temp = info_temp.split("\n", 1)
             arg_loc_x, arg_loc_y, arg_loc_z = arg_loc.split(",")
             info_text, info_temp = info_temp.split("相位:", 1)
             arg_rot, info_temp = info_temp.split("/4 pi\n", 1)
             info_text, info_temp = info_temp.split("驻扎于:", 1)
             arg_gar, info_temp = info_temp.split("\n", 1)
             info_text, info_temp = info_temp.split("状态:", 1)
             arg_sts, info_temp = info_temp.split("\n", 1)
             info_text, arg_frm = info_temp.split("帧位:", 1)
             new_unit_id = int(arg_id)
             new_unit_const = int(arg_cns)
             new_unit_player = Player(int(arg_ply))
             new_unit_x = float(arg_loc_x)
             new_unit_y = float(arg_loc_y)
             new_unit_z = float(arg_loc_z)
             new_unit_rotation = int(arg_rot) / 4.0 * 3.1415927410125732
             new_unit_garrison = int(arg_gar)
             new_unit_status = int(arg_sts)
             new_unit_frame = int(arg_frm)
             break
         except:
             result = tk.messagebox.askokcancel(title='提交失败',
                                                message='格式可能不正确,是否放弃编辑?',
                                                parent=w_unit_edit)
             if result == True:
                 w_unit_edit.quit()
                 w_unit_edit.destroy()
             return
     #unit_to_edit.player=new_unit_player
     unit_to_edit.reference_id = new_unit_id
     unit_to_edit.unit_const = new_unit_const
     unit_to_edit.x = new_unit_x
     unit_to_edit.y = new_unit_y
     unit_to_edit.z = new_unit_z
     unit_to_edit.garrisoned_in_id = new_unit_garrison
     unit_to_edit.status = new_unit_status
     unit_to_edit.initial_animation_frame = new_unit_frame
     if round(unit_to_edit.rotation / 3.1415927410125732 *
              4) != int(arg_rot):
         unit_to_edit.rotation = new_unit_rotation
     get_units_list()
     w_unit_edit.quit()
     w_unit_edit.destroy()
Exemplo n.º 5
0
    def change_ownership(self, unit: UnitObject, to_player: Player) -> None:
        """
        Changes a unit's ownership to the given player.

        Args:
            unit: The unit object which ownership will be changed
            to_player: The player that'll get ownership over the unit (using Player enum)
        """
        for i, player_unit in enumerate(self.units[unit.player.value]):
            if player_unit == unit:
                del self.units[unit.player.value][i]
                self.units[to_player.value].append(unit)
                unit._player = Player(to_player)
                return
Exemplo n.º 6
0
def copy_unit(scn: AoE2Scenario, unit: UnitStruct, player: int) -> UnitStruct:
    """
    Adds a copy of unit to the player's list of units in scenario scn.

    Returns the unit that is added.
    """
    unit_id = util_scn.get_and_inc_unit_id(scn)
    u = scn.object_manager.unit_manager.add_unit(player=Player(player),
                                                 x=unit.x,
                                                 y=unit.y,
                                                 z=unit.z,
                                                 unit_id=unit.unit_id,
                                                 rotation=unit.rotation)
    set_id(u, unit_id)
    return u
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    def copy_trigger_per_player(
        self,
        from_player,
        trigger_select,
        change_from_player_only=False,
        include_player_source=True,
        include_player_target=False,
        trigger_ce_lock=None,
        include_gaia: bool = False,
        create_copy_for_players: List[IntEnum] = None
    ) -> Dict[Player, TriggerObject]:
        """
        Copies a trigger for all or a selection of players. Every copy will change desired player attributes with it.

        Args:
            from_player (IntEnum): The central player this trigger is created for. This is the player that will not get
                a copy.
            trigger_select (TriggerSelect): An object used to identify which trigger to select.
            change_from_player_only (bool): If set to True, only change player attributes in effects and conditions that
                are equal to the player defined using the `from_player` parameter.
            include_player_source (bool): If set to True, allow player source attributes to be changed while copying.
                Player source attributes are attributes where a player is defined to perform an action such as create an
                object. If set to False these attributes will remain unchanged.
            include_player_target (bool): If set to True, allow player target attributes to be changed while copying.
                Player target attributes are attributes where a player is defined as the target such as change ownership
                or sending resources. If set to False these attributes will remain unchanged.
            trigger_ce_lock (TriggerCELock): The TriggerCELock object. Used to lock certain (types) of conditions or
                effects from being changed while copying.
            include_gaia (bool): If True, GAIA is included in the copied list. (Also when `create_copy_for_players` is
                defined)
            create_copy_for_players (List[IntEnum]): A list of Players to create a copy for. The `from_player` will be
                excluded from this list.

        Returns:
            A dict with all the new created triggers. The key is the player for which the trigger is
                created using the IntEnum associated with it. Example:
                {Player.TWO: TriggerObject, Player.FIVE: TriggerObject}

        Raises:
            ValueError: if more than one trigger selection is used. Any of (trigger_index, display_index or trigger)
                Or if Both `include_player_source` and `include_player_target` are `False`

        :Authors:
            KSneijders

        """
        trigger_index, display_index, trigger = self._validate_and_retrieve_trigger_info(
            trigger_select)
        if not include_player_source and not include_player_target:
            raise ValueError("Cannot exclude player source and target.")

        if create_copy_for_players is None:
            create_copy_for_players = [
                Player.ONE, Player.TWO, Player.THREE, Player.FOUR, Player.FIVE,
                Player.SIX, Player.SEVEN, Player.EIGHT
            ]
        if include_gaia and Player.GAIA not in create_copy_for_players:
            create_copy_for_players.append(Player.GAIA)

        alter_conditions, alter_effects = TriggersObject._find_alterable_ce(
            trigger, trigger_ce_lock)

        return_dict: Dict[Player, TriggerObject] = {}
        for player in create_copy_for_players:
            if not player == from_player:
                new_trigger = self.copy_trigger(TS.trigger(trigger))
                new_trigger.name += f" (p{player})"
                return_dict[player] = new_trigger

                for cond_x in alter_conditions:
                    cond = new_trigger.conditions[cond_x]
                    # Player not set
                    if cond.source_player == -1:
                        continue
                    # Player not equal to 'from_player'
                    if change_from_player_only:
                        if not cond.source_player == from_player:
                            continue
                    # Change source player
                    if include_player_source:
                        cond.source_player = Player(player)
                    # Change target player
                    if include_player_target:
                        cond.target_player = Player(player)
                for effect_x in alter_effects:
                    effect = new_trigger.effects[effect_x]
                    # Player not set
                    if effect.source_player == -1:
                        continue
                    # Player not equal to 'from_player'
                    if change_from_player_only:
                        if not effect.source_player == from_player:
                            continue
                    # Change source player
                    if include_player_source:
                        effect.source_player = Player(player)
                    # Change target player
                    if include_player_target:
                        effect.target_player = Player(player)

        return return_dict
Exemplo n.º 9
0
def copy_trigger_per_player_fix(
    trigger_obj: TriggersObject,
    from_player,
    trigger_select,
    change_from_player_only=False,
    include_player_source=True,
    include_player_target=False,
    trigger_ce_lock=None,
    exclude_self=False,
    include_gaia: bool = False,
    create_copy_for_players: List[IntEnum] = None
) -> Dict[Player, TriggerObject]:
    """
	Copies a trigger for all or a selection of players. Every copy will change desired player attributes with it.

	Args:
		from_player (IntEnum): The central player this trigger is created for. This is the player that will not get
			a copy.
		trigger_select (TriggerSelect): An object used to identify which trigger to select.
		change_from_player_only (bool): If set to True, only change player attributes in effects and conditions that
			are equal to the player defined using the `from_player` parameter.
		include_player_source (bool): If set to True, allow player source attributes to be changed while copying.
			Player source attributes are attributes where a player is defined to perform an action such as create an
			object. If set to False these attributes will remain unchanged.
		include_player_target (bool): If set to True, allow player target attributes to be changed while copying.
			Player target attributes are attributes where a player is defined as the target such as change ownership
			or sending resources. If set to False these attributes will remain unchanged.
		trigger_ce_lock (TriggerCELock): The TriggerCELock object. Used to lock certain (types) of conditions or
			effects from being changed while copying.
		include_gaia (bool): If True, GAIA is included in the copied list. (Also when `create_copy_for_players` is
			defined)
		create_copy_for_players (List[IntEnum]): A list of Players to create a copy for. The `from_player` will be
			excluded from this list.

		exclude_self: If target trigger has a 1 -> 7 or 7 -> 1 effect group, set this to duplicate effects for
			7 players excluding from_player.

	Returns:
		A dict with all the new created triggers. The key is the player for which the trigger is
			created using the IntEnum associated with it. Example:
			{Player.TWO: TriggerObject, Player.FIVE: TriggerObject}

	Raises:
		ValueError: if more than one trigger selection is used. Any of (trigger_index, display_index or trigger)
			Or if Both `include_player_source` and `include_player_target` are `False`

	:Authors:
		KSneijders

	"""
    trigger_index, display_index, trigger = trigger_obj._validate_and_retrieve_trigger_info(
        trigger_select)
    if not include_player_source and not include_player_target:
        raise ValueError("Cannot exclude player source and target.")

    if create_copy_for_players is None:
        create_copy_for_players = [
            Player.ONE, Player.TWO, Player.THREE, Player.FOUR, Player.FIVE,
            Player.SIX, Player.SEVEN, Player.EIGHT
        ]
    if include_gaia and Player.GAIA not in create_copy_for_players:
        create_copy_for_players.append(Player.GAIA)

    alter_conditions, alter_effects = TriggersObject._find_alterable_ce(
        trigger, trigger_ce_lock)

    return_dict: Dict[Player, TriggerObject] = {}
    for player in create_copy_for_players:
        if not player == from_player:
            new_trigger = trigger_obj.copy_trigger(TS.trigger(trigger))
            # 移除库函数添加的(copy)后缀
            if new_trigger.name.endswith(" (copy)"):
                new_trigger.name = new_trigger.name[:-7]
            new_trigger.name += f" (p{player})"
            return_dict[player] = new_trigger

            # 条件遍历
            for cond_x in alter_conditions:
                cond = new_trigger.conditions[cond_x]
                # 起始单位
                for object in duplicate_config.object_config:
                    if object[1] == cond.unit_object:
                        cond.unit_object = object[player]
                # 目标单位
                for object in duplicate_config.object_config:
                    if object[1] == cond.next_object:
                        cond.next_object = object[player]
                # 目标区域坐标 1
                for location in duplicate_config.location_config:
                    if location[1][0] == cond.area_1_x and location[1][
                            1] == cond.area_1_y:
                        cond.area_1_x = location[player][0]
                        cond.area_1_y = location[player][1]
                # 目标区域坐标 2
                for location in duplicate_config.location_config:
                    if location[1][0] == cond.area_2_x and location[1][
                            1] == cond.area_2_y:
                        cond.area_2_x = location[player][0]
                        cond.area_2_y = location[player][1]
                # 坐标顺序校正
                if cond.area_1_x > cond.area_2_x:
                    cond.area_1_x, cond.area_2_x = cond.area_2_x, cond.area_1_x
                if cond.area_1_y > cond.area_2_y:
                    cond.area_1_y, cond.area_2_y = cond.area_2_y, cond.area_1_y
                # 跳过无玩家条件
                if cond.source_player == -1:
                    continue
                # 跳过非起始玩家条件
                if change_from_player_only:
                    if not cond.source_player == from_player:
                        continue
                # 改变起始玩家
                if include_player_source:
                    cond.source_player = Player(player)
                # 改变目标玩家
                if include_player_target:
                    cond.target_player = Player(player)

            # 效果遍历
            for effect_x in alter_effects:
                effect = new_trigger.effects[effect_x]
                # 效果文本
                for text in duplicate_config.text_config:
                    if effect.message.find(text[1]) != -1:
                        effect.message = effect.message.replace(
                            text[1], text[player])
                # 目标区域坐标 1
                for location in duplicate_config.location_config:
                    if location[1][0] == effect.area_1_x and location[1][
                            1] == effect.area_1_y:
                        effect.area_1_x = location[player][0]
                        effect.area_1_y = location[player][1]
                # 目标区域坐标 2
                for location in duplicate_config.location_config:
                    if location[1][0] == effect.area_2_x and location[1][
                            1] == effect.area_2_y:
                        effect.area_2_x = location[player][0]
                        effect.area_2_y = location[player][1]
                # 坐标顺序校正
                if effect.area_1_x > effect.area_2_x:
                    effect.area_1_x, effect.area_2_x = effect.area_2_x, effect.area_1_x
                if effect.area_1_y > effect.area_2_y:
                    effect.area_1_y, effect.area_2_y = effect.area_2_y, effect.area_1_y
                # 目标点坐标
                for location in duplicate_config.location_config:
                    if location[1][0] == effect.location_x and location[1][
                            1] == effect.location_y:
                        effect.location_x = location[player][0]
                        effect.location_y = location[player][1]
                # 选择单位
                for object in duplicate_config.object_config:
                    for (object_enum,
                         object_id) in enumerate(effect.selected_object_ids):
                        if object[1] == object_id:
                            effect.selected_object_ids[object_enum] = object[
                                player]
                # 目标点单位
                for object in duplicate_config.object_config:
                    if object[1] == effect.location_object_reference:
                        effect.location_object_reference = object[player]
                # 一对多/多对一型效果
                if exclude_self and effect.source_player == from_player and effect.target_player == Player(
                        player):
                    effect.source_player = Player(player)
                    effect.target_player = from_player
                    continue
                if exclude_self and effect.target_player == from_player and effect.source_player == Player(
                        player):
                    effect.source_player = from_player
                    effect.target_player = Player(player)
                    continue
                if exclude_self and effect.source_player == Player(player):
                    effect.source_player = from_player
                    continue
                if exclude_self and effect.target_player == Player(player):
                    effect.target_player = from_player
                    continue
                # 跳过无玩家效果
                if effect.source_player == -1:
                    continue
                # 跳过非起始玩家效果
                if change_from_player_only:
                    if not ((include_player_source
                             and effect.source_player == from_player) or
                            (include_player_target
                             and effect.target_player == from_player)):
                        continue
                # 改变起始玩家
                if include_player_source:
                    effect.source_player = Player(player)
                # 改变目标玩家
                if include_player_target:
                    effect.target_player = Player(player)

    return return_dict