Commit 46c12e4b authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/service/select_chain_response' into 'main'

Feat/service/select chain response

See merge request !64
parents 8a9039bf f8e76037
...@@ -16,6 +16,22 @@ export interface CardMeta { ...@@ -16,6 +16,22 @@ export interface CardMeta {
name?: string; name?: string;
types?: string; types?: string;
desc?: string; desc?: string;
str1?: string;
str2?: string;
str3?: string;
str4?: string;
str5?: string;
str6?: string;
str7?: string;
str8?: string;
str9?: string;
str10?: string;
str11?: string;
str12?: string;
str13?: string;
str14?: string;
str15?: string;
str16?: string;
}; };
} }
...@@ -31,3 +47,59 @@ export async function fetchCard(id: number): Promise<CardMeta> { ...@@ -31,3 +47,59 @@ export async function fetchCard(id: number): Promise<CardMeta> {
return res.data; return res.data;
} }
export function getCardStr(meta: CardMeta, idx: number): string | undefined {
switch (idx) {
case 0: {
return meta.text.str1;
}
case 1: {
return meta.text.str2;
}
case 2: {
return meta.text.str3;
}
case 3: {
return meta.text.str4;
}
case 4: {
return meta.text.str5;
}
case 5: {
return meta.text.str6;
}
case 6: {
return meta.text.str7;
}
case 7: {
return meta.text.str8;
}
case 8: {
return meta.text.str9;
}
case 9: {
return meta.text.str10;
}
case 10: {
return meta.text.str11;
}
case 11: {
return meta.text.str12;
}
case 12: {
return meta.text.str13;
}
case 13: {
return meta.text.str14;
}
case 14: {
return meta.text.str15;
}
case 15: {
return meta.text.str16;
}
default: {
return undefined;
}
}
}
...@@ -27,6 +27,7 @@ import { ...@@ -27,6 +27,7 @@ import {
setCardListModalInfoImpl, setCardListModalInfoImpl,
setCheckCardModalIsOpenImpl, setCheckCardModalIsOpenImpl,
setCheckCardModalMinMaxImpl, setCheckCardModalMinMaxImpl,
setCheckCardModalOnSubmitImpl,
resetCheckCardModalImpl, resetCheckCardModalImpl,
checkCardModalCase, checkCardModalCase,
} from "./modalSlice"; } from "./modalSlice";
...@@ -123,6 +124,7 @@ const duelSlice = createSlice({ ...@@ -123,6 +124,7 @@ const duelSlice = createSlice({
setCardListModalInfo: setCardListModalInfoImpl, setCardListModalInfo: setCardListModalInfoImpl,
setCheckCardModalIsOpen: setCheckCardModalIsOpenImpl, setCheckCardModalIsOpen: setCheckCardModalIsOpenImpl,
setCheckCardModalMinMax: setCheckCardModalMinMaxImpl, setCheckCardModalMinMax: setCheckCardModalMinMaxImpl,
setCheckCardModalOnSubmit: setCheckCardModalOnSubmitImpl,
resetCheckCardModal: resetCheckCardModalImpl, resetCheckCardModal: resetCheckCardModalImpl,
}, },
extraReducers(builder) { extraReducers(builder) {
...@@ -159,6 +161,7 @@ export const { ...@@ -159,6 +161,7 @@ export const {
setCardListModalInfo, setCardListModalInfo,
setCheckCardModalIsOpen, setCheckCardModalIsOpen,
setCheckCardModalMinMax, setCheckCardModalMinMax,
setCheckCardModalOnSubmit,
resetCheckCardModal, resetCheckCardModal,
} = duelSlice.actions; } = duelSlice.actions;
export const selectDuelHsStart = (state: RootState) => { export const selectDuelHsStart = (state: RootState) => {
......
...@@ -4,7 +4,7 @@ import { ...@@ -4,7 +4,7 @@ import {
createAsyncThunk, createAsyncThunk,
ActionReducerMapBuilder, ActionReducerMapBuilder,
} from "@reduxjs/toolkit"; } from "@reduxjs/toolkit";
import { fetchCard } from "../../api/cards"; import { fetchCard, getCardStr } from "../../api/cards";
import { RootState } from "../../store"; import { RootState } from "../../store";
import { DuelState } from "./mod"; import { DuelState } from "./mod";
import { judgeSelf } from "./util"; import { judgeSelf } from "./util";
...@@ -30,6 +30,7 @@ export interface ModalState { ...@@ -30,6 +30,7 @@ export interface ModalState {
// 卡牌选择弹窗 // 卡牌选择弹窗
checkCardModal: { checkCardModal: {
isOpen: boolean; isOpen: boolean;
onSubmit?: string;
selectMin?: number; selectMin?: number;
selectMax?: number; selectMax?: number;
tags: { tags: {
...@@ -38,6 +39,7 @@ export interface ModalState { ...@@ -38,6 +39,7 @@ export interface ModalState {
code: number; code: number;
name?: string; name?: string;
desc?: string; desc?: string;
effectDesc?: string;
response: number; response: number;
}[]; }[];
}[]; }[];
...@@ -115,15 +117,26 @@ export const setCheckCardModalMinMaxImpl: CaseReducer< ...@@ -115,15 +117,26 @@ export const setCheckCardModalMinMaxImpl: CaseReducer<
state.modalState.checkCardModal.selectMax = action.payload.max; state.modalState.checkCardModal.selectMax = action.payload.max;
}; };
// 更新卡牌选择弹窗的提交回调
export const setCheckCardModalOnSubmitImpl: CaseReducer<
DuelState,
PayloadAction<string>
> = (state, action) => {
state.modalState.checkCardModal.onSubmit = action.payload;
};
// 增加卡牌选择选项 // 增加卡牌选择选项
export const fetchCheckCardMeta = createAsyncThunk( export const fetchCheckCardMeta = createAsyncThunk(
"duel/fetchCheckCardMeta", "duel/fetchCheckCardMeta",
async (param: { async (param: {
controler: number; controler: number;
tagName: string; tagName: string;
option: { code: number; response: number }; option: { code: number; response: number; effectDescCode?: number };
}) => { }) => {
const meta = await fetchCard(param.option.code); const meta = await fetchCard(param.option.code);
const effectDesc = param.option.effectDescCode
? getCardStr(meta, param.option.effectDescCode & 0xf)
: undefined;
const response = { const response = {
controler: param.controler, controler: param.controler,
tagName: param.tagName, tagName: param.tagName,
...@@ -131,6 +144,7 @@ export const fetchCheckCardMeta = createAsyncThunk( ...@@ -131,6 +144,7 @@ export const fetchCheckCardMeta = createAsyncThunk(
code: meta.id, code: meta.id,
name: meta.text.name, name: meta.text.name,
desc: meta.text.desc, desc: meta.text.desc,
effectDesc,
}, },
}; };
...@@ -159,7 +173,7 @@ export const checkCardModalCase = ( ...@@ -159,7 +173,7 @@ export const checkCardModalCase = (
} }
state.modalState.checkCardModal.tags.push({ state.modalState.checkCardModal.tags.push({
tagName, tagName: combinedTagName,
options: [{ code, response }], options: [{ code, response }],
}); });
}); });
...@@ -178,6 +192,7 @@ export const checkCardModalCase = ( ...@@ -178,6 +192,7 @@ export const checkCardModalCase = (
if (option.code == meta.code) { if (option.code == meta.code) {
option.name = meta.name; option.name = meta.name;
option.desc = meta.desc; option.desc = meta.desc;
option.effectDesc = meta.effectDesc;
} }
} }
} }
...@@ -216,3 +231,5 @@ export const selectCheckCardModalMinMax = (state: RootState) => { ...@@ -216,3 +231,5 @@ export const selectCheckCardModalMinMax = (state: RootState) => {
}; };
export const selectCheckCardModalTags = (state: RootState) => export const selectCheckCardModalTags = (state: RootState) =>
state.duel.modalState.checkCardModal.tags; state.duel.modalState.checkCardModal.tags;
export const selectCheckCardModalOnSubmit = (state: RootState) =>
state.duel.modalState.checkCardModal.onSubmit;
...@@ -3,6 +3,7 @@ import { AppDispatch } from "../../store"; ...@@ -3,6 +3,7 @@ import { AppDispatch } from "../../store";
import { import {
setCheckCardModalIsOpen, setCheckCardModalIsOpen,
setCheckCardModalMinMax, setCheckCardModalMinMax,
setCheckCardModalOnSubmit,
} from "../../reducers/duel/mod"; } from "../../reducers/duel/mod";
import { fetchCheckCardMeta } from "../../reducers/duel/modalSlice"; import { fetchCheckCardMeta } from "../../reducers/duel/modalSlice";
import MsgSelectCard = ygopro.StocGameMessage.MsgSelectCard; import MsgSelectCard = ygopro.StocGameMessage.MsgSelectCard;
...@@ -16,6 +17,7 @@ export default (selectCard: MsgSelectCard, dispatch: AppDispatch) => { ...@@ -16,6 +17,7 @@ export default (selectCard: MsgSelectCard, dispatch: AppDispatch) => {
const cards = selectCard.cards; const cards = selectCard.cards;
dispatch(setCheckCardModalMinMax({ min, max })); dispatch(setCheckCardModalMinMax({ min, max }));
dispatch(setCheckCardModalOnSubmit("sendSelectCardResponse"));
for (const card of cards) { for (const card of cards) {
const tagName = CardZoneToChinese(card.location.location); const tagName = CardZoneToChinese(card.location.location);
......
import { ygopro } from "../../api/ocgcore/idl/ocgcore"; import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { sendSelectChainResponse } from "../../api/ocgcore/ocgHelper";
import {
setCheckCardModalIsOpen,
setCheckCardModalMinMax,
setCheckCardModalOnSubmit,
} from "../../reducers/duel/mod";
import { fetchCheckCardMeta } from "../../reducers/duel/modalSlice";
import { AppDispatch } from "../../store"; import { AppDispatch } from "../../store";
import { CardZoneToChinese } from "./util";
import MsgSelectChain = ygopro.StocGameMessage.MsgSelectChain; import MsgSelectChain = ygopro.StocGameMessage.MsgSelectChain;
export default (selectChain: MsgSelectChain, dispatch: AppDispatch) => { export default (selectChain: MsgSelectChain, dispatch: AppDispatch) => {
console.log(selectChain); const player = selectChain.player;
const spCount = selectChain.special_count;
const forced = selectChain.forced;
const hint0 = selectChain.hint0;
const hint1 = selectChain.hint1;
const chains = selectChain.chains;
let handle_flag = 0;
if (!forced) {
// 无强制发动的卡
if (spCount == 0) {
// 无关键卡
if (chains.length == 0) {
// 直接回答
handle_flag = 0;
} else {
// 处理多张
handle_flag = 2;
}
} else {
// 有关键卡
if (chains.length == 0) {
// 根本没卡,直接回答
handle_flag = 0;
} else {
// 处理多张
handle_flag = 2;
}
}
} else {
// 有强制发动的卡
if (chains.length == 1) {
// 只有一个强制发动的连锁项,直接回应
handle_flag = 4;
} else {
// 处理强制发动的卡
handle_flag = 3;
}
}
switch (handle_flag) {
case 0: {
// 直接回答
sendSelectChainResponse(-1);
break;
}
case 2: // 处理多张
case 3: {
// 处理强制发动的卡
// TODO:非强制发动的场景需要支持取消
dispatch(setCheckCardModalMinMax({ min: 1, max: 1 }));
dispatch(setCheckCardModalOnSubmit("sendSelectChainResponse"));
for (const chain of chains) {
const tagName = CardZoneToChinese(chain.location.location);
dispatch(
fetchCheckCardMeta({
controler: chain.location.controler,
tagName,
option: {
code: chain.code,
response: chain.response,
effectDescCode: chain.effect_description,
},
})
);
}
dispatch(setCheckCardModalIsOpen(true));
break;
}
case 4: {
// 有一张强制发动的卡,直接回应
sendSelectChainResponse(chains[0].response);
break;
}
default: {
console.log(`Unhandled flag: ${handle_flag}`);
}
}
}; };
...@@ -70,9 +70,13 @@ const CCemetery = (props: { ...@@ -70,9 +70,13 @@ const CCemetery = (props: {
<box <box
name="cemetery" name="cemetery"
ref={boxRef} ref={boxRef}
width={shape.width} scaling={
height={shape.height} new BABYLON.Vector3(
depth={depth * props.state.length} shape.width,
shape.height,
depth * props.state.length
)
}
position={props.position} position={props.position}
rotation={props.rotation} rotation={props.rotation}
> >
......
...@@ -4,21 +4,26 @@ import { store } from "../../store"; ...@@ -4,21 +4,26 @@ import { store } from "../../store";
import { import {
selectCheckCardModalIsOpen, selectCheckCardModalIsOpen,
selectCheckCardModalMinMax, selectCheckCardModalMinMax,
selectCheckCardModalOnSubmit,
selectCheckCardModalTags, selectCheckCardModalTags,
} from "../../reducers/duel/modalSlice"; } from "../../reducers/duel/modalSlice";
import { import {
resetCheckCardModal, resetCheckCardModal,
setCheckCardModalIsOpen, setCheckCardModalIsOpen,
} from "../../reducers/duel/mod"; } from "../../reducers/duel/mod";
import { Modal, Button, Row, Col } from "antd"; import { Modal, Button, Row, Col, Popover } from "antd";
import { CheckCard } from "@ant-design/pro-components"; import { CheckCard } from "@ant-design/pro-components";
import { sendSelectCardResponse } from "../../api/ocgcore/ocgHelper"; import {
sendSelectCardResponse,
sendSelectChainResponse,
} from "../../api/ocgcore/ocgHelper";
const CheckCardModal = () => { const CheckCardModal = () => {
const dispatch = store.dispatch; const dispatch = store.dispatch;
const isOpen = useAppSelector(selectCheckCardModalIsOpen); const isOpen = useAppSelector(selectCheckCardModalIsOpen);
const { min, max } = useAppSelector(selectCheckCardModalMinMax); const { min, max } = useAppSelector(selectCheckCardModalMinMax);
const tabs = useAppSelector(selectCheckCardModalTags); const tabs = useAppSelector(selectCheckCardModalTags);
const onSubmit = useAppSelector(selectCheckCardModalOnSubmit);
const [response, setResponse] = useState<number[]>([]); const [response, setResponse] = useState<number[]>([]);
const defaultValue: number[] = []; const defaultValue: number[] = [];
...@@ -31,12 +36,25 @@ const CheckCardModal = () => { ...@@ -31,12 +36,25 @@ const CheckCardModal = () => {
<Button <Button
disabled={response.length < min || response.length > max} disabled={response.length < min || response.length > max}
onClick={() => { onClick={() => {
sendSelectCardResponse(response); switch (onSubmit) {
case "sendSelectChainResponse": {
sendSelectChainResponse(response[0]);
break;
}
case "sendSelectCardResponse": {
sendSelectCardResponse(response);
break;
}
default: {
}
}
dispatch(setCheckCardModalIsOpen(false)); dispatch(setCheckCardModalIsOpen(false));
dispatch(resetCheckCardModal()); dispatch(resetCheckCardModal());
}} }}
> >
summit submit
</Button> </Button>
} }
width={800} width={800}
...@@ -51,25 +69,34 @@ const CheckCardModal = () => { ...@@ -51,25 +69,34 @@ const CheckCardModal = () => {
setResponse(value); setResponse(value);
}} }}
> >
{tabs.map((tab) => { {tabs.map((tab, idx) => {
return ( return (
<Row> <Row key={idx}>
{tab.options.map((option) => { {tab.options.map((option, idx) => {
return ( return (
<Col span={4}> <Col span={4} key={idx}>
<CheckCard <Popover
title={option.name} content={
description={option.desc} <div>
style={{ width: 120 }} <p>{option.name}</p>
cover={ <p>{option.effectDesc}</p>
<img </div>
alt={option.code.toString()}
src={`https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${option.code}.jpg`}
style={{ width: 100 }}
/>
} }
value={option.response} >
/> <CheckCard
title={option.name}
description={option.desc}
style={{ width: 120 }}
cover={
<img
alt={option.code.toString()}
src={`https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${option.code}.jpg`}
style={{ width: 100 }}
/>
}
value={option.response}
/>
</Popover>
</Col> </Col>
); );
})} })}
......
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