Commit b5e2cf80 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/ui/rock_paper_scissors' into 'main'

Feat/ui/rock paper scissors

See merge request !238
parents 8988e67a c5475a23
......@@ -66,3 +66,4 @@ export const MSG_TOSS_COIN = 130;
export const MSG_TOSS_DICE = 131;
export const MSG_SHUFFLE_SET_CARD = 36;
export const MSG_FIELD_DISABLED = 56;
export const MSG_HAND_RES = 133;
......@@ -15,6 +15,7 @@ import MsgAttack from "./attack";
import MsgDamage from "./damage";
import MsgDrawAdapter from "./draw";
import MsgFieldDisabledAdapter from "./fieldDisabled";
import MsgHandResultAdapter from "./handResult";
import MsgHintAdapter from "./hint";
import MsgNewPhaseAdapter from "./newPhase";
import MsgNewTurnAdapter from "./newTurn";
......@@ -250,6 +251,11 @@ export default class GameMsgAdapter implements StocAdapter {
break;
}
case GAME_MSG.MSG_HAND_RES: {
gameMsg.hand_res = MsgHandResultAdapter(gameData);
break;
}
default: {
gameMsg.unimplemented = new ygopro.StocGameMessage.MsgUnimplemented({
command: func,
......
......@@ -330,7 +330,7 @@ async function _handleGameMsg(pb: ygopro.YgoStocMsg) {
break;
}
case "rock_paper_scissors": {
onMsgRockPaperScissors(msg.rock_paper_scissors);
await onMsgRockPaperScissors(msg.rock_paper_scissors);
break;
}
......
import { ygopro } from "@/api";
import { matStore } from "@/stores";
import MsgHandResult = ygopro.StocGameMessage.MsgHandResult;
export default (res: MsgHandResult) => {
console.log(res);
// TODO
const { result1, result2 } = res;
matStore.handResults.set(0, result1);
matStore.handResults.set(1, result2);
};
import { ygopro } from "@/api";
import { displayOptionModal } from "@/ui/Duel/Message";
export default (mora: ygopro.StocGameMessage.MsgRockPaperScissors) => {
console.log(mora);
// TODO
export default async (mora: ygopro.StocGameMessage.MsgRockPaperScissors) => {
const _player = mora.player;
// TODO: I18n
await displayOptionModal("请选择猜拳", [
{ msg: "剪刀", response: 1 },
{ msg: "石头", response: 2 },
{ msg: "", response: 3 },
]);
};
import { fetchCard, getCardStr, ygopro } from "@/api";
import { fetchCard, fetchStrings, getCardStr, ygopro } from "@/api";
import MsgSelectOption = ygopro.StocGameMessage.MsgSelectOption;
import { displayOptionModal } from "@/ui/Duel/Message";
export default async (selectOption: MsgSelectOption) => {
const options = selectOption.options;
await displayOptionModal(
fetchStrings("!system", 556),
await Promise.all(
options.map(async ({ code, response }) => {
const meta = await fetchCard(code >> 4);
......
......@@ -81,6 +81,14 @@ export const matStore: MatState = proxy<MatState>({
enableEp: false, // 允许回合结束
},
unimplemented: 0,
handResults: {
me: 0,
op: 0,
of: (controller: number) => matStore.handResults[getWhom(controller)],
set(controller, result) {
matStore.handResults[getWhom(controller)] = result;
},
},
// methods
isMe,
});
......
......@@ -37,6 +37,10 @@ export interface MatState {
tossResult?: string; // 骰子/硬币结果
handResults: BothSide<HandResult> & {
set: (controller: number, result: HandResult) => void;
}; // 猜拳结果
/** 根据自己的先后手判断是否是自己 */
isMe: (player: number) => boolean;
}
......@@ -94,4 +98,11 @@ export interface PhaseState {
enableM2: boolean; // 允许进入M2阶段
enableEp: boolean; // 允许回合结束
}
export enum HandResult {
UNKNOWN = 0,
SCISSOR = 1,
ROCK = 2,
PAPER = 3,
}
// <<< play mat state <<<
......@@ -7,7 +7,7 @@ import { useSnapshot } from "valtio";
import { fetchStrings } from "@/api";
import { Phase2StringCodeMap } from "@/common";
import { useConfig } from "@/config";
import { matStore } from "@/stores";
import { HandResult, matStore } from "@/stores";
const style = {
borderStyle: "groove",
......@@ -22,9 +22,8 @@ export const HintNotification = () => {
const snap = useSnapshot(matStore);
const hintState = snap.hint;
const toss = snap.tossResult;
const handResults = snap.handResults;
const currentPhase = snap.phase.currentPhase;
// const waiting = snap.waiting;
const result = snap.result;
const [notify, notifyContextHolder] = notification.useNotification({
......@@ -54,6 +53,21 @@ export const HintNotification = () => {
}
}, [toss]);
// TODO: I18n
useEffect(() => {
const meHand = handResults.me;
const opHand = handResults.op;
if (meHand !== HandResult.UNKNOWN && opHand !== HandResult.UNKNOWN) {
notify.open({
message: `{我方出示${getHandResultText(
meHand
)},对方出示${getHandResultText(opHand)}}`,
placement: "topLeft",
style: style,
});
}
}, [handResults]);
useEffect(() => {
if (currentPhase) {
const message = fetchStrings(
......@@ -117,3 +131,17 @@ export const showWaiting = (open: boolean) => {
}
}
};
// TODO: I18n
function getHandResultText(res: HandResult): string {
switch (res) {
case HandResult.UNKNOWN:
return "[?]";
case HandResult.ROCK:
return "拳头";
case HandResult.PAPER:
return "";
case HandResult.SCISSOR:
return "剪刀";
}
}
......@@ -5,6 +5,7 @@ import { proxy, useSnapshot } from "valtio";
import {
type CardMeta,
fetchStrings,
getCardStr,
sendSelectIdleCmdResponse,
sendSelectOptionResponse,
......@@ -15,6 +16,7 @@ import { NeosModal } from "./NeosModal";
type Options = { msg: string; response: number }[];
const defaultStore = {
title: "",
isOpen: false,
options: [] satisfies Options as Options,
};
......@@ -23,7 +25,7 @@ const store = proxy(defaultStore);
export const OptionModal = () => {
const snap = useSnapshot(store);
const { isOpen, options } = snap;
const { title, isOpen, options } = snap;
const [selected, setSelected] = useState<number | undefined>(undefined);
......@@ -36,7 +38,7 @@ export const OptionModal = () => {
return (
<NeosModal
title="请选择需要发动的效果"
title={title}
open={isOpen}
footer={
<Button disabled={selected === undefined} onClick={onClick}>
......@@ -54,9 +56,10 @@ export const OptionModal = () => {
};
let rs: (v?: any) => void = () => {};
export const displayOptionModal = async (options: Options) => {
store.isOpen = true;
export const displayOptionModal = async (title: string, options: Options) => {
store.title = title;
store.options = options;
store.isOpen = true;
await new Promise((resolve) => (rs = resolve));
store.isOpen = false;
};
......@@ -87,6 +90,6 @@ export const handleEffectActivation = async (
response: effect.response,
};
});
await displayOptionModal(options); // 主动发动效果,所以不需要await,但是以后可能要留心
await displayOptionModal(fetchStrings("!system", 556), options); // 主动发动效果,所以不需要await,但是以后可能要留心
}
};
......@@ -6,7 +6,12 @@ import classnames from "classnames";
import React, { type CSSProperties, useEffect, useState } from "react";
import { proxy, useSnapshot } from "valtio";
import { getCardStr, sendSelectIdleCmdResponse, ygopro } from "@/api";
import {
fetchStrings,
getCardStr,
sendSelectIdleCmdResponse,
ygopro,
} from "@/api";
import { eventbus, Task } from "@/infra";
import { cardStore, CardType, Interactivity, InteractType } from "@/stores";
import { showCardModal as displayCardModal } from "@/ui/Duel/Message/CardModal";
......@@ -250,7 +255,7 @@ const handleEffectActivation = (
response: effect.response,
};
});
displayOptionModal(options); // 主动发动效果,所以不需要await,但是以后可能要留心
displayOptionModal(fetchStrings("!system", 556), options); // 主动发动效果,所以不需要await,但是以后可能要留心
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment