Ejemplo n.º 1
0
    def _update_from_pokedex(self, species: str, store_species: bool = True) -> None:
        species = to_id_str(species)
        dex_entry = POKEDEX[species]
        if store_species:
            self._species = species
        self._base_stats = dex_entry["baseStats"]

        self._type_1 = PokemonType.from_name(dex_entry["types"][0])
        if len(dex_entry["types"]) == 1:
            self._type_2 = None
        else:
            self._type_2 = PokemonType.from_name(dex_entry["types"][1])

        self._possible_abilities = dex_entry["abilities"]
        self._heightm = dex_entry["heightm"]
        self._weightkg = dex_entry["weightkg"]
Ejemplo n.º 2
0
    def __init__(self, move_id: str, raw_id: Optional[str] = None):
        self._id = move_id
        self._base_power_override = None

        if move_id.startswith("hiddenpower") and raw_id is not None:
            base_power = "".join([c for c in raw_id if c in STR_DIGITS])
            self._id = "".join([c for c in to_id_str(raw_id) if c not in STR_DIGITS])

            if base_power:
                try:
                    base_power = int(base_power)
                    self._base_power_override = base_power
                except ValueError:
                    pass

        self._current_pp = self.max_pp
        self._is_empty: bool = False

        self._dynamaxed_move = None
        self._request_target = None
Ejemplo n.º 3
0
 async def _parse_message(self, split_message: List[str]) -> None:
     if split_message[1] in self.MESSAGES_TO_IGNORE:
         return
     elif split_message[1] == "-ability":
         pokemon, ability = split_message[2:4]
         self.get_pokemon(pokemon).ability = ability
     elif split_message[1] == "-activate":
         target, effect = split_message[2:4]
         self.get_pokemon(target)._start_effect(effect)
     elif split_message[1] == "-boost":
         pokemon, stat, amount = split_message[2:5]
         self.get_pokemon(pokemon)._boost(stat, int(amount))
     elif split_message[1] == "-burst":
         pokemon, species, item = split_message[2:5]
         self.get_pokemon(pokemon).burst(species, item)
     elif split_message[1] == "-clearallboost":
         self.active_pokemon._clear_boosts()
         self.opponent_active_pokemon._clear_boosts()
     elif split_message[1] == "-clearboost":
         pokemon = split_message[2]
         self.get_pokemon(pokemon)._clear_boosts()
     elif split_message[1] == "-clearnegativeboost":
         pokemon = split_message[2]
         self.get_pokemon(pokemon)._clear_negative_boosts()
     elif split_message[1] == "-clearpositiveboost":
         pokemon = split_message[2]
         self.get_pokemon(pokemon)._clear_positive_boosts()
     elif split_message[1] == "-copyboost":
         source, target = split_message[2:4]
         self.get_pokemon(target).copy_boosts(self.get_pokemon(source))
     elif split_message[1] == "-curestatus":
         pokemon, status = split_message[2:4]
         self.get_pokemon(pokemon)._cure_status(status)
     elif split_message[1] == "-cureteam":
         self.logger.warning(
             "cureteam management not implemented in battle. Message: %s"
             % split_message
         )
     elif split_message[1] == "-damage":
         pokemon, hp_status = split_message[2:4]
         self.get_pokemon(pokemon)._damage(hp_status)
     elif split_message[1] == "-end":
         pokemon, effect = split_message[2:4]
         self.get_pokemon(pokemon)._end_effect(effect)
     elif split_message[1] == "-endability":
         pokemon = split_message[2]
         self.get_pokemon(pokemon).ability = None
     elif split_message[1] == "-enditem":
         pokemon, item = split_message[2:4]
         self.get_pokemon(pokemon)._end_item(item)
     elif split_message[1] == "-fieldend":
         condition = split_message[2]
         self._field_end(condition)
     elif split_message[1] == "-fieldstart":
         condition = split_message[2]
         self._field_start(condition)
     elif split_message[1] in ["-formechange", "detailschange"]:
         pokemon, species = split_message[2:4]
         self.get_pokemon(pokemon)._forme_change(species)
     elif split_message[1] == "-heal":
         pokemon, hp_status = split_message[2:4]
         self.get_pokemon(pokemon)._heal(hp_status)
     elif split_message[1] == "-invertboost":
         pokemon = split_message[2]
         self.get_pokemon(pokemon).invertboosts()
     elif split_message[1] == "-item":
         pokemon, item = split_message[2:4]
         self.get_pokemon(pokemon).item = to_id_str(item)
     elif split_message[1] == "-mega":
         pokemon, megastone = split_message[2:4]
         self.get_pokemon(pokemon)._mega_evolve(megastone)
     elif split_message[1] == "-mustrecharge":
         pokemon = split_message[2]
         self.get_pokemon(pokemon).must_recharge = True
     elif split_message[1] == "-prepare":
         attacker, move, defender = split_message[2:5]
         self.get_pokemon(attacker)._prepare(move, self.get_pokemon(defender))
     elif split_message[1] == "-primal":
         pokemon = split_message[2]
         self.get_pokemon(pokemon)._primal()
     elif split_message[1] == "-setboost":
         pokemon, stat, amount = split_message[2:5]
         self.get_pokemon(pokemon)._set_boost(stat, int(amount))
     elif split_message[1] == "-sethp":
         pokemon, hp_status = split_message[2:4]
         self.get_pokemon(pokemon)._set_hp(hp_status)
     elif split_message[1] == "-sideend":
         side, condition = split_message[2:4]
         self._side_end(side, condition)
     elif split_message[1] == "-sidestart":
         side, condition = split_message[2:4]
         self._side_start(side, condition)
     elif split_message[1] == "-start":
         pokemon, effect = split_message[2:4]
         self.get_pokemon(pokemon)._start_effect(effect)
     elif split_message[1] == "-status":
         pokemon, status = split_message[2:4]
         self.get_pokemon(pokemon).status = status
     elif split_message[1] == "-swapboost":
         source, target, stats = split_message[2:5]
         self.get_pokemon(source).swap_boosts(self.get_pokemon(target))
     elif split_message[1] == "-transform":
         pokemon, into = split_message[2:4]
         self.get_pokemon(pokemon)._transform(self.get_pokemon(into))
     elif split_message[1] == "-unboost":
         pokemon, stat, amount = split_message[2:5]
         self.get_pokemon(pokemon)._boost(stat, -int(amount))
     elif split_message[1] == "-weather":
         weather = split_message[2]
         self.weather = weather
     elif split_message[1] == "-zpower":
         pokemon = split_message[2]
         self.get_pokemon(pokemon)._used_z_move()
     elif split_message[1] == "clearpoke":
         self._in_team_preview = True
     elif split_message[1] in ["drag", "switch"]:
         pokemon, details, hp_status = split_message[2:5]
         self._switch(pokemon, hp_status)
     elif split_message[1] == "faint":
         pokemon = split_message[2]
         self.get_pokemon(pokemon)._faint()
     elif split_message[1] == "gen":
         self._format = split_message[2]
     elif split_message[1] == "move":
         pokemon, move, target = split_message[2:5]
         self.get_pokemon(pokemon)._moved(move)
     elif split_message[1] == "player":
         player, username, avatar, rating = split_message[2:6]
         if username == self._player_username:
             self._player_role = player
         return self._players.append(
             {
                 "username": username,
                 "player": player,
                 "avatar": avatar,
                 "rating": rating,
             }
         )
     elif split_message[1] == "poke":
         player, details, item = split_message[2:5]
         self.register_pokemon(player, details, item)
     elif split_message[1] == "replace":
         pokemon = split_message[2]
         self._end_illusion(pokemon)
     elif split_message[1] == "rule":
         self._rules.append(split_message[2])
     elif split_message[1] == "start":
         self._in_team_preview = False
     elif split_message[1] == "swap":
         pokemon, position = split_message[2:4]
         self._swap(pokemon, position)
     else:
         raise NotImplementedError(split_message)
