Commit f48543df authored by Chunchi Che's avatar Chunchi Che

alloc uuid

parent 16a8bd13
Pipeline #21434 passed with stages
in 20 minutes and 49 seconds
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
"@babylonjs/gui": "^5.54.0", "@babylonjs/gui": "^5.54.0",
"@types/google-protobuf": "^3.15.6", "@types/google-protobuf": "^3.15.6",
"@types/lodash-es": "^4.17.7", "@types/lodash-es": "^4.17.7",
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.57.1", "@typescript-eslint/eslint-plugin": "^5.57.1",
"@typescript-eslint/parser": "^5.57.1", "@typescript-eslint/parser": "^5.57.1",
"@vitejs/plugin-react": "^3.1.0", "@vitejs/plugin-react": "^3.1.0",
...@@ -3711,6 +3712,12 @@ ...@@ -3711,6 +3712,12 @@
"@types/jest": "*" "@types/jest": "*"
} }
}, },
"node_modules/@types/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==",
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.57.1", "version": "5.57.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.57.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.57.1.tgz",
...@@ -31226,6 +31233,12 @@ ...@@ -31226,6 +31233,12 @@
"@types/jest": "*" "@types/jest": "*"
} }
}, },
"@types/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==",
"dev": true
},
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "5.57.1", "version": "5.57.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.57.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.57.1.tgz",
import { ygopro } from "@/api"; import { ygopro } from "@/api";
import { fetchEsHintMeta, matStore } from "@/stores"; import { fetchEsHintMeta, matStore } from "@/stores";
import { zip } from "@/ui/Duel/utils";
export default (draw: ygopro.StocGameMessage.MsgDraw) => { export default (draw: ygopro.StocGameMessage.MsgDraw) => {
fetchEsHintMeta({ originMsg: "玩家抽卡时" }); fetchEsHintMeta({ originMsg: "玩家抽卡时" });
matStore.hands.of(draw.player).add(draw.cards);
const deckLength = matStore.decks.of(draw.player).length;
const drawLength = draw.cards.length;
const popCards = matStore.decks
.of(draw.player)
.slice(deckLength - drawLength, drawLength);
const data = zip(popCards, draw.cards).map(([pop, hand]) => {
return { uuid: pop.uuid, id: hand };
});
matStore.hands.of(draw.player).add(data);
}; };
...@@ -6,7 +6,7 @@ import { REASON_MATERIAL } from "../../common"; ...@@ -6,7 +6,7 @@ import { REASON_MATERIAL } from "../../common";
const { matStore } = store; const { matStore } = store;
const OVERLAY_STACK: { code: number; sequence: number }[] = []; const OVERLAY_STACK: { uuid: string; code: number; sequence: number }[] = [];
export default (move: MsgMove) => { export default (move: MsgMove) => {
const code = move.code; const code = move.code;
...@@ -14,9 +14,9 @@ export default (move: MsgMove) => { ...@@ -14,9 +14,9 @@ export default (move: MsgMove) => {
const to = move.to; const to = move.to;
const reason = move.reason; const reason = move.reason;
// TODO: 如果后面做动画的话,要考虑DECK的情况。 // FIXME: 考虑超量素材的情况
// 现在不会对DECK做判断
let uuid;
switch (from.location) { switch (from.location) {
case ygopro.CardZone.MZONE: case ygopro.CardZone.MZONE:
case ygopro.CardZone.SZONE: { case ygopro.CardZone.SZONE: {
...@@ -31,9 +31,15 @@ export default (move: MsgMove) => { ...@@ -31,9 +31,15 @@ export default (move: MsgMove) => {
case ygopro.CardZone.REMOVED: case ygopro.CardZone.REMOVED:
case ygopro.CardZone.GRAVE: case ygopro.CardZone.GRAVE:
case ygopro.CardZone.HAND: case ygopro.CardZone.HAND:
case ygopro.CardZone.DECK:
case ygopro.CardZone.EXTRA: { case ygopro.CardZone.EXTRA: {
// 其余区域就是在list删掉这张卡 // 其余区域就是在list删掉这张卡
matStore.in(from.location).of(from.controler).remove(from.sequence); const removed = matStore
.in(from.location)
.of(from.controler)
.remove(from.sequence);
uuid = removed.uuid;
break; break;
} }
// 仅仅去除超量素材 // 仅仅去除超量素材
...@@ -44,10 +50,6 @@ export default (move: MsgMove) => { ...@@ -44,10 +50,6 @@ export default (move: MsgMove) => {
} }
break; break;
} }
default: {
console.log(`Unhandled zone type ${from.location}`);
break;
}
} }
switch (to.location) { switch (to.location) {
...@@ -72,17 +74,19 @@ export default (move: MsgMove) => { ...@@ -72,17 +74,19 @@ export default (move: MsgMove) => {
case ygopro.CardZone.GRAVE: case ygopro.CardZone.GRAVE:
case ygopro.CardZone.EXTRA: case ygopro.CardZone.EXTRA:
case ygopro.CardZone.HAND: { case ygopro.CardZone.HAND: {
matStore if (uuid) {
.in(to.location) matStore
.of(to.controler) .in(to.location)
.insert(code, to.sequence, to.position); .of(to.controler)
.insert(uuid, code, to.sequence, to.position);
}
break; break;
} }
case ygopro.CardZone.OVERLAY: { case ygopro.CardZone.OVERLAY: {
if (reason == REASON_MATERIAL) { if (reason == REASON_MATERIAL && uuid) {
// 超量素材在进行超量召唤时,若玩家未选择超量怪兽的位置,会“沉到决斗盘下面”,`reason`字段值是`REASON_MATERIAL` // 超量素材在进行超量召唤时,若玩家未选择超量怪兽的位置,会“沉到决斗盘下面”,`reason`字段值是`REASON_MATERIAL`
// 这时候将它们放到一个栈中,待超量怪兽的Move消息到来时从栈中获取超量素材补充到状态中 // 这时候将它们放到一个栈中,待超量怪兽的Move消息到来时从栈中获取超量素材补充到状态中
OVERLAY_STACK.push({ code, sequence: to.overlay_sequence }); OVERLAY_STACK.push({ uuid, code, sequence: to.overlay_sequence });
} else { } else {
// 其他情况下,比如“宵星的机神 丁吉尔苏”的“补充超量素材”效果,直接更新状态中 // 其他情况下,比如“宵星的机神 丁吉尔苏”的“补充超量素材”效果,直接更新状态中
fetchOverlayMeta(to.controler, to.sequence, [code], true); fetchOverlayMeta(to.controler, to.sequence, [code], true);
......
import { v4 as uuidv4 } from "uuid";
import { ygopro } from "@/api"; import { ygopro } from "@/api";
import { matStore } from "@/stores"; import { matStore } from "@/stores";
...@@ -40,6 +42,7 @@ function reloadDuelField( ...@@ -40,6 +42,7 @@ function reloadDuelField(
const cards = zoneActions.map((action) => { const cards = zoneActions.map((action) => {
// FIXME: OVERLAY // FIXME: OVERLAY
return { return {
uuid: uuidv4(), // 因为是重连,所以这里重新申请UUID
location: { location: {
controler: controller, controler: controller,
zone: action.zone, zone: action.zone,
......
import { ygopro } from "@/api"; import { ygopro } from "@/api";
import { matStore } from "@/stores"; import { matStore } from "@/stores";
import { zip } from "@/ui/Duel/utils";
type MsgShuffleHand = ygopro.StocGameMessage.MsgShuffleHand; type MsgShuffleHand = ygopro.StocGameMessage.MsgShuffleHand;
export default (shuffleHand: MsgShuffleHand) => { export default (shuffleHand: MsgShuffleHand) => {
const { hands: codes, player: controller } = shuffleHand; const { hands: codes, player: controller } = shuffleHand;
const uuids = matStore.hands.of(controller).map((hand) => hand.uuid);
const data = zip(uuids, codes).map(([uuid, id]) => {
return { uuid, id };
});
matStore.hands.of(controller).length = 0; matStore.hands.of(controller).length = 0;
matStore.hands.of(controller).add(codes); matStore.hands.of(controller).add(data);
}; };
import { cloneDeep } from "lodash-es"; import { cloneDeep } from "lodash-es";
import { v4 as v4uuid } from "uuid";
import { proxy } from "valtio"; import { proxy } from "valtio";
import { ygopro } from "@/api"; import { ygopro } from "@/api";
...@@ -25,10 +26,12 @@ class CardArray extends Array<CardState> implements ArrayCardState { ...@@ -25,10 +26,12 @@ class CardArray extends Array<CardState> implements ArrayCardState {
public zone: ygopro.CardZone = ygopro.CardZone.MZONE; public zone: ygopro.CardZone = ygopro.CardZone.MZONE;
public getController: () => number = () => 1; public getController: () => number = () => 1;
private genCard = async ( private genCard = async (
uuid: string,
controller: number, controller: number,
id: number, id: number,
position?: ygopro.CardPosition position?: ygopro.CardPosition
) => ({ ) => ({
uuid,
occupant: await fetchCard(id, true), occupant: await fetchCard(id, true),
location: { location: {
controler: controller, controler: controller,
...@@ -41,15 +44,25 @@ class CardArray extends Array<CardState> implements ArrayCardState { ...@@ -41,15 +44,25 @@ class CardArray extends Array<CardState> implements ArrayCardState {
}); });
// methods // methods
remove(sequence: number) { remove(sequence: number) {
this.splice(sequence, 1); return this.splice(sequence, 1)[0];
} }
async insert(sequence: number, id: number, position?: ygopro.CardPosition) { async insert(
const card = await this.genCard(this.getController(), id, position); uuid: string,
sequence: number,
id: number,
position?: ygopro.CardPosition
) {
const card = await this.genCard(uuid, this.getController(), id, position);
this.splice(sequence, 0, card); this.splice(sequence, 0, card);
} }
async add(ids: number[], position?: ygopro.CardPosition) { async add(
data: { uuid: string; id: number }[],
position?: ygopro.CardPosition
) {
const cards = await Promise.all( const cards = await Promise.all(
ids.map(async (id) => this.genCard(this.getController(), id, position)) data.map(async ({ uuid, id }) =>
this.genCard(uuid, this.getController(), id, position)
)
); );
this.splice(this.length, 0, ...cards); this.splice(this.length, 0, ...cards);
} }
...@@ -131,6 +144,7 @@ const genBlock = (zone: ygopro.CardZone, n: number) => ...@@ -131,6 +144,7 @@ const genBlock = (zone: ygopro.CardZone, n: number) =>
Array(n) Array(n)
.fill(null) .fill(null)
.map((_) => ({ .map((_) => ({
uuid: v4uuid(), // WARN: 这里其实应该不分配UUID
location: { location: {
zone, zone,
}, },
......
...@@ -14,15 +14,19 @@ export interface BothSide<T> { ...@@ -14,15 +14,19 @@ export interface BothSide<T> {
*/ */
export interface DuelFieldState extends Array<CardState> { export interface DuelFieldState extends Array<CardState> {
/** 移除特定位置的卡片 */ /** 移除特定位置的卡片 */
remove: (sequence: number) => void; remove: (sequence: number) => CardState;
/** 在指定位置插入卡片 */ /** 在指定位置插入卡片 */
insert: ( insert: (
uuid: string,
id: number, id: number,
sequence: number, sequence: number,
position?: ygopro.CardPosition position?: ygopro.CardPosition
) => Promise<void>; ) => Promise<void>;
/** 在末尾添加卡片 */ /** 在末尾添加卡片 */
add: (ids: number[], position?: ygopro.CardPosition) => Promise<void>; add: (
data: { uuid: string; id: number }[],
position?: ygopro.CardPosition
) => Promise<void>;
/** 设置占据这个位置的卡片信息 */ /** 设置占据这个位置的卡片信息 */
setOccupant: ( setOccupant: (
sequence: number, sequence: number,
...@@ -106,6 +110,7 @@ export interface InitInfo { ...@@ -106,6 +110,7 @@ export interface InitInfo {
* 以后会更名为 BlockState * 以后会更名为 BlockState
*/ */
export interface CardState { export interface CardState {
uuid: string; // 一张卡的唯一标识
occupant?: CardMeta; // 占据此位置的卡牌元信息 occupant?: CardMeta; // 占据此位置的卡牌元信息
location: { location: {
controler?: number; // 控制这个位置的玩家,0或1 controler?: number; // 控制这个位置的玩家,0或1
...@@ -118,7 +123,7 @@ export interface CardState { ...@@ -118,7 +123,7 @@ export interface CardState {
zone: ygopro.CardZone; zone: ygopro.CardZone;
sequence: number; sequence: number;
}>; // 选择位置状态下的互动信息 }>; // 选择位置状态下的互动信息
overlay_materials?: CardMeta[]; // 超量素材 overlay_materials?: CardMeta[]; // 超量素材, FIXME: 这里需要加上UUID
counters: { [type: number]: number }; // 指示器 counters: { [type: number]: number }; // 指示器
reload?: boolean; // 这个字段会在收到MSG_RELOAD_FIELD的时候设置成true,在收到MSG_UPDATE_DATE的时候设置成false reload?: boolean; // 这个字段会在收到MSG_RELOAD_FIELD的时候设置成true,在收到MSG_UPDATE_DATE的时候设置成false
} }
......
...@@ -22,6 +22,7 @@ import { ...@@ -22,6 +22,7 @@ import {
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import rustInit from "rust-src"; import rustInit from "rust-src";
import { v4 as v4uuid } from "uuid";
import { useSnapshot } from "valtio"; import { useSnapshot } from "valtio";
import YGOProDeck from "ygopro-deck-encode"; import YGOProDeck from "ygopro-deck-encode";
...@@ -144,7 +145,9 @@ const WaitRoom = () => { ...@@ -144,7 +145,9 @@ const WaitRoom = () => {
const onDeckReady = async (deck: IDeck) => { const onDeckReady = async (deck: IDeck) => {
sendUpdateDeck(deck); sendUpdateDeck(deck);
store.matStore.extraDecks.me.add( store.matStore.extraDecks.me.add(
deck.extra?.reverse() || [], (deck.extra?.reverse() || []).map((id) => {
return { uuid: v4uuid(), id };
}),
ygopro.CardPosition.FACEDOWN_ATTACK ygopro.CardPosition.FACEDOWN_ATTACK
); );
setChoseDeck(true); setChoseDeck(true);
......
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