diff --git a/packages/backend/src/core/GlobalEventService.ts b/packages/backend/src/core/GlobalEventService.ts index 57c1b3da40..d7318a43ad 100644 --- a/packages/backend/src/core/GlobalEventService.ts +++ b/packages/backend/src/core/GlobalEventService.ts @@ -205,18 +205,23 @@ export interface MahjongRoomEventTypes { room: Packed<'MahjongRoomDetailed'>; }; tsumo: { - house: Mahjong.Engine.House; + house: Mahjong.Common.House; tile: Mahjong.Common.Tile; }; dahai: { - house: Mahjong.Engine.House; + house: Mahjong.Common.House; tile: Mahjong.Common.Tile; }; dahaiAndTsumo: { - house: Mahjong.Engine.House; + dahaiHouse: Mahjong.Common.House; dahaiTile: Mahjong.Common.Tile; tsumoTile: Mahjong.Common.Tile; }; + ponned: { + source: Mahjong.Common.House; + target: Mahjong.Common.House; + tile: Mahjong.Common.Tile; + }; } //#endregion diff --git a/packages/backend/src/core/MahjongService.ts b/packages/backend/src/core/MahjongService.ts index 82bd7e8818..3e8b20a5a1 100644 --- a/packages/backend/src/core/MahjongService.ts +++ b/packages/backend/src/core/MahjongService.ts @@ -412,6 +412,25 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit { await this.dahai(room, engine, myHouse, tile); } + @bindThis + public async op_ron(roomId: MiMahjongGame['id'], user: MiUser) { + const room = await this.getRoom(roomId); + if (room == null) return; + if (room.gameState == null) return; + + const engine = new Mahjong.Engine.MasterGameEngine(room.gameState); + const myHouse = user.id === room.user1Id ? engine.state.user1House : user.id === room.user2Id ? engine.state.user2House : user.id === room.user3Id ? engine.state.user3House : engine.state.user4House; + + // TODO: 自分にロン回答する権利がある状態かバリデーション + + // TODO: この辺の処理はアトミックに行いたいけどJSONサポートはRedis Stackが必要 + const current = await this.redisClient.get(`mahjong:gameCallAndRonAsking:${room.id}`); + if (current == null) throw new Error('no asking found'); + const currentAnswers = JSON.parse(current) as CallAndRonAnswers; + currentAnswers.ron[myHouse] = true; + await this.redisClient.set(`mahjong:gameCallAndRonAsking:${room.id}`, JSON.stringify(currentAnswers)); + } + @bindThis public async op_pon(roomId: MiMahjongGame['id'], user: MiUser) { const room = await this.getRoom(roomId); diff --git a/packages/backend/src/server/api/stream/channels/mahjong-room.ts b/packages/backend/src/server/api/stream/channels/mahjong-room.ts index 1472a7013a..e3556fbc8b 100644 --- a/packages/backend/src/server/api/stream/channels/mahjong-room.ts +++ b/packages/backend/src/server/api/stream/channels/mahjong-room.ts @@ -39,6 +39,7 @@ class MahjongRoomChannel extends Channel { case 'updateSettings': this.updateSettings(body.key, body.value); break; case 'addAi': this.addAi(); break; case 'dahai': this.dahai(body.tile); break; + case 'ron': this.ron(); break; case 'pon': this.pon(); break; case 'nop': this.nop(); break; case 'claimTimeIsUp': this.claimTimeIsUp(); break; @@ -73,6 +74,13 @@ class MahjongRoomChannel extends Channel { this.mahjongService.op_dahai(this.roomId!, this.user, tile); } + @bindThis + private async ron() { + if (this.user == null) return; + + this.mahjongService.op_ron(this.roomId!, this.user); + } + @bindThis private async pon() { if (this.user == null) return; diff --git a/packages/frontend/assets/mahjong/tile-top-h.png b/packages/frontend/assets/mahjong/tile-top-h.png new file mode 100644 index 0000000000..a575deca27 Binary files /dev/null and b/packages/frontend/assets/mahjong/tile-top-h.png differ diff --git a/packages/frontend/assets/mahjong/tile-top-v.png b/packages/frontend/assets/mahjong/tile-top-v.png new file mode 100644 index 0000000000..d087d195b4 Binary files /dev/null and b/packages/frontend/assets/mahjong/tile-top-v.png differ diff --git a/packages/frontend/assets/mahjong/tile-top.png b/packages/frontend/assets/mahjong/tile-top.png deleted file mode 100644 index 861608a43d..0000000000 Binary files a/packages/frontend/assets/mahjong/tile-top.png and /dev/null differ diff --git a/packages/frontend/src/pages/mahjong/room.game.vue b/packages/frontend/src/pages/mahjong/room.game.vue index ab4572e508..a38df8025e 100644 --- a/packages/frontend/src/pages/mahjong/room.game.vue +++ b/packages/frontend/src/pages/mahjong/room.game.vue @@ -28,28 +28,28 @@ SPDX-License-Identifier: AGPL-3.0-only