Ejemplo n.º 4
0
	def embed_battle(self, battle):
		final_state_dict = {}
		team = []
		active_pokemon = battle.active_pokemon
		switches = battle.available_switches
		fainted_padding = [None] * (5 - len(switches))
		pokemon_objects = [active_pokemon] + switches + fainted_padding
		assert len(pokemon_objects) == 6
		for idx, pokemon in enumerate(pokemon_objects):#battle.team.keys(): #thought this was a method
			#pokemon = battle.team[pokemon_key]
			pokemon_information = {}

			#TODO: Bump the rest of these declarations to the top.
			species_id = 0
			types = [0,0]
			move_ids = [0,0,0,0]
			move_pp = [0,0,0,0]
			move_type_ids = [0,0,0,0]
			move_powers = [0,0,0,0]
			move_accuracies = [0,0,0,0]
			move_physical_or_special = [0,0,0,0]
			item_id = 0
			hp_percentage = [0]
			ability_id = 0
			status_id = 0
			scaled_stats = [0] * 6
			boosts = [0] * 7
			volatiles = [0] * len(relevant_conditions.volatiles)

			if not pokemon == None and not pokemon.fainted and not pokemon._species == "zoroark":
				# -1 indicates that the move does not have a base power
				# or is not available

				species_id = STR_TO_ID["species"][to_id_str(pokemon._species)]


				#Type ids

				types[0] = STR_TO_ID["types"][fix_type(pokemon.type_1.name)]
				if pokemon.type_2 is not None:
					types[1] = STR_TO_ID["types"][fix_type(pokemon.type_2.name)]
				else:
					pass

				#Move ids
				#move pp
				#move type
				#move power
				#move accuracy
				#physical or special or nondamaging


				for i, move in enumerate(pokemon.moves):
					if i == 4:
						break
					move_obj = pokemon.moves[move]
					#TODO: Sometimes this throws an error. Why?
					try:
						move_ids[i] = STR_TO_ID["moves"][move]
					except IndexError:
						print(pokemon)
						print(pokemon.moves)
						print(move_ids, move_obj)
						print("weirdo move error", move,  i)
						print(STR_TO_ID["moves"][move])
					try:
						move_pp[i] = move_obj._current_pp / move_obj.max_pp
					except ZeroDivisionError:
						print("Move division by zero for pp calc", move, move_obj._current_pp, pokemon._species)
					move_accuracies[i] = move_obj.accuracy
					move_type_ids[i] = STR_TO_ID["types"][fix_type(move_obj.type.name)]
					move_powers[i] = move_obj.base_power / 150.0 #TODO: Explosion?
					if move_obj.category.name == "PHYSICAL":
						move_physical_or_special[i] = 0
					elif move_obj.category.name == "SPECIAL":
						move_physical_or_special[i] = 1
					elif move_obj.category.name == "STATUS":
						move_physical_or_special[i] = 2
					else:
						print("woops")
						sys.exit(1)



				#Item id

				if pokemon.item is not None:
					try:
						item_id = STR_TO_ID["items"][to_id_str(pokemon._item)] #noitem offset
					except KeyError: #TODO: Why does this happen?
						pass


				#Ability id
				ability_id = STR_TO_ID["abilities"][to_id_str(pokemon._ability)]
				#status
				if pokemon.status == Status.FNT:
					print("You shouldn't be in here")
					sys.exit(1)
				else:
					status_id = relevant_conditions.statuses.index(pokemon.status)

				#HP (%perentage)

				try:
					hp_percentage[0] = pokemon._current_hp * 1.0 / pokemon._max_hp
				except TypeError:
					print("calculating hp percentage failed for {}".format(pokemon._species))




				for i, name in enumerate(["hp", "atk", "def", "spa", "spd", "spe"]):
					if name == "hp":
						stat = pokemon._max_hp
						stat_max = 669
						stat_min = 15
						#Min HP at level 50: 15
						#Max HP at level 100: 669
					else:
						stat = pokemon.stats[name]
						stat_max = 714
						stat_min = 70
						#Min other stat at level 100: 70
						#Max other stat at level 100: 714
					try:
						scaled_stats[i] = (stat - stat_min) / (1.0 * stat_max - stat_min)
					except TypeError:
						print("TypeError: Zoroark")
						scaled_stats[i] = 0



				'''#TODO (longterm): NATURES

				#Base stats
				scaled_base_stats = [0] * 6
				for i, (name, scaling_factor) in enumerate([
						("hp", 255),
						("atk", 170),
						("def", 230),
						("spa", 170),
						("spd", 230),
						("spe", 160),
						]):
					scaled_base_stats[i] = pokemon._base_stats[name] / (1.0 * scaling_factor)

				pokemon_information["base_stats"] = scaled_base_stats


				#IVs
				ivs = [0] * 6
				print(pokemon.stats)
				for i, name in enumerate(["hp","atk", "def","spa","spd","spe"]):
					ivs[i] = pokemon.ivs[name] / 32.0
				pokemon_information["ivs"] = ivs

				#EVs
				#Total EVs: 510
				#Max per stat: 252
				#Can only increment by 4 at a time
				#Number of increments = 252 / 4
				evs = [0] * 6
				for i, name in enumerate(["hp","atk", "def","spa","spd","spe"]):
					evs[i] = pokemon.evs[name] / 252.0
				pokemon_information["evs"] = evs'''

				#boosts
				#For each stat "hp","atk", "def","spa","spd","spe" AND "eva", "acc"
				#Multipliers for stats
				#13 levels [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 ]
				#Acc: [-3, -2, -1, 0, 1, 2, 3]

				#TODO (longterm): What is the best encoding of these values? Scalar? 0 to 1? -1 to 1?
				#TODO: Change this for opponent too

				for i, name in enumerate(["atk", "def","spa","spd","spe", "evasion"]):
					boosts[i] = (pokemon.boosts[name] + 6) / 12.0
				boosts[-1] = (pokemon.boosts["accuracy"] + 3) / 6.0


				#volatiles

				active_effects = pokemon.effects
				volatiles = [1 if x in active_effects else 0 for x in relevant_conditions.volatiles]

			pokemon_information["species_id"] = species_id
			pokemon_information["type_ids"] = types
			pokemon_information["move_ids"] = move_ids
			pokemon_information["pp"] = move_pp
			pokemon_information["move_type_ids"] = move_type_ids
			pokemon_information["move_powers"] = move_powers
			pokemon_information["move_accuracies"] = move_accuracies
			pokemon_information["move_physical_or_special"] = move_physical_or_special

			pokemon_information["item_id"] = item_id
			pokemon_information["ability_id"] = ability_id
			pokemon_information["status_id"] = status_id

			pokemon_information["stats"] = scaled_stats
			pokemon_information["hp_percentage"] = hp_percentage

			pokemon_information["boosts"] = boosts
			pokemon_information["volatiles"] = volatiles

			team.append(pokemon_information)
			#isActive

		side_conditions = [0] * len(relevant_conditions.side_conditions)
		active_side_conditions = battle.side_conditions
		our_side_conditions = [1 if x in active_side_conditions else 0 for x in relevant_conditions.side_conditions ]


		final_state_dict["team"] = team
		final_state_dict["player_side_conditions"] = our_side_conditions

		opponent_team = []
		opponent_pokemon_information = {}
		opponent_pokemon = battle.opponent_active_pokemon


		opponent_types = [0,0]
		opponent_species_id = 0
		opponent_hp_percentage = [1]
		opponent_status_id = 0
		opponent_scaled_base_stats = [0] * 6
		opponent_boosts = [0] * 7
		opponent_volatiles = [0] * len(relevant_conditions.volatiles)

		#opponent active pokemon id
		if battle.opponent_active_pokemon.fainted == False:
			opponent_species_id = STR_TO_ID["species"][to_id_str(opponent_pokemon._species)]

			#opponent pokemon type ids

			opponent_types[0] = STR_TO_ID["types"][fix_type(opponent_pokemon.type_1.name)]
			if opponent_pokemon.type_2 is not None:
				opponent_types[1] = STR_TO_ID["types"][fix_type(opponent_pokemon.type_2.name)]
			else:
				pass


			#Opponent HP (%expected perentage)
			#TODO: Does this code actually get the expected percentage based on the opponent's health bar?

			try:
				opponent_hp_percentage[0] = opponent_pokemon._current_hp * 1.0 / opponent_pokemon._max_hp
			except TypeError:
				print("calculating hp percentage failed for {}".format(opponent_pokemon._species))


			#opponent status
			opponent_status_id = relevant_conditions.statuses.index(opponent_pokemon.status)

			#opponent base stats
			for i, (name, scaling_factor) in enumerate([
					("hp", 255),
					("atk", 170),
					("def", 230),
					("spa", 170),
					("spd", 230),
					("spe", 160),
					]):
				opponent_scaled_base_stats[i] = opponent_pokemon._base_stats[name] / (1.0 * scaling_factor)

			#opponent boost


			for i, name in enumerate(["atk", "def","spa","spd","spe", "evasion"]):
				opponent_boosts[i] = (opponent_pokemon.boosts[name] + 6) / 12.0
			opponent_boosts[-1] = (opponent_pokemon.boosts["accuracy"] + 3) / 6.0



			#opponent volatiles
			active_effects = opponent_pokemon.effects
			opponent_volatiles = [1 if x in active_effects else 0 for x in relevant_conditions.volatiles]


		#TODO (longterm):
		#Keeping track of opponent's moves
		#Keeping track of opponent's item
		#Keeping track of opponent's ability
		#Possible abilities

		opponent_pokemon_information["species_id"] = opponent_species_id
		opponent_pokemon_information["type_ids"] = opponent_types
		opponent_pokemon_information["hp_percentage"] = opponent_hp_percentage
		opponent_pokemon_information["boosts"] = opponent_boosts
		opponent_pokemon_information["base_stats"] = opponent_scaled_base_stats
		opponent_pokemon_information["volatiles"] = opponent_volatiles
		opponent_pokemon_information["status_id"] = opponent_status_id

		opponent_team.append(opponent_pokemon_information)

		opponent_side_conditions = [0] * len(relevant_conditions.side_conditions)
		opponent_active_side_conditions = battle.opponent_side_conditions
		opponent_side_conditions = [1 if x in opponent_active_side_conditions else 0 for x in relevant_conditions.side_conditions]

		final_state_dict["opponent_team"] = opponent_team
		final_state_dict["opponent_side_conditions"] = opponent_side_conditions


		weather = relevant_conditions.weathers.index(battle.weather)
		final_state_dict["weather"] = [weather]


		fields = [0] * len(relevant_conditions.fields)
		active_fields = battle.fields
		fields = [1 if x in active_fields else 0 for x in relevant_conditions.fields ]
		final_state_dict["fields"] = fields
		return final_state_dict
