Commit 00bbfcce authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/announce' into 'main'

Feat/announce

See merge request !208
parents 255aa6df e14b2781
Pipeline #21831 passed with stages
in 13 minutes and 8 seconds
Subproject commit 48be6a827024995962fc479db1ec69bde38a72f6
Subproject commit ee85cb1d1f71ad6b44f1daf1877b63fa2ac1991f
This diff is collapsed.
......@@ -57,3 +57,7 @@ export const MSG_REMOVE_COUNTER = 102;
export const MSG_SELECT_COUNTER = 22;
export const MSG_SORT_CARD = 25;
export const MSG_ATTACK = 110;
export const MSG_ANNOUNCE_RACE = 140;
export const MSG_ANNOUNCE_ATTRIB = 141;
export const MSG_ANNOUNCE_CARD = 142;
export const MSG_ANNOUNCE_NUMBER = 143;
import { BufferReader } from "rust-src";
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import MsgAnnounce = ygopro.StocGameMessage.MsgAnnounce;
/*
* Announce Attribute
*
* @param - TODO
* @usage - 声明属性
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data);
const player = reader.readUint8();
const min = reader.readUint8();
const avaiable = reader.readUint32();
const options = [];
for (let i = 0; i < 7; i++) {
if ((avaiable & (1 << i)) > 0) {
options.push(
new MsgAnnounce.Option({
code: i,
response: 1 << i,
})
);
}
}
return new MsgAnnounce({
player,
announce_type: MsgAnnounce.AnnounceType.Attribute,
min,
options,
});
};
import { BufferReader } from "rust-src";
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import MsgAnnounce = ygopro.StocGameMessage.MsgAnnounce;
/*
* Announce Card
*
* @param - TODO
* @usage - 声明卡片
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data);
const player = reader.readUint8();
const count = reader.readUint8();
const options = [];
for (let i = 0; i < count; i++) {
const code = reader.readUint32();
options.push(
new MsgAnnounce.Option({
code,
response: code,
})
);
}
return new MsgAnnounce({
player,
announce_type: MsgAnnounce.AnnounceType.Card,
options,
});
};
import { BufferReader } from "rust-src";
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import MsgAnnounce = ygopro.StocGameMessage.MsgAnnounce;
/*
* Announce Number
*
* @param - TODO
* @usage - 声明数字
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data);
const player = reader.readUint8();
const count = reader.readUint8();
const options = [];
for (let i = 0; i < count; i++) {
const num = reader.readUint32();
options.push(
new MsgAnnounce.Option({
code: num,
response: i,
})
);
}
return new MsgAnnounce({
player,
announce_type: MsgAnnounce.AnnounceType.Number,
options,
});
};
import { BufferReader } from "rust-src";
import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import MsgAnnounce = ygopro.StocGameMessage.MsgAnnounce;
/*
* Announce Race
*
* @param - TODO
* @usage - 声明种族
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data);
const player = reader.readUint8();
const min = reader.readUint8();
const avaiable = reader.readUint32();
const options = [];
for (let i = 0; i < 25; i++) {
if ((avaiable & (1 << i)) > 0) {
options.push(
new MsgAnnounce.Option({
code: i,
response: 1 << i,
})
);
}
}
return new MsgAnnounce({
player,
announce_type: MsgAnnounce.AnnounceType.RACE,
min,
options,
});
};
......@@ -7,6 +7,10 @@ import { ygopro } from "../../../idl/ocgcore";
import { StocAdapter, YgoProPacket } from "../../packet";
import * as GAME_MSG from "../../protoDecl";
import MsgAddCounter from "./addCounter";
import MsgAnnounceAttribute from "./announceAttrib";
import MsgAnnounceCard from "./announceCard";
import MsgAnnounceNumber from "./announceNumber";
import MsgAnnounceRace from "./announceRace";
import MsgAttack from "./attack";
import MsgDamage from "./damage";
import MsgDrawAdapter from "./draw";
......@@ -196,6 +200,26 @@ export default class GameMsgAdapter implements StocAdapter {
break;
}
case GAME_MSG.MSG_ANNOUNCE_RACE: {
gameMsg.announce = MsgAnnounceRace(gameData);
break;
}
case GAME_MSG.MSG_ANNOUNCE_ATTRIB: {
gameMsg.announce = MsgAnnounceAttribute(gameData);
break;
}
case GAME_MSG.MSG_ANNOUNCE_CARD: {
gameMsg.announce = MsgAnnounceCard(gameData);
break;
}
case GAME_MSG.MSG_ANNOUNCE_NUMBER: {
gameMsg.announce = MsgAnnounceNumber(gameData);
break;
}
default: {
gameMsg.unimplemented = new ygopro.StocGameMessage.MsgUnimplemented({
command: func,
......
import { fetchCard, fetchStrings, ygopro } from "@/api";
import { messageStore } from "@/stores";
import MsgAnnounce = ygopro.StocGameMessage.MsgAnnounce;
const { announceModal } = messageStore;
export default async (announce: MsgAnnounce) => {
const type_ = announce.announce_type;
let min = announce.min;
if (
type_ == MsgAnnounce.AnnounceType.Card ||
type_ == MsgAnnounce.AnnounceType.Number
) {
min = 1;
}
announceModal.min = min;
switch (type_) {
case MsgAnnounce.AnnounceType.RACE: {
announceModal.title = fetchStrings("!system", 563);
announceModal.options = announce.options.map((option) => ({
info: fetchStrings("!system", 1200 + option.code),
response: option.response,
}));
announceModal.isOpen = true;
break;
}
case MsgAnnounce.AnnounceType.Attribute: {
announceModal.title = fetchStrings("!system", 562);
announceModal.options = announce.options.map((option) => ({
info: fetchStrings("!system", 1010 + option.code),
response: option.response,
}));
announceModal.isOpen = true;
break;
}
case MsgAnnounce.AnnounceType.Card: {
announceModal.title = fetchStrings("!system", 564);
announceModal.options = await Promise.all(
announce.options.map(async (option) => ({
info: await fetchCard(option.code).then(
(meta) => meta.text.name ?? "[?]"
),
response: option.response,
}))
);
announceModal.isOpen = true;
break;
}
case MsgAnnounce.AnnounceType.Number: {
announceModal.title = fetchStrings("!system", 565);
announceModal.options = announce.options.map((option) => ({
info: option.code.toString(),
response: option.response,
}));
announceModal.isOpen = true;
break;
}
default: {
console.warn(`Unknown announce_type = ${type_}`);
}
}
};
import { ygopro } from "@/api";
import { matStore } from "@/stores";
import onAnnounce from "./announce";
import onMsgAttack from "./attack";
import onMsgAttackDisable from "./attackDisable";
import onMsgChainEnd from "./chainEnd";
......@@ -270,6 +271,11 @@ export default async function handleGameMsg(pb: ygopro.YgoStocMsg) {
break;
}
case "announce": {
await onAnnounce(msg.announce);
break;
}
case "unimplemented": {
onUnimplemented(msg.unimplemented);
......
......@@ -25,6 +25,11 @@ export const messageStore = proxy<ModalState>({
isOpen: false,
options: [],
},
announceModal: {
isOpen: false,
min: 1,
options: [],
},
});
// >>> modal types >>>
......@@ -87,4 +87,14 @@ export interface ModalState {
response: number;
}[];
};
// 宣言弹窗
announceModal: {
isOpen: boolean;
title?: string;
min: number;
options: {
info: string;
response: number;
}[];
};
}
......@@ -2,6 +2,7 @@ import React from "react";
import {
Alert,
AnnounceModal,
CardListModal,
CardModal,
CheckCounterModal,
......@@ -28,6 +29,7 @@ const NeosDuel = () => {
<OptionModal />
<CheckCounterModal />
<SortCardModal />
<AnnounceModal />
</>
);
};
......
import { CheckCard } from "@ant-design/pro-components";
import { Button } from "antd";
import React, { useState } from "react";
import { useSnapshot } from "valtio";
import { sendSelectOptionResponse } from "@/api";
import { messageStore } from "@/stores";
import { DragModal } from "./DragModal";
const { announceModal } = messageStore;
export const AnnounceModal = () => {
const snap = useSnapshot(announceModal);
const isOpen = snap.isOpen;
const title = snap.title;
const min = snap.min;
const options = snap.options;
const [selected, setSelected] = useState<number[]>([]);
return (
<DragModal
title={title}
open={isOpen}
closable={false}
footer={
<Button
disabled={selected.length != min}
onClick={() => {
let response = selected.reduce((res, current) => res | current, 0); // 多个选择求或
sendSelectOptionResponse(response);
announceModal.isOpen = false;
announceModal.title = undefined;
announceModal.options = [];
}}
>
submit
</Button>
}
>
<CheckCard.Group
bordered
multiple
size="small"
onChange={(value: any) => {
setSelected(value);
}}
>
{options.map((option, idx) => (
<CheckCard key={idx} title={option.info} value={option.response} />
))}
</CheckCard.Group>
</DragModal>
);
};
export * from "./Alert";
export * from "./AnnounceModal";
export * from "./CardListModal";
export * from "./CardModal";
export * from "./CheckCounterModal";
......
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