easterobot 1.3.2__py3-none-any.whl → 1.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- easterobot/bot.py +14 -1
- easterobot/casino/__init__.py +1 -0
- easterobot/casino/roulette.py +269 -0
- easterobot/commands/__init__.py +2 -0
- easterobot/commands/game.py +127 -118
- easterobot/commands/reset.py +11 -14
- easterobot/commands/roulette.py +34 -0
- easterobot/commands/top.py +73 -65
- easterobot/config.py +35 -8
- easterobot/games/{connect.py → connect4.py} +25 -28
- easterobot/games/game.py +126 -54
- easterobot/games/rock_paper_scissor.py +33 -30
- easterobot/games/skyjo.py +805 -0
- easterobot/games/tic_tac_toe.py +19 -18
- easterobot/hunts/hunt.py +49 -18
- easterobot/hunts/rank.py +24 -2
- easterobot/locker.py +180 -0
- easterobot/models.py +9 -0
- easterobot/resources/config.example.yml +8 -2
- easterobot/resources/credits.txt +2 -0
- easterobot/resources/emotes/placements/s1.png +0 -0
- easterobot/resources/emotes/placements/s10.png +0 -0
- easterobot/resources/emotes/placements/s11.png +0 -0
- easterobot/resources/emotes/placements/s12.png +0 -0
- easterobot/resources/emotes/placements/s2.png +0 -0
- easterobot/resources/emotes/placements/s3.png +0 -0
- easterobot/resources/emotes/placements/s4.png +0 -0
- easterobot/resources/emotes/placements/s5.png +0 -0
- easterobot/resources/emotes/placements/s6.png +0 -0
- easterobot/resources/emotes/placements/s7.png +0 -0
- easterobot/resources/emotes/placements/s8.png +0 -0
- easterobot/resources/emotes/placements/s9.png +0 -0
- easterobot/resources/emotes/placements/sA.png +0 -0
- easterobot/resources/emotes/placements/sB.png +0 -0
- easterobot/resources/emotes/placements/sC.png +0 -0
- easterobot/resources/emotes/placements/sD.png +0 -0
- easterobot/resources/emotes/placements/sE.png +0 -0
- easterobot/resources/emotes/placements/sF.png +0 -0
- easterobot/resources/emotes/placements/sG.png +0 -0
- easterobot/resources/emotes/placements/sH.png +0 -0
- easterobot/resources/emotes/placements/sI.png +0 -0
- easterobot/resources/emotes/placements/sJ.png +0 -0
- easterobot/resources/emotes/placements/sK.png +0 -0
- easterobot/resources/emotes/placements/sL.png +0 -0
- easterobot/resources/emotes/placements/sM.png +0 -0
- easterobot/resources/emotes/placements/sN.png +0 -0
- easterobot/resources/emotes/placements/sO.png +0 -0
- easterobot/resources/emotes/placements/sP.png +0 -0
- easterobot/resources/emotes/placements/sQ.png +0 -0
- easterobot/resources/emotes/placements/sR.png +0 -0
- easterobot/resources/emotes/placements/sS.png +0 -0
- easterobot/resources/emotes/placements/sT.png +0 -0
- easterobot/resources/emotes/placements/sU.png +0 -0
- easterobot/resources/emotes/placements/sV.png +0 -0
- easterobot/resources/emotes/placements/sW.png +0 -0
- easterobot/resources/emotes/placements/sX.png +0 -0
- easterobot/resources/emotes/placements/sY.png +0 -0
- easterobot/resources/emotes/placements/sZ.png +0 -0
- easterobot/resources/emotes/placements/s_.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_back.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_m1.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_m2.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p0.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p1.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p10.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p11.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p12.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p2.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p3.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p4.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p5.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p6.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p7.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p8.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p9.png +0 -0
- {easterobot-1.3.2.dist-info → easterobot-1.5.1.dist-info}/METADATA +1 -1
- easterobot-1.5.1.dist-info/RECORD +130 -0
- easterobot-1.3.2.dist-info/RECORD +0 -70
- {easterobot-1.3.2.dist-info → easterobot-1.5.1.dist-info}/WHEEL +0 -0
- {easterobot-1.3.2.dist-info → easterobot-1.5.1.dist-info}/entry_points.txt +0 -0
- {easterobot-1.3.2.dist-info → easterobot-1.5.1.dist-info}/licenses/LICENSE +0 -0
easterobot/games/game.py
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
import asyncio
|
4
4
|
import logging
|
5
|
-
from collections.abc import Coroutine
|
5
|
+
from collections.abc import Coroutine, Iterable
|
6
6
|
from dataclasses import dataclass
|
7
|
-
from typing import Any, Callable, Optional
|
7
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional
|
8
8
|
from uuid import uuid4
|
9
9
|
|
10
10
|
import discord
|
@@ -13,7 +13,7 @@ from discord.message import convert_emoji_reaction
|
|
13
13
|
|
14
14
|
from easterobot.bot import Easterobot
|
15
15
|
from easterobot.commands.base import Context, Interaction, InteractionChannel
|
16
|
-
from easterobot.config import RAND
|
16
|
+
from easterobot.config import RAND, agree
|
17
17
|
from easterobot.utils import in_seconds
|
18
18
|
|
19
19
|
logger = logging.getLogger(__name__)
|
@@ -38,22 +38,35 @@ class InvalidPlayerError(GameError):
|
|
38
38
|
)
|
39
39
|
|
40
40
|
|
41
|
-
@dataclass
|
41
|
+
@dataclass(frozen=True)
|
42
42
|
class Player:
|
43
43
|
member: discord.Member
|
44
44
|
number: int
|
45
45
|
|
46
46
|
|
47
47
|
class Game:
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
def __init__(
|
49
|
+
self,
|
50
|
+
bot: Easterobot,
|
51
|
+
message: discord.Message,
|
52
|
+
*members: discord.Member,
|
53
|
+
) -> None:
|
51
54
|
"""Instantiate Game."""
|
52
55
|
self.id = uuid4()
|
56
|
+
if self.minimum_player() > len(members):
|
57
|
+
error_message = "Not enough players."
|
58
|
+
raise InvalidActionError(error_message)
|
59
|
+
if self.maximum_player() < len(members):
|
60
|
+
error_message = "Too many players."
|
61
|
+
raise InvalidActionError(error_message)
|
62
|
+
self.bot = bot
|
63
|
+
self.players = [Player(member, i) for i, member in enumerate(members)]
|
53
64
|
self.message = message
|
54
65
|
self.terminate = False
|
55
|
-
self.winner: Optional[
|
66
|
+
self.winner: Optional[Player] = None
|
56
67
|
self.lock = asyncio.Lock()
|
68
|
+
|
69
|
+
# Manager
|
57
70
|
self._cleanup: Optional[AsyncCallback] = None
|
58
71
|
self._completion: Optional[AsyncCallback] = None
|
59
72
|
self._end_event = asyncio.Event()
|
@@ -62,12 +75,23 @@ class Game:
|
|
62
75
|
self._reset_countdown_event = asyncio.Event()
|
63
76
|
self._timeout_task: Optional[asyncio.Task[None]] = None
|
64
77
|
self._timeout_lock: asyncio.Lock = asyncio.Lock()
|
78
|
+
self.in_seconds: Optional[str] = None
|
65
79
|
|
66
80
|
async def set_completion(self, callback: AsyncCallback) -> None:
|
67
81
|
"""Get the current state for a player."""
|
68
82
|
self._completion = callback
|
69
83
|
|
70
|
-
|
84
|
+
@classmethod
|
85
|
+
def minimum_player(cls) -> int:
|
86
|
+
"""Get the minimum player number."""
|
87
|
+
return 2
|
88
|
+
|
89
|
+
@classmethod
|
90
|
+
def maximum_player(cls) -> int:
|
91
|
+
"""Get the maximum player number."""
|
92
|
+
return 2
|
93
|
+
|
94
|
+
async def wait_winner(self) -> Optional[Player]:
|
71
95
|
"""Wait the end of the game."""
|
72
96
|
await self._end_event.wait()
|
73
97
|
return self.winner
|
@@ -85,7 +109,7 @@ class Game:
|
|
85
109
|
async def on_timeout(self) -> None:
|
86
110
|
"""Can when game timeout."""
|
87
111
|
|
88
|
-
async def set_winner(self, winner: Optional[
|
112
|
+
async def set_winner(self, winner: Optional[Player]) -> None:
|
89
113
|
"""Remove the game from the manager."""
|
90
114
|
self.terminate = True
|
91
115
|
self.winner = winner
|
@@ -98,6 +122,11 @@ class Game:
|
|
98
122
|
async def start_timer(self, seconds: float) -> str:
|
99
123
|
"""Start the timer for turn."""
|
100
124
|
async with self._timeout_lock:
|
125
|
+
if self._timeout_task and (
|
126
|
+
self._timeout_task.done() or self._timeout_task.cancelled()
|
127
|
+
):
|
128
|
+
error_message = "Timer was already started"
|
129
|
+
raise RuntimeError(error_message)
|
101
130
|
logger.info(
|
102
131
|
"Start timer of %s seconds for %s",
|
103
132
|
seconds,
|
@@ -106,7 +135,8 @@ class Game:
|
|
106
135
|
self._timeout_task = asyncio.create_task(
|
107
136
|
self._timeout_worker(seconds)
|
108
137
|
)
|
109
|
-
|
138
|
+
self.in_seconds = in_seconds(seconds)
|
139
|
+
return self.in_seconds
|
110
140
|
|
111
141
|
async def stop_timer(self) -> None:
|
112
142
|
"""Stop the timer and wait it end."""
|
@@ -119,8 +149,8 @@ class Game:
|
|
119
149
|
):
|
120
150
|
self._reset_countdown_event.set()
|
121
151
|
await self._timeout_task
|
122
|
-
|
123
|
-
|
152
|
+
self._timeout_task = None
|
153
|
+
self._reset_countdown_event = asyncio.Event()
|
124
154
|
logger.info("Timer stopped for %s", self)
|
125
155
|
|
126
156
|
async def _timeout_worker(self, seconds: float) -> None:
|
@@ -130,9 +160,12 @@ class Game:
|
|
130
160
|
await asyncio.wait_for(event.wait(), timeout=seconds)
|
131
161
|
except asyncio.TimeoutError:
|
132
162
|
if not event.is_set():
|
163
|
+
logger.info("Acquire lock for %s", self)
|
133
164
|
async with self.lock:
|
134
165
|
logger.info("Timeout for %s", self)
|
135
|
-
|
166
|
+
# TODO(dashstrom): Handle the task at end !
|
167
|
+
asyncio.create_task(self.on_timeout()) # noqa: RUF006
|
168
|
+
logger.info("Terminate worker for %s ", self)
|
136
169
|
|
137
170
|
def __repr__(self) -> str:
|
138
171
|
"""Get game representation."""
|
@@ -160,20 +193,29 @@ class GameCog(commands.Cog):
|
|
160
193
|
reference: discord.Message,
|
161
194
|
user1: discord.Member,
|
162
195
|
user2: discord.Member,
|
163
|
-
) -> Optional[
|
196
|
+
) -> Optional[Player]:
|
164
197
|
"""Start a dual between two players."""
|
165
|
-
from easterobot.games.
|
198
|
+
from easterobot.games.connect4 import Connect4
|
166
199
|
from easterobot.games.rock_paper_scissor import RockPaperScissor
|
200
|
+
from easterobot.games.skyjo import Skyjo
|
167
201
|
from easterobot.games.tic_tac_toe import TicTacToe
|
168
202
|
|
169
|
-
cls = RAND.choice([Connect4, TicTacToe, RockPaperScissor])
|
203
|
+
cls = RAND.choice([Connect4, TicTacToe, RockPaperScissor, Skyjo])
|
170
204
|
msg = await channel.send(
|
171
205
|
f"{user1.mention} et {user2.mention} "
|
172
|
-
f"vont s'affronter {in_seconds(
|
206
|
+
f"vont s'affronter {in_seconds(300)} ...",
|
173
207
|
reference=reference,
|
174
208
|
)
|
175
|
-
await asyncio.sleep(
|
176
|
-
|
209
|
+
await asyncio.sleep(270)
|
210
|
+
await msg.reply(
|
211
|
+
content=(
|
212
|
+
f"{user1.mention} et {user2.mention} vont commencer le duel "
|
213
|
+
f"{in_seconds(30)}"
|
214
|
+
),
|
215
|
+
delete_after=30,
|
216
|
+
)
|
217
|
+
await asyncio.sleep(30)
|
218
|
+
game: Game = cls(self.bot, msg, user1, user2)
|
177
219
|
await self.run(game)
|
178
220
|
return await game.wait_winner()
|
179
221
|
|
@@ -196,18 +238,19 @@ class GameCog(commands.Cog):
|
|
196
238
|
|
197
239
|
self._games[message_id] = game
|
198
240
|
game._cleanup = _cleanup # noqa: SLF001
|
199
|
-
game.bot = self.bot
|
200
241
|
await game.on_start()
|
201
242
|
|
202
|
-
async def ask_dual(
|
243
|
+
async def ask_dual( # noqa: C901, PLR0915
|
203
244
|
self,
|
204
245
|
ctx: Context,
|
205
|
-
|
246
|
+
members: Iterable[discord.Member],
|
206
247
|
bet: int,
|
207
248
|
) -> Optional[discord.Message]:
|
208
249
|
"""Send basic message for initialization."""
|
209
|
-
|
210
|
-
|
250
|
+
event = asyncio.Event()
|
251
|
+
pending_members = list(members)
|
252
|
+
accepted_members: list[discord.Member] = [ctx.user]
|
253
|
+
cancel_by: Optional[discord.Member] = None
|
211
254
|
|
212
255
|
view = discord.ui.View()
|
213
256
|
yes_btn: Button = discord.ui.Button(
|
@@ -218,26 +261,47 @@ class GameCog(commands.Cog):
|
|
218
261
|
)
|
219
262
|
|
220
263
|
async def yes(interaction: Interaction) -> Any:
|
221
|
-
|
222
|
-
if
|
223
|
-
|
264
|
+
nonlocal cancel_by
|
265
|
+
if TYPE_CHECKING:
|
266
|
+
assert isinstance(interaction.user, discord.Member)
|
267
|
+
if not event.is_set() and any(
|
268
|
+
interaction.user.id == m.id for m in pending_members
|
269
|
+
):
|
270
|
+
await interaction.response.send_message(
|
271
|
+
"Vous avez accepté le duel !",
|
272
|
+
ephemeral=True,
|
273
|
+
)
|
274
|
+
accepted_members.append(interaction.user)
|
275
|
+
pending_members.remove(interaction.user)
|
276
|
+
if not pending_members:
|
277
|
+
event.set()
|
278
|
+
else:
|
279
|
+
await interaction.response.defer()
|
224
280
|
|
225
281
|
async def no(interaction: Interaction) -> Any:
|
282
|
+
nonlocal cancel_by
|
283
|
+
if TYPE_CHECKING:
|
284
|
+
assert isinstance(interaction.user, discord.Member)
|
226
285
|
await interaction.response.defer()
|
227
|
-
if not
|
228
|
-
if interaction.user
|
229
|
-
|
230
|
-
|
231
|
-
|
286
|
+
if not event.is_set():
|
287
|
+
if interaction.user in pending_members:
|
288
|
+
pending_members.remove(interaction.user)
|
289
|
+
cancel_by = interaction.user
|
290
|
+
event.set()
|
291
|
+
elif interaction.user in accepted_members:
|
292
|
+
accepted_members.remove(interaction.user)
|
293
|
+
cancel_by = interaction.user
|
294
|
+
event.set()
|
232
295
|
|
233
296
|
yes_btn.callback = yes # type: ignore[method-assign,assignment]
|
234
297
|
no_btn.callback = no # type: ignore[method-assign,assignment]
|
235
298
|
view.add_item(yes_btn)
|
236
299
|
view.add_item(no_btn)
|
237
|
-
seconds =
|
300
|
+
seconds = 300
|
301
|
+
mention = " ".join(m.mention for m in pending_members)
|
238
302
|
result = await ctx.response.send_message(
|
239
|
-
f"{
|
240
|
-
f"vous demande en duel pour `{bet}` œufs ⚔️"
|
303
|
+
f"{mention}, "
|
304
|
+
f"{ctx.user.mention} vous demande en duel pour `{bet}` œufs ⚔️"
|
241
305
|
f"\nVous devez repondre {in_seconds(seconds)} !",
|
242
306
|
view=view,
|
243
307
|
)
|
@@ -246,32 +310,34 @@ class GameCog(commands.Cog):
|
|
246
310
|
error_message = f"Invalid kind of message: {message!r}"
|
247
311
|
raise TypeError(error_message)
|
248
312
|
try:
|
249
|
-
|
313
|
+
await asyncio.wait_for(event.wait(), timeout=seconds)
|
250
314
|
except asyncio.TimeoutError:
|
315
|
+
mention = " ".join(m.mention for m in accepted_members)
|
251
316
|
await message.edit(
|
252
317
|
content=(
|
253
|
-
f"{
|
254
|
-
f"{
|
255
|
-
|
318
|
+
f"{mention}, "
|
319
|
+
f"{' '.join(m.mention for m in pending_members)} "
|
320
|
+
+ agree("n'a pas", "n'ont pas", len(pending_members) - 1)
|
321
|
+
+ " accepté le duel 🛡️"
|
322
|
+
+ "\n-# Ce message disparaîtra {in_seconds(30)}"
|
256
323
|
),
|
257
324
|
delete_after=30,
|
258
325
|
view=None,
|
259
326
|
)
|
260
327
|
return None
|
261
|
-
if
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
328
|
+
if cancel_by:
|
329
|
+
mention = " ".join(
|
330
|
+
m.mention
|
331
|
+
for group in (
|
332
|
+
accepted_members,
|
333
|
+
pending_members,
|
334
|
+
)
|
335
|
+
for m in group
|
269
336
|
)
|
270
|
-
|
271
|
-
if not accept:
|
337
|
+
word = "refusé" if cancel_by == ctx.user else "annulé"
|
272
338
|
await message.edit(
|
273
339
|
content=(
|
274
|
-
f"{
|
340
|
+
f"{mention}, {cancel_by.mention} a {word} le duel 🛡️"
|
275
341
|
f"\n-# Ce message disparaîtra {in_seconds(30)}"
|
276
342
|
),
|
277
343
|
delete_after=30,
|
@@ -281,12 +347,18 @@ class GameCog(commands.Cog):
|
|
281
347
|
if not isinstance(result.resource, discord.Message):
|
282
348
|
error_message = f"Invalid kind of message: {result.resource!r}"
|
283
349
|
raise TypeError(error_message)
|
350
|
+
mention = " ".join(
|
351
|
+
m.mention for m in accepted_members if m != ctx.user
|
352
|
+
)
|
284
353
|
await result.resource.reply(
|
285
|
-
f"{ctx.user.mention}, {
|
286
|
-
|
354
|
+
f"{ctx.user.mention}, {mention} "
|
355
|
+
+ agree("a", "ont", len(accepted_members) - 1)
|
356
|
+
+ " accepté le duel ⚔️"
|
357
|
+
+ f"\n-# Début du duel {in_seconds(30)}",
|
287
358
|
delete_after=30,
|
288
359
|
)
|
289
|
-
|
360
|
+
await asyncio.sleep(30)
|
361
|
+
return await ctx.channel.fetch_message(result.resource.id)
|
290
362
|
|
291
363
|
@commands.Cog.listener()
|
292
364
|
async def on_raw_reaction_add(
|
@@ -7,6 +7,7 @@ from typing import Optional
|
|
7
7
|
import discord
|
8
8
|
from typing_extensions import override
|
9
9
|
|
10
|
+
from easterobot.bot import Easterobot
|
10
11
|
from easterobot.commands.base import Interaction
|
11
12
|
from easterobot.games.game import Button, Game
|
12
13
|
|
@@ -21,9 +22,9 @@ class RockPaperScissor(Game):
|
|
21
22
|
|
22
23
|
def __init__(
|
23
24
|
self,
|
24
|
-
|
25
|
-
player2: discord.Member,
|
25
|
+
bot: Easterobot,
|
26
26
|
message: discord.Message,
|
27
|
+
*members: discord.Member,
|
27
28
|
win_count: int = 3,
|
28
29
|
max_turn: int = 10,
|
29
30
|
) -> None:
|
@@ -31,12 +32,10 @@ class RockPaperScissor(Game):
|
|
31
32
|
self.timeout = False
|
32
33
|
self.max_turn = max_turn
|
33
34
|
self.win_count = win_count
|
34
|
-
self.player1 = player1
|
35
|
-
self.player2 = player2
|
36
35
|
self.play1: Optional[str] = None
|
37
36
|
self.play2: Optional[str] = None
|
38
37
|
self.history: list[tuple[str, str]] = []
|
39
|
-
super().__init__(message)
|
38
|
+
super().__init__(bot, message, *members)
|
40
39
|
|
41
40
|
@override
|
42
41
|
async def on_start(self) -> None:
|
@@ -64,14 +63,15 @@ class RockPaperScissor(Game):
|
|
64
63
|
label: str,
|
65
64
|
) -> None:
|
66
65
|
update = False
|
66
|
+
user = interaction.user
|
67
67
|
|
68
68
|
# Player 1 click on button
|
69
|
-
if
|
69
|
+
if user == self.players[0].member and self.play1 is None:
|
70
70
|
self.play1 = label
|
71
71
|
update = True
|
72
72
|
|
73
73
|
# Player 2 click on button
|
74
|
-
elif
|
74
|
+
elif user == self.players[1].member and self.play2 is None:
|
75
75
|
self.play2 = label
|
76
76
|
update = True
|
77
77
|
|
@@ -105,15 +105,15 @@ class RockPaperScissor(Game):
|
|
105
105
|
if self.play1 is None and self.play2 is None:
|
106
106
|
icon_url = self.bot.app_emojis["wait"].url
|
107
107
|
info = (
|
108
|
-
f"En attente de {self.
|
109
|
-
f"et {self.
|
108
|
+
f"En attente de {self.players[0].member.mention} "
|
109
|
+
f"et {self.players[1].member.mention} ..."
|
110
110
|
)
|
111
111
|
elif self.play1 is None:
|
112
|
-
icon_url = self.
|
113
|
-
info = f"En attente de {self.
|
112
|
+
icon_url = self.players[0].member.display_avatar.url
|
113
|
+
info = f"En attente de {self.players[0].member.mention} ..."
|
114
114
|
elif self.play2 is None:
|
115
|
-
icon_url = self.
|
116
|
-
info = f"En attente de {self.
|
115
|
+
icon_url = self.players[1].member.display_avatar.url
|
116
|
+
info = f"En attente de {self.players[1].member.mention} ..."
|
117
117
|
else:
|
118
118
|
# Play and fight
|
119
119
|
self.history.append((self.play1, self.play2))
|
@@ -121,8 +121,8 @@ class RockPaperScissor(Game):
|
|
121
121
|
self.play2 = None
|
122
122
|
icon_url = self.bot.app_emojis["wait"].url
|
123
123
|
info = (
|
124
|
-
f"En attente de {self.
|
125
|
-
f"et {self.
|
124
|
+
f"En attente de {self.players[0].member.mention} "
|
125
|
+
f"et {self.players[1].member.mention} ..."
|
126
126
|
)
|
127
127
|
pt1 = 0
|
128
128
|
pt2 = 0
|
@@ -132,10 +132,10 @@ class RockPaperScissor(Game):
|
|
132
132
|
i2 = EMOJIS.index(play2)
|
133
133
|
if i1 == (i2 - 1) % 3:
|
134
134
|
pt1 += 1
|
135
|
-
text = self.
|
135
|
+
text = self.players[0].member.mention
|
136
136
|
elif i1 == (i2 + 1) % 3:
|
137
137
|
pt2 += 1
|
138
|
-
text = self.
|
138
|
+
text = self.players[1].member.mention
|
139
139
|
else:
|
140
140
|
text = "**égalité**"
|
141
141
|
morsels.append(
|
@@ -154,21 +154,21 @@ class RockPaperScissor(Game):
|
|
154
154
|
if self.timeout:
|
155
155
|
final_winner = self.winner
|
156
156
|
elif pt1 < pt2:
|
157
|
-
final_winner = self.
|
157
|
+
final_winner = self.players[1]
|
158
158
|
elif pt2 < pt1:
|
159
|
-
final_winner = self.
|
159
|
+
final_winner = self.players[0]
|
160
160
|
else:
|
161
161
|
final_winner = None
|
162
162
|
if final_winner:
|
163
163
|
forfait = "par forfait " if self.timeout else ""
|
164
164
|
embed.description += (
|
165
|
-
f"## Gagnant {forfait}{final_winner.mention} 🎉"
|
165
|
+
f"## Gagnant {forfait}{final_winner.member.mention} 🎉"
|
166
166
|
)
|
167
|
-
icon_url = final_winner.display_avatar.url
|
167
|
+
icon_url = final_winner.member.display_avatar.url
|
168
168
|
else:
|
169
169
|
embed.description += (
|
170
|
-
f"## Égalité entre {self.
|
171
|
-
f"et {self.
|
170
|
+
f"## Égalité entre {self.players[0].member.mention} "
|
171
|
+
f"et {self.players[1].member.mention} 🤝"
|
172
172
|
)
|
173
173
|
icon_url = self.bot.app_emojis["end"].url
|
174
174
|
self.view.stop()
|
@@ -182,7 +182,10 @@ class RockPaperScissor(Game):
|
|
182
182
|
await self.message.edit(
|
183
183
|
embed=embed,
|
184
184
|
view=self.view,
|
185
|
-
content=(
|
185
|
+
content=(
|
186
|
+
f"-# {self.players[0].member.mention} "
|
187
|
+
f"{self.players[1].member.mention}"
|
188
|
+
),
|
186
189
|
)
|
187
190
|
|
188
191
|
def compute_winner(
|
@@ -192,9 +195,9 @@ class RockPaperScissor(Game):
|
|
192
195
|
i1 = EMOJIS.index(play1)
|
193
196
|
i2 = EMOJIS.index(play2)
|
194
197
|
if i1 == (i2 + 1) % 3:
|
195
|
-
return self.
|
198
|
+
return self.players[0].member
|
196
199
|
if i1 == (i2 - 1) % 3:
|
197
|
-
return self.
|
200
|
+
return self.players[1].member
|
198
201
|
return None # Draw
|
199
202
|
|
200
203
|
def color(
|
@@ -203,9 +206,9 @@ class RockPaperScissor(Game):
|
|
203
206
|
"""Color of the embed."""
|
204
207
|
if member is None:
|
205
208
|
return discord.Colour.from_str("#d4d5d6")
|
206
|
-
if member == self.
|
209
|
+
if member == self.players[0]:
|
207
210
|
return discord.Colour.from_str("#ca2a3e")
|
208
|
-
if member == self.
|
211
|
+
if member == self.players[1]:
|
209
212
|
return discord.Colour.from_str("#5865F2")
|
210
213
|
error_message = f"Invalid member: {member!r}"
|
211
214
|
raise ValueError(error_message)
|
@@ -214,7 +217,7 @@ class RockPaperScissor(Game):
|
|
214
217
|
async def on_timeout(self) -> None:
|
215
218
|
self.timeout = True
|
216
219
|
if self.play1 is None:
|
217
|
-
await self.set_winner(self.
|
220
|
+
await self.set_winner(self.players[1])
|
218
221
|
if self.play2 is None:
|
219
|
-
await self.set_winner(self.
|
222
|
+
await self.set_winner(self.players[0])
|
220
223
|
await self.update()
|