Commit 7ac66454 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'optimize/select_idle_cmd' into 'main'

Optimize/select idle cmd

See merge request !91
parents 1cd22c1c bce1c2f5
Pipeline #19767 passed with stages
in 3 minutes and 8 seconds
...@@ -13,6 +13,9 @@ import { ...@@ -13,6 +13,9 @@ import {
extendState, extendState,
extendMeta, extendMeta,
removeCard, removeCard,
DuelReducer,
Interactivity,
extendIdleInteractivities,
} from "./generic"; } from "./generic";
export interface CemeteryState extends DuelFieldState {} export interface CemeteryState extends DuelFieldState {}
...@@ -79,6 +82,21 @@ export const removeCemeteryImpl: CaseReducer< ...@@ -79,6 +82,21 @@ export const removeCemeteryImpl: CaseReducer<
removeCard(cemetery, action.payload.sequence); removeCard(cemetery, action.payload.sequence);
}; };
export const addCemeteryIdleInteractivitiesImpl: DuelReducer<{
player: number;
sequence: number;
interactivity: Interactivity<number>;
}> = (state, action) => {
const cemetery = judgeSelf(action.payload.player, state)
? state.meCemetery
: state.opCemetery;
extendIdleInteractivities(
cemetery,
action.payload.sequence,
action.payload.interactivity
);
};
export const selectMeCemetery = (state: RootState) => export const selectMeCemetery = (state: RootState) =>
state.duel.meCemetery || { inner: [] }; state.duel.meCemetery || { inner: [] };
export const selectOpCemetery = (state: RootState) => export const selectOpCemetery = (state: RootState) =>
......
import {
clearIdleInteractivities,
clearPlaceInteractivities,
DuelReducer,
} from "./generic";
import { judgeSelf } from "./util";
export const clearAllIdleInteractivitiesImpl: DuelReducer<number> = (
state,
action
) => {
const player = action.payload;
const states = judgeSelf(player, state)
? [
state.meHands,
state.meMonsters,
state.meMagics,
state.meCemetery,
state.meExclusion,
]
: [
state.opHands,
state.opMonsters,
state.opMagics,
state.opCemetery,
state.opExclusion,
];
states.forEach((item) => clearIdleInteractivities(item));
};
export const clearAllPlaceInteractivitiesImpl: DuelReducer<number> = (
state,
action
) => {
const player = action.payload;
const states = judgeSelf(player, state)
? [
state.meHands,
state.meMonsters,
state.meMagics,
state.meCemetery,
state.meExclusion,
]
: [
state.opHands,
state.opMonsters,
state.opMagics,
state.opCemetery,
state.opExclusion,
];
states.forEach((item) => clearPlaceInteractivities(item));
};
...@@ -13,6 +13,9 @@ import { ...@@ -13,6 +13,9 @@ import {
extendState, extendState,
extendMeta, extendMeta,
removeCard, removeCard,
DuelReducer,
Interactivity,
extendIdleInteractivities,
} from "./generic"; } from "./generic";
export interface ExclusionState extends DuelFieldState {} export interface ExclusionState extends DuelFieldState {}
...@@ -81,6 +84,21 @@ export const removeExclusionImpl: CaseReducer< ...@@ -81,6 +84,21 @@ export const removeExclusionImpl: CaseReducer<
removeCard(exclusion, action.payload.sequence); removeCard(exclusion, action.payload.sequence);
}; };
export const addExclusionIdleInteractivitiesImpl: DuelReducer<{
player: number;
sequence: number;
interactivity: Interactivity<number>;
}> = (state, action) => {
const exclusion = judgeSelf(action.payload.player, state)
? state.meExclusion
: state.opExclusion;
extendIdleInteractivities(
exclusion,
action.payload.sequence,
action.payload.interactivity
);
};
export const selectMeExclusion = (state: RootState) => export const selectMeExclusion = (state: RootState) =>
state.duel.meExclusion || { inner: [] }; state.duel.meExclusion || { inner: [] };
export const selectopExclusion = (state: RootState) => export const selectopExclusion = (state: RootState) =>
......
...@@ -81,14 +81,20 @@ import { ...@@ -81,14 +81,20 @@ import {
initCemeteryImpl, initCemeteryImpl,
removeCemeteryImpl, removeCemeteryImpl,
cemeteryCase, cemeteryCase,
addCemeteryIdleInteractivitiesImpl,
} from "./cemeretySlice"; } from "./cemeretySlice";
import { import {
ExclusionState, ExclusionState,
initExclusionImpl, initExclusionImpl,
removeExclusionImpl, removeExclusionImpl,
exclusionCase, exclusionCase,
addExclusionIdleInteractivitiesImpl,
} from "./exclusionSlice"; } from "./exclusionSlice";
import { DeckState, initDeckImpl } from "./deckSlice"; import { DeckState, initDeckImpl } from "./deckSlice";
import {
clearAllIdleInteractivitiesImpl,
clearAllPlaceInteractivitiesImpl,
} from "./commonSlice";
export interface DuelState { export interface DuelState {
selfType?: number; selfType?: number;
...@@ -183,10 +189,12 @@ const duelSlice = createSlice({ ...@@ -183,10 +189,12 @@ const duelSlice = createSlice({
// 墓地相关`Reducer` // 墓地相关`Reducer`
initCemetery: initCemeteryImpl, initCemetery: initCemeteryImpl,
removeCemetery: removeCemeteryImpl, removeCemetery: removeCemeteryImpl,
addCemeteryIdleInteractivities: addCemeteryIdleInteractivitiesImpl,
// 除外区相关`Reducer` // 除外区相关`Reducer`
initExclusion: initExclusionImpl, initExclusion: initExclusionImpl,
removeExclusion: removeExclusionImpl, removeExclusion: removeExclusionImpl,
addExclusionIdleInteractivities: addExclusionIdleInteractivitiesImpl,
// 卡组相关`Reducer` // 卡组相关`Reducer`
initDeck: initDeckImpl, initDeck: initDeckImpl,
...@@ -222,6 +230,10 @@ const duelSlice = createSlice({ ...@@ -222,6 +230,10 @@ const duelSlice = createSlice({
setCheckCardModalV2IsOpen: setCheckCardModalV2IsOpenImpl, setCheckCardModalV2IsOpen: setCheckCardModalV2IsOpenImpl,
resetCheckCardModalV2: resetCheckCardModalV2Impl, resetCheckCardModalV2: resetCheckCardModalV2Impl,
setCheckCardModalV2ResponseAble: setCheckCardModalV2ResponseAbleImpl, setCheckCardModalV2ResponseAble: setCheckCardModalV2ResponseAbleImpl,
// 通用的`Reducer`
clearAllIdleInteractivities: clearAllIdleInteractivitiesImpl,
clearAllPlaceInteractivities: clearAllPlaceInteractivitiesImpl,
}, },
extraReducers(builder) { extraReducers(builder) {
handsCase(builder); handsCase(builder);
...@@ -269,6 +281,7 @@ export const { ...@@ -269,6 +281,7 @@ export const {
removeHand, removeHand,
initCemetery, initCemetery,
removeCemetery, removeCemetery,
addCemeteryIdleInteractivities,
setCardListModalIsOpen, setCardListModalIsOpen,
setCardListModalInfo, setCardListModalInfo,
setCheckCardModalIsOpen, setCheckCardModalIsOpen,
...@@ -286,12 +299,15 @@ export const { ...@@ -286,12 +299,15 @@ export const {
initDeck, initDeck,
initExclusion, initExclusion,
removeExclusion, removeExclusion,
addExclusionIdleInteractivities,
setCheckCardModalV2IsOpen, setCheckCardModalV2IsOpen,
setCheckCardModalV2MinMax, setCheckCardModalV2MinMax,
setCheckCardModalV2CancelAble, setCheckCardModalV2CancelAble,
setCheckCardModalV2FinishAble, setCheckCardModalV2FinishAble,
resetCheckCardModalV2, resetCheckCardModalV2,
setCheckCardModalV2ResponseAble, setCheckCardModalV2ResponseAble,
clearAllIdleInteractivities,
clearAllPlaceInteractivities,
} = duelSlice.actions; } = duelSlice.actions;
export const selectDuelHsStart = (state: RootState) => { export const selectDuelHsStart = (state: RootState) => {
return state.duel.meInitInfo != null; return state.duel.meInitInfo != null;
......
...@@ -13,7 +13,14 @@ export const setCardListModalIsOpenImpl: CaseReducer< ...@@ -13,7 +13,14 @@ export const setCardListModalIsOpenImpl: CaseReducer<
// 更新卡牌列表数据 // 更新卡牌列表数据
export const setCardListModalInfoImpl: CaseReducer< export const setCardListModalInfoImpl: CaseReducer<
DuelState, DuelState,
PayloadAction<{ name?: string; desc?: string; imgUrl?: string }[]> PayloadAction<
{
name?: string;
desc?: string;
imgUrl?: string;
interactivies: { desc: string; response: number }[];
}[]
>
> = (state, action) => { > = (state, action) => {
const list = action.payload; const list = action.payload;
......
...@@ -16,6 +16,7 @@ export interface ModalState { ...@@ -16,6 +16,7 @@ export interface ModalState {
name?: string; name?: string;
desc?: string; desc?: string;
imgUrl?: string; imgUrl?: string;
interactivies: { desc: string; response: number }[];
}[]; }[];
}; };
// 卡牌选择弹窗 // 卡牌选择弹窗
......
...@@ -2,14 +2,14 @@ import { ygopro } from "../../api/ocgcore/idl/ocgcore"; ...@@ -2,14 +2,14 @@ import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { AppDispatch } from "../../store"; import { AppDispatch } from "../../store";
import { Interactivity, InteractType } from "../../reducers/duel/generic"; import { Interactivity, InteractType } from "../../reducers/duel/generic";
import { import {
clearHandsIdleInteractivity,
addHandsIdleInteractivity, addHandsIdleInteractivity,
addMonsterIdleInteractivities, addMonsterIdleInteractivities,
addMagicIdleInteractivities, addMagicIdleInteractivities,
clearMonsterIdleInteractivities,
clearMagicIdleInteractivities,
setEnableBp, setEnableBp,
setEnableEp, setEnableEp,
addCemeteryIdleInteractivities,
clearAllIdleInteractivities,
addExclusionIdleInteractivities,
} from "../../reducers/duel/mod"; } from "../../reducers/duel/mod";
import MsgSelectIdleCmd = ygopro.StocGameMessage.MsgSelectIdleCmd; import MsgSelectIdleCmd = ygopro.StocGameMessage.MsgSelectIdleCmd;
import { ActionCreatorWithPayload } from "@reduxjs/toolkit"; import { ActionCreatorWithPayload } from "@reduxjs/toolkit";
...@@ -19,9 +19,7 @@ export default (selectIdleCmd: MsgSelectIdleCmd, dispatch: AppDispatch) => { ...@@ -19,9 +19,7 @@ export default (selectIdleCmd: MsgSelectIdleCmd, dispatch: AppDispatch) => {
const cmds = selectIdleCmd.idle_cmds; const cmds = selectIdleCmd.idle_cmds;
// 先清掉之前的互动性 // 先清掉之前的互动性
dispatch(clearHandsIdleInteractivity(player)); dispatch(clearAllIdleInteractivities(player));
dispatch(clearMonsterIdleInteractivities(player));
dispatch(clearMagicIdleInteractivities(player));
const dispatcher = ( const dispatcher = (
idleData: MsgSelectIdleCmd.IdleCmd.IdleData, idleData: MsgSelectIdleCmd.IdleCmd.IdleData,
...@@ -83,7 +81,18 @@ export default (selectIdleCmd: MsgSelectIdleCmd, dispatch: AppDispatch) => { ...@@ -83,7 +81,18 @@ export default (selectIdleCmd: MsgSelectIdleCmd, dispatch: AppDispatch) => {
break; break;
} }
case ygopro.CardZone.GRAVE: {
dispatcher(data, interactType, addCemeteryIdleInteractivities);
break;
}
case ygopro.CardZone.REMOVED: {
dispatcher(data, interactType, addExclusionIdleInteractivities);
break;
}
default: { default: {
console.log(`Unhandled zone type: ${cardInfo.location}`);
} }
} }
}); });
......
...@@ -5,10 +5,13 @@ import { ...@@ -5,10 +5,13 @@ import {
selectCardListModalIsOpen, selectCardListModalIsOpen,
selectCardListModalInfo, selectCardListModalInfo,
} from "../../reducers/duel/modal/mod"; } from "../../reducers/duel/modal/mod";
import { setCardListModalIsOpen } from "../../reducers/duel/mod"; import {
import { Modal, List, Popover, Card } from "antd"; clearAllIdleInteractivities,
setCardListModalIsOpen,
} from "../../reducers/duel/mod";
import { Modal, List, Button } from "antd";
import { sendSelectIdleCmdResponse } from "../../api/ocgcore/ocgHelper";
const { Meta } = Card;
const CARD_WIDTH = 100; const CARD_WIDTH = 100;
const CardListModal = () => { const CardListModal = () => {
...@@ -26,21 +29,30 @@ const CardListModal = () => { ...@@ -26,21 +29,30 @@ const CardListModal = () => {
itemLayout="horizontal" itemLayout="horizontal"
dataSource={list} dataSource={list}
renderItem={(item) => ( renderItem={(item) => (
<Popover <List.Item
content={ actions={item.interactivies.map((interactivy, idx) => (
<Card <Button
hoverable key={idx}
style={{ width: CARD_WIDTH }} onClick={() => {
cover={<img alt={item.name} src={item.imgUrl} />} sendSelectIdleCmdResponse(interactivy.response);
dispatch(setCardListModalIsOpen(false));
dispatch(clearAllIdleInteractivities(0));
dispatch(clearAllIdleInteractivities(1));
}}
> >
<Meta title={item.name} /> {interactivy.desc}
</Card> </Button>
))}
extra={
<img
alt={item.name}
src={item.imgUrl}
style={{ width: CARD_WIDTH }}
/>
} }
> >
<List.Item> <List.Item.Meta title={item.name} description={item.desc} />
<List.Item.Meta title={item.name} description={item.desc} /> </List.Item>
</List.Item>
</Popover>
)} )}
></List> ></List>
</Modal> </Modal>
......
...@@ -10,7 +10,7 @@ import { ...@@ -10,7 +10,7 @@ import {
} from "../../reducers/duel/modal/mod"; } from "../../reducers/duel/modal/mod";
import { import {
setCardModalIsOpen, setCardModalIsOpen,
clearHandsIdleInteractivity, clearAllIdleInteractivities,
} from "../../reducers/duel/mod"; } from "../../reducers/duel/mod";
import { Modal, Card, Button } from "antd"; import { Modal, Card, Button } from "antd";
import { sendSelectIdleCmdResponse } from "../../api/ocgcore/ocgHelper"; import { sendSelectIdleCmdResponse } from "../../api/ocgcore/ocgHelper";
...@@ -47,7 +47,8 @@ const CardModal = () => { ...@@ -47,7 +47,8 @@ const CardModal = () => {
onClick={() => { onClick={() => {
sendSelectIdleCmdResponse(interactive.response); sendSelectIdleCmdResponse(interactive.response);
dispatch(setCardModalIsOpen(false)); dispatch(setCardModalIsOpen(false));
dispatch(clearHandsIdleInteractivity(0)); dispatch(clearAllIdleInteractivities(0));
dispatch(clearAllIdleInteractivities(1));
}} }}
> >
{interactive.desc} {interactive.desc}
......
...@@ -20,30 +20,34 @@ const Magics = () => { ...@@ -20,30 +20,34 @@ const Magics = () => {
return ( return (
<> <>
{zip(meMagics, meMagicPositions).map(([magic, position], sequence) => { {zip(meMagics, meMagicPositions)
return ( .slice(0, 5)
<FixedSlot .map(([magic, position], sequence) => {
state={magic} return (
key={sequence} <FixedSlot
sequence={sequence} state={magic}
position={position} key={sequence}
rotation={CONFIG.CardSlotRotation(false)} sequence={sequence}
clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities} position={position}
/> rotation={CONFIG.CardSlotRotation(false)}
); clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities}
})} />
{zip(opMagics, opMagicPositions).map(([magic, position], sequence) => { );
return ( })}
<FixedSlot {zip(opMagics, opMagicPositions)
state={magic} .slice(0, 5)
key={sequence} .map(([magic, position], sequence) => {
sequence={sequence} return (
position={position} <FixedSlot
rotation={CONFIG.CardSlotRotation(true)} state={magic}
clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities} key={sequence}
/> sequence={sequence}
); position={position}
})} rotation={CONFIG.CardSlotRotation(true)}
clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities}
/>
);
})}
</> </>
); );
}; };
......
...@@ -23,40 +23,32 @@ const Monsters = () => { ...@@ -23,40 +23,32 @@ const Monsters = () => {
return ( return (
<> <>
{zip(meMonsters, meMonsterPositions).map( {zip(meMonsters, meMonsterPositions)
([monster, position], sequence) => { .slice(0, 5)
return sequence < 5 ? ( .map(([monster, position], sequence) => (
<FixedSlot <FixedSlot
state={monster} state={monster}
key={sequence} key={sequence}
sequence={sequence} sequence={sequence}
position={position} position={position}
rotation={CONFIG.CardSlotRotation(false)} rotation={CONFIG.CardSlotRotation(false)}
deffenseRotation={CONFIG.CardSlotDefenceRotation()} deffenseRotation={CONFIG.CardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities} clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities}
/> />
) : ( ))}
<></> {zip(opMonsters, opMonsterPositions)
); .slice(0, 5)
} .map(([monster, position], sequence) => (
)} <FixedSlot
{zip(opMonsters, opMonsterPositions).map( state={monster}
([monster, position], sequence) => { key={sequence}
return sequence < 5 ? ( sequence={sequence}
<FixedSlot position={position}
state={monster} rotation={CONFIG.CardSlotRotation(true)}
key={sequence} deffenseRotation={CONFIG.CardSlotDefenceRotation()}
sequence={sequence} clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities}
position={position} />
rotation={CONFIG.CardSlotRotation(true)} ))}
deffenseRotation={CONFIG.CardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities}
/>
) : (
<></>
);
}
)}
<ExtraMonsters meMonsters={meMonsters} opMonsters={opMonsters} /> <ExtraMonsters meMonsters={meMonsters} opMonsters={opMonsters} />
</> </>
); );
......
...@@ -8,6 +8,7 @@ import { ...@@ -8,6 +8,7 @@ import {
setCardListModalInfo, setCardListModalInfo,
setCardListModalIsOpen, setCardListModalIsOpen,
} from "../../reducers/duel/mod"; } from "../../reducers/duel/mod";
import { interactTypeToString } from "./util";
const shape = CONFIG.SingleSlotShape; const shape = CONFIG.SingleSlotShape;
export const Depth = 0.005; export const Depth = 0.005;
...@@ -19,6 +20,12 @@ const SingleSlot = (props: { ...@@ -19,6 +20,12 @@ const SingleSlot = (props: {
}) => { }) => {
const boxRef = useRef(null); const boxRef = useRef(null);
const dispatch = store.dispatch; const dispatch = store.dispatch;
const edgeRender =
props.state.find((item) =>
item === undefined ? false : item.idleInteractivities.length > 0
) !== undefined;
const edgesWidth = 2.0;
const edgesColor = BABYLON.Color4.FromColor3(BABYLON.Color3.Yellow());
useClick( useClick(
(_event) => { (_event) => {
...@@ -34,6 +41,12 @@ const SingleSlot = (props: { ...@@ -34,6 +41,12 @@ const SingleSlot = (props: {
name: item.occupant?.text.name, name: item.occupant?.text.name,
desc: item.occupant?.text.desc, desc: item.occupant?.text.desc,
imgUrl: `https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${item.occupant?.id}.jpg`, imgUrl: `https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${item.occupant?.id}.jpg`,
interactivies: item.idleInteractivities.map((interactivy) => {
return {
desc: interactTypeToString(interactivy.interactType),
response: interactivy.response,
};
}),
}; };
}) })
) )
...@@ -58,6 +71,9 @@ const SingleSlot = (props: { ...@@ -58,6 +71,9 @@ const SingleSlot = (props: {
} }
position={props.position} position={props.position}
rotation={props.rotation} rotation={props.rotation}
enableEdgesRendering
edgesWidth={edgeRender ? edgesWidth : 0}
edgesColor={edgesColor}
> >
<standardMaterial <standardMaterial
name="single-slot-mat" name="single-slot-mat"
......
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