Commit 67d5bd0d authored by timel's avatar timel

feat: valtio store logic 100%, ui/mat

parent 0ee5f4d1
Pipeline #21363 passed with stages
in 15 minutes and 54 seconds
...@@ -10,3 +10,10 @@ interface ImportMetaEnv { ...@@ -10,3 +10,10 @@ interface ImportMetaEnv {
interface ImportMeta { interface ImportMeta {
readonly env: ImportMetaEnv; readonly env: ImportMetaEnv;
} }
// 重新声明useSnapshot,暂时先这么写。原版的会把所有的改成readonly,引发一些棘手的类型报错。
import "valtio/react";
declare module "valtio/react" {
export declare function useSnapshot<T extends object>(proxyObject: T): T;
export {};
}
...@@ -16,6 +16,7 @@ import { store } from "@/store"; ...@@ -16,6 +16,7 @@ import { store } from "@/store";
import { import {
messageStore, messageStore,
matStore,
clearAllIdleInteractivities as FIXME_clearAllIdleInteractivities, clearAllIdleInteractivities as FIXME_clearAllIdleInteractivities,
} from "@/valtioStores"; } from "@/valtioStores";
import { useSnapshot } from "valtio"; import { useSnapshot } from "valtio";
...@@ -44,7 +45,6 @@ export const CardListModal = () => { ...@@ -44,7 +45,6 @@ export const CardListModal = () => {
<Drawer open={isOpen} onClose={handleOkOrCancel}> <Drawer open={isOpen} onClose={handleOkOrCancel}>
<List <List
itemLayout="horizontal" itemLayout="horizontal"
// @ts-ignore 报错是因为类型不可变,实际上是没问题的
dataSource={list} dataSource={list}
renderItem={(item) => ( renderItem={(item) => (
<List.Item <List.Item
......
...@@ -10,20 +10,27 @@ import { ...@@ -10,20 +10,27 @@ import {
import { cardSlotRotation } from "../utils"; import { cardSlotRotation } from "../utils";
import { Depth, SingleSlot } from "./SingleSlot"; import { Depth, SingleSlot } from "./SingleSlot";
import { matStore } from "@/valtioStores";
import { useSnapshot } from "valtio";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
export const BanishedZone = () => { export const BanishedZone = () => {
const meBanishedZone = useAppSelector(selectMeBanishedZone).inner; // const meBanishedZone = useAppSelector(selectMeBanishedZone).inner;
const opBanishedZone = useAppSelector(selectOpBanishedZone).inner; // const opBanishedZone = useAppSelector(selectOpBanishedZone).inner;
const meBanishedZone = useSnapshot(matStore.banishedZones.me);
const opBanishedZone = useSnapshot(matStore.banishedZones.op);
return ( return (
<> <>
<SingleSlot <SingleSlot
state={meBanishedZone} // 因为singleSlot里面会有snap,所以这儿可以直接传入store
state={matStore.banishedZones.me}
position={banishedZonePosition(0, meBanishedZone.length)} position={banishedZonePosition(0, meBanishedZone.length)}
rotation={cardSlotRotation(false)} rotation={cardSlotRotation(false)}
/> />
<SingleSlot <SingleSlot
state={opBanishedZone} state={matStore.banishedZones.op}
position={banishedZonePosition(1, opBanishedZone.length)} position={banishedZonePosition(1, opBanishedZone.length)}
rotation={cardSlotRotation(true)} rotation={cardSlotRotation(true)}
/> />
......
...@@ -8,19 +8,26 @@ import { cardSlotRotation } from "../utils"; ...@@ -8,19 +8,26 @@ import { cardSlotRotation } from "../utils";
import { Depth, SingleSlot } from "./SingleSlot"; import { Depth, SingleSlot } from "./SingleSlot";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
import { matStore } from "@/valtioStores";
import { useSnapshot } from "valtio";
export const CommonDeck = () => { export const CommonDeck = () => {
const meDeck = useAppSelector(selectMeDeck).inner; // const meDeck = useAppSelector(selectMeDeck).inner;
const opDeck = useAppSelector(selectOpDeck).inner; // const opDeck = useAppSelector(selectOpDeck).inner;
const meDeck = useSnapshot(matStore.decks.me);
const opDeck = useSnapshot(matStore.decks.op);
return ( return (
<> <>
<SingleSlot <SingleSlot
state={meDeck} state={matStore.decks.me}
position={deckPosition(0, meDeck.length)} position={deckPosition(0, meDeck.length)}
rotation={cardSlotRotation(false)} rotation={cardSlotRotation(false)}
/> />
<SingleSlot <SingleSlot
state={opDeck} state={matStore.decks.op}
position={deckPosition(1, opDeck.length)} position={deckPosition(1, opDeck.length)}
rotation={cardSlotRotation(true)} rotation={cardSlotRotation(true)}
/> />
......
...@@ -12,19 +12,24 @@ import { Depth, SingleSlot } from "./SingleSlot"; ...@@ -12,19 +12,24 @@ import { Depth, SingleSlot } from "./SingleSlot";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
import { matStore } from "@/valtioStores";
import { useSnapshot } from "valtio";
export const ExtraDeck = () => { export const ExtraDeck = () => {
const meExtraDeck = useAppSelector(selectMeExtraDeck).inner; // const meExtraDeck = useAppSelector(selectMeExtraDeck).inner;
const opExtraDeck = useAppSelector(selectOpExtraDeck).inner; // const opExtraDeck = useAppSelector(selectOpExtraDeck).inner;
const meExtraDeck = useSnapshot(matStore.extraDecks.me);
const opExtraDeck = useSnapshot(matStore.extraDecks.op);
return ( return (
<> <>
<SingleSlot <SingleSlot
state={meExtraDeck} state={matStore.extraDecks.me}
position={extraDeckPosition(0, meExtraDeck.length)} position={extraDeckPosition(0, meExtraDeck.length)}
rotation={cardSlotRotation(false)} rotation={cardSlotRotation(false)}
/> />
<SingleSlot <SingleSlot
state={opExtraDeck} state={matStore.extraDecks.op}
position={extraDeckPosition(1, opExtraDeck.length)} position={extraDeckPosition(1, opExtraDeck.length)}
rotation={cardSlotRotation(true)} rotation={cardSlotRotation(true)}
/> />
......
...@@ -10,34 +10,47 @@ import { FixedSlot } from "./FixedSlot"; ...@@ -10,34 +10,47 @@ import { FixedSlot } from "./FixedSlot";
import { Depth } from "./SingleSlot"; import { Depth } from "./SingleSlot";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
import { matStore, clearAllPlaceInteradtivities } from "@/valtioStores";
import { useSnapshot } from "valtio";
export const Field = () => { export const Field = () => {
const meField = useAppSelector(selectMeMagics).inner.find( // const meField = useAppSelector(selectMeMagics).inner.find(
(_, sequence) => sequence == 5 // (_, sequence) => sequence == 5
); // );
const opField = useAppSelector(selectOpMagics).inner.find( // const opField = useAppSelector(selectOpMagics).inner.find(
(_, sequence) => sequence == 5 // (_, sequence) => sequence == 5
); // );
// 这儿的find可能是出于某种考虑,以后再深思
const meField = useSnapshot(matStore.magics.me[5]);
const opField = useSnapshot(matStore.magics.op[5]);
const clearPlaceInteractivitiesAction = (controller: number) =>
matStore.magics.of(controller).clearPlaceInteractivity();
return ( return (
<> <>
{meField ? ( {meField ? (
<FixedSlot <FixedSlot
state={meField} snapState={meField}
sequence={0} sequence={0}
position={fieldPosition(0)} position={fieldPosition(0)}
rotation={cardSlotRotation(false)} rotation={cardSlotRotation(false)}
clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities} // clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/> />
) : ( ) : (
<></> <></>
)} )}
{opField ? ( {opField ? (
<FixedSlot <FixedSlot
state={opField} snapState={opField}
sequence={0} sequence={0}
position={fieldPosition(1)} position={fieldPosition(1)}
rotation={cardSlotRotation(true)} rotation={cardSlotRotation(true)}
clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities} // clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/> />
) : ( ) : (
<></> <></>
......
...@@ -18,6 +18,9 @@ import { ...@@ -18,6 +18,9 @@ import {
import { store } from "@/store"; import { store } from "@/store";
import { interactTypeToString } from "../utils"; import { interactTypeToString } from "../utils";
import { useSnapshot } from "valtio";
import { clearAllIdleInteractivities } from "@/valtioStores";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
...@@ -30,19 +33,22 @@ const cardDefenceRotation = new BABYLON.Vector3( ...@@ -30,19 +33,22 @@ const cardDefenceRotation = new BABYLON.Vector3(
); );
export const FixedSlot = (props: { export const FixedSlot = (props: {
state: CardState; snapState: CardState;
sequence: number; sequence: number;
position: BABYLON.Vector3; position: BABYLON.Vector3;
rotation: BABYLON.Vector3; rotation: BABYLON.Vector3;
deffenseRotation?: BABYLON.Vector3; deffenseRotation?: BABYLON.Vector3;
clearPlaceInteractivitiesAction: ActionCreatorWithPayload<number, string>; // clearPlaceInteractivitiesAction: ActionCreatorWithPayload<number, string>;
clearPlaceInteractivitiesAction: (controller: number) => void;
}) => { }) => {
const planeRef = useRef(null); const planeRef = useRef(null);
// const snapState = useSnapshot(props.state);
const snapState = props.snapState;
const rotation = const rotation =
props.state.location.position === ygopro.CardPosition.DEFENSE || snapState.location.position === ygopro.CardPosition.DEFENSE ||
props.state.location.position === ygopro.CardPosition.FACEUP_DEFENSE || snapState.location.position === ygopro.CardPosition.FACEUP_DEFENSE ||
props.state.location.position === ygopro.CardPosition.FACEDOWN_DEFENSE snapState.location.position === ygopro.CardPosition.FACEDOWN_DEFENSE
? props.deffenseRotation || cardDefenceRotation ? props.deffenseRotation || cardDefenceRotation
: props.rotation; : props.rotation;
const edgesWidth = 2.0; const edgesWidth = 2.0;
...@@ -50,22 +56,24 @@ export const FixedSlot = (props: { ...@@ -50,22 +56,24 @@ export const FixedSlot = (props: {
const dispatch = store.dispatch; const dispatch = store.dispatch;
const faceDown = const faceDown =
props.state.location.position === ygopro.CardPosition.FACEDOWN_DEFENSE || snapState.location.position === ygopro.CardPosition.FACEDOWN_DEFENSE ||
props.state.location.position === ygopro.CardPosition.FACEDOWN_ATTACK || snapState.location.position === ygopro.CardPosition.FACEDOWN_ATTACK ||
props.state.location.position === ygopro.CardPosition.FACEDOWN; snapState.location.position === ygopro.CardPosition.FACEDOWN;
useClick( useClick(
(_event) => { (_event) => {
if (props.state.placeInteractivities) { if (snapState.placeInteractivities) {
sendSelectPlaceResponse(props.state.placeInteractivities.response); sendSelectPlaceResponse(snapState.placeInteractivities.response);
dispatch(props.clearPlaceInteractivitiesAction(0)); // dispatch(props.clearPlaceInteractivitiesAction(0));
dispatch(props.clearPlaceInteractivitiesAction(1)); // dispatch(props.clearPlaceInteractivitiesAction(1));
} else if (props.state.occupant) { clearAllIdleInteractivities(0);
clearAllIdleInteractivities(1);
} else if (snapState.occupant) {
// 中央弹窗展示选中卡牌信息 // 中央弹窗展示选中卡牌信息
dispatch(setCardModalMeta(props.state.occupant)); dispatch(setCardModalMeta(snapState.occupant));
dispatch( dispatch(
setCardModalInteractivies( setCardModalInteractivies(
props.state.idleInteractivities.map((interactivity) => { snapState.idleInteractivities.map((interactivity) => {
return { return {
desc: interactTypeToString(interactivity.interactType), desc: interactTypeToString(interactivity.interactType),
response: interactivity.response, response: interactivity.response,
...@@ -73,17 +81,17 @@ export const FixedSlot = (props: { ...@@ -73,17 +81,17 @@ export const FixedSlot = (props: {
}) })
) )
); );
dispatch(setCardModalCounters(props.state.counters)); dispatch(setCardModalCounters(snapState.counters));
dispatch(setCardModalIsOpen(true)); dispatch(setCardModalIsOpen(true));
// 侧边栏展示超量素材信息 // 侧边栏展示超量素材信息
if ( if (
props.state.overlay_materials && snapState.overlay_materials &&
props.state.overlay_materials.length > 0 snapState.overlay_materials.length > 0
) { ) {
dispatch( dispatch(
setCardListModalInfo( setCardListModalInfo(
props.state.overlay_materials?.map((overlay) => { snapState.overlay_materials?.map((overlay) => {
return { return {
meta: overlay, meta: overlay,
interactivies: [], interactivies: [],
...@@ -96,7 +104,7 @@ export const FixedSlot = (props: { ...@@ -96,7 +104,7 @@ export const FixedSlot = (props: {
} }
}, },
planeRef, planeRef,
[props.state] [snapState]
); );
return ( return (
...@@ -109,8 +117,8 @@ export const FixedSlot = (props: { ...@@ -109,8 +117,8 @@ export const FixedSlot = (props: {
rotation={rotation} rotation={rotation}
enableEdgesRendering enableEdgesRendering
edgesWidth={ edgesWidth={
props.state.placeInteractivities || snapState.placeInteractivities ||
props.state.idleInteractivities.length > 0 snapState.idleInteractivities.length > 0
? edgesWidth ? edgesWidth
: 0 : 0
} }
...@@ -119,15 +127,15 @@ export const FixedSlot = (props: { ...@@ -119,15 +127,15 @@ export const FixedSlot = (props: {
<standardMaterial <standardMaterial
name={`fixedslot-mat-${props.sequence}`} name={`fixedslot-mat-${props.sequence}`}
diffuseTexture={ diffuseTexture={
props.state.occupant snapState.occupant
? faceDown ? faceDown
? new BABYLON.Texture(`${NeosConfig.assetsPath}/card_back.jpg`) ? new BABYLON.Texture(`${NeosConfig.assetsPath}/card_back.jpg`)
: new BABYLON.Texture( : new BABYLON.Texture(
`${NeosConfig.cardImgUrl}/${props.state.occupant.id}.jpg` `${NeosConfig.cardImgUrl}/${snapState.occupant.id}.jpg`
) )
: new BABYLON.Texture(`${NeosConfig.assetsPath}/card_slot.png`) : new BABYLON.Texture(`${NeosConfig.assetsPath}/card_slot.png`)
} }
alpha={props.state.occupant ? 1 : 0} alpha={snapState.occupant ? 1 : 0}
></standardMaterial> ></standardMaterial>
</plane> </plane>
); );
......
...@@ -10,20 +10,26 @@ import { ...@@ -10,20 +10,26 @@ import {
import { cardSlotRotation } from "../utils"; import { cardSlotRotation } from "../utils";
import { Depth, SingleSlot } from "./SingleSlot"; import { Depth, SingleSlot } from "./SingleSlot";
import { matStore } from "@/valtioStores";
import { useSnapshot } from "valtio";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
export const Graveyard = () => { export const Graveyard = () => {
const meGraveyard = useAppSelector(selectMeGraveyard).inner; // const meGraveyard = useAppSelector(selectMeGraveyard).inner;
const opGraveyard = useAppSelector(selectOpGraveyard).inner; // const opGraveyard = useAppSelector(selectOpGraveyard).inner;
const meGraveyard = useSnapshot(matStore.graveyards.me);
const opGraveyard = useSnapshot(matStore.graveyards.op);
return ( return (
<> <>
<SingleSlot <SingleSlot
state={meGraveyard} state={matStore.graveyards.me}
position={graveyardPosition(0, meGraveyard.length)} position={graveyardPosition(0, meGraveyard.length)}
rotation={cardSlotRotation(false)} rotation={cardSlotRotation(false)}
/> />
<SingleSlot <SingleSlot
state={opGraveyard} state={matStore.graveyards.op}
position={graveyardPosition(1, opGraveyard.length)} position={graveyardPosition(1, opGraveyard.length)}
rotation={cardSlotRotation(true)} rotation={cardSlotRotation(true)}
/> />
......
...@@ -4,7 +4,7 @@ import { useHover } from "react-babylonjs"; ...@@ -4,7 +4,7 @@ import { useHover } from "react-babylonjs";
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { useAppSelector, useClick } from "@/hook"; import { useAppSelector, useClick } from "@/hook";
import { CardState } from "@/reducers/duel/generic"; // import { CardState } from "@/reducers/duel/generic";
import { selectMeHands, selectOpHands } from "@/reducers/duel/handsSlice"; import { selectMeHands, selectOpHands } from "@/reducers/duel/handsSlice";
import { import {
setCardModalInteractivies, setCardModalInteractivies,
...@@ -12,6 +12,8 @@ import { ...@@ -12,6 +12,8 @@ import {
setCardModalMeta, setCardModalMeta,
} from "@/reducers/duel/mod"; } from "@/reducers/duel/mod";
import { store } from "@/store"; import { store } from "@/store";
import { matStore, type CardState, messageStore } from "@/valtioStores";
import { useSnapshot } from "valtio";
import { animated, useSpring } from "../spring"; import { animated, useSpring } from "../spring";
import { interactTypeToString, zip } from "../utils"; import { interactTypeToString, zip } from "../utils";
...@@ -26,9 +28,12 @@ const handRotation = new BABYLON.Vector3(rotation.x, rotation.y, rotation.z); ...@@ -26,9 +28,12 @@ const handRotation = new BABYLON.Vector3(rotation.x, rotation.y, rotation.z);
const hoverScaling = NeosConfig.ui.card.handHoverScaling; const hoverScaling = NeosConfig.ui.card.handHoverScaling;
export const Hands = () => { export const Hands = () => {
const meHands = useAppSelector(selectMeHands).inner; const meHands = useSnapshot(matStore.hands.me);
const opHands = useSnapshot(matStore.hands.op);
// const meHands = useAppSelector(selectMeHands).inner;
// const opHands = useAppSelector(selectOpHands).inner;
const meHandPositions = handPositons(0, meHands); const meHandPositions = handPositons(0, meHands);
const opHands = useAppSelector(selectOpHands).inner;
const opHandPositions = handPositons(1, opHands); const opHandPositions = handPositons(1, opHands);
return ( return (
...@@ -116,6 +121,7 @@ const CHand = (props: { ...@@ -116,6 +121,7 @@ const CHand = (props: {
() => { () => {
if (state.occupant) { if (state.occupant) {
dispatch(setCardModalMeta(state.occupant)); dispatch(setCardModalMeta(state.occupant));
messageStore.cardModal.meta = state.occupant;
} }
dispatch( dispatch(
setCardModalInteractivies( setCardModalInteractivies(
...@@ -127,7 +133,14 @@ const CHand = (props: { ...@@ -127,7 +133,14 @@ const CHand = (props: {
}) })
) )
); );
messageStore.cardModal.interactivies = state.idleInteractivities.map(
(interactive) => ({
desc: interactTypeToString(interactive.interactType),
response: interactive.response,
})
);
dispatch(setCardModalIsOpen(true)); dispatch(setCardModalIsOpen(true));
messageStore.cardModal.isOpen = true;
}, },
planeRef, planeRef,
[state] [state]
...@@ -145,7 +158,8 @@ const CHand = (props: { ...@@ -145,7 +158,8 @@ const CHand = (props: {
rotation={props.rotation} rotation={props.rotation}
enableEdgesRendering enableEdgesRendering
edgesWidth={ edgesWidth={
state.idleInteractivities.length > 0 || state.placeInteractivities // state.idleInteractivities.length > 0 || state.placeInteractivities
state.idleInteractivities.length > 0 || state.placeInteractivity
? edgesWidth ? edgesWidth
: 0 : 0
} }
......
...@@ -2,13 +2,16 @@ import * as BABYLON from "@babylonjs/core"; ...@@ -2,13 +2,16 @@ import * as BABYLON from "@babylonjs/core";
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { useAppSelector } from "@/hook"; import { useAppSelector } from "@/hook";
import { CardState } from "@/reducers/duel/generic"; // import { CardState } from "@/reducers/duel/generic";
import { selectMeMagics, selectOpMagics } from "@/reducers/duel/magicSlice"; import { selectMeMagics, selectOpMagics } from "@/reducers/duel/magicSlice";
import { clearMagicPlaceInteractivities } from "@/reducers/duel/mod"; import { clearMagicPlaceInteractivities } from "@/reducers/duel/mod";
import { cardSlotRotation, zip } from "../utils"; import { cardSlotRotation, zip } from "../utils";
import { FixedSlot } from "./FixedSlot"; import { FixedSlot } from "./FixedSlot";
import { matStore, type CardState, messageStore } from "@/valtioStores";
import { useSnapshot } from "valtio";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
// TODO: use config // TODO: use config
const left = -2.15; const left = -2.15;
...@@ -16,11 +19,17 @@ const gap = 1.05; ...@@ -16,11 +19,17 @@ const gap = 1.05;
const transform = NeosConfig.ui.card.transform; const transform = NeosConfig.ui.card.transform;
export const Magics = () => { export const Magics = () => {
const meMagics = useAppSelector(selectMeMagics).inner; // const meMagics = useAppSelector(selectMeMagics).inner;
// const opMagics = useAppSelector(selectOpMagics).inner;
const meMagics = useSnapshot(matStore.magics.me);
const opMagics = useSnapshot(matStore.magics.op);
const meMagicPositions = magicPositions(0, meMagics); const meMagicPositions = magicPositions(0, meMagics);
const opMagics = useAppSelector(selectOpMagics).inner;
const opMagicPositions = magicPositions(1, opMagics); const opMagicPositions = magicPositions(1, opMagics);
const clearPlaceInteractivitiesAction = (controller: number) =>
matStore.magics.of(controller).clearPlaceInteractivity();
return ( return (
<> <>
{zip(meMagics, meMagicPositions) {zip(meMagics, meMagicPositions)
...@@ -28,12 +37,13 @@ export const Magics = () => { ...@@ -28,12 +37,13 @@ export const Magics = () => {
.map(([magic, position], sequence) => { .map(([magic, position], sequence) => {
return ( return (
<FixedSlot <FixedSlot
state={magic} snapState={magic}
key={sequence} key={sequence}
sequence={sequence} sequence={sequence}
position={position} position={position}
rotation={cardSlotRotation(false)} rotation={cardSlotRotation(false)}
clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities} // clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/> />
); );
})} })}
...@@ -42,12 +52,13 @@ export const Magics = () => { ...@@ -42,12 +52,13 @@ export const Magics = () => {
.map(([magic, position], sequence) => { .map(([magic, position], sequence) => {
return ( return (
<FixedSlot <FixedSlot
state={magic} snapState={magic}
key={sequence} key={sequence}
sequence={sequence} sequence={sequence}
position={position} position={position}
rotation={cardSlotRotation(true)} rotation={cardSlotRotation(true)}
clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities} // clearPlaceInteractivitiesAction={clearMagicPlaceInteractivities}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/> />
); );
})} })}
......
...@@ -4,7 +4,7 @@ import * as BABYLON from "@babylonjs/core"; ...@@ -4,7 +4,7 @@ import * as BABYLON from "@babylonjs/core";
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { useAppSelector } from "@/hook"; import { useAppSelector } from "@/hook";
import { CardState } from "@/reducers/duel/generic"; // import { CardState } from "@/reducers/duel/generic";
import { clearMonsterPlaceInteractivities } from "@/reducers/duel/mod"; import { clearMonsterPlaceInteractivities } from "@/reducers/duel/mod";
import { import {
selectMeMonsters, selectMeMonsters,
...@@ -14,16 +14,24 @@ import { ...@@ -14,16 +14,24 @@ import {
import { cardSlotDefenceRotation, cardSlotRotation, zip } from "../utils"; import { cardSlotDefenceRotation, cardSlotRotation, zip } from "../utils";
import { FixedSlot } from "./FixedSlot"; import { FixedSlot } from "./FixedSlot";
import { matStore, type CardState, messageStore } from "@/valtioStores";
import { useSnapshot } from "valtio";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
const transform = NeosConfig.ui.card.transform; const transform = NeosConfig.ui.card.transform;
const floating = NeosConfig.ui.card.floating; const floating = NeosConfig.ui.card.floating;
const left = -2.15; // TODO: config const left = -2.15; // TODO: config
const gap = 1.05; const gap = 1.05;
const clearPlaceInteractivitiesAction = (controller: number) =>
matStore.monsters.of(controller).clearPlaceInteractivity();
export const Monsters = () => { export const Monsters = () => {
const meMonsters = useAppSelector(selectMeMonsters).inner; // const meMonsters = useAppSelector(selectMeMonsters).inner;
// const opMonsters = useAppSelector(selectOpMonsters).inner;
const meMonsters = useSnapshot(matStore.monsters.me);
const opMonsters = useSnapshot(matStore.monsters.op);
const meMonsterPositions = monsterPositions(0, meMonsters); const meMonsterPositions = monsterPositions(0, meMonsters);
const opMonsters = useAppSelector(selectOpMonsters).inner;
const opMonsterPositions = monsterPositions(1, opMonsters); const opMonsterPositions = monsterPositions(1, opMonsters);
return ( return (
...@@ -32,26 +40,28 @@ export const Monsters = () => { ...@@ -32,26 +40,28 @@ export const Monsters = () => {
.slice(0, 5) .slice(0, 5)
.map(([monster, position], sequence) => ( .map(([monster, position], sequence) => (
<FixedSlot <FixedSlot
state={monster} snapState={monster}
key={sequence} key={sequence}
sequence={sequence} sequence={sequence}
position={position} position={position}
rotation={cardSlotRotation(false)} rotation={cardSlotRotation(false)}
deffenseRotation={cardSlotDefenceRotation()} deffenseRotation={cardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities} // clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/> />
))} ))}
{zip(opMonsters, opMonsterPositions) {zip(opMonsters, opMonsterPositions)
.slice(0, 5) .slice(0, 5)
.map(([monster, position], sequence) => ( .map(([monster, position], sequence) => (
<FixedSlot <FixedSlot
state={monster} snapState={monster}
key={sequence} key={sequence}
sequence={sequence} sequence={sequence}
position={position} position={position}
rotation={cardSlotRotation(true)} rotation={cardSlotRotation(true)}
deffenseRotation={cardSlotDefenceRotation()} deffenseRotation={cardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities} // clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/> />
))} ))}
<ExtraMonsters meMonsters={meMonsters} opMonsters={opMonsters} /> <ExtraMonsters meMonsters={meMonsters} opMonsters={opMonsters} />
...@@ -79,31 +89,33 @@ const ExtraMonsters = (props: { ...@@ -79,31 +89,33 @@ const ExtraMonsters = (props: {
<> <>
{meLeft ? ( {meLeft ? (
<FixedSlot <FixedSlot
state={meLeft} snapState={meLeft}
sequence={5} sequence={5}
position={leftPosition} position={leftPosition}
rotation={meRotation} rotation={meRotation}
deffenseRotation={cardSlotDefenceRotation()} deffenseRotation={cardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities} // clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/> />
) : ( ) : (
<></> <></>
)} )}
{meRight ? ( {meRight ? (
<FixedSlot <FixedSlot
state={meRight} snapState={meRight}
sequence={6} sequence={6}
position={rightPosition} position={rightPosition}
rotation={meRotation} rotation={meRotation}
deffenseRotation={cardSlotDefenceRotation()} deffenseRotation={cardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities} // clearPlaceInteractivitiesAction={clearMonsterPlaceInteractivities}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/> />
) : ( ) : (
<></> <></>
)} )}
{opLeft ? ( {opLeft ? (
<FixedSlot <FixedSlot
state={opLeft} snapState={opLeft}
sequence={5} sequence={5}
position={rightPosition} position={rightPosition}
rotation={opRotation} rotation={opRotation}
...@@ -115,7 +127,7 @@ const ExtraMonsters = (props: { ...@@ -115,7 +127,7 @@ const ExtraMonsters = (props: {
)} )}
{opRight ? ( {opRight ? (
<FixedSlot <FixedSlot
state={opRight} snapState={opRight}
sequence={6} sequence={6}
position={leftPosition} position={leftPosition}
rotation={opRotation} rotation={opRotation}
......
...@@ -11,6 +11,7 @@ import { ...@@ -11,6 +11,7 @@ import {
import { store } from "@/store"; import { store } from "@/store";
import { interactTypeToString } from "../utils"; import { interactTypeToString } from "../utils";
import { useSnapshot } from "valtio";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
const transform = NeosConfig.ui.card.transform; const transform = NeosConfig.ui.card.transform;
...@@ -21,10 +22,11 @@ export const SingleSlot = (props: { ...@@ -21,10 +22,11 @@ export const SingleSlot = (props: {
position: BABYLON.Vector3; position: BABYLON.Vector3;
rotation: BABYLON.Vector3; rotation: BABYLON.Vector3;
}) => { }) => {
const snapState = useSnapshot(props.state);
const boxRef = useRef(null); const boxRef = useRef(null);
const dispatch = store.dispatch; const dispatch = store.dispatch;
const edgeRender = const edgeRender =
props.state.find((item) => snapState.find((item) =>
item === undefined ? false : item.idleInteractivities.length > 0 item === undefined ? false : item.idleInteractivities.length > 0
) !== undefined; ) !== undefined;
const edgesWidth = 2.0; const edgesWidth = 2.0;
...@@ -32,10 +34,10 @@ export const SingleSlot = (props: { ...@@ -32,10 +34,10 @@ export const SingleSlot = (props: {
useClick( useClick(
(_event) => { (_event) => {
if (props.state.length != 0) { if (snapState.length != 0) {
dispatch( dispatch(
setCardListModalInfo( setCardListModalInfo(
props.state snapState
.filter( .filter(
(item) => item.occupant !== undefined && item.occupant.id !== 0 (item) => item.occupant !== undefined && item.occupant.id !== 0
) )
...@@ -56,7 +58,7 @@ export const SingleSlot = (props: { ...@@ -56,7 +58,7 @@ export const SingleSlot = (props: {
} }
}, },
boxRef, boxRef,
[props.state] [snapState]
); );
return ( return (
...@@ -64,11 +66,7 @@ export const SingleSlot = (props: { ...@@ -64,11 +66,7 @@ export const SingleSlot = (props: {
name="single-slot" name="single-slot"
ref={boxRef} ref={boxRef}
scaling={ scaling={
new BABYLON.Vector3( new BABYLON.Vector3(transform.x, transform.y, Depth * snapState.length)
transform.x,
transform.y,
Depth * props.state.length
)
} }
position={props.position} position={props.position}
rotation={props.rotation} rotation={props.rotation}
...@@ -81,7 +79,7 @@ export const SingleSlot = (props: { ...@@ -81,7 +79,7 @@ export const SingleSlot = (props: {
diffuseTexture={ diffuseTexture={
new BABYLON.Texture(`${NeosConfig.assetsPath}/card_back.jpg`) new BABYLON.Texture(`${NeosConfig.assetsPath}/card_back.jpg`)
} }
alpha={props.state.length == 0 ? 0 : 1} alpha={snapState.length == 0 ? 0 : 1}
/> />
</box> </box>
); );
......
...@@ -42,6 +42,8 @@ export type DuelFieldState = CardState[] & { ...@@ -42,6 +42,8 @@ export type DuelFieldState = CardState[] & {
clearPlaceInteractivity: () => void; clearPlaceInteractivity: () => void;
}; };
type test = DuelFieldState extends (infer S)[] ? S : never;
export interface MatState { export interface MatState {
selfType: number; selfType: number;
......
import { matStore } from "@/valtioStores";
import { ygopro } from "@/api";
/** 清空所有place互动性,也可以删除某一个zone的互动性。zone为空则为清除所有。 */
export const clearAllPlaceInteradtivities = (
controller: number,
zone?: ygopro.CardZone
) => {
if (zone) {
matStore.in(zone).of(controller).clearPlaceInteractivity();
} else {
matStore.banishedZones.of(controller).clearPlaceInteractivity();
matStore.decks.of(controller).clearPlaceInteractivity();
matStore.extraDecks.of(controller).clearPlaceInteractivity();
matStore.graveyards.of(controller).clearPlaceInteractivity();
matStore.hands.of(controller).clearPlaceInteractivity();
matStore.magics.of(controller).clearPlaceInteractivity();
matStore.monsters.of(controller).clearPlaceInteractivity();
}
};
export * from "./clearAllIdleInteractivities"; export * from "./clearAllIdleInteractivities";
export * from "./fetchCheckCardMetasV2"; export * from "./fetchCheckCardMetasV2";
export * from "./fetchCheckCardMetasV3"; export * from "./fetchCheckCardMetasV3";
export * from "./clearAllPlaceInteradtivities";
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