Ejemplo n.º 5
0
    def _parse_message(self, split_message: List[str]) -> None:
        if split_message[1] in self.MESSAGES_TO_IGNORE:
            return
        elif split_message[1] == "-ability":
            pokemon, ability = split_message[2:4]
            self.get_pokemon(pokemon).ability = ability
        elif split_message[1] == "-activate":
            target, effect = split_message[2:4]
            if target:
                self.get_pokemon(target)._start_effect(effect)
        elif split_message[1] == "-boost":
            pokemon, stat, amount = split_message[2:5]
            self.get_pokemon(pokemon)._boost(stat, int(amount))
        elif split_message[1] == "-clearallboost":
            self.active_pokemon._clear_boosts()
            if self.opponent_active_pokemon is not None:
                self.opponent_active_pokemon._clear_boosts()  # pyre-ignore
        elif split_message[1] == "-clearboost":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._clear_boosts()
        elif split_message[1] == "-clearnegativeboost":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._clear_negative_boosts()
        elif split_message[1] == "-clearpositiveboost":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._clear_positive_boosts()
        elif split_message[1] == "-copyboost":
            source, target = split_message[2:4]
            self.get_pokemon(target)._copy_boosts(self.get_pokemon(source))
        elif split_message[1] == "-curestatus":
            pokemon, status = split_message[2:4]
            self.get_pokemon(pokemon)._cure_status(status)
        elif split_message[1] == "-cureteam":
            self.logger.warning(
                "cureteam management not implemented in battle. Message: %s"
                % split_message
            )
        elif split_message[1] == "-damage":
            pokemon, hp_status = split_message[2:4]
            self.get_pokemon(pokemon)._damage(hp_status)
        elif split_message[1] == "-end":
            pokemon, effect = split_message[2:4]
            self.get_pokemon(pokemon)._end_effect(effect)
        elif split_message[1] == "-endability":
            pokemon = split_message[2]
            self.get_pokemon(pokemon).ability = None
        elif split_message[1] == "-enditem":
            pokemon, item = split_message[2:4]
            self.get_pokemon(pokemon)._end_item(item)
        elif split_message[1] == "-fieldend":
            condition = split_message[2]
            self._field_end(condition)
        elif split_message[1] == "-fieldstart":
            condition = split_message[2]
            self._field_start(condition)
        elif split_message[1] in ["-formechange", "detailschange"]:
            pokemon, species = split_message[2:4]
            self.get_pokemon(pokemon)._forme_change(species)
        elif split_message[1] == "-heal":
            pokemon, hp_status = split_message[2:4]
            self.get_pokemon(pokemon)._heal(hp_status)
        elif split_message[1] == "-invertboost":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._invert_boosts()
        elif split_message[1] == "-item":
            pokemon, item = split_message[2:4]
            self.get_pokemon(pokemon).item = to_id_str(item)
        elif split_message[1] == "-mega":
            pokemon, megastone = split_message[2:4]
            self.get_pokemon(pokemon)._mega_evolve(megastone)
        elif split_message[1] == "-mustrecharge":
            pokemon = split_message[2]
            self.get_pokemon(pokemon).must_recharge = True
        elif split_message[1] == "-prepare":
            try:
                attacker, move, defender = split_message[2:5]
                self.get_pokemon(defender)
            except ValueError:
                attacker, move = split_message[2:4]
                defender = None
            self.get_pokemon(attacker)._prepare(move, defender)
        elif split_message[1] == "-primal":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._primal()
        elif split_message[1] == "-setboost":
            pokemon, stat, amount = split_message[2:5]
            self.get_pokemon(pokemon)._set_boost(stat, int(amount))
        elif split_message[1] == "-sethp":
            pokemon, hp_status = split_message[2:4]
            self.get_pokemon(pokemon)._set_hp(hp_status)
        elif split_message[1] == "-sideend":
            side, condition = split_message[2:4]
            self._side_end(side, condition)
        elif split_message[1] == "-sidestart":
            side, condition = split_message[2:4]
            self._side_start(side, condition)
        elif split_message[1] == "-start":
            pokemon, effect = split_message[2:4]
            pokemon = self.get_pokemon(pokemon)
            pokemon._start_effect(effect)

            if pokemon.is_dynamaxed:
                if pokemon in set(self.team.values()) and self._dynamax_turn is None:
                    self._dynamax_turn = self.turn
                    # self._can_dynamax value is set via _parse_request()
                elif (
                    pokemon in set(self.opponent_team.values())
                    and self._opponent_dynamax_turn is None
                ):
                    self._opponent_dynamax_turn = self.turn
                    self._opponent_can_dynamax = False
        elif split_message[1] == "-status":
            pokemon, status = split_message[2:4]
            self.get_pokemon(pokemon).status = status
        elif split_message[1] == "-swapboost":
            source, target, stats = split_message[2:5]
            self.get_pokemon(target)._swap_boosts()
        elif split_message[1] == "-transform":
            pokemon, into = split_message[2:4]
            self.get_pokemon(pokemon)._transform(self.get_pokemon(into))
        elif split_message[1] == "-unboost":
            pokemon, stat, amount = split_message[2:5]
            self.get_pokemon(pokemon)._boost(stat, -int(amount))
        elif split_message[1] == "-weather":
            weather = split_message[2]
            self.weather = weather
        elif split_message[1] == "-zpower":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._used_z_move()
        elif split_message[1] == "clearpoke":
            self._in_team_preview = True
        elif split_message[1] in ["drag", "switch"]:
            pokemon, details, hp_status = split_message[2:5]
            self._switch(pokemon, details, hp_status)
        elif split_message[1] == "faint":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._faint()
        elif split_message[1] == "gen":
            self._format = split_message[2]
        elif split_message[1] == "move":
            pokemon, move, target = split_message[2:5]
            self.get_pokemon(pokemon)._moved(move)
        elif split_message[1] == "player":
            player, username, avatar, rating = split_message[2:6]
            if username == self._player_username:
                self._player_role = player
            return self._players.append(
                {
                    "username": username,
                    "player": player,
                    "avatar": avatar,
                    "rating": rating,
                }
            )
        elif split_message[1] == "poke":
            player, details = split_message[2:4]
            self._register_teampreview_pokemon(player, details)
        elif split_message[1] == "raw":
            username, rating_info = split_message[2].split("'s rating: ")
            rating = int(rating_info[:4])
            if username == self.player_username:
                self._rating = rating
            elif username == self.opponent_username:
                self._opponent_rating = rating
            else:
                self.logger.warning(
                    "Rating information regarding an unrecognized username received. "
                    "Received '%s', while only known players are '%s' and '%s'",
                    username,
                    self.player_username,
                    self.opponent_username,
                )
        elif split_message[1] == "replace":
            pokemon = split_message[2]
            details = split_message[3]
            self._end_illusion(pokemon, details)
        elif split_message[1] == "rule":
            self._rules.append(split_message[2])
        elif split_message[1] == "start":
            self._in_team_preview = False
        elif split_message[1] == "swap":
            pokemon, position = split_message[2:4]
            self._swap(pokemon, position)
        elif split_message[1] == "teamsize":
            player, number = split_message[2:4]
            number = int(number)
            self._team_size[player] = number
        else:
            raise NotImplementedError(split_message)
