Commit e9d1b91f authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/waiting' into 'main'

Feat/waiting

See merge request !145
parents 3bfe5d4e e273124f
Pipeline #20781 passed with stages
in 16 minutes and 23 seconds
Subproject commit 9711eef553da455be0d01238dae7f026d8d5650e
Subproject commit 3973685c657030b845ef385e8a0610971c8c60b9
......@@ -66,6 +66,9 @@
"avatarSize": 40,
"meAvatarColor": "#0e63e1",
"opAvatarColor": "#e10e68"
},
"hint": {
"waitingDuration": 1.5
}
}
}
......@@ -66,6 +66,9 @@
"avatarSize": 40,
"meAvatarColor": "#0e63e1",
"opAvatarColor": "#e10e68"
},
"hint": {
"waitingDuration": 1.5
}
}
}
This diff is collapsed.
......@@ -48,3 +48,4 @@ export const MSG_DAMAGE = 91;
export const MSG_RECOVER = 92;
export const MSG_PAY_LP_COST = 100;
export const MSG_WIN = 5;
export const MSG_WAITING = 3;
......@@ -21,6 +21,7 @@ import MsgSelectPositionAdapter from "./selectPosition";
import MsgSelectOptionAdapter from "./selectOption";
import MsgSelectBattleCmdAdapter from "./selectBattleCmd";
import MsgSelectUnselectCardAdapter from "./selectUnselectCard";
import MsgWaitAdapter from "./wait";
import MsgDamage from "./damage";
import MsgRecover from "./recover";
import MsgWin from "./win";
......@@ -142,6 +143,11 @@ export default class GameMsgAdapter implements StocAdapter {
break;
}
case GAME_MSG.MSG_WAITING: {
gameMsg.wait = MsgWaitAdapter(gameData);
break;
}
default: {
console.log("Unhandled GameMessage function=", func);
......
import { ygopro } from "../../../idl/ocgcore";
import MsgWait = ygopro.StocGameMessage.MsgWait;
/*
* Msg Wait
*
* @param - null
*
* @usage - 后端通知前端等待对手操作
* */
export default (_data: Uint8Array) => {
return new MsgWait({});
};
......@@ -142,6 +142,8 @@ export interface DuelState {
result?: MsgWin.ActionType;
waiting?: boolean;
// UI相关
modalState: ModalState;
}
......@@ -257,6 +259,11 @@ const duelSlice = createSlice({
setResult: (state, action: PayloadAction<MsgWin.ActionType>) => {
state.result = action.payload;
},
// 等待状态`Reducer`
setWaiting: (state, action: PayloadAction<boolean>) => {
state.waiting = action.payload;
},
},
extraReducers(builder) {
handsCase(builder);
......@@ -336,6 +343,7 @@ export const {
clearAllIdleInteractivities,
clearAllPlaceInteractivities,
setResult,
setWaiting,
} = duelSlice.actions;
export const selectDuelHsStart = (state: RootState) => {
return state.duel.meInitInfo != null;
......@@ -343,4 +351,7 @@ export const selectDuelHsStart = (state: RootState) => {
export const selectDuelResult = (state: RootState) => {
return state.duel.result;
};
export const selectWaiting = (state: RootState) => {
return state.duel.waiting;
};
export default duelSlice.reducer;
......@@ -20,11 +20,30 @@ import onMsgSelectUnselectCard from "./selectUnselectCard";
import onMsgSelectYesNo from "./selectYesNo";
import onMsgUpdateHp from "./updateHp";
import onMsgWin from "./win";
import onMsgWait from "./wait";
import { setWaiting } from "../../reducers/duel/mod";
const ActiveList = [
"select_idle_cmd",
"select_place",
"select_card",
"select_chain",
"select_effect_yn",
"select_position",
"select_option",
"select_battle_cmd",
"select_unselect_card",
"select_yes_no",
];
export default function handleGameMsg(pb: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
const msg = pb.stoc_game_msg;
if (ActiveList.includes(msg.gameMsg)) {
dispatch(setWaiting(false));
}
switch (msg.gameMsg) {
case "start": {
onMsgStart(msg.start, dispatch);
......@@ -126,6 +145,11 @@ export default function handleGameMsg(pb: ygopro.YgoStocMsg) {
break;
}
case "wait": {
onMsgWait(msg.wait, dispatch);
break;
}
default: {
break;
}
......
......@@ -5,9 +5,7 @@ import {
addHandsIdleInteractivity,
addMagicIdleInteractivities,
addMonsterIdleInteractivities,
clearHandsIdleInteractivity,
clearMagicIdleInteractivities,
clearMonsterIdleInteractivities,
clearAllIdleInteractivities,
setEnableEp,
setEnableM2,
} from "../../reducers/duel/mod";
......@@ -19,9 +17,7 @@ export default (selectBattleCmd: MsgSelectBattleCmd, dispatch: AppDispatch) => {
const cmds = selectBattleCmd.battle_cmds;
// 先清掉之前的互动性
dispatch(clearHandsIdleInteractivity(player));
dispatch(clearMonsterIdleInteractivities(player));
dispatch(clearMagicIdleInteractivities(player));
dispatch(clearAllIdleInteractivities(player));
const dispatcher = (
battleData: MsgSelectBattleCmd.BattleCmd.BattleData,
......
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import {
clearAllIdleInteractivities,
setWaiting,
} from "../../reducers/duel/mod";
import { AppDispatch } from "../../store";
export default (
_wait: ygopro.StocGameMessage.MsgWait,
dispatch: AppDispatch
) => {
dispatch(clearAllIdleInteractivities(0));
dispatch(clearAllIdleInteractivities(1));
dispatch(setWaiting(true));
};
......@@ -3,15 +3,17 @@ import { useAppSelector } from "../../hook";
import { selectMeHint, selectOpHint } from "../../reducers/duel/hintSlice";
import { selectCurrentPhase } from "../../reducers/duel/phaseSlice";
import { notification } from "antd";
import { selectDuelResult } from "../../reducers/duel/mod";
import { selectDuelResult, selectWaiting } from "../../reducers/duel/mod";
import { useNavigate } from "react-router-dom";
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import MsgWin = ygopro.StocGameMessage.MsgWin;
import NeosConfig from "../../../neos.config.json";
const HintNotification = () => {
const meHint = useAppSelector(selectMeHint);
const opHint = useAppSelector(selectOpHint);
const currentPhase = useAppSelector(selectCurrentPhase);
const waiting = useAppSelector(selectWaiting);
const result = useAppSelector(selectDuelResult);
const navigate = useNavigate();
......@@ -43,6 +45,16 @@ const HintNotification = () => {
}
}, [currentPhase]);
useEffect(() => {
if (waiting) {
api.info({
message: "...等待对方行动中...",
placement: "top",
duration: NeosConfig.ui.hint.waitingDuration,
});
}
}, [waiting]);
useEffect(() => {
if (result) {
const message =
......
......@@ -9,6 +9,7 @@ import {
selectOpInitInfo,
} from "../../reducers/duel/initInfoSlice";
import { selectCurrentPlayerIsMe } from "../../reducers/duel/turnSlice";
import { selectWaiting } from "../../reducers/duel/mod";
const Config = NeosConfig.ui.status;
const avatarSize = 40;
......@@ -18,13 +19,13 @@ const OP_VALUE = "opponent";
const PlayerStatus = () => {
const meInfo = useAppSelector(selectMeInitInfo);
const opInfo = useAppSelector(selectOpInitInfo);
const myTurn = useAppSelector(selectCurrentPlayerIsMe);
const waiting = useAppSelector(selectWaiting) || false;
return (
<CheckCard.Group
bordered
style={{ height: `${NeosConfig.ui.layout.header.height}` }}
value={myTurn ? ME_VALUE : OP_VALUE}
value={waiting ? OP_VALUE : ME_VALUE}
>
<CheckCard
avatar={
......
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