def _parse_args(args, draft_len): ban_per_team = 0 if len(args) >= 6: if not args[5].isdigit(): raise InvalidArgs( f"Number of ban per team must be a int, not \"{args[5]}\"") ban_per_team = int(args[5]) pick_per_team = (draft_len - ban_per_team * 2) // 2 if len(args) >= 5: if args[4] != "max": if not args[4].isdigit(): raise InvalidArgs( f"Number of pick per team must be a int or \"max\", not \"{args[4]}\"" ) pick_per_team = int(args[4]) if pick_per_team > (draft_len - ban_per_team * 2) // 2: raise InvalidArgs( f"There is not enough draft for this number of ban/pick per team" ) timer = 60 if len(args) >= 7: if not args[6].isdigit(): raise InvalidArgs(f"Timer must be a int, not \"{args[6]}\"") timer = int(args[6]) return ban_per_team, pick_per_team, timer
async def cmd_randomgroup(self, *args, channel, member, client, **_): if len(args) >= 2: if not args[1].isdigit(): raise InvalidArgs("2nd Argument must be a channel ID") target = client.get_channel(int(args[1])) if not target: raise NotFound(f"Channel ID {args[1]} not found") else: if not member.voice or not member.voice.channel: raise NotFound("Impossible de récupérer les joueurs : Vous n'êtes pas connecté à un channel vocal") target = member.voice.channel members = target.members if not members: raise NotFound("Member not found in channels") if not args: raise InvalidArgs("Invalid syntax: `/randomgroup {number_of_group}`") if not args[0].isdigit(): raise InvalidArgs("1st Argument must be a number") random.shuffle(members) nb = int(args[0]) groups = [] div, mod = divmod(len(members), nb) x = 0 for i in range(nb): y = div+(i<mod) await channel.send(f"`group {i+1}`: {', '.join(f'<@{i.id}>' for i in members[x:x+y])}") x += y
async def cmd_unvalidreport(self, *args, member, force, client, channel, **_): if not is_arbitre(member, client=client) and not force: raise Forbidden("You must be Arbitre for use this command") if not args: raise InvalidArgs("Command must take one argument") if not args[0].isdigit(): raise InvalidArgs("Argument must be a number") match = db.get_match(args[0]) if not match: raise NotFound("Match not found") if not match.validated: raise BotError("Match is already unvalided") db.unvalid_match(match) # update Players Stats database for i in match.report.players: db.unregister_plstats( i.id, match.report.gametype, i.position <= POSITION_REQUIRE_FOR_WIN[match.report.gametype]) # Verif if players are eligible to new roles civfr: nextcord.Guild = client.get_guild(CIVFR_GUILD_ID) tasks = [ recalc_role_for(civfr.get_member(i.id)) for i in match.report.players ] await asyncio.gather(*tasks) # Change embed validation_msg = await client.get_channel( REPORT_CHANNEL).fetch_message(match.check_msg_id) await validation_msg.edit(embed=match.to_embed(member.id)) await validation_msg.clear_reactions() await channel.send("Match invalidé.")
def parse_expr(expr: str) -> Tuple[List[Dice], int]: dices = [] # type: List[Dice] bonus = 0 # type: int expr.replace(' ', '').lower() ex_list = re.split(r"([\+-])", expr) if ex_list[0] == '': del ex_list[0] else: ex_list.insert(0, '+') ex_list = [(ex_list[i * 2] + ex_list[i * 2 + 1]) for i in range(len(ex_list) // 2)] for ex in ex_list: r = re.findall(r"^([\+-])?(\d+)d(\d+)$", ex) b = re.findall(r"^([\+-])?(\d+)$", ex) if r: r = r[0] if r[1] == '0': raise InvalidArgs( "Le nombre de dé à lancer ne peut pas être égal à 0.") if r[2] == '0': raise InvalidArgs( "Le dé ne peut pas avoir 0 face ... c'est physiquement impossible !" ) dices.append(Dice(int(r[1]), int(r[2]), r[0] == '-')) elif b: b = b[0] bonus += int(b[0] + b[1]) else: raise InvalidArgs( f"L'expression \"{ex}\" ne correspond pas à une formule connu, consultez le ``/help Roll``" ) return dices, bonus
def get_raw_draft(nb : int, *args) -> Iterable[List[Leader]]: pool = leaders.leaders[:] if len(args) >= 1: ban_query = args[0].split('.') for ban in ban_query: if not ban: continue sp = SPECIAL_BANS.get(ban.lower()) if sp: for i in sp: pool.remove(leaders.get_leader_named(i)) else: lead = leaders.get_leader_named(ban) if not lead: raise InvalidArgs(f"Leader \"{ban}\" non trouvé") pool.remove(lead) leader_per_player = len(pool) // nb if len(args) >= 2: if args[1] != 'max': if not args[1].isdigit(): raise InvalidArgs( "3rd Argument (max civ per draft) must be a integer or \"max\" (exemple: ``/draft 8 Maori.Colombie 4``)") leader_per_player = int(args[1]) random.shuffle(pool) return (pool[i * leader_per_player:i * leader_per_player + leader_per_player] for i in range(nb))
async def sell_champ(*args, channel, member): if len(args) < 2: raise InvalidArgs("/tftsell {nom du champion} {niveau}") if not args[-1].isdigit(): raise InvalidArgs( f"Le niveau doit être un nombre et non \"{args[-1]}\"") champion = ' '.join(args[:-1]) level = int(args[-1]) d = {"name": champion, "level": level} if champion not in CHAMPIONS_PRICES.keys(): raise NotFound( f"Le champion nommé \"{champion}\" n'est pas disponible dans ce set" ) with Database() as db: # type: Database champ_json = db.get_champions(member.id) if not champ_json: raise NotFound(f"No champion found for {member}") if d not in champ_json: raise NotFound( f"Champion {champion} lvl: {level} non trouvé dans l'équipe" ) champ_json.remove(d) gold = db.get_gold(member.id) gain = CHAMPIONS_PRICES[champion] * 3**(level - 1) db.update_gold(member.id, gold + gain) db.update_champions(member.id, champ_json) await channel.send( f"{member.mention} a vendu {champion} lvl {level} pour {gain} gold ({gold + gain})" )
async def cmd_draft(self, *args: str, channel, client, member, guild, **_): if not args: raise InvalidArgs("Command should take at least one parameter") if args[0].lower() == 'ffa': members = get_member_in_channel(member.voice) nb = len(members) generator = (m.mention for m in members) else: if not args[0].isdigit(): raise InvalidArgs( "1st Argument must be a integer (exemple: ``/draft 2``) or 'FFA'" ) nb = int(args[0]) if nb > 100: raise AntiRelouException( "Atempting to run a draft with more than 100 lines") generator = (f"n°{i+1}" for i in range(nb)) if guild and guild.id in [ 291751672106188800, 746790444171657347, 745407180638912582, 365593396548730883, 470335770972913664 ]: drafts = get_draft(nb, *args[1:], client=client, display_name="cpl") else: drafts = get_draft(nb, *args[1:], client=client) await draw_draft(drafts, generator, channel)
async def cmd_lolquizz(self, *args, channel, client, **_): """ Args: *args: channel (discord.TextChannel): **_: Returns: """ if not args: max_question = 10 else: try: max_question = int(''.join(args)) except: raise InvalidArgs( "Le nombre max de question doit être un nombre") if max_question > 500: raise InvalidArgs("Déso pas déso, le max c'est 500") points = {} old = [] for current_question in range(max_question): second_time = False spell = RandomSpell(old=old) old.append(spell.answer) check = lambda m: m.channel == channel and spell.check_if_correct( m.content) while True: if not second_time: msg = await channel.send(embed=spell.to_embed( footer_text= f"question {current_question + 1}/{max_question}", with_image=False)) else: await msg.edit(embed=spell.to_embed( footer_text= f"question {current_question + 1}/{max_question}", with_image=True)) try: answer = await client.wait_for('message', check=check, timeout=15 ) # type: discord.Message except asyncio.TimeoutError: second_time = True continue points[answer.author.name] = points.get(answer.author.name, 0) + 1 await channel.send( f"{answer.author.mention} a gagné un point" + "```{}```".format('\n'.join( [f'{k} : {v}' for k, v in points.items()]))) break
async def cmd_ffa(self, *args, **kwargs): if not args: raise InvalidArgs( f"Aucune sous-commande donnée. Veuillez entrez une des sous-commandes valides suivante: {'/'.join(commands.keys())}" ) cmd = commands.get(args[0]) if not cmd: raise InvalidArgs( f"Sous-commande donné inconnue. Veuillez entrez une des sous-commandes valides suivante: {'/'.join(commands.keys())}" ) await cmd(*args[1:], **kwargs)
async def cmd_validreport(self, *args, member, force, client, guild, channel, **_): if not is_arbitre(member, client=client) and not force: raise Forbidden("You must be Arbitre for use this command") if not args: raise InvalidArgs("Command must take one argument") if not args[0].isdigit(): raise InvalidArgs("Argument must be a number") r = await valid_report(int(args[0]), channel.id, guild, client, member) if r: raise BotError(r) else: await channel.send("Report validé de force")
async def force_valid_match(*args: str, member, force, channel, client, **_): if len(args) < 1: raise InvalidArgs("Match ID is needed") if not args[0].isdigit(): raise InvalidArgs("Match ID must be a int") if not is_arbitre(member) and not force: raise Forbidden("Only a Arbitre can use this command") match = db.get_match(int(args[0])) match.is_valided = True db.save() await channel.send( f"Le match {match.report_message_id}/{match.confirm_message_id} opposant {', '.join(f'<@{i}>' for i in match.result_dict.keys())} a été validé de force par {member.mention}" ) await update_leaderboard(client)
async def cmd_draft(self, *args : str, channel, client, member, **_): if not args: raise InvalidArgs("Command should take at least one parameter") if args[0].lower() == 'ffa': members = get_member_in_channel(member.voice) nb = len(members) generator = (m.mention for m in members) else: if not args[0].isdigit(): raise InvalidArgs("1st Argument must be a integer (exemple: ``/draft 2``) or 'FFA'") nb = int(args[0]) generator = (f"n°{i+1}" for i in range(nb)) drafts = get_draft(nb, *args[1:], client=client) await draw_draft(drafts, generator, channel)
async def cmd_dindon(self, *args, channel, **_): if not is_civfr_guild_or_mp(channel): raise Forbidden("This commands is only aviable on CivFR") if not args: raise InvalidArgs("Command argument must be 'now' or 'xxhxx'") if args[0] == 'now': await channel.send("@here la partie va bientôt commencer. Veuillez vous connecter dans 'Salle d'attente' 🦃", allowed_mentions=AllowedMentions(everyone=True))
async def cmd_mithroll(self, *args, message, channel, member, guild, content, **_): if '#' in content: content, target_query = content.split('#', 1) target = get_member(guild, target_query.strip()) else: target = member if not args: raise InvalidArgs("Usage: /mithroll {comp_name} [+/-][nombre]") try: wsh = gc.open_by_key(CHAR_SHEET[str(target.id)]).sheet1 except: raise BotError("Impossible d'ouvrir la fiche de personnage du membre") comp = parse_competences(wsh) re_result = re.search(r".*([+-])\s*(\d+)\s*$", content) if re_result: sign_char = re_result.group(1) name = content.split(sign_char, 1)[0] bonus = int(sign_char + re_result.group(2)) else: name, bonus = content, 0 d = await roll_by_comp(comp, name.strip().lower(), bonus) em = discord.Embed( title="Lancé de dés", description=COMPROLL_DESC.format(**d, member=member), colour=target.colour ).set_footer(text=message.content).set_author(name=target.name, icon_url=target.avatar_url) em.add_field(name="Résultat", value=f"```diff\n{d['verdict']}```") if d['verdict'] == "- Echec Critique": em.set_image(url=random_choice(FAIL_GIF)) elif d['verdict'] == "+ Réussite Critique": em.set_image(url=random_choice(SUCCES_GIF)) await channel.send(embed=em)
async def cmd_mithrollversus(self, *args, message, content, member, channel, guild, **_): match = CMD_VERSUS_REGEX.match(content) if not match: raise InvalidArgs(f"The command content must match regular the regular expression\n``{CMD_VERSUS_REGEX.pattern}``") d = {k:v for k, v in match.groupdict().items() if v is not None} comp_atk = d['comp_atk'] atk_bonus = int(d.get('atk_bonus_sign', '+') + d.get('atk_bonus', '0')) comp_def = d.get('comp_def', comp_atk) def_bonus = int(d.get('def_bonus_sign', '+') + d.get('def_bonus', '0')) defenser = get_member(guild, d['def']) attacker = d.get('roller', None) attacker = member if attacker is None else get_member(guild, attacker) try: wsh1 = gc.open_by_key(CHAR_SHEET[str(attacker.id)]).sheet1 wsh2 = gc.open_by_key(CHAR_SHEET[str(defenser.id)]).sheet1 except: raise BotError("Impossible d'ouvrir la fiche de personnage du membre") datk = await roll_by_comp(parse_competences(wsh1), comp_atk.strip().lower(), atk_bonus) ddef = await roll_by_comp(parse_competences(wsh2), comp_def.strip().lower(), def_bonus) em = discord.Embed( title="Lancé de dés", description=f"{attacker.mention} **vs** {defenser.mention}", colour=attacker.colour ).set_footer(text=message.content).set_author(name=attacker.name, icon_url=attacker.avatar_url) em.add_field(name="Attaque", value=COMPROLL_DESC.format(**datk, member=attacker), inline=True) em.add_field(name="Défense", value=COMPROLL_DESC.format(**ddef, member=defenser), inline=True) em.add_field(name="Résultat", value=f"```diff\n{datk['verdict']}```**VS**```diff\n{ddef['verdict']}```", inline=False) if datk['verdict'] == "- Echec Critique": em.set_image(url=random_choice(FAIL_GIF)) elif datk['verdict'] == "+ Réussite Critique": em.set_image(url=random_choice(SUCCES_GIF)) await channel.send(embed=em)
async def cmd_addreaction(self, *args: str, client, channel, message, **_): if len(args) < 2: raise InvalidArgs( "Invalid syntax, ``/addreaction message_id emoji_name``") if not args[0].isdigit(): raise InvalidArgs( f"First argument must be a number, got \"{args[0]}\"") msg = await channel.fetch_message(int(args[0])) if not msg: raise NotFound(f"Message with id \"{args[0]}\" not found") emoji = nextcord.utils.get(client.emojis, name=args[1]) if not emoji: raise NotFound(f"Emoji named \"{args[1]}\" not found") try: await message.delete() except: pass await msg.add_reaction(emoji)
async def cmd_ddraft(self, *args: str, channel, client, member, guild, **_): """/ddraft {nb} {bans} {leader_per_draft} {pick_per_team} {ban_per_team} {timer}""" if not args: raise InvalidArgs("Command should take at least two parameter") if not args[1].isdigit(): raise InvalidArgs( "2nd Argument must be a integer (exemple: ``/ddraft @iElden 8``)" ) nb = int(args[1]) drafts_lines = get_draft(nb, *args[2:4], client=client) draft = DynamicDraft(args, drafts_lines, member, get_member(guild, args[0])) msg = await channel.send(embed=draft.to_embed()) for i, _ in enumerate(draft.drafts): await msg.add_reaction(emoji.NB[i]) while True: try: reaction, _ = await client.wait_for( 'reaction_add', timeout=3, check=lambda reaction, user: user == draft.get_member_needed_for_action( ) and reaction.message.id == msg.id) except asyncio.TimeoutError: if draft.timer > -5: draft.update_timer(3) asyncio.create_task(msg.edit(embed=draft.to_embed())) else: draft.reset_timer() draft.update(None) await msg.edit(embed=draft.to_embed()) continue try: n = emoji.NB.index(str(reaction)) except: continue draft.reset_timer() rt = draft.update(n) await msg.edit(embed=draft.to_embed()) if rt: break
async def cmd_ladder(self, *args, message, **_): if not args or args[0] not in ['SoloQ', 'FlexQ', '3v3TT', 'TFT']: raise InvalidArgs("Préciser la queue [SoloQ/FlexQ/3v3TT/TFT]") lst = await get_leader(message, args[0]) lst = lst[:20] tasks = [panth.getSummoner(summ_id) for summ_id in [i[0] for i in lst]] summ_name = [i['name'] for i in await asyncio.gather(*tasks)] txt = "```{}```".format('\n'.join(["{:>2}.{:>16} {}".format(i+1, summ_name[i], j[1][1]) for i,j in enumerate(lst)])) await message.channel.send(txt)
def cmd_roledel(self, *args, channel, guild, **_): """/roledel {role}""" global openrole if not args: raise InvalidArgs("Aucun argument envoyé") role = find_role_named(guild, ' '.join(args).lower()) if role.id in openrole[str(guild.id)]: raise Error("Le Role n'est pas dans la liste, hop là, travail vite fait !") openrole[str(guild.id)].remove(role.id) save_openrole(openrole) await channel.send("Role supprimé")
async def cmd_vote(self, *args, member, message: nextcord.Message, channel, client, **_): if not args: members = get_member_in_channel(member.voice) else: members = message.mentions if not members: raise InvalidArgs( "Vous devez sois laisser la commande vide, ou bien notifier chacune des personnes participant au vote" ) voting = Voting(members) await voting.run(channel, client)
async def cmd_mdelete(self, *args, message, channel, member, **_): """/mdelete {message_id} [!][*raison]""" if not args: raise InvalidArgs("Pas d'argument reçu") msg = await channel.fetch_message(int(args[0])) await msg.delete() await message.delete() if len(args) >= 2: reason = ' '.join(args[1:]) if reason.startswith('!'): await msg.author.send( MOD_DELETED.format(member.mention, reason[1:], msg.content))
def cmd_roleadd(self, *args, channel, guild, **_): """/roleadd {role}""" global openrole if not args: raise InvalidArgs("Aucun argument envoyé") role = find_role_named(guild, ' '.join(args).lower()) if str(guild.id) not in openrole: openrole[str(guild.id)] = [] if role.id in openrole[str(guild.id)]: raise Error("Role déjà dans la liste, mon papa dit que vous êtes un \"user\"") openrole[str(guild.id)].append(role.id) save_openrole(openrole) await channel.send("Role ajouté")
async def add_match(*args, client, member, force, channel, **_): if len(args) < 1: raise InvalidArgs("Match ID is needed") if not args[0].isdigit(): raise InvalidArgs("Match ID must be a int") if not is_arbitre(member) and not force: raise Forbidden("Only a Arbitre can use this command") report_channel = client.get_channel( 714564031737757876) # type: nextcord.TextChannel msg = await report_channel.fetch_message(int(args[0])) date = msg.created_at - timedelta(hours=6) result = Match.parse_report(msg.content) result_len = len(result) if result_len <= 1: return if result_len < 6: raise ParsingError( f"Le rapport de match doit contenir au moins 6 mentions. {result_len} mentions ont été parsé." ) db.add_match(Match(result, msg.id, None, True, date)) await channel.send(f"Le match {msg.id} a bien été ajouté et vérifié") await update_leaderboard(client)
async def cmd_mmove(self, *args, message, member, channel, client, **_): """/mmove {message_id} {channel} [!][*raison]""" await message.delete() if not args: raise InvalidArgs("Pas d'argument reçu") msg = await channel.fetch_message(int(args[0])) target = client.get_channel(int(args[1])) reason = None if len(args) >= 3: reason = ' '.join(args[2:]) if reason.startswith('!'): reason = MOD_MOVE.format(channel.mention, target.mention, member.mention, reason[1:]) await move_message(msg, target, reason)
async def show_history(*args: str, member, channel, message, **_): if args: l = message.mentions if len(l) != 1: raise InvalidArgs( "Mentionnez une et une seule personne dont vous souhaitez voir l'historique (Il y a trop de monde sur ce serveur, j'ai eu la flemme de faire un gros truc)" ) target = l[0] else: target = member history = db.get_history_for(target.id) history = keep_best_matches(history, target.id) await channel.send("```diff\n{}```".format('\n'.join( str(match) for match in history)))
async def cmd_music(self, *args, message, channel, force, client, **_): global clients if not args: raise InvalidArgs("Aucun argument reçu.") music_client = await get_client(message, client) if args[0] == "disconnect": await music_client.disconnect() await channel.send("Client déconnecté") elif args[0] == "pause": if not music_client.voice_client: await channel.send("le client n'est pas connecté") elif music_client.voice_client.is_paused(): await channel.send("déjà en pause") elif not music_client.voice_client.is_playing(): await channel.send("aucune musique en cours") else: music_client.voice_client.pause() await channel.send( "mise en pause ... (``/music resume`` pour reprendre)") elif args[0] == "resume": if not music_client.voice_client: await channel.send("le client n'est pas connecté") elif not music_client.voice_client.is_paused(): await channel.send("la pause n'est pas activé") else: music_client.voice_client.resume() elif args[0] == "skip": await music_client.play_next_music() elif args[0] == "queue": await music_client.display_queue(channel) elif args[0] == "search": music = await search_music('+'.join(args[1:])) if not music: raise NotFound("J'ai trouvé aucune musique portant ce nom :(") await music_client.add_to_queue([music]) else: if not re.match(r".*www\.youtube\.com/watch\?v=.*", args[0]): music = await search_music('+'.join(args)) if not music: raise NotFound( "J'ai trouvé aucune musique portant ce nom :(") return await music_client.add_to_queue([music]) await music_client.add_to_queue(args)
async def cmd_mmoveafter(self, *args, channel, member, message, client, **_): """/mmoveafter {message_id} {channel} [!][*raison]""" await message.delete() if not args: raise InvalidArgs("Pas d'argument reçu") msg = await channel.fetch_message(int(args[0])) target = client.get_channel(int(args[1])) reason = None if len(args) >= 3: reason = ' '.join(args[2:]) if reason.startswith('!'): reason = MOD_MOVE.format(channel.mention, target.mention, member.mention, reason[1:]) history = await channel.history(after=msg.created_at - datetime.timedelta(milliseconds=1), limit=None).flatten() notified = set() for msg in history: await move_message(msg, target, reason if msg.author not in notified else None) notified.add(msg.author)
async def cmd_premade(self, *args, message, member, **_): if not args: summonerName = member.name else: summonerName = " ".join(args) accountId, summonerId, iconId = await getSummoner(summonerName) if not accountId: raise InvalidArgs("Invocateur non trouvé") result = {} msg = await message.channel.send("Récupération de l'historique") matchs = await getLastYearHistory(accountId) await msg.edit(content="Analyse des matchs") for match in matchs: for player in [ i["player"]["summonerId"] for i in match["participantIdentities"] if "summonerId" in i["player"].keys() and i["player"]["summonerId"] != summonerId ]: if player in result.keys(): result[player] += 1 else: result[player] = 1 await msg.edit(content="Tri des données") result = {player: nb for player, nb in result.items() if nb >= 5} r = sorted(result.items(), key=lambda x: x[1])[::-1] await msg.edit(content="Récupération des noms d'invocateur") tasks = [panth.getSummoner(summonerId) for summonerId, nb in r] response = await asyncio.gather(*tasks) txt = "```{}```".format("\n".join([ "{:>3}: {}".format(r[i][1], response[i]['name']) for i in range(len(r)) ])) if len(txt) >= 2000: txt = txt[:1996] + "```" em = nextcord.Embed( title="Invocateurs rencontrés les 365 derniers jours", description=txt) em.set_author( name=summonerName, icon_url="http://ddragon.canisback.com/latest/img/profileicon/" + str(iconId) + ".png") await msg.edit(content="done", embed=em)
def manual_query_set(self, *args): if len(args) != 3: raise InvalidArgs("Args must be the discord_id, key and the value") self.set(args[0], args[1], args[2])
async def cmd_takedamage(self, *args : List[str], message, member, channel, guild, client, heal=False, **_): """ Args: *args (str): member (discord.Member): channel (discord.Channel): guild (discord.Guild): client (discord.Client): **_: Returns: """ if len(args) < 1: raise InvalidArgs("Usage: /takedamage [joueur] {domage}") if len(args) == 1: target = member else: membername = ' '.join(args[:-(len(args) - 1)]) target = get_member(guild, membername) # type: discord.Member if not target: raise NotFound(f"Member named {membername} not found") expr = args[-1] roll_result = roll(expr) damage = roll_result.total if damage < 0: damage = 0 elif heal: damage = -damage wsh = gc.open_by_key(CHAR_SHEET[str(target.id)]).sheet1 cell_list = wsh.range('P3:P6') old_hp = int(cell_list[0].value) new_hp = old_hp - damage if new_hp > int(cell_list[1].value): new_hp = int(cell_list[1].value) if old_hp > 0 and new_hp < 0: new_hp = 0 knock = cell_list[2].value == 'TRUE' injury = cell_list[3].value == 'TRUE' em = discord.Embed(colour=target.colour) if roll_result.dices: em.add_field(name="Lancé de dé", value=f"{member.mention} {roll_result.intro_sentence}\n{roll_result.format_results}") if damage > 0: em.add_field(name="Resultat", value=f"{target.mention} a pris **{damage}** point{'s' if damage > 1 else ''} de dégats.\n" f"Il lui reste **{new_hp}** / {cell_list[1].value}", inline=False) else: em.add_field(name="Resultat", value=f"{target.mention} a gagné **{-damage}** point{'s' if damage > 1 else ''} de vie.\n" f"Il lui reste **{new_hp}** / {cell_list[1].value}", inline=False) em.set_author(name=target.name, icon_url=target.avatar_url) em.set_footer(text=message.content) msg = await channel.send(embed=em) img = await create_image(target.avatar_url_as(format="png", size=1024), new_hp, int(cell_list[1].value), injury, knock) trash_msg = await client.get_channel(POUBELLE_ID).send(file=discord.File(fp=img, filename="a.png")) #type: discord.Message em.set_image(url=trash_msg.attachments[0].url) await msg.edit(embed=em) cell_list[0].value = new_hp wsh.update_cell(3, 12, new_hp)