Ejemplo n.º 6
0
 def check_move_is_gyro_ball(self, move: Move) -> bool:
     return move.id == to_id_str("Gyro Ball")
Ejemplo n.º 7
0
 def ability(self, ability: Optional[str]):
     if ability is None:
         self._ability = None
     else:
         self._ability = to_id_str(ability)
Ejemplo n.º 8
0
    def _parse_message(self, split_message: List[str]) -> None:
        if self._save_replays:
            self._replay_data.append(split_message)

        if split_message[1] in self.MESSAGES_TO_IGNORE:
            return
        elif split_message[1] in ["drag", "switch"]:
            pokemon, details, hp_status = split_message[2:5]
            self._switch(pokemon, details, hp_status)
        elif split_message[1] == "-damage":
            pokemon, hp_status = split_message[2:4]
            self.get_pokemon(pokemon)._damage(hp_status)
            self._check_damage_message_for_item(split_message)
            self._check_damage_message_for_ability(split_message)
        elif split_message[1] == "move":
            failed = False
            override_move = None
            reveal_other_move = False

            for move_failed_suffix in ["[miss]", "[still]", "[notarget]"]:
                if split_message[-1] == move_failed_suffix:
                    split_message = split_message[:-1]
                    failed = True

            if split_message[-1] == "[notarget]":
                split_message = split_message[:-1]

            if split_message[-1] in {
                    "[from]lockedmove", "[from]Pursuit", "[zeffect]"
            }:
                split_message = split_message[:-1]

            if split_message[-1].startswith("[anim]"):
                split_message = split_message[:-1]

            if split_message[-1] == "null":
                split_message = split_message[:-1]

            if split_message[-1].startswith("[from]move: "):
                override_move = split_message.pop()[12:]

                if override_move == "Sleep Talk":
                    # Sleep talk was used, but also reveals another move
                    reveal_other_move = True
                elif override_move == "Copycat":
                    pass
                else:
                    self.logger.warning(
                        "Unmanaged [from]move message received - move %s in cleaned up "
                        "message %s in battle %s turn %d",
                        override_move,
                        split_message,
                        self.battle_tag,
                        self.turn,
                    )

            if split_message[-1].startswith("[from]ability: "):
                revealed_ability = split_message.pop()[15:]
                pokemon = split_message[2]
                self.get_pokemon(pokemon).ability = revealed_ability

                if revealed_ability == "Magic Bounce":
                    return
                elif revealed_ability == "Dancer":
                    return
                else:
                    self.logger.warning(
                        "Unmanaged [from]ability: message received - ability %s in "
                        "cleaned up message %s in battle %s turn %d",
                        revealed_ability,
                        split_message,
                        self.battle_tag,
                        self.turn,
                    )
            if split_message[-1] == "[from]Magic Coat":
                return

            if split_message[-1] == "":
                split_message = split_message[:-1]

            if len(split_message) == 4:
                pokemon, move = split_message[2:4]
            elif len(split_message) == 5:
                pokemon, move, presumed_target = split_message[2:5]

                if len(presumed_target) > 4 and presumed_target[:4] in {
                        "p1: ",
                        "p2: ",
                        "p1a:",
                        "p1b:",
                        "p2a:",
                        "p2b:",
                }:
                    pass
                else:
                    self.logger.warning(
                        "Unmanaged move message format received - cleaned up message %s"
                        " in battle %s turn %d",
                        split_message,
                        self.battle_tag,
                        self.turn,
                    )
            else:
                pokemon, move, presumed_target = split_message[2:5]
                self.logger.warning(
                    "Unmanaged move message format received - cleaned up message %s in "
                    "battle %s turn %d",
                    split_message,
                    self.battle_tag,
                    self.turn,
                )

            if override_move:
                self.get_pokemon(pokemon)._moved(override_move, failed=failed)
            if override_move is None or reveal_other_move:
                self.get_pokemon(pokemon)._moved(move,
                                                 failed=failed,
                                                 use=not reveal_other_move)
        elif split_message[1] == "cant":
            pokemon, _ = split_message[2:4]
            self.get_pokemon(pokemon)._cant_move()
        elif split_message[1] == "turn":
            self.end_turn(int(split_message[2]))
        elif split_message[1] == "-heal":
            pokemon, hp_status = split_message[2:4]
            self.get_pokemon(pokemon)._heal(hp_status)
            self._check_heal_message_for_ability(split_message)
            self._check_heal_message_for_item(split_message)
        elif split_message[1] == "-boost":
            pokemon, stat, amount = split_message[2:5]
            self.get_pokemon(pokemon)._boost(stat, int(amount))
        elif split_message[1] == "-weather":
            weather = split_message[2]
            if weather == "none":
                self._weather = {}
                return
            else:
                self._weather = {
                    Weather.from_showdown_message(weather): self.turn
                }
        elif split_message[1] == "faint":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._faint()
        elif split_message[1] == "-unboost":
            pokemon, stat, amount = split_message[2:5]
            self.get_pokemon(pokemon)._boost(stat, -int(amount))
        elif split_message[1] == "-ability":
            pokemon, ability = split_message[2:4]
            self.get_pokemon(pokemon).ability = ability
        elif split_message[1] == "-start":
            pokemon, effect = split_message[2:4]
            pokemon = self.get_pokemon(pokemon)
            pokemon._start_effect(effect)

            if pokemon.is_dynamaxed:
                if pokemon in set(
                        self.team.values()) and self._dynamax_turn is None:
                    self._dynamax_turn = self.turn
                # self._can_dynamax value is set via _parse_request()
                elif (pokemon in set(self.opponent_team.values())
                      and self._opponent_dynamax_turn is None):
                    self._opponent_dynamax_turn = self.turn
                    self.opponent_can_dynamax = False
        elif split_message[1] == "-activate":
            target, effect = split_message[2:4]
            if target:
                self.get_pokemon(target)._start_effect(effect)
        elif split_message[1] == "-status":
            pokemon, status = split_message[2:4]
            self.get_pokemon(pokemon).status = status
        elif split_message[1] == "rule":
            self._rules.append(split_message[2])

        elif split_message[1] == "-clearallboost":
            self._clear_all_boosts()
        elif split_message[1] == "-clearboost":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._clear_boosts()
        elif split_message[1] == "-clearnegativeboost":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._clear_negative_boosts()
        elif split_message[1] == "-clearpositiveboost":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._clear_positive_boosts()
        elif split_message[1] == "-copyboost":
            source, target = split_message[2:4]
            self.get_pokemon(target)._copy_boosts(self.get_pokemon(source))
        elif split_message[1] == "-curestatus":
            pokemon, status = split_message[2:4]
            self.get_pokemon(pokemon)._cure_status(status)
        elif split_message[1] == "-cureteam":
            pokemon = split_message[2]
            team = (self.team if pokemon[:2] == self._player_role else
                    self._opponent_team)
            for mon in team.values():
                mon._cure_status()
        elif split_message[1] == "-end":
            pokemon, effect = split_message[2:4]
            self.get_pokemon(pokemon)._end_effect(effect)
        elif split_message[1] == "-endability":
            pokemon = split_message[2]
            self.get_pokemon(pokemon).ability = None
        elif split_message[1] == "-enditem":
            pokemon, item = split_message[2:4]
            self.get_pokemon(pokemon)._end_item(item)
        elif split_message[1] == "-fieldend":
            condition = split_message[2]
            self._field_end(condition)
        elif split_message[1] == "-fieldstart":
            condition = split_message[2]
            self._field_start(condition)
        elif split_message[1] in ["-formechange", "detailschange"]:
            pokemon, species = split_message[2:4]
            self.get_pokemon(pokemon)._forme_change(species)
        elif split_message[1] == "-invertboost":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._invert_boosts()
        elif split_message[1] == "-item":
            pokemon, item = split_message[2:4]
            self.get_pokemon(pokemon).item = to_id_str(item)
        elif split_message[1] == "-mega":
            if not split_message[2].startswith(
                    self._player_role):  # pyre-ignore
                self._opponent_can_mega_evolve = False  # pyre-ignore
            pokemon, megastone = split_message[2:4]
            self.get_pokemon(pokemon)._mega_evolve(megastone)
        elif split_message[1] == "-mustrecharge":
            pokemon = split_message[2]
            self.get_pokemon(pokemon).must_recharge = True
        elif split_message[1] == "-prepare":
            try:
                attacker, move, defender = split_message[2:5]
                defender = self.get_pokemon(defender)
                if to_id_str(move) == "skydrop":
                    defender._start_effect("Sky Drop")
            except ValueError:
                attacker, move = split_message[2:4]
                defender = None
            self.get_pokemon(attacker)._prepare(move, defender)
        elif split_message[1] == "-primal":
            pokemon = split_message[2]
            self.get_pokemon(pokemon)._primal()
        elif split_message[1] == "-setboost":
            pokemon, stat, amount = split_message[2:5]
            self.get_pokemon(pokemon)._set_boost(stat, int(amount))
        elif split_message[1] == "-sethp":
            pokemon, hp_status = split_message[2:4]
            self.get_pokemon(pokemon)._set_hp(hp_status)
        elif split_message[1] == "-sideend":
            side, condition = split_message[2:4]
            self._side_end(side, condition)
        elif split_message[1] == "-sidestart":
            side, condition = split_message[2:4]
            self._side_start(side, condition)
        elif split_message[1] == "-swapboost":
            source, target, stats = split_message[2:5]
            source = self.get_pokemon(source)
            target = self.get_pokemon(target)
            for stat in stats.split(", "):
                source._boosts[stat], target._boosts[stat] = (
                    target._boosts[stat],
                    source._boosts[stat],
                )
        elif split_message[1] == "-transform":
            pokemon, into = split_message[2:4]
            self.get_pokemon(pokemon)._transform(self.get_pokemon(into))
        elif split_message[1] == "-zpower":
            if not split_message[2].startswith(
                    self._player_role):  # pyre-ignore
                self._opponent_can_mega_z_move = False  # pyre-ignore

            pokemon = split_message[2]
            self.get_pokemon(pokemon)._used_z_move()
        elif split_message[1] == "clearpoke":
            self._in_team_preview = True
        elif split_message[1] == "gen":
            self._format = split_message[2]
        elif split_message[1] == "player":
            player, username, avatar, rating = split_message[2:6]
            if username == self._player_username:
                self._player_role = player
            return self._players.append({
                "username": username,
                "player": player,
                "avatar": avatar,
                "rating": rating,
            })
        elif split_message[1] == "poke":
            player, details = split_message[2:4]
            self._register_teampreview_pokemon(player, details)
        elif split_message[1] == "raw":
            username, rating_info = split_message[2].split("'s rating: ")
            rating = int(rating_info[:4])
            if username == self.player_username:
                self._rating = rating
            elif username == self.opponent_username:
                self._opponent_rating = rating
            else:
                self.logger.warning(
                    "Rating information regarding an unrecognized username received. "
                    "Received '%s', while only known players are '%s' and '%s'",
                    username,
                    self.player_username,
                    self.opponent_username,
                )
        elif split_message[1] == "replace":
            pokemon = split_message[2]
            details = split_message[3]
            self._end_illusion(pokemon, details)
        elif split_message[1] == "start":
            self._in_team_preview = False
        elif split_message[1] == "swap":
            pokemon, position = split_message[2:4]
            self._swap(pokemon, position)
        elif split_message[1] == "teamsize":
            player, number = split_message[2:4]
            number = int(number)
            self._team_size[player] = number
        elif split_message[1] in {"message", "-message"}:
            self.logger.info("Received message: %s", split_message[2])
        elif split_message[1] == "-immune":
            if len(split_message) == 4:
                mon, cause = split_message[2:]

                if cause.startswith("[from] ability:"):
                    ability = cause.replace("[from] ability:", "")
                    self.get_pokemon(mon).ability = to_id_str(ability)
        elif split_message[1] == "-swapsideconditions":
            self._side_conditions, self._opponent_side_conditions = (
                self._opponent_side_conditions,
                self._side_conditions,
            )
        elif split_message[1] == "title":
            player_1, player_2 = split_message[2].split(" vs. ")
            self.players = player_1, player_2
        else:
            raise NotImplementedError(split_message)