diff --git a/client/.eslintrc.cjs b/client/.eslintrc.cjs index 92d50668..d0369267 100644 --- a/client/.eslintrc.cjs +++ b/client/.eslintrc.cjs @@ -12,6 +12,7 @@ module.exports = { 'no-duplicate-imports': 'error', /* Maybe remove in future */ + 'no-shadow': ['warn'], '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/ban-ts-comment': 0, '@typescript-eslint/no-extra-semi': 0, diff --git a/client/src/components/GamesTable.vue b/client/src/components/GamesTable.vue index d434437c..fd4285aa 100644 --- a/client/src/components/GamesTable.vue +++ b/client/src/components/GamesTable.vue @@ -94,6 +94,7 @@ :clickable="false" :nameFirst="false" :username="player" + :bot="slotProps.data.bots[slotProps.data.players.indexOf(player)] != null" /> diff --git a/client/src/components/PlatformStats/BotStats.vue b/client/src/components/PlatformStats/BotStats.vue new file mode 100644 index 00000000..e5bcceb6 --- /dev/null +++ b/client/src/components/PlatformStats/BotStats.vue @@ -0,0 +1,58 @@ + + + diff --git a/client/src/components/PlatformStats/PlatformStats.vue b/client/src/components/PlatformStats/PlatformStats.vue index b084ba41..fe315a70 100644 --- a/client/src/components/PlatformStats/PlatformStats.vue +++ b/client/src/components/PlatformStats/PlatformStats.vue @@ -28,6 +28,10 @@
+

{{ $t('Stats.headerBotWinshare') }}

+
+ +
diff --git a/client/src/components/WaitingOverview.vue b/client/src/components/WaitingOverview.vue index f6326511..1f218cad 100644 --- a/client/src/components/WaitingOverview.vue +++ b/client/src/components/WaitingOverview.vue @@ -161,8 +161,11 @@ class="activeGame" :game="waitingStore.ownGame" :active="true" + @add-bot="addBot" @move-player="movePlayer" + @move-bot="moveBot" @remove-player="removePlayer" + @remove-bot="removeBot" @ready-player="setPlayerReady" @color-player="setPlayerColor" /> @@ -271,10 +274,18 @@ function joinGame(game: WaitingGameType) { socket.emitWithAck(5000, 'waiting:joinGame', game.id) } +function addBot(data: { gameID: number; botID: number; playerIndex: number }) { + socket.emitWithAck(5000, 'waiting:addBot', data.gameID, data.botID, data.playerIndex) +} + function movePlayer(data: { gameID: number; username: string; steps: number }) { socket.emitWithAck(5000, 'waiting:movePlayer', data) } +function moveBot(data: { gameID: number; playerIndex: number; steps: number }) { + socket.emitWithAck(5000, 'waiting:moveBot', data) +} + function removePlayer(usernameToRemove: string) { const confirmText = i18n.global.t(usernameToRemove === username.value ? 'Waiting.removePlayerConfirmSelf' : 'Waiting.removePlayerConfirmOther') if (confirm(confirmText)) { @@ -282,17 +293,22 @@ function removePlayer(usernameToRemove: string) { } } +function removeBot(data: { gameID: number; playerIndex: number }) { + socket.emitWithAck(5000, 'waiting:removeBot', data.gameID, data.playerIndex) +} + function setPlayerReady(gameID: number) { socket.emitWithAck(5000, 'waiting:readyPlayer', { gameID: gameID, }) } -function setPlayerColor(usernameToChange: string, gameID: number, color: string) { +function setPlayerColor(usernameToChange: string, gameID: number, color: string, botIndex: number | null) { socket.emitWithAck(5000, 'waiting:switchColor', { - gameID: gameID, + gameID, username: usernameToChange, - color: color, + color, + botIndex, }) } diff --git a/client/src/components/game/PlayerInformation.vue b/client/src/components/game/PlayerInformation.vue index 718960af..5ba16247 100644 --- a/client/src/components/game/PlayerInformation.vue +++ b/client/src/components/game/PlayerInformation.vue @@ -49,6 +49,7 @@ /> +
+ 🤖 +
diff --git a/client/src/components/game/RematchForm.vue b/client/src/components/game/RematchForm.vue index 8dc1de4d..5f23698b 100644 --- a/client/src/components/game/RematchForm.vue +++ b/client/src/components/game/RematchForm.vue @@ -4,8 +4,11 @@ @@ -93,21 +96,38 @@ async function createRematch() { toast.add({ severity: 'error', summary, detail, life: 5000 }) } +function addBot(data: { gameID: number; botID: number; playerIndex: number }) { + socket.emitWithAck(5000, 'waiting:addBot', data.gameID, data.botID, data.playerIndex) +} + function movePlayer(data: { gameID: number; username: string; steps: number }) { socket.emitWithAck(5000, 'waiting:movePlayer', data) } +function moveBot(data: { gameID: number; playerIndex: number; steps: number }) { + socket.emitWithAck(5000, 'waiting:moveBot', data) +} + function removePlayer(username: string) { if (confirm(i18n.global.t('Waiting.leaveRematch'))) { socket.emitWithAck(5000, 'waiting:removePlayer', username) } } +function removeBot(data: { gameID: number; playerIndex: number }) { + socket.emitWithAck(5000, 'waiting:removeBot', data.gameID, data.playerIndex) +} + function setPlayerReady(gameID: number) { socket.emitWithAck(5000, 'waiting:readyPlayer', { gameID: gameID }) } -function setPlayerColor(username: string, gameID: number, color: string) { - socket.emitWithAck(5000, 'waiting:switchColor', { gameID: gameID, username: username, color: color }) +function setPlayerColor(usernameToChange: string, gameID: number, color: string, botIndex: number | null) { + socket.emitWithAck(5000, 'waiting:switchColor', { + gameID, + username: usernameToChange, + color, + botIndex, + }) } diff --git a/client/src/components/gameModal/GameModalSubstitution.vue b/client/src/components/gameModal/GameModalSubstitution.vue index ad8971e7..07aba439 100644 --- a/client/src/components/gameModal/GameModalSubstitution.vue +++ b/client/src/components/gameModal/GameModalSubstitution.vue @@ -4,31 +4,69 @@ {{ $t('Game.GameModal.Substitution.explanation') }} -