Commit 745e7944 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'fix/start' into 'main'

Fix/start

See merge request mycard/Neos!214
parents 6ef9a17f 667cb96c
Pipeline #22135 passed with stages
in 15 minutes and 14 seconds
......@@ -10,12 +10,13 @@
"cardImgUrl":"https://cdn02.moecube.com:444/images/ygopro-images-zh-CN",
"cardsDbUrl":"https://cdn02.moecube.com:444/ygopro-database/zh-CN/cards.cdb",
"stringsUrl":"https://cdn02.moecube.com:444/ygopro-database/zh-CN/strings.conf",
"chainALL": false,
"streamInterval": 20,
"chainALL":false,
"streamInterval":20,
"startDelay":1000,
"ui":{
"hint":{
"waitingDuration":1.5,
"maxCount": 1
"maxCount":1
}
},
"unimplementedWhiteList":[
......
......@@ -10,12 +10,13 @@
"cardImgUrl":"https://cdn02.moecube.com:444/images/ygopro-images-zh-CN",
"cardsDbUrl":"https://cdn02.moecube.com:444/ygopro-database/zh-CN/cards.cdb",
"stringsUrl":"https://cdn02.moecube.com:444/ygopro-database/zh-CN/strings.conf",
"chainALL": false,
"streamInterval": 20,
"chainALL":false,
"streamInterval":20,
"startDelay":1000,
"ui":{
"hint":{
"waitingDuration":1.5,
"maxCount": 1
"maxCount":1
}
},
"unimplementedWhiteList":[
......
{
"50": {
"protoType": "move",
"fields": [
{
"fieldName": "code",
"fieldType": "uint32"
},
{
"fieldName": "from",
"fieldType": "CardLocation"
},
{
"fieldName": "to",
"fieldType": "CardLocation"
},
{
"fieldName": "reason",
"fieldType": "uint8"
}
]
},
"33": {
"protoType": "shuffle_hand",
"fields": [
{
"fieldName": "player",
"fieldType": "uint8"
},
{
"fieldName": "hands",
"fieldType": "repeated",
"repeatedType": "uint32"
}
]
},
"53": {
"protoType": "pos_change",
"fields": [
{
"fieldName": "card_info",
"fieldType": "CardInfo"
},
{
"fieldName": "pre_position",
"fieldType": "CardPosition"
},
{
"fieldName": "cur_position",
"fieldType": "CardPosition"
}
]
},
"13": {
"protoType": "select_yes_no",
"fields": [
{ "fieldName": "player","fieldType": "uint8" },
{ "fieldName": "effect_description", "fieldType": "uint32" }
]
},
"54": {
"protoType": "set",
"fields": []
},
"55": {
"protoType": "swap",
"fields": []
},
"60": {
"protoType": "summoning",
"fields": [
{ "fieldName": "code", "fieldType": "uint32" },
{ "fieldName": "location", "fieldType": "CardLocation" }
]
},
"61": {
"protoType": "summoned",
"fields": []
},
"62": {
"protoType": "sp_summoning",
"fields": [
{ "fieldName": "code", "fieldType": "uint32" },
{ "fieldName": "location", "fieldType": "CardLocation" }
]
},
"63": {
"protoType": "sp_summoned",
"fields": []
},
"64": {
"protoType": "flip_summoning",
"fields": [
{ "fieldName": "code", "fieldType": "uint32" },
{ "fieldName": "location", "fieldType": "CardLocation" }
]
},
"65": {
"protoType": "flip_summoned",
"fields": []
},
"70": {
"protoType": "chaining",
"fields": [
{ "fieldName": "code", "fieldType": "uint32" },
{ "fieldName": "location", "fieldType": "CardLocation" }
]
},
"112": {
"protoType": "attack_disable",
"fields": []
},
"73": {
"protoType": "chain_solved",
"fields": [{ "fieldName": "solved_index", "fieldType": "uint8"}]
},
"74": {
"protoType": "chain_end",
"fields": []
},
"75": {
"protoType": "chain_solved",
"fields": [{ "fieldName": "solved_index", "fieldType": "uint8"}]
},
"76": {
"protoType": "chain_solved",
"fields": [{ "fieldName": "solved_index", "fieldType": "uint8"}]
},
"94": {
"protoType": "lp_update",
"fields": [
{ "fieldName": "player", "fieldType": "uint8" },
{ "fieldName": "new_lp", "fieldType": "uint32" }
]
},
"30": {
"protoType": "confirm_cards",
"fields": [
{
"fieldName": "player",
"fieldType": "uint8"
},
{
"fieldName": "cards",
"fieldType": "repeated",
"repeatedType": "CardInfo"
}
]
},
"31": {
"protoType": "confirm_cards",
"fields": [
{
"fieldName": "player",
"fieldType": "uint8"
},
{
"fieldName": "cards",
"fieldType": "repeated",
"repeatedType": "CardInfo"
}
]
}
"50":{
"protoType":"move",
"fields":[
{
"fieldName":"code",
"fieldType":"uint32"
},
{
"fieldName":"from",
"fieldType":"CardLocation"
},
{
"fieldName":"to",
"fieldType":"CardLocation"
},
{
"fieldName":"reason",
"fieldType":"uint8"
}
]
},
"33":{
"protoType":"shuffle_hand",
"fields":[
{
"fieldName":"player",
"fieldType":"uint8"
},
{
"fieldName":"hands",
"fieldType":"repeated",
"repeatedType":"uint32"
}
]
},
"53":{
"protoType":"pos_change",
"fields":[
{
"fieldName":"card_info",
"fieldType":"CardInfo"
},
{
"fieldName":"pre_position",
"fieldType":"CardPosition"
},
{
"fieldName":"cur_position",
"fieldType":"CardPosition"
}
]
},
"13":{
"protoType":"select_yes_no",
"fields":[
{
"fieldName":"player",
"fieldType":"uint8"
},
{
"fieldName":"effect_description",
"fieldType":"uint32"
}
]
},
"54":{
"protoType":"set",
"fields":[
]
},
"55":{
"protoType":"swap",
"fields":[
]
},
"60":{
"protoType":"summoning",
"fields":[
{
"fieldName":"code",
"fieldType":"uint32"
},
{
"fieldName":"location",
"fieldType":"CardLocation"
}
]
},
"61":{
"protoType":"summoned",
"fields":[
]
},
"62":{
"protoType":"sp_summoning",
"fields":[
{
"fieldName":"code",
"fieldType":"uint32"
},
{
"fieldName":"location",
"fieldType":"CardLocation"
}
]
},
"63":{
"protoType":"sp_summoned",
"fields":[
]
},
"64":{
"protoType":"flip_summoning",
"fields":[
{
"fieldName":"code",
"fieldType":"uint32"
},
{
"fieldName":"location",
"fieldType":"CardLocation"
}
]
},
"65":{
"protoType":"flip_summoned",
"fields":[
]
},
"70":{
"protoType":"chaining",
"fields":[
{
"fieldName":"code",
"fieldType":"uint32"
},
{
"fieldName":"location",
"fieldType":"CardLocation"
}
]
},
"112":{
"protoType":"attack_disable",
"fields":[
]
},
"73":{
"protoType":"chain_solved",
"fields":[
{
"fieldName":"solved_index",
"fieldType":"uint8"
}
]
},
"74":{
"protoType":"chain_end",
"fields":[
]
},
"75":{
"protoType":"chain_solved",
"fields":[
{
"fieldName":"solved_index",
"fieldType":"uint8"
}
]
},
"76":{
"protoType":"chain_solved",
"fields":[
{
"fieldName":"solved_index",
"fieldType":"uint8"
}
]
},
"94":{
"protoType":"lp_update",
"fields":[
{
"fieldName":"player",
"fieldType":"uint8"
},
{
"fieldName":"new_lp",
"fieldType":"uint32"
}
]
},
"30":{
"protoType":"confirm_cards",
"fields":[
{
"fieldName":"player",
"fieldType":"uint8"
},
{
"fieldName":"cards",
"fieldType":"repeated",
"repeatedType":"CardInfo"
}
]
},
"31":{
"protoType":"confirm_cards",
"fields":[
{
"fieldName":"player",
"fieldType":"uint8"
},
{
"fieldName":"cards",
"fieldType":"repeated",
"repeatedType":"CardInfo"
}
]
}
}
import { ygopro } from "@/api";
import { cardStore, fetchEsHintMeta, matStore } from "@/stores";
import { cardStore, fetchEsHintMeta } from "@/stores";
export default async (attack: ygopro.StocGameMessage.MsgAttack) => {
fetchEsHintMeta({
......@@ -15,10 +15,7 @@ export default async (attack: ygopro.StocGameMessage.MsgAttack) => {
if (attacker) {
if (attack.direct_attack) {
attacker.directAttack = true;
// await sleep(500);
attacker.directAttack = false;
// TODO: 实现直接攻击的动画
} else {
const target = cardStore.at(
attack.target_location.zone,
......@@ -27,14 +24,12 @@ export default async (attack: ygopro.StocGameMessage.MsgAttack) => {
);
if (target) {
attacker.attackTarget = {
opponent: !matStore.isMe(attack.target_location.controller),
...target,
};
// await sleep(500);
attacker.attackTarget = undefined;
// TODO: 实现攻击`target`的动画
} else {
console.warn(`<Attack>target from ${attack.target_location} is null`);
}
}
} else {
console.warn(`<Attack>attacker from ${attack.attacker_location} is null`);
}
};
......@@ -8,18 +8,17 @@ export default async (chaining: ygopro.StocGameMessage.MsgChaining) => {
cardID: chaining.code,
});
await cardStore.setChaining(chaining.location, chaining.code, true);
const location = chaining.location;
// 恢复成非`chaining`状态
await cardStore.setChaining(location, chaining.code, false);
// 将`location`添加到连锁栈
matStore.chains.push(location);
// 设置被连锁状态
const target = cardStore.find(location);
if (target) {
// 设置连锁序号
target.chainIndex = matStore.chains.length;
// 发动效果动画
await eventbus.call(Task.Focus, target.uuid);
console.color("blue")(`${target.meta.text.name} chaining`);
} else {
......
......@@ -2,8 +2,6 @@ import { fetchCard, ygopro } from "@/api";
import { eventbus, Task } from "@/infra";
import { cardStore, fetchEsHintMeta } from "@/stores";
let cnt = 0;
export default async (draw: ygopro.StocGameMessage.MsgDraw) => {
fetchEsHintMeta({ originMsg: "玩家抽卡时" });
......@@ -25,11 +23,6 @@ export default async (draw: ygopro.StocGameMessage.MsgDraw) => {
card.location.sequence = Number(idx) + handsLength;
}
if (cnt++ < 2) {
// FIXME 暂时性的解决方案,头两回抽卡(双方各自初始手卡)先屏蔽掉
// 不然会出现一些问题...
return;
}
// 抽卡动画
await Promise.all(
cardStore
......
......@@ -76,7 +76,7 @@ async function _handleGameMsg(pb: ygopro.YgoStocMsg) {
switch (msg.gameMsg) {
case "start": {
onMsgStart(msg.start);
await onMsgStart(msg.start);
break;
}
......
......@@ -4,11 +4,13 @@ import { proxy } from "valtio";
import { subscribeKey } from "valtio/utils";
import { fetchCard, ygopro } from "@/api";
import { useConfig } from "@/config";
import { sleep } from "@/infra";
import { cardStore, CardType, store } from "@/stores";
const { matStore } = store;
const TOKEN_SIZE = 13; // 每人场上最多就只可能有13个token
export default (start: ygopro.StocGameMessage.MsgStart) => {
export default async (start: ygopro.StocGameMessage.MsgStart) => {
// 先初始化`matStore`
matStore.selfType = start.playerType;
const opponent =
......@@ -61,8 +63,6 @@ export default (start: ygopro.StocGameMessage.MsgStart) => {
text: {},
},
isToken: !((i + 1) % 3),
chaining: false,
directAttack: false,
})
)
)
......@@ -73,6 +73,10 @@ export default (start: ygopro.StocGameMessage.MsgStart) => {
cardStore
.at(ygopro.CardZone.EXTRA, 1 - opponent)
.forEach((card) => (card.code = myExtraDeckCodes.pop()!));
// 初始化完后,sleep 1s,让UI初始化完成,
// 否则在和AI对战时,由于后端给传给前端的`MSG`频率太高,会导致一些问题。
await sleep(useConfig().startDelay);
};
// 自动从code推断出occupant
......
import { proxy } from "valtio";
import { CardMeta, fetchCard, ygopro } from "@/api";
import { CardMeta, ygopro } from "@/api";
import type { Interactivity } from "./matStore/types";
......@@ -23,12 +23,8 @@ export interface CardType {
reload?: boolean; // 这个字段会在收到MSG_RELOAD_FIELD的时候设置成true,在收到MSG_UPDATE_DATE的时候设置成false
isToken: boolean; // 是否是token
// 新的字段(从matstore之中搬过来的)
chaining: boolean; // 是否在连锁中
chainIndex?: number /*连锁的序号,如果为空表示不在连锁
TODO: 目前是妥协的设计,因为其实一张卡是可以在同一个连锁链中被连锁多次的,这里为了避免太过复杂只保存最后的连锁序号*/;
directAttack: boolean; // 是否正在直接攻击为玩家
attackTarget?: CardType & { opponent: boolean }; // 攻击目标。(嵌套结构可行么?)
}
class CardStore {
......@@ -95,30 +91,6 @@ class CardStore {
card.location.is_overlay
);
}
async setChaining(
location: ygopro.CardLocation,
code: number,
isChaining: boolean
): Promise<void> {
const target = this.find(location);
if (target) {
target.chaining = isChaining;
if (isChaining) {
// 目前需要判断`isChaining`为ture才设置meta,因为有些手坑发效果后会move到墓地,
// 运行到这里的时候已经和原来的位置对不上了,这时候不设置meta
const meta = await fetchCard(code);
// 这里不能设置`code`,因为存在一个场景:
// 对方的`魔神仪-曼德拉护肤草`发动效果后,后端会发一次`MSG_SHUFFLE_HAND`,但传给前端的codes全是0,如果这里设置了`code`的话,在后面的`MSG_SHUFFLE_HAND`处理就会有问题。
// target.code = meta.id;
target.meta = meta;
}
if (target.location.zone == ygopro.CardZone.HAND) {
target.location.position = isChaining
? ygopro.CardPosition.FACEUP_ATTACK
: ygopro.CardPosition.FACEDOWN_ATTACK;
}
}
}
}
export const cardStore = proxy(new CardStore());
......
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