You need to sign in or sign up before continuing.
Commit 983baaf5 authored by timel's avatar timel Committed by Chunchi Che

feat: mat bg action

parent 4af2045b
...@@ -35,11 +35,9 @@ const root = ReactDOM.createRoot( ...@@ -35,11 +35,9 @@ const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement document.getElementById("root") as HTMLElement
); );
root.render( root.render(
<React.StrictMode> <BrowserRouter>
<BrowserRouter> <ConfigProvider theme={{ algorithm: theme.darkAlgorithm }} locale={zhCN}>
<ConfigProvider theme={{ algorithm: theme.darkAlgorithm }} locale={zhCN}> <Neos />
<Neos /> </ConfigProvider>
</ConfigProvider> </BrowserRouter>
</BrowserRouter>
</React.StrictMode>
); );
...@@ -4,6 +4,7 @@ import { ...@@ -4,6 +4,7 @@ import {
type Interactivity, type Interactivity,
InteractType, InteractType,
matStore, matStore,
cardStore,
} from "@/stores"; } from "@/stores";
import MsgSelectBattleCmd = ygopro.StocGameMessage.MsgSelectBattleCmd; import MsgSelectBattleCmd = ygopro.StocGameMessage.MsgSelectBattleCmd;
...@@ -14,6 +15,9 @@ export default (selectBattleCmd: MsgSelectBattleCmd) => { ...@@ -14,6 +15,9 @@ export default (selectBattleCmd: MsgSelectBattleCmd) => {
// 先清掉之前的互动性 // 先清掉之前的互动性
clearAllIdleInteractivities(player); clearAllIdleInteractivities(player);
cardStore.inner.forEach((card) => {
card.idleInteractivities = [];
});
cmds.forEach((cmd) => { cmds.forEach((cmd) => {
const interactType = battleTypeToInteracType(cmd.battle_type); const interactType = battleTypeToInteracType(cmd.battle_type);
...@@ -38,6 +42,11 @@ export default (selectBattleCmd: MsgSelectBattleCmd) => { ...@@ -38,6 +42,11 @@ export default (selectBattleCmd: MsgSelectBattleCmd) => {
interactType, interactType,
response: data.response, response: data.response,
}); });
cardStore.at(location, player)[sequence].idleInteractivities.push({
...tmp,
interactType,
response: data.response,
});
} else { } else {
console.warn(`Undefined InteractType`); console.warn(`Undefined InteractType`);
} }
......
...@@ -4,6 +4,7 @@ import { ...@@ -4,6 +4,7 @@ import {
type Interactivity, type Interactivity,
InteractType, InteractType,
matStore, matStore,
cardStore,
} from "@/stores"; } from "@/stores";
import MsgSelectIdleCmd = ygopro.StocGameMessage.MsgSelectIdleCmd; import MsgSelectIdleCmd = ygopro.StocGameMessage.MsgSelectIdleCmd;
...@@ -14,6 +15,9 @@ export default (selectIdleCmd: MsgSelectIdleCmd) => { ...@@ -14,6 +15,9 @@ export default (selectIdleCmd: MsgSelectIdleCmd) => {
// 先清掉之前的互动性 // 先清掉之前的互动性
clearAllIdleInteractivities(player); clearAllIdleInteractivities(player);
cardStore.inner.forEach((card) => {
card.idleInteractivities = [];
});
cmds.forEach((cmd) => { cmds.forEach((cmd) => {
const interactType = idleTypeToInteractType(cmd.idle_type); const interactType = idleTypeToInteractType(cmd.idle_type);
...@@ -37,6 +41,11 @@ export default (selectIdleCmd: MsgSelectIdleCmd) => { ...@@ -37,6 +41,11 @@ export default (selectIdleCmd: MsgSelectIdleCmd) => {
interactType, interactType,
response: data.response, response: data.response,
}); });
cardStore.at(location, player)[sequence].idleInteractivities.push({
...tmp,
interactType,
response: data.response,
});
} else { } else {
console.warn(`Undefined InteractType`); console.warn(`Undefined InteractType`);
} }
......
import { ygopro } from "@/api"; import { ygopro } from "@/api";
import { InteractType, matStore } from "@/stores"; import { InteractType, matStore, placeStore } from "@/stores";
type MsgSelectPlace = ygopro.StocGameMessage.MsgSelectPlace; type MsgSelectPlace = ygopro.StocGameMessage.MsgSelectPlace;
...@@ -9,6 +9,22 @@ export default (selectPlace: MsgSelectPlace) => { ...@@ -9,6 +9,22 @@ export default (selectPlace: MsgSelectPlace) => {
return; return;
} }
for (const place of selectPlace.places) {
switch (place.zone) {
case ygopro.CardZone.MZONE:
case ygopro.CardZone.SZONE:
placeStore.set(place.zone, place.controler, place.sequence, {
interactType: InteractType.PLACE_SELECTABLE,
response: {
controler: place.controler,
zone: place.zone,
sequence: place.sequence,
},
});
break;
}
}
for (const place of selectPlace.places) { for (const place of selectPlace.places) {
switch (place.zone) { switch (place.zone) {
case ygopro.CardZone.MZONE: { case ygopro.CardZone.MZONE: {
......
import { CardData, CardText, fetchCard, ygopro } from "@/api"; import { CardData, CardText, fetchCard, ygopro } from "@/api";
import { proxy } from "valtio"; import { proxy } from "valtio";
import { Interactivity } from "./matStore/types"; import type { Interactivity } from "./matStore/types";
/** /**
* 场上某位置的状态, * 场上某位置的状态,
......
...@@ -5,6 +5,7 @@ export * from "./messageStore"; ...@@ -5,6 +5,7 @@ export * from "./messageStore";
export * from "./moraStore"; export * from "./moraStore";
export * from "./playerStore"; export * from "./playerStore";
export * from "./cardStore"; export * from "./cardStore";
export * from "./placeStore";
import { proxy } from "valtio"; import { proxy } from "valtio";
import { devtools } from "valtio/utils"; import { devtools } from "valtio/utils";
...@@ -16,6 +17,7 @@ import { messageStore } from "./messageStore"; ...@@ -16,6 +17,7 @@ import { messageStore } from "./messageStore";
import { moraStore } from "./moraStore"; import { moraStore } from "./moraStore";
import { playerStore } from "./playerStore"; import { playerStore } from "./playerStore";
import { cardStore } from "./cardStore"; import { cardStore } from "./cardStore";
import { placeStore } from "./placeStore";
export const store = proxy({ export const store = proxy({
playerStore, playerStore,
...@@ -25,6 +27,7 @@ export const store = proxy({ ...@@ -25,6 +27,7 @@ export const store = proxy({
matStore, // 决斗盘 matStore, // 决斗盘
messageStore, // 决斗的信息,包括模态框 messageStore, // 决斗的信息,包括模态框
cardStore, cardStore,
placeStore,
}); });
devtools(store, { name: "valtio store", enabled: true }); devtools(store, { name: "valtio store", enabled: true });
import { ygopro } from "@/api";
import { proxy } from "valtio";
import type { Interactivity } from "./matStore/types";
import { matStore } from "@/stores";
export type PlaceInteractivity =
| Interactivity<{
controler: number;
zone: ygopro.CardZone;
sequence: number;
}>
| undefined;
const { MZONE, SZONE } = ygopro.CardZone;
export const placeStore = proxy({
inner: {
[MZONE]: {
me: Array.from({ length: 7 }).map(() => undefined as PlaceInteractivity),
op: Array.from({ length: 7 }).map(() => undefined as PlaceInteractivity),
},
[SZONE]: {
me: Array.from({ length: 6 }).map(() => undefined as PlaceInteractivity),
op: Array.from({ length: 6 }).map(() => undefined as PlaceInteractivity),
},
},
set(
zone: ygopro.CardZone.MZONE | ygopro.CardZone.SZONE,
controller: number,
sequence: number,
placeInteractivity: PlaceInteractivity
) {
placeStore.inner[zone][matStore.isMe(controller) ? "me" : "op"][sequence] =
placeInteractivity;
},
clearAll() {
placeStore.inner[MZONE].me = placeStore.inner[MZONE].me.map(
() => undefined
);
placeStore.inner[MZONE].op = placeStore.inner[MZONE].op.map(
() => undefined
);
placeStore.inner[SZONE].me = placeStore.inner[SZONE].me.map(
() => undefined
);
placeStore.inner[SZONE].op = placeStore.inner[SZONE].op.map(
() => undefined
);
},
});
...@@ -9,6 +9,9 @@ section#mat { ...@@ -9,6 +9,9 @@ section#mat {
.bg-row { .bg-row {
display: flex; display: flex;
column-gap: var(--col-gap); column-gap: var(--col-gap);
&.opponent {
flex-direction: row-reverse;
}
} }
} }
...@@ -23,5 +26,9 @@ section#mat { ...@@ -23,5 +26,9 @@ section#mat {
&.szone { &.szone {
height: var(--block-height-s); height: var(--block-height-s);
} }
&.highlight {
box-shadow: 0 0 0 1px #00b0ff, 0 0 13px 0px #0077ff,
0 0 11px 0 skyblue inset;
}
} }
} }
import { type FC } from "react"; import { type FC } from "react";
import classnames from "classnames"; import classnames from "classnames";
import "./index.scss"; import "./index.scss";
import {
placeStore,
type PlaceInteractivity,
messageStore,
CardType,
cardStore,
} from "@/stores";
import { useSnapshot, type INTERNAL_Snapshot as Snapshot } from "valtio";
import { sendSelectPlaceResponse, ygopro } from "@/api";
import { interactTypeToString } from "../../utils";
const BgRow: FC<{ isExtra?: boolean; isSzone?: boolean }> = ({ const BgExtraRow: FC = () => {
isExtra = false, return (
isSzone = false, <div className={classnames("bg-row")}>
}) => ( {Array.from({ length: 2 }).map((_, i) => (
<div className={classnames("bg-row")}> <div key={i} className={classnames("block", "extra")}></div>
{Array.from({ length: isExtra ? 2 : 5 }).map((_, i) => ( ))}
</div>
);
};
const BgRow: FC<{
isSzone?: boolean;
opponent?: boolean;
snap: Snapshot<PlaceInteractivity[]>;
}> = ({ isSzone = false, opponent = false, snap }) => (
<div className={classnames("bg-row", { opponent })}>
{Array.from({ length: 5 }).map((_, i) => (
<div <div
key={i} key={i}
className={classnames("block", { extra: isExtra }, { szone: isSzone })} className={classnames("block", {
szone: isSzone,
highlight: !!snap[i],
})}
onClick={() => onBlockClick(snap[i])}
></div> ></div>
))} ))}
</div> </div>
); );
export const Bg: FC = () => { export const Bg: FC = () => {
const snap = useSnapshot(placeStore.inner);
return ( return (
<div className="mat-bg"> <div className="mat-bg">
<BgRow isSzone /> <BgRow snap={snap[ygopro.CardZone.SZONE].op} isSzone opponent />
<BgRow /> <BgRow snap={snap[ygopro.CardZone.MZONE].op} opponent />
<BgRow isExtra /> <BgExtraRow />
<BgRow /> <BgRow snap={snap[ygopro.CardZone.MZONE].me} />
<BgRow isSzone /> <BgRow snap={snap[ygopro.CardZone.SZONE].me} isSzone />
</div> </div>
); );
}; };
const onBlockClick = (placeInteractivity: PlaceInteractivity) => {
if (placeInteractivity) {
sendSelectPlaceResponse(placeInteractivity.response);
cardStore.inner.forEach((card) => (card.idleInteractivities = []));
placeStore.clearAll();
}
};
...@@ -12,7 +12,7 @@ section#mat { ...@@ -12,7 +12,7 @@ section#mat {
position: relative; position: relative;
height: 100%; height: 100%;
width: 100%; width: 100%;
transform: translateZ(calc(var(--z) * 1px)) transform: translateZ(calc(var(--z) * 1px + 0.1px))
rotateY(calc(var(--ry) * 1deg)); rotateY(calc(var(--ry) * 1deg));
.card-cover, .card-cover,
.card-back { .card-back {
...@@ -31,5 +31,18 @@ section#mat { ...@@ -31,5 +31,18 @@ section#mat {
transform: translateZ(0px); transform: translateZ(0px);
} }
} }
.card-shadow {
// position: absolute;
// left: 0;
// top: 0;
// width: 100%;
// height: 100%;
// background-color: #0000005e;
// filter: blur(2px);
}
} }
} }
.highlight {
box-shadow: 0 0 10px 2px #5db7ff;
}
import React, { useEffect, type CSSProperties, type FC } from "react"; import React, { useEffect, type CSSProperties, type FC, useState } from "react";
import { cardStore, messageStore, CardType } from "@/stores"; import { cardStore, messageStore, CardType } from "@/stores";
import "./index.scss"; import "./index.scss";
import { useSnapshot } from "valtio"; import { useSnapshot } from "valtio";
...@@ -6,9 +6,10 @@ import { watch } from "valtio/utils"; ...@@ -6,9 +6,10 @@ import { watch } from "valtio/utils";
import { useSpring, animated, to } from "@react-spring/web"; import { useSpring, animated, to } from "@react-spring/web";
import { ygopro } from "@/api"; import { ygopro } from "@/api";
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { moveToDeck, moveToField, moveToHand, moveToOutside } from "./springs"; import { moveToDeck, moveToGround, moveToHand, moveToOutside } from "./springs";
import { ReportEnum } from "./springs/types"; import { ReportEnum } from "./springs/types";
import { interactTypeToString } from "../../utils"; import { interactTypeToString } from "../../utils";
import classnames from "classnames";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
...@@ -35,7 +36,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => { ...@@ -35,7 +36,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
case MZONE: case MZONE:
case SZONE: case SZONE:
case OVERLAY: case OVERLAY:
moveToField({ card: state, api, report }); moveToGround({ card: state, api, report });
break; break;
case HAND: case HAND:
moveToHand({ card: state, api, report }); moveToHand({ card: state, api, report });
...@@ -54,16 +55,28 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => { ...@@ -54,16 +55,28 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
reload(state.zone, false); reload(state.zone, false);
}, []); }, []);
const [highlight, setHighlight] = useState(false);
const [shadowOpacity, setShadowOpacity] = useState(0);
watch((get) => { watch((get) => {
const { zone, sequence, controller, xyzMonster } = get(state); const { zone, sequence, controller, xyzMonster, idleInteractivities } =
get(state);
reload(zone, true); reload(zone, true);
}); });
useEffect(() => {
setHighlight(!!snap.idleInteractivities.length);
}, [snap.idleInteractivities]);
// 在别的手卡更改时候,刷新这张手卡 // 在别的手卡更改时候,刷新这张手卡
eventBus.on( eventBus.on(
ReportEnum.ReloadHand, ReportEnum.ReloadHand,
({ sequence, controller }: { sequence: number; controller: number }) => { ({ sequence, controller }: { sequence: number; controller: number }) => {
if (state.sequence !== sequence && state.controller === controller) { if (
state.zone === HAND &&
state.sequence !== sequence &&
state.controller === controller
) {
reload(state.zone, false); reload(state.zone, false);
} }
} }
...@@ -71,7 +84,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => { ...@@ -71,7 +84,7 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
return ( return (
<animated.div <animated.div
className="mat-card" className={classnames("mat-card", { highlight })}
style={ style={
{ {
transform: to( transform: to(
...@@ -82,17 +95,20 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => { ...@@ -82,17 +95,20 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
"--z": styles.z, "--z": styles.z,
"--ry": styles.ry, "--ry": styles.ry,
height: styles.height, height: styles.height,
zIndex: styles.zIndex,
} as any as CSSProperties } as any as CSSProperties
} }
onClick={() => onClick={() => {
[MZONE, SZONE, HAND].includes(state.zone) && onCardClick(state) if ([MZONE, SZONE, HAND].includes(state.zone)) {
} onCardClick(state);
}
}}
> >
<div className="card-shadow" />
<div className="card-img-wrap"> <div className="card-img-wrap">
<img className="card-cover" src={getCardImgUrl(snap.code)} alt="" /> <img className="card-cover" src={getCardImgUrl(snap.code)} alt="" />
<img className="card-back" src={getCardImgUrl(0, true)} alt="" /> <img className="card-back" src={getCardImgUrl(0, true)} alt="" />
</div> </div>
<div className="card-shadow" />
</animated.div> </animated.div>
); );
}); });
...@@ -108,7 +124,7 @@ function getCardImgUrl(code: number, back = false) { ...@@ -108,7 +124,7 @@ function getCardImgUrl(code: number, back = false) {
return NeosConfig.cardImgUrl + "/" + code + ".jpg"; return NeosConfig.cardImgUrl + "/" + code + ".jpg";
} }
const onCardClick = (card: CardType) => () => { const onCardClick = (card: CardType) => {
// 中央弹窗展示选中卡牌信息 // 中央弹窗展示选中卡牌信息
messageStore.cardModal.meta = { messageStore.cardModal.meta = {
id: card.code, id: card.code,
......
export * from "./toField"; export * from "./toGround";
export * from "./toHand"; export * from "./toHand";
export * from "./toDeck"; export * from "./toDeck";
export * from "./toOutside"; export * from "./toOutside";
...@@ -48,16 +48,15 @@ export const moveToDeck = async (props: { ...@@ -48,16 +48,15 @@ export const moveToDeck = async (props: {
if (zone === EXTRA) { if (zone === EXTRA) {
x = isMe(controller) ? leftX : rightX; x = isMe(controller) ? leftX : rightX;
} }
let rz = isMe(controller) ? 180 - DECK_ROTATE_Z.value : -DECK_ROTATE_Z.value; let rz = zone === EXTRA ? DECK_ROTATE_Z.value : -DECK_ROTATE_Z.value;
if (zone === EXTRA) { rz += isMe(controller) ? 0 : 180;
rz = isMe(controller) ? DECK_ROTATE_Z.value : DECK_ROTATE_Z.value;
}
const z = sequence; const z = sequence;
api.start({ api.start({
x, x,
y, y,
z, z,
rz, rz,
ry: isMe(controller) ? (zone === DECK ? 180 : 0) : 180,
zIndex: z, zIndex: z,
height: DECK_CARD_HEIGHT.value, height: DECK_CARD_HEIGHT.value,
}); });
......
...@@ -24,7 +24,7 @@ const { ...@@ -24,7 +24,7 @@ const {
const { HAND, GRAVE, REMOVED, DECK, EXTRA, MZONE, SZONE, TZONE, OVERLAY } = const { HAND, GRAVE, REMOVED, DECK, EXTRA, MZONE, SZONE, TZONE, OVERLAY } =
ygopro.CardZone; ygopro.CardZone;
export const moveToField = async (props: { export const moveToGround = async (props: {
card: CardType; card: CardType;
api: SpringApi; api: SpringApi;
report: boolean; report: boolean;
...@@ -40,7 +40,7 @@ export const moveToField = async (props: { ...@@ -40,7 +40,7 @@ export const moveToField = async (props: {
? BLOCK_HEIGHT_S.value * CARD_RATIO.value ? BLOCK_HEIGHT_S.value * CARD_RATIO.value
: BLOCK_HEIGHT_M.value * CARD_RATIO.value; : BLOCK_HEIGHT_M.value * CARD_RATIO.value;
const height = zone === SZONE ? BLOCK_HEIGHT_S.value : BLOCK_HEIGHT_M.value; let height = zone === SZONE ? BLOCK_HEIGHT_S.value : BLOCK_HEIGHT_M.value;
// 首先计算 x 和 y // 首先计算 x 和 y
let x = 0, let x = 0,
...@@ -94,6 +94,17 @@ export const moveToField = async (props: { ...@@ -94,6 +94,17 @@ export const moveToField = async (props: {
y = -y; y = -y;
} }
// 判断是不是防御表示
const defence = [
ygopro.CardPosition.DEFENSE,
ygopro.CardPosition.FACEDOWN_DEFENSE,
ygopro.CardPosition.FACEUP_DEFENSE,
].includes(position ?? 5);
height = defence ? BLOCK_WIDTH.value : height;
let rz = isMe(controller) ? 0 : 180;
rz += defence ? 90 : 0;
// 动画
await asyncStart(api)({ await asyncStart(api)({
x, x,
y, y,
...@@ -106,17 +117,17 @@ export const moveToField = async (props: { ...@@ -106,17 +117,17 @@ export const moveToField = async (props: {
].includes(position ?? 5) ].includes(position ?? 5)
? 180 ? 180
: 0, : 0,
rz: isMe(controller) ? 0 : 180, rz,
config: { config: {
// mass: 0.5, // mass: 0.5,
easing: easings.easeOutSine, easing: easings.easeInSine,
}, },
}); });
await asyncStart(api)({ await asyncStart(api)({
z: 0, z: 0,
zIndex: overlayMaterials.length ? 3 : 1, zIndex: overlayMaterials.length ? 3 : 1,
config: { config: {
easing: easings.easeInSine, easing: easings.easeOutSine,
mass: 5, mass: 5,
tension: 300, // 170 tension: 300, // 170
friction: 12, // 26 friction: 12, // 26
......
...@@ -70,8 +70,11 @@ export const moveToHand = async (props: { ...@@ -70,8 +70,11 @@ export const moveToHand = async (props: {
api.start({ api.start({
x: isMe(controller) ? x : -x, x: isMe(controller) ? x : -x,
y: isMe(controller) ? y : -y, y: isMe(controller) ? y : -y,
z: 0,
rz: isMe(controller) ? _rz : 180 - _rz, rz: isMe(controller) ? _rz : 180 - _rz,
ry: isMe(controller) ? 0 : 180,
height: HAND_CARD_HEIGHT.value, height: HAND_CARD_HEIGHT.value,
zIndex: sequence,
// rx: -PLANE_ROTATE_X.value, // rx: -PLANE_ROTATE_X.value,
}); });
}; };
...@@ -34,14 +34,8 @@ export const moveToOutside = async (props: { ...@@ -34,14 +34,8 @@ export const moveToOutside = async (props: {
const { zone, sequence, controller, xyzMonster, position, overlayMaterials } = const { zone, sequence, controller, xyzMonster, position, overlayMaterials } =
card; card;
let x = 0, let x = (BLOCK_WIDTH.value + COL_GAP.value) * 3,
y = 0; y = zone === GRAVE ? BLOCK_HEIGHT_M.value + ROW_GAP.value : 0;
if (zone === GRAVE) {
x = (BLOCK_WIDTH.value + COL_GAP.value) * 3;
y = BLOCK_HEIGHT_M.value + ROW_GAP.value;
} else if (zone === REMOVED) {
x = (BLOCK_WIDTH.value + COL_GAP.value) * 2;
}
if (!isMe(controller)) { if (!isMe(controller)) {
x = -x; x = -x;
y = -y; y = -y;
...@@ -50,6 +44,7 @@ export const moveToOutside = async (props: { ...@@ -50,6 +44,7 @@ export const moveToOutside = async (props: {
x, x,
y, y,
z: 0, z: 0,
height: BLOCK_HEIGHT_S.value,
rz: isMe(controller) ? 0 : 180, rz: isMe(controller) ? 0 : 180,
}); });
}; };
...@@ -21,10 +21,8 @@ section#mat { ...@@ -21,10 +21,8 @@ section#mat {
.mat-card-container { .mat-card-container {
position: absolute; position: absolute;
top: 0; top: 50%;
left: 0; left: 50%;
width: 100%;
height: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
......
import "@/styles/mat.css"; import "@/styles/mat.css";
import Icon from "@ant-design/icons";
import { Button, Modal } from "antd"; import { Button, Modal } from "antd";
import { ReactComponent as BattleSvg } from "neos-assets/crossed-swords.svg";
import { ReactComponent as EpSvg } from "neos-assets/power-button.svg";
import { ReactComponent as Main2Svg } from "neos-assets/sword-in-stone.svg";
import { ReactComponent as SurrenderSvg } from "neos-assets/truce.svg";
import React, { useState } from "react"; import React, { useState } from "react";
import { useSnapshot } from "valtio"; import { useSnapshot } from "valtio";
import { import {
fetchStrings,
sendSelectBattleCmdResponse, sendSelectBattleCmdResponse,
sendSelectIdleCmdResponse, sendSelectIdleCmdResponse,
sendSurrender, sendSurrender,
ygopro,
} from "@/api"; } from "@/api";
import { import {
clearAllIdleInteractivities as clearAllIdleInteractivities, clearAllIdleInteractivities as clearAllIdleInteractivities,
matStore, matStore,
} from "@/stores"; } from "@/stores";
import PhaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType;
const IconSize = "150%";
const PhaseButton = (props: {
text: string;
enable: boolean;
onClick: () => void;
icon?: React.ReactNode;
}) => {
return (
<Button
icon={props.icon}
disabled={!props.enable}
onClick={props.onClick}
size="large"
>
{props.text}
</Button>
);
};
const { phase } = matStore; const { phase } = matStore;
...@@ -51,30 +29,30 @@ export const Menu = () => { ...@@ -51,30 +29,30 @@ export const Menu = () => {
const [modalOpen, setModalOpen] = useState(false); const [modalOpen, setModalOpen] = useState(false);
const response = const response =
currentPhase === "BATTLE_START" || currentPhase === PhaseType.BATTLE_START ||
currentPhase === "BATTLE_STEP" || currentPhase === PhaseType.BATTLE_STEP ||
currentPhase === "DAMAGE" || currentPhase === PhaseType.DAMAGE ||
currentPhase === "DAMAGE_GAL" || currentPhase === PhaseType.DAMAGE_GAL ||
currentPhase === "BATTLE" currentPhase === PhaseType.BATTLE
? 3 ? 3
: 7; : 7;
const onBp = () => { const onBp = () => {
sendSelectIdleCmdResponse(6); sendSelectIdleCmdResponse(6);
clearAllIdleInteractivities(0); // 为什么要clear两次?
clearAllIdleInteractivities(0); clearAllIdleInteractivities(0);
clearAllIdleInteractivities(1);
phase.enableBp = false; phase.enableBp = false;
}; };
const onM2 = () => { const onM2 = () => {
sendSelectBattleCmdResponse(2); sendSelectBattleCmdResponse(2);
clearAllIdleInteractivities(0); clearAllIdleInteractivities(0);
clearAllIdleInteractivities(0); clearAllIdleInteractivities(1);
phase.enableM2 = false; phase.enableM2 = false;
}; };
const onEp = () => { const onEp = () => {
sendSelectIdleCmdResponse(response); sendSelectIdleCmdResponse(response);
clearAllIdleInteractivities(0); clearAllIdleInteractivities(0);
clearAllIdleInteractivities(0); clearAllIdleInteractivities(1);
phase.enableEp = false; phase.enableEp = false;
}; };
const onSurrender = () => { const onSurrender = () => {
...@@ -83,30 +61,16 @@ export const Menu = () => { ...@@ -83,30 +61,16 @@ export const Menu = () => {
return ( return (
<div id="controller"> <div id="controller">
<PhaseButton <button disabled={!enableBp} onClick={onBp}>
icon={<Icon component={BattleSvg} style={{ fontSize: IconSize }} />} {fetchStrings("!system", 80)}
enable={enableBp} </button>
text="战斗阶段" <button disabled={!enableM2} onClick={onM2}>
onClick={onBp} 进入主要阶段2
/> </button>
<PhaseButton <button disabled={!enableEp} onClick={onEp}>
icon={<Icon component={Main2Svg} style={{ fontSize: IconSize }} />} {fetchStrings("!system", 81)}
enable={enableM2} </button>
text="主要阶段2" <button onClick={onSurrender}>{fetchStrings("!system", 1351)}</button>
onClick={onM2}
/>
<PhaseButton
icon={<Icon component={EpSvg} style={{ fontSize: IconSize }} />}
enable={enableEp}
text="结束回合"
onClick={onEp}
/>
<PhaseButton
icon={<Icon component={SurrenderSvg} style={{ fontSize: IconSize }} />}
enable={true}
text="投降"
onClick={onSurrender}
/>
<Modal <Modal
title="是否确认要投降?" title="是否确认要投降?"
open={modalOpen} open={modalOpen}
......
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