diff --git a/locales/index.d.ts b/locales/index.d.ts
index e1e829ac20..48d4e892be 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -9633,6 +9633,22 @@ export interface Locale extends ILocale {
* CPUを追加
*/
"addCpu": string;
+ /**
+ * 東
+ */
+ "east": string;
+ /**
+ * 南
+ */
+ "south": string;
+ /**
+ * 西
+ */
+ "west": string;
+ /**
+ * 北
+ */
+ "north": string;
};
"_offlineScreen": {
/**
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index a330e26995..25cc7e63a5 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -2567,6 +2567,10 @@ _mahjong:
cancelReady: "準備を再開"
leave: "退室"
addCpu: "CPUを追加"
+ east: "東"
+ south: "南"
+ west: "西"
+ north: "北"
_offlineScreen:
title: "オフライン - サーバーに接続できません"
diff --git a/packages/backend/src/core/MahjongService.ts b/packages/backend/src/core/MahjongService.ts
index 27a3c5c495..b862e2404e 100644
--- a/packages/backend/src/core/MahjongService.ts
+++ b/packages/backend/src/core/MahjongService.ts
@@ -362,20 +362,7 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
this.dahai(room, engine, turn, engine.state.handTiles[turn].at(-1));
}, 500);
} else {
- if (engine.state.riichis[turn]) {
- // リーチ時はアガリ牌でない限りツモ切り
- const handTiles = engine.state.handTiles[turn];
- const horaSets = Mahjong.Utils.getHoraSets(handTiles);
- if (horaSets.length === 0) {
- setTimeout(() => {
- this.dahai(room, engine, turn, handTiles.at(-1));
- }, 500);
- } else {
- this.waitForTurn(room, turn, engine);
- }
- } else {
- this.waitForTurn(room, turn, engine);
- }
+ this.waitForTurn(room, turn, engine);
}
}
@@ -621,6 +608,18 @@ export class MahjongService implements OnApplicationShutdown, OnModuleInit {
*/
@bindThis
private async waitForTurn(room: Room, house: Mahjong.Common.House, engine: Mahjong.MasterGameEngine) {
+ if (engine.state.riichis[house]) {
+ // リーチ時はアガリ牌でない限りツモ切り
+ const handTiles = engine.state.handTiles[house];
+ const horaSets = Mahjong.Utils.getHoraSets(handTiles);
+ if (horaSets.length === 0) {
+ setTimeout(() => {
+ this.dahai(room, engine, house, handTiles.at(-1));
+ }, 500);
+ return;
+ }
+ }
+
const id = Math.random().toString(36).slice(2);
console.log('waitForTurn', house, id);
this.redisClient.sadd(`mahjong:gameTurnWaiting:${room.id}`, id);
diff --git a/packages/frontend/assets/mahjong/bg.jpg b/packages/frontend/assets/mahjong/bg.jpg
new file mode 100644
index 0000000000..528c8b154e
Binary files /dev/null and b/packages/frontend/assets/mahjong/bg.jpg differ
diff --git a/packages/frontend/assets/mahjong/putted-tile-1.png b/packages/frontend/assets/mahjong/putted-tile-1.png
new file mode 100644
index 0000000000..88de9a6412
Binary files /dev/null and b/packages/frontend/assets/mahjong/putted-tile-1.png differ
diff --git a/packages/frontend/assets/mahjong/putted-tile-2.png b/packages/frontend/assets/mahjong/putted-tile-2.png
new file mode 100644
index 0000000000..e3192b19f6
Binary files /dev/null and b/packages/frontend/assets/mahjong/putted-tile-2.png differ
diff --git a/packages/frontend/assets/mahjong/putted-tile-3.png b/packages/frontend/assets/mahjong/putted-tile-3.png
new file mode 100644
index 0000000000..b258a1bfa2
Binary files /dev/null and b/packages/frontend/assets/mahjong/putted-tile-3.png differ
diff --git a/packages/frontend/assets/mahjong/putted-tile-4.png b/packages/frontend/assets/mahjong/putted-tile-4.png
new file mode 100644
index 0000000000..4617f883d3
Binary files /dev/null and b/packages/frontend/assets/mahjong/putted-tile-4.png differ
diff --git a/packages/frontend/assets/mahjong/putted-tile-5.png b/packages/frontend/assets/mahjong/putted-tile-5.png
new file mode 100644
index 0000000000..5c61c62308
Binary files /dev/null and b/packages/frontend/assets/mahjong/putted-tile-5.png differ
diff --git a/packages/frontend/assets/mahjong/tile-top-h.png b/packages/frontend/assets/mahjong/tile-top-h.png
deleted file mode 100644
index a575deca27..0000000000
Binary files a/packages/frontend/assets/mahjong/tile-top-h.png and /dev/null differ
diff --git a/packages/frontend/assets/mahjong/tile-top-v.png b/packages/frontend/assets/mahjong/tile-top-v.png
deleted file mode 100644
index d087d195b4..0000000000
Binary files a/packages/frontend/assets/mahjong/tile-top-v.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 b62786cd28..90d7f418fe 100644
--- a/packages/frontend/src/pages/mahjong/room.game.vue
+++ b/packages/frontend/src/pages/mahjong/room.game.vue
@@ -8,15 +8,28 @@ SPDX-License-Identifier: AGPL-3.0-only
-
{{ Mahjong.Utils.prevHouse(Mahjong.Utils.prevHouse(engine.myHouse)) }} {{ engine.state.points[Mahjong.Utils.prevHouse(Mahjong.Utils.prevHouse(engine.myHouse))] }}
-
{{ Mahjong.Utils.prevHouse(engine.myHouse) }} {{ engine.state.points[Mahjong.Utils.prevHouse(engine.myHouse)] }} | {{ engine.state.tilesCount }} | {{ Mahjong.Utils.nextHouse(engine.myHouse) }} {{ engine.state.points[Mahjong.Utils.nextHouse(engine.myHouse)] }}
-
{{ engine.myHouse }} {{ engine.state.points[engine.myHouse] }}
+
+ {{ Mahjong.Utils.prevHouse(Mahjong.Utils.prevHouse(engine.myHouse)) === 'e' ? i18n.ts._mahjong.east : Mahjong.Utils.prevHouse(Mahjong.Utils.prevHouse(engine.myHouse)) === 's' ? i18n.ts._mahjong.south : Mahjong.Utils.prevHouse(Mahjong.Utils.prevHouse(engine.myHouse)) === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}
+ {{ engine.state.points[Mahjong.Utils.prevHouse(Mahjong.Utils.prevHouse(engine.myHouse))] }}
+
+
+ {{ Mahjong.Utils.prevHouse(engine.myHouse) === 'e' ? i18n.ts._mahjong.east : Mahjong.Utils.prevHouse(engine.myHouse) === 's' ? i18n.ts._mahjong.south : Mahjong.Utils.prevHouse(engine.myHouse) === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}
+ {{ engine.state.points[Mahjong.Utils.prevHouse(engine.myHouse)] }}
+
+
+ {{ Mahjong.Utils.nextHouse(engine.myHouse) === 'e' ? i18n.ts._mahjong.east : Mahjong.Utils.nextHouse(engine.myHouse) === 's' ? i18n.ts._mahjong.south : Mahjong.Utils.nextHouse(engine.myHouse) === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}
+ {{ engine.state.points[Mahjong.Utils.nextHouse(engine.myHouse)] }}
+
+
+ {{ engine.myHouse === 'e' ? i18n.ts._mahjong.east : engine.myHouse === 's' ? i18n.ts._mahjong.south : engine.myHouse === 'w' ? i18n.ts._mahjong.west : i18n.ts._mahjong.north }}
+ {{ engine.state.points[engine.myHouse] }}
+
-
+
@@ -35,40 +48,49 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
-
+
@@ -77,9 +99,9 @@ SPDX-License-Identifier: AGPL-3.0-only
@@ -128,6 +150,9 @@ const isMyTurn = computed(() => {
const canHora = computed(() => {
return Mahjong.Utils.getHoraSets(engine.value.myHandTiles).length > 0;
});
+
+const selectableTiles = ref
(null);
+
/*
console.log(Mahjong.Utils.getTilesForRiichi([
'm1',
@@ -206,37 +231,37 @@ if (!props.room.isEnded) {
}
*/
-function dahai(tile: Mahjong.Common.Tile, ev: MouseEvent) {
+let riichiSelect = false;
+
+function chooseTile(tile: Mahjong.Common.Tile, ev: MouseEvent) {
if (!isMyTurn.value) return;
- engine.value.commit_dahai(engine.value.myHouse, tile);
+ sound.playUrl('/client-assets/mahjong/dahai.mp3', {
+ volume: 1,
+ playbackRate: 1,
+ });
+
iTsumoed.value = false;
- triggerRef(engine);
props.connection!.send('dahai', {
tile: tile,
+ riichi: riichiSelect,
});
+
+ riichiSelect = false;
+ selectableTiles.value = null;
}
function riichi() {
if (!isMyTurn.value) return;
- engine.value.commit_dahai(engine.value.myHouse, tile, true);
- iTsumoed.value = false;
- triggerRef(engine);
-
- props.connection!.send('dahai', {
- tile: tile,
- riichi: true,
- });
+ riichiSelect = true;
+ selectableTiles.value = Mahjong.Utils.getTilesForRiichi(engine.value.myHandTiles);
}
function kakan() {
if (!isMyTurn.value) return;
- engine.value.commit_kakan(engine.value.myHouse);
- triggerRef(engine);
-
props.connection!.send('kakan', {
});
}
@@ -244,9 +269,6 @@ function kakan() {
function hora() {
if (!isMyTurn.value) return;
- engine.value.commit_hora(engine.value.myHouse);
- triggerRef(engine);
-
props.connection!.send('hora', {
});
}
@@ -326,10 +348,13 @@ function onStreamDahaiAndTsumo(log) {
// return;
//}
- if (log.dahaiHouse !== engine.value.myHouse) {
- engine.value.commit_dahai(log.dahaiHouse, log.dahaiTile);
- triggerRef(engine);
- }
+ sound.playUrl('/client-assets/mahjong/dahai.mp3', {
+ volume: 1,
+ playbackRate: 1,
+ });
+
+ engine.value.commit_dahai(log.dahaiHouse, log.dahaiTile);
+ triggerRef(engine);
window.setTimeout(() => {
engine.value.commit_tsumo(Mahjong.Utils.nextHouse(log.dahaiHouse), log.tsumoTile);
@@ -429,6 +454,10 @@ onUnmounted(() => {
diff --git a/packages/misskey-mahjong/src/engine.master.ts b/packages/misskey-mahjong/src/engine.master.ts
index 6a3bd45ca4..67ec730791 100644
--- a/packages/misskey-mahjong/src/engine.master.ts
+++ b/packages/misskey-mahjong/src/engine.master.ts
@@ -239,7 +239,9 @@ export class MasterGameEngine {
if (this.state.turn !== house) throw new Error('Not your turn');
if (riichi) {
- if (Utils.getHoraTiles(this.state.handTiles[house]).length === 0) throw new Error('Not tenpai');
+ const tempHandTiles = [...this.state.handTiles[house]];
+ tempHandTiles.splice(tempHandTiles.indexOf(tile), 1);
+ if (Utils.getHoraTiles(tempHandTiles).length === 0) throw new Error('Not tenpai');
if (this.state.points[house] < 1000) throw new Error('Not enough points');
}