Commit 9c5dd29f authored by timel's avatar timel Committed by Chunchi Che

feat: just a test

parent 3b474171
......@@ -11,9 +11,5 @@ interface ImportMeta {
readonly env: ImportMetaEnv;
}
// // 重新声明useSnapshot,暂时先这么写。原版的会把所有的改成readonly,引发一些棘手的类型报错。
// import "valtio/react";
// declare module "valtio/react" {
// export declare function useSnapshot<T extends object>(proxyObject: T): T;
// export {};
// }
// 定义一个全局的myExtraDeckCodes变量
declare var myExtraDeckCodes: number[];
import { ygopro } from "@/api";
import { sleep } from "@/infra";
import { fetchEsHintMeta, matStore } from "@/stores";
import { fetchCard, ygopro } from "@/api";
import { fetchEsHintMeta, matStore, cardStore } from "@/stores";
import { zip } from "@/ui/Duel/utils";
export default async (draw: ygopro.StocGameMessage.MsgDraw) => {
......@@ -25,4 +25,15 @@ export default async (draw: ygopro.StocGameMessage.MsgDraw) => {
for (const hand of matStore.hands.of(draw.player)) {
hand.focus = false;
}
// 将卡从卡组移到手牌:设置zone、occupant、sequence
const handsLength = cardStore.at(ygopro.CardZone.HAND, draw.player).length;
cardStore
.at(ygopro.CardZone.DECK, draw.player)
.slice(-drawLength)
.forEach(async (card, idx) => {
card.zone = ygopro.CardZone.HAND;
card.code = draw.cards[idx];
card.sequence = idx + handsLength;
});
};
import { v4 as v4uuid } from "uuid";
import { ygopro } from "@/api";
import { fetchOverlayMeta, store } from "@/stores";
import { fetchOverlayMeta, store, cardStore } from "@/stores";
type MsgMove = ygopro.StocGameMessage.MsgMove;
import { useConfig } from "@/config";
import { sleep } from "@/infra";
......@@ -19,6 +19,12 @@ export default async (move: MsgMove) => {
const to = move.to;
const reason = move.reason;
const card = cardStore.at(from.location, from.controler, from.sequence);
card.zone = to.location;
card.sequence = to.sequence;
card.position = to.position;
card.code = code;
// FIXME: 考虑超量素材的情况
let uuid;
......
import { v4 as v4uuid } from "uuid";
import { ygopro } from "@/api";
import { playerStore, store } from "@/stores";
import { fetchCard, ygopro } from "@/api";
import { playerStore, store, cardStore, CardType } from "@/stores";
import { flatten } from "lodash-es";
import { proxy } from "valtio";
import { subscribeKey } from "valtio/utils";
const { matStore } = store;
export default (start: ygopro.StocGameMessage.MsgStart) => {
......@@ -95,4 +99,41 @@ export default (start: ygopro.StocGameMessage.MsgStart) => {
matStore
.in(ygopro.CardZone.EXTRA)
.me.forEach((state) => (state.location.controler = 1 - opponent));
/** 自动从code推断出occupant */
const genCard = (o: CardType) => {
// FIXME 还没处理超量
const t = proxy(o);
subscribeKey(t, "code", async (code) => {
const { text, data } = await fetchCard(code ?? 0);
t.text = text;
t.data = data;
});
return t;
};
const cards = flatten(
[start.deckSize1, start.extraSize1, start.deckSize2, start.extraSize2].map(
(length, i) =>
Array.from({ length }).map((_, sequence) =>
genCard({
uuid: v4uuid(),
code: 0,
controller: i < 2 ? 1 - opponent : opponent, // 前两个是自己的卡组,后两个是对手的卡组
zone: i % 2 ? ygopro.CardZone.EXTRA : ygopro.CardZone.DECK,
counters: {},
idleInteractivities: [],
sequence,
data: {},
text: {},
})
)
)
);
cardStore.inner.push(...cards);
// 设置自己的额外卡组,信息是在waitroom之中拿到的
cardStore
.at(ygopro.CardZone.EXTRA, 1 - opponent)
.forEach((card) => (card.code = myExtraDeckCodes.shift()!));
};
import { CardData, CardMeta, CardText, fetchCard, ygopro } from "@/api";
import { proxy } from "valtio";
import { Interactivity } from "./matStore/types";
/**
* 场上某位置的状态,
* 以后会更名为 BlockState
*/
export interface CardType {
uuid: string; // 一张卡的唯一标识
code: number;
data: CardData;
text: CardText;
controller?: number; // 控制这个位置的玩家,0或1
zone: ygopro.CardZone; // 怪兽区/魔法陷阱区/手牌/卡组/墓地/除外区
position?: ygopro.CardPosition; // 卡片的姿势:攻击还是守备
sequence: number; // 卡片在区域中的序号
idleInteractivities: Interactivity<number>[]; // IDLE状态下的互动信息
placeInteractivity?: Interactivity<{
controler: number;
zone: ygopro.CardZone;
sequence: number;
}>; // 选择位置状态下的互动信息
overlay_materials?: CardMeta[]; // 超量素材, FIXME: 这里需要加上UUID
counters: { [type: number]: number }; // 指示器
reload?: boolean; // 这个字段会在收到MSG_RELOAD_FIELD的时候设置成true,在收到MSG_UPDATE_DATE的时候设置成false
}
class CardStore {
inner: CardType[] = [];
at(zone: ygopro.CardZone, controller: number): CardType[];
at(zone: ygopro.CardZone, controller: number, sequence?: number): CardType;
at(zone: ygopro.CardZone, controller: number, sequence?: number) {
if (sequence !== undefined) {
return this.inner.filter(
(card) =>
card.zone === zone &&
card.controller === controller &&
card.sequence === sequence
)[0];
} else {
return this.inner.filter(
(card) => card.zone === zone && card.controller === controller
);
}
}
}
export const cardStore = proxy(new CardStore());
// @ts-ignore
window.cardStore = cardStore;
......@@ -4,6 +4,7 @@ export * from "./matStore";
export * from "./messageStore";
export * from "./moraStore";
export * from "./playerStore";
export * from "./cardStore";
import { proxy } from "valtio";
import { devtools } from "valtio/utils";
......@@ -14,6 +15,7 @@ import { matStore } from "./matStore";
import { messageStore } from "./messageStore";
import { moraStore } from "./moraStore";
import { playerStore } from "./playerStore";
import { cardStore } from "./cardStore";
export const store = proxy({
playerStore,
......@@ -22,6 +24,7 @@ export const store = proxy({
moraStore,
matStore, // 决斗盘
messageStore, // 决斗的信息,包括模态框
cardStore,
});
devtools(store, { name: "valtio store", enabled: true });
......@@ -14,11 +14,13 @@ import {
YesNoModal,
} from "./Message";
import Mat from "./PlayMat";
import { Test } from "./Test";
const NeosDuel = () => {
return (
<>
<Alert />
<Test />
<Mat />
<CardModal />
<CardListModal />
......
import { cardStore } from "@/stores";
import { useSnapshot } from "valtio";
import { FC } from "react";
import { ygopro } from "@/api";
export const Test = () => {
return (
<div
style={{
background: "white",
position: "fixed",
left: 0,
top: 0,
color: "black",
zIndex: 9999,
fontSize: 12,
}}
>
{cardStore.inner.map((cardState) => (
<Card state={cardState} key={cardState.uuid} />
))}
</div>
);
};
export const Card: FC<{ state: (typeof cardStore.inner)[number] }> = ({
state,
}) => {
const snap = useSnapshot(state);
const show = ![ygopro.CardZone.DECK].includes(snap.zone);
return show ? (
<div>
<div>code: {snap.code}</div>
{/* <div>zone: {ygopro.CardZone[snap.zone]}</div> */}
<div>{(Math.random() * 100).toFixed(0)}</div>
</div>
) : (
<></>
);
};
......@@ -151,6 +151,8 @@ const WaitRoom = () => {
ygopro.CardPosition.FACEDOWN_ATTACK
);
setChoseDeck(true);
window.myExtraDeckCodes = deck.extra;
};
const handleChoseDeck = async (deckName: string) => {
......
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