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