Commit f054851f authored by chechunchi's avatar chechunchi Committed by Chunchi Che

refactor store

parent 128d5827
Pipeline #28467 passed with stages
in 9 minutes and 14 seconds
import { ygopro } from "@/api";
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
import { cardStore, fetchEsHintMeta } from "@/stores";
import { callCardAttack } from "@/ui/Duel/PlayMat/Card";
export default async (attack: ygopro.StocGameMessage.MsgAttack) => {
import { fetchEsHintMeta } from "./util";
export default async (
container: Container,
attack: ygopro.StocGameMessage.MsgAttack,
) => {
const context = container.context;
fetchEsHintMeta({
context,
originMsg: "「[?]」攻击时",
location: attack.attacker_location,
});
const attacker = cardStore.at(
const attacker = context.cardStore.at(
attack.attacker_location.zone,
attack.attacker_location.controller,
attack.attacker_location.sequence,
......
import { ygopro } from "@/api";
import { fetchEsHintMeta } from "@/stores";
import { Container } from "@/container";
export default (_: ygopro.StocGameMessage.MsgAttackDisabled) => {
fetchEsHintMeta({ originMsg: "攻击被无效时" });
import { fetchEsHintMeta } from "./util";
export default (
container: Container,
_: ygopro.StocGameMessage.MsgAttackDisabled,
) => {
fetchEsHintMeta({ context: container.context, originMsg: "攻击被无效时" });
};
import { ygopro } from "@/api";
import { cardStore } from "@/stores";
import { Container } from "@/container";
export default (becomeTarget: ygopro.StocGameMessage.MsgBecomeTarget) => {
export default (
container: Container,
becomeTarget: ygopro.StocGameMessage.MsgBecomeTarget,
) => {
const context = container.context;
for (const location of becomeTarget.locations) {
const target = cardStore.at(
const target = context.cardStore.at(
location.zone,
location.controller,
location.sequence,
......
import { ygopro } from "@/api";
import { Container } from "@/container";
import { cardStore, matStore } from "@/stores";
export default (
container: Container,
......@@ -10,7 +9,7 @@ export default (
const context = container.context;
while (true) {
const chain = matStore.chains.pop();
const chain = context.matStore.chains.pop();
if (chain === undefined) {
break;
}
......@@ -27,7 +26,7 @@ export default (
// 因此在连锁结束的时候把selected标记清掉。
//
// TODO: 这里每次都要全部遍历一遍,后续可以优化下
for (const card of cardStore.inner) {
for (const card of context.cardStore.inner) {
card.targeted = false;
}
};
import { ygopro } from "@/api";
import { Container } from "@/container";
import { matStore } from "@/stores";
// FIXME: 处理连锁会存在三种结果:
// 1. Solved - 已处理;
......@@ -17,7 +16,7 @@ export default async (
console.info(`<ChainSolved>solved_index = ${chainSolved.solved_index}`);
const context = container.context;
const location = matStore.chains
const location = context.matStore.chains
.splice(chainSolved.solved_index - 1, 1)
.at(0);
if (location) {
......@@ -31,7 +30,7 @@ export default async (
} else {
console.warn(
`pop from chains return null! solved_index=${chainSolved.solved_index},
len of chains in store=${matStore.chains.length}`,
len of chains in store=${context.matStore.chains.length}`,
);
}
};
import { fetchCard, ygopro } from "@/api";
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
import { cardStore, fetchEsHintMeta, matStore } from "@/stores";
import { callCardFocus } from "@/ui/Duel/PlayMat/Card";
import { fetchEsHintMeta } from "./util";
export default async (
container: Container,
chaining: ygopro.StocGameMessage.MsgChaining,
) => {
playEffect(AudioActionType.SOUND_ACTIVATE);
const context = container.context;
fetchEsHintMeta({
context,
originMsg: "「[?]」被发动时",
cardID: chaining.code,
});
const context = container.context;
const location = chaining.location;
// 将`location`添加到连锁栈
matStore.chains.push(location);
context.matStore.chains.push(location);
const target = cardStore.find(location);
const target = context.cardStore.find(location);
if (target) {
// 设置连锁序号
const block = context.placeStore.of(context, location);
if (block) {
block.chainIndex.push(matStore.chains.length);
block.chainIndex.push(context.matStore.chains.length);
} else {
console.warn(`<Chaining>block from ${location} is null`);
}
......@@ -45,7 +47,9 @@ export default async (
// 发动效果动画
await callCardFocus(target.uuid);
console.color("blue")(`${target.meta.text.name} chaining`);
console.info(`<Chaining>chain stack length = ${matStore.chains.length}`);
console.info(
`<Chaining>chain stack length = ${context.matStore.chains.length}`,
);
} else {
console.warn(`<Chaining>target from ${location} is null`);
}
......
import { fetchCard, ygopro } from "@/api";
import { Container } from "@/container";
import { sleep } from "@/infra";
import { AudioActionType, playEffect } from "@/infra/audio";
import { cardStore } from "@/stores";
import { callCardFocus, callCardMove } from "@/ui/Duel/PlayMat/Card";
const { MZONE, SZONE } = ygopro.CardZone;
......@@ -10,13 +10,21 @@ const { FACEUP_ATTACK, FACEDOWN_ATTACK, FACEDOWN_DEFENSE, FACEDOWN } =
const WAIT_TIME = 100;
export default async (confirmCards: ygopro.StocGameMessage.MsgConfirmCards) => {
export default async (
container: Container,
confirmCards: ygopro.StocGameMessage.MsgConfirmCards,
) => {
playEffect(AudioActionType.SOUND_REVEAL);
const context = container.context;
const cards = confirmCards.cards;
console.color("pink")(`confirmCards: ${cards}`);
for (const card of cards) {
const target = cardStore.at(card.location, card.controller, card.sequence);
const target = context.cardStore.at(
card.location,
card.controller,
card.sequence,
);
if (target) {
// 设置`occupant`
......
import { fetchCard, ygopro } from "@/api";
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
import { cardStore, fetchEsHintMeta } from "@/stores";
import { callCardMove } from "@/ui/Duel/PlayMat/Card";
export default async (draw: ygopro.StocGameMessage.MsgDraw) => {
fetchEsHintMeta({ originMsg: "玩家抽卡时" });
import { fetchEsHintMeta } from "./util";
export default async (
container: Container,
draw: ygopro.StocGameMessage.MsgDraw,
) => {
const context = container.context;
fetchEsHintMeta({ context, originMsg: "玩家抽卡时" });
const drawLength = draw.cards.length;
// 将卡从卡组移到手牌:设置zone、occupant、sequence
const handsLength = cardStore.at(ygopro.CardZone.HAND, draw.player).length;
const newHands = cardStore
const handsLength = context.cardStore.at(
ygopro.CardZone.HAND,
draw.player,
).length;
const newHands = context.cardStore
.at(ygopro.CardZone.DECK, draw.player)
.sort((a, b) => a.location.sequence - b.location.sequence)
.slice(-drawLength);
......@@ -29,7 +38,7 @@ export default async (draw: ygopro.StocGameMessage.MsgDraw) => {
// 抽卡动画
await Promise.all(
cardStore
context.cardStore
.at(ygopro.CardZone.HAND, draw.player)
.map((card) => callCardMove(card.uuid)),
);
......
import { ygopro } from "@/api";
import { fetchEsHintMeta } from "@/stores";
import { Container } from "@/container";
export default (_: ygopro.StocGameMessage.MsgFlipSummoned) => {
fetchEsHintMeta({ originMsg: 1608 });
import { fetchEsHintMeta } from "./util";
export default (
container: Container,
_: ygopro.StocGameMessage.MsgFlipSummoned,
) => {
fetchEsHintMeta({ context: container.context, originMsg: 1608 });
};
import { ygopro } from "@/api";
import { fetchEsHintMeta } from "@/stores";
import { Container } from "@/container";
export default (flipSummoning: ygopro.StocGameMessage.MsgFlipSummoning) => {
import { fetchEsHintMeta } from "./util";
export default (
container: Container,
flipSummoning: ygopro.StocGameMessage.MsgFlipSummoning,
) => {
// playEffect(AudioActionType.SOUND_FILP);
fetchEsHintMeta({
context: container.context,
originMsg: "「[?]」反转召唤宣言时",
cardID: flipSummoning.code,
});
......
......@@ -119,27 +119,27 @@ export default async function handleGameMsg(
break;
}
case "draw": {
await onMsgDraw(msg.draw);
await onMsgDraw(container, msg.draw);
break;
}
case "new_turn": {
onMsgNewTurn(msg.new_turn);
onMsgNewTurn(container, msg.new_turn);
break;
}
case "new_phase": {
onMsgNewPhase(msg.new_phase);
onMsgNewPhase(container, msg.new_phase);
break;
}
case "hint": {
await onMsgHint(msg.hint);
await onMsgHint(container, msg.hint);
break;
}
case "select_idle_cmd": {
onMsgSelectIdleCmd(msg.select_idle_cmd);
onMsgSelectIdleCmd(container, msg.select_idle_cmd);
break;
}
......@@ -149,7 +149,7 @@ export default async function handleGameMsg(
break;
}
case "move": {
await onMsgMove(msg.move);
await onMsgMove(container, msg.move);
break;
}
case "select_card": {
......@@ -178,22 +178,22 @@ export default async function handleGameMsg(
break;
}
case "shuffle_hand_extra": {
await onMsgShuffleHandExtra(msg.shuffle_hand_extra);
await onMsgShuffleHandExtra(container, msg.shuffle_hand_extra);
break;
}
case "select_battle_cmd": {
onMsgSelectBattleCmd(msg.select_battle_cmd);
onMsgSelectBattleCmd(container, msg.select_battle_cmd);
break;
}
case "pos_change": {
await onMsgPosChange(msg.pos_change);
await onMsgPosChange(container, msg.pos_change);
break;
}
case "select_unselect_card": {
await onMsgSelectUnselectCard(msg.select_unselect_card);
await onMsgSelectUnselectCard(container, msg.select_unselect_card);
break;
}
......@@ -203,47 +203,47 @@ export default async function handleGameMsg(
break;
}
case "update_hp": {
onMsgUpdateHp(msg.update_hp);
onMsgUpdateHp(container, msg.update_hp);
break;
}
case "win": {
await onMsgWin(msg.win);
await onMsgWin(container, msg.win);
break;
}
case "wait": {
onMsgWait(msg.wait);
onMsgWait(container, msg.wait);
break;
}
case "update_data": {
await onMsgUpdateData(msg.update_data);
await onMsgUpdateData(container, msg.update_data);
break;
}
case "reload_field": {
onMsgReloadField(msg.reload_field);
onMsgReloadField(container, msg.reload_field);
break;
}
case "select_sum": {
onMsgSelectSum(msg.select_sum);
onMsgSelectSum(container, msg.select_sum);
break;
}
case "select_tribute": {
onMsgSelectTribute(msg.select_tribute);
onMsgSelectTribute(container, msg.select_tribute);
break;
}
case "update_counter": {
onMsgUpdateCounter(msg.update_counter);
onMsgUpdateCounter(container, msg.update_counter);
break;
}
case "select_counter": {
await onMsgSelectCounter(msg.select_counter);
await onMsgSelectCounter(container, msg.select_counter);
break;
}
......@@ -253,22 +253,22 @@ export default async function handleGameMsg(
break;
}
case "set": {
onMsgSet(msg.set);
onMsgSet(container, msg.set);
break;
}
case "swap": {
onMsgSwap(msg.swap);
onMsgSwap(container, msg.swap);
break;
}
case "attack": {
await onMsgAttack(msg.attack);
await onMsgAttack(container, msg.attack);
break;
}
case "attack_disable": {
onMsgAttackDisable(msg.attack_disable);
onMsgAttackDisable(container, msg.attack_disable);
break;
}
......@@ -287,32 +287,32 @@ export default async function handleGameMsg(
break;
}
case "summoning": {
onMsgSummoning(msg.summoning);
onMsgSummoning(container, msg.summoning);
break;
}
case "summoned": {
onMsgSummoned(msg.summoned);
onMsgSummoned(container, msg.summoned);
break;
}
case "flip_summoning": {
onMsgFlipSummoning(msg.flip_summoning);
onMsgFlipSummoning(container, msg.flip_summoning);
break;
}
case "flip_summoned": {
onMsgFilpSummoned(msg.flip_summoned);
onMsgFilpSummoned(container, msg.flip_summoned);
break;
}
case "sp_summoning": {
onMsgSpSummoning(msg.sp_summoning);
onMsgSpSummoning(container, msg.sp_summoning);
break;
}
case "sp_summoned": {
onMsgSpSummoned(msg.sp_summoned);
onMsgSpSummoned(container, msg.sp_summoned);
break;
}
......@@ -322,26 +322,26 @@ export default async function handleGameMsg(
break;
}
case "lp_update": {
onLpUpdate(msg.lp_update);
onLpUpdate(container, msg.lp_update);
break;
}
case "confirm_cards": {
await onConfirmCards(msg.confirm_cards);
await onConfirmCards(container, msg.confirm_cards);
break;
}
case "become_target": {
onMsgBecomeTarget(msg.become_target);
onMsgBecomeTarget(container, msg.become_target);
break;
}
case "toss": {
onMsgToss(msg.toss);
onMsgToss(container, msg.toss);
break;
}
case "shuffle_set_card": {
await onMsgShuffleSetCard(msg.shuffle_set_card);
await onMsgShuffleSetCard(container, msg.shuffle_set_card);
break;
}
......@@ -351,7 +351,7 @@ export default async function handleGameMsg(
break;
}
case "shuffle_deck": {
onMsgShuffleDeck(msg.shuffle_deck);
onMsgShuffleDeck(container, msg.shuffle_deck);
break;
}
......@@ -361,12 +361,12 @@ export default async function handleGameMsg(
break;
}
case "hand_res": {
onMsgHandResult(msg.hand_res);
onMsgHandResult(container, msg.hand_res);
break;
}
case "swap_grave_deck": {
await onMsgSwapGraveDeck(msg.swap_grave_deck);
await onMsgSwapGraveDeck(container, msg.swap_grave_deck);
break;
}
......@@ -376,7 +376,7 @@ export default async function handleGameMsg(
break;
}
case "unimplemented": {
onUnimplemented(msg.unimplemented);
onUnimplemented(container, msg.unimplemented);
break;
}
......
import { ygopro } from "@/api";
import { matStore } from "@/stores";
import MsgHandResult = ygopro.StocGameMessage.MsgHandResult;
import { Container } from "@/container";
export default (res: MsgHandResult) => {
export default (container: Container, res: MsgHandResult) => {
const context = container.context;
const { result1, result2 } = res;
matStore.handResults.set(0, result1);
matStore.handResults.set(1, result2);
context.matStore.handResults.set(0, result1);
context.matStore.handResults.set(1, result2);
};
import { ygopro } from "@/api";
import {
fetchCommonHintMeta,
fetchEsHintMeta,
fetchSelectHintMeta,
} from "@/stores";
import { fetchCommonHintMeta, fetchSelectHintMeta } from "@/stores";
import MsgHint = ygopro.StocGameMessage.MsgHint;
import { Container } from "@/container";
export default async (hint: MsgHint) => {
import { fetchEsHintMeta } from "./util";
export default async (container: Container, hint: MsgHint) => {
switch (hint.hint_type) {
case MsgHint.HintType.HINT_EVENT: {
await fetchEsHintMeta({ originMsg: hint.hint_data });
await fetchEsHintMeta({
context: container.context,
originMsg: hint.hint_data,
});
break;
}
case MsgHint.HintType.HINT_MESSAGE: {
......
import { ygopro } from "@/api";
import { matStore } from "@/stores";
import { Container } from "@/container";
export default (lpUpdate: ygopro.StocGameMessage.MsgLpUpdate) => {
export default (
container: Container,
lpUpdate: ygopro.StocGameMessage.MsgLpUpdate,
) => {
const player = lpUpdate.player;
const newLp = lpUpdate.new_lp;
matStore.initInfo.of(player).life = newLp;
container.context.matStore.initInfo.of(player).life = newLp;
};
import { fetchCard, ygopro } from "@/api";
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
import { cardStore, CardType } from "@/stores";
import { CardType } from "@/stores";
import { callCardMove } from "@/ui/Duel/PlayMat/Card";
import { REASON_DESTROY, REASON_MATERIAL, TYPE_TOKEN } from "../../common";
......@@ -31,7 +32,8 @@ const overlayStack: ygopro.CardLocation[] = [];
* - 通过`meta.data.type`判断一张卡是否是衍生物。
*
* */
export default async (move: MsgMove) => {
export default async (container: Container, move: MsgMove) => {
const context = container.context;
const code = move.code;
const from = move.from;
const to = move.to;
......@@ -63,7 +65,7 @@ export default async (move: MsgMove) => {
if (from.is_overlay) {
// 超量素材的去除
const overlayMaterial = cardStore.at(
const overlayMaterial = context.cardStore.at(
from.zone,
from.controller,
from.sequence,
......@@ -79,14 +81,18 @@ export default async (move: MsgMove) => {
return;
}
} else {
const card = cardStore.at(from.zone, from.controller, from.sequence);
const card = context.cardStore.at(
from.zone,
from.controller,
from.sequence,
);
if (card) {
target = card;
} else {
console.warn(
`<Move>card from zone=${from.zone}, controller=${from.controller} sequence=${from.sequence} is null`,
);
console.info(cardStore.at(from.zone, from.controller));
console.info(context.cardStore.at(from.zone, from.controller));
return;
}
}
......@@ -105,7 +111,7 @@ export default async (move: MsgMove) => {
// 超量素材出栈
const xyzLocations = overlayStack.splice(0, overlayStack.length);
for (const location of xyzLocations) {
const overlayMaterial = cardStore.at(
const overlayMaterial = context.cardStore.at(
location.zone,
location.controller,
location.sequence,
......@@ -132,8 +138,8 @@ export default async (move: MsgMove) => {
}
// 维护sequence
const fromCards = cardStore.at(from.zone, from.controller);
const toCards = cardStore.at(to.zone, to.controller);
const fromCards = context.cardStore.at(from.zone, from.controller);
const toCards = context.cardStore.at(to.zone, to.controller);
if (
[HAND, GRAVE, REMOVED, DECK, EXTRA, TZONE].includes(from.zone) &&
......@@ -149,7 +155,7 @@ export default async (move: MsgMove) => {
if (from.is_overlay) {
// 超量素材的序号也需要维护
const overlay_sequence = from.overlay_sequence;
for (const overlay of cardStore.findOverlay(
for (const overlay of context.cardStore.findOverlay(
from.zone,
from.controller,
from.sequence,
......@@ -182,7 +188,7 @@ export default async (move: MsgMove) => {
const p = callCardMove(target.uuid, { fromZone: from.zone });
// 如果from或者to是手卡,那么需要刷新除了这张卡之外,这个玩家的所有手卡
if ([from.zone, to.zone].includes(HAND)) {
const pHands = cardStore
const pHands = context.cardStore
.at(HAND, target.location.controller)
.filter((c) => c.uuid !== target.uuid)
.map(async (c) => await callCardMove(c.uuid));
......@@ -193,7 +199,7 @@ export default async (move: MsgMove) => {
// 超量素材位置跟随超量怪兽移动
if (from.zone === MZONE && !from.is_overlay) {
for (const overlay of cardStore.findOverlay(
for (const overlay of context.cardStore.findOverlay(
from.zone,
from.controller,
from.sequence,
......
import { ygopro } from "@/api";
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
import { matStore } from "@/stores";
export default (newPhase: ygopro.StocGameMessage.MsgNewPhase) => {
export default (
container: Container,
newPhase: ygopro.StocGameMessage.MsgNewPhase,
) => {
playEffect(AudioActionType.SOUND_PHASE);
// ts本身还没有这么智能,所以需要手动指定类型
matStore.phase.currentPhase = newPhase.phase_type;
container.context.matStore.phase.currentPhase = newPhase.phase_type;
};
import { ygopro } from "@/api";
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
import { matStore } from "@/stores";
export default (newTurn: ygopro.StocGameMessage.MsgNewTurn) => {
export default (
container: Container,
newTurn: ygopro.StocGameMessage.MsgNewTurn,
) => {
playEffect(AudioActionType.SOUND_NEXT_TURN);
const context = container.context;
const player = newTurn.player;
matStore.currentPlayer = player;
matStore.turnCount = matStore.turnCount + 1;
context.matStore.currentPlayer = player;
context.matStore.turnCount = context.matStore.turnCount + 1;
};
import { ygopro } from "@/api";
import MsgPosChange = ygopro.StocGameMessage.MsgPosChange;
import { cardStore, fetchEsHintMeta } from "@/stores";
import { Container } from "@/container";
import { callCardMove } from "@/ui/Duel/PlayMat/Card";
export default async (posChange: MsgPosChange) => {
import { fetchEsHintMeta } from "./util";
export default async (container: Container, posChange: MsgPosChange) => {
const context = container.context;
const { location, controller, sequence } = posChange.card_info;
const target = cardStore.at(location, controller, sequence);
const target = context.cardStore.at(location, controller, sequence);
if (target) {
target.location.position = posChange.cur_position;
......@@ -17,6 +20,7 @@ export default async (posChange: MsgPosChange) => {
}
fetchEsHintMeta({
context,
originMsg: 1600,
});
};
import { v4 as v4uuid } from "uuid";
import { ygopro } from "@/api";
import { cardStore, matStore } from "@/stores";
import { Container } from "@/container";
import { genCard } from "../utils";
type MsgReloadField = ygopro.StocGameMessage.MsgReloadField;
export default (field: MsgReloadField) => {
export default (container: Container, field: MsgReloadField) => {
const context = container.context;
// 重置
cardStore.reset();
context.cardStore.reset();
const actions = field.actions;
actions.forEach((action) => {
const controller = action.player;
// 更新生命值
matStore.initInfo.of(controller).life = action.lp;
context.matStore.initInfo.of(controller).life = action.lp;
// 更新卡片集合
const cards = action.zone_actions
.map((zoneAction) =>
......@@ -44,6 +45,6 @@ export default (field: MsgReloadField) => {
),
)
.flat();
cardStore.inner.push(...cards);
context.cardStore.inner.push(...cards);
});
};
import { ygopro } from "@/api";
import {
cardStore,
type Interactivity,
InteractType,
matStore,
} from "@/stores";
import { type Interactivity, InteractType } from "@/stores";
import MsgSelectBattleCmd = ygopro.StocGameMessage.MsgSelectBattleCmd;
import { Container } from "@/container";
export default async (selectBattleCmd: MsgSelectBattleCmd) => {
export default async (
container: Container,
selectBattleCmd: MsgSelectBattleCmd,
) => {
const context = container.context;
const player = selectBattleCmd.player;
const cmds = selectBattleCmd.battle_cmds;
// 先清掉之前的互动性
// TODO: 确认这里在AI托管的模式下是否需要
cardStore.inner.forEach((card) => {
context.cardStore.inner.forEach((card) => {
card.idleInteractivities = [];
});
......@@ -33,7 +33,7 @@ export default async (selectBattleCmd: MsgSelectBattleCmd) => {
[InteractType.ATTACK]: { directAttackAble: data.direct_attackable },
};
const tmp = map[interactType]; // 添加额外信息
const target = cardStore.at(location, player, sequence);
const target = context.cardStore.at(location, player, sequence);
if (target) {
target.idleInteractivities.push({
...tmp,
......@@ -50,8 +50,8 @@ export default async (selectBattleCmd: MsgSelectBattleCmd) => {
}
});
});
matStore.phase.enableM2 = selectBattleCmd.enable_m2;
matStore.phase.enableEp = selectBattleCmd.enable_ep;
context.matStore.phase.enableM2 = selectBattleCmd.enable_m2;
context.matStore.phase.enableEp = selectBattleCmd.enable_ep;
};
function battleTypeToInteracType(
......
......@@ -9,6 +9,7 @@ import { fetchCheckCardMeta } from "../utils";
export default async (container: Container, selectCard: MsgSelectCard) => {
const { cancelable, min, max, cards } = selectCard;
const conn = container.conn;
const context = container.context;
// TODO: handle release_param
......@@ -19,6 +20,7 @@ export default async (container: Container, selectCard: MsgSelectCard) => {
}
const { selecteds, mustSelects, selectables } = await fetchCheckCardMeta(
context,
cards,
);
await displaySelectActionsModal({
......
import { sendSelectSingleResponse, ygopro } from "@/api";
import { Container } from "@/container";
import { ChainSetting, fetchSelectHintMeta, matStore } from "@/stores";
import { ChainSetting, fetchSelectHintMeta } from "@/stores";
import { displaySelectActionsModal } from "@/ui/Duel/Message/SelectActionsModal";
import { fetchCheckCardMeta } from "../utils";
......@@ -8,12 +8,13 @@ import { fetchCheckCardMeta } from "../utils";
type MsgSelectChain = ygopro.StocGameMessage.MsgSelectChain;
export default async (container: Container, selectChain: MsgSelectChain) => {
const conn = container.conn;
const context = container.context;
const spCount = selectChain.special_count;
const forced = selectChain.forced;
const _hint0 = selectChain.hint0;
const _hint1 = selectChain.hint1;
const chains = selectChain.chains;
const chainSetting = matStore.chainSetting;
const chainSetting = context.matStore.chainSetting;
if (chainSetting === ChainSetting.CHAIN_IGNORE) {
// 如果玩家配置了忽略连锁,直接回应后端并返回
......@@ -73,6 +74,7 @@ export default async (container: Container, selectChain: MsgSelectChain) => {
selectHintData: 203,
});
const { selecteds, mustSelects, selectables } = await fetchCheckCardMeta(
context,
chains,
);
await displaySelectActionsModal({
......
import { ygopro } from "@/api";
import { cardStore } from "@/stores";
import { Container } from "@/container";
import { displayCheckCounterModal } from "@/ui/Duel/Message";
type MsgSelectCounter = ygopro.StocGameMessage.MsgSelectCounter;
export default async (selectCounter: MsgSelectCounter) => {
export default async (
container: Container,
selectCounter: MsgSelectCounter,
) => {
const context = container.context;
await displayCheckCounterModal({
counterType: selectCounter.counter_type,
min: selectCounter.min,
options: selectCounter.options!.map(({ location, code, counter_count }) => {
const id = cardStore.find(location)?.code;
const id = context.cardStore.find(location)?.code;
const newCode = code ? code : id || 0;
return {
......
import { ygopro } from "@/api";
import {
cardStore,
type Interactivity,
InteractType,
matStore,
} from "@/stores";
import { type Interactivity, InteractType } from "@/stores";
import MsgSelectIdleCmd = ygopro.StocGameMessage.MsgSelectIdleCmd;
import { Container } from "@/container";
export default async (selectIdleCmd: MsgSelectIdleCmd) => {
export default async (
container: Container,
selectIdleCmd: MsgSelectIdleCmd,
) => {
const context = container.context;
const player = selectIdleCmd.player;
const cmds = selectIdleCmd.idle_cmds;
// 先清掉之前的互动性
// TODO: 确认这里是否需要在AI托管的时候调用
cardStore.inner.forEach((card) => {
context.cardStore.inner.forEach((card) => {
card.idleInteractivities = [];
});
......@@ -32,7 +32,7 @@ export default async (selectIdleCmd: MsgSelectIdleCmd) => {
[InteractType.ACTIVATE]: { activateIndex: data.effect_description },
};
const tmp = map[interactType];
const target = cardStore.at(location, player, sequence);
const target = context.cardStore.at(location, player, sequence);
if (target) {
target.idleInteractivities.push({
...tmp,
......@@ -50,8 +50,8 @@ export default async (selectIdleCmd: MsgSelectIdleCmd) => {
});
});
matStore.phase.enableBp = selectIdleCmd.enable_bp;
matStore.phase.enableEp = selectIdleCmd.enable_ep;
context.matStore.phase.enableBp = selectIdleCmd.enable_bp;
context.matStore.phase.enableEp = selectIdleCmd.enable_ep;
};
function idleTypeToInteractType(
......
import { ygopro } from "@/api";
import { Container } from "@/container";
import { displaySelectActionsModal } from "@/ui/Duel/Message/SelectActionsModal";
import { fetchCheckCardMeta } from "../utils";
type MsgSelectSum = ygopro.StocGameMessage.MsgSelectSum;
export default async (selectSum: MsgSelectSum) => {
export default async (container: Container, selectSum: MsgSelectSum) => {
const context = container.context;
const {
selecteds: selecteds1,
mustSelects: mustSelect1,
selectables: selectable1,
} = await fetchCheckCardMeta(selectSum.must_select_cards, false, true);
} = await fetchCheckCardMeta(
context,
selectSum.must_select_cards,
false,
true,
);
const {
selecteds: selecteds2,
mustSelects: mustSelect2,
selectables: selectable2,
} = await fetchCheckCardMeta(selectSum.selectable_cards);
} = await fetchCheckCardMeta(context, selectSum.selectable_cards);
await displaySelectActionsModal({
overflow: selectSum.overflow !== 0,
totalLevels: selectSum.level_sum,
......
import { ygopro } from "@/api";
import { Container } from "@/container";
import { displaySelectActionsModal } from "@/ui/Duel/Message/SelectActionsModal";
import { fetchCheckCardMeta } from "../utils";
type MsgSelectTribute = ygopro.StocGameMessage.MsgSelectTribute;
export default async (selectTribute: MsgSelectTribute) => {
export default async (
container: Container,
selectTribute: MsgSelectTribute,
) => {
const { selecteds, mustSelects, selectables } = await fetchCheckCardMeta(
container.context,
selectTribute.selectable_cards,
);
// TODO: 当玩家选择卡数大于`max`时,是否也合法?
......
import { ygopro } from "@/api";
import { cardStore, matStore } from "@/stores";
import { Container } from "@/container";
import { displaySelectActionsModal } from "@/ui/Duel/Message/SelectActionsModal";
import { fetchCheckCardMeta } from "../utils";
import { isAllOnField } from "./util";
type MsgSelectUnselectCard = ygopro.StocGameMessage.MsgSelectUnselectCard;
export default async (selectUnselectCards: MsgSelectUnselectCard) => {
export default async (
container: Container,
selectUnselectCards: MsgSelectUnselectCard,
) => {
const context = container.context;
const cardStore = context.cardStore;
const matStore = context.matStore;
const {
finishable,
cancelable,
......@@ -48,12 +54,12 @@ export default async (selectUnselectCards: MsgSelectUnselectCard) => {
selecteds: selecteds1,
mustSelects: mustSelect1,
selectables: selectable1,
} = await fetchCheckCardMeta(selectableCards);
} = await fetchCheckCardMeta(context, selectableCards);
const {
selecteds: selecteds2,
mustSelects: mustSelect2,
selectables: selectable2,
} = await fetchCheckCardMeta(selectedCards, true);
} = await fetchCheckCardMeta(context, selectedCards, true);
await displaySelectActionsModal({
finishable,
cancelable,
......
import { ygopro } from "@/api";
import { fetchEsHintMeta } from "@/stores";
import { Container } from "@/container";
export default (_set: ygopro.StocGameMessage.MsgSet) => {
fetchEsHintMeta({ originMsg: 1601 });
import { fetchEsHintMeta } from "./util";
export default (container: Container, _set: ygopro.StocGameMessage.MsgSet) => {
fetchEsHintMeta({ context: container.context, originMsg: 1601 });
};
import { ygopro } from "@/api";
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
import { cardStore } from "@/stores";
export default (shuffleDeck: ygopro.StocGameMessage.MsgShuffleDeck) => {
export default (
container: Container,
shuffleDeck: ygopro.StocGameMessage.MsgShuffleDeck,
) => {
const context = container.context;
playEffect(AudioActionType.SOUND_SHUFFLE);
const player = shuffleDeck.player;
for (const card of cardStore.at(ygopro.CardZone.DECK, player)) {
for (const card of context.cardStore.at(ygopro.CardZone.DECK, player)) {
// 把数据抹掉就好了
card.code = 0;
card.meta = { id: 0, data: {}, text: {} };
......
import { ygopro } from "@/api";
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
import { cardStore } from "@/stores";
import { callCardMove } from "@/ui/Duel/PlayMat/Card";
type MsgShuffleHandExtra = ygopro.StocGameMessage.MsgShuffleHandExtra;
export default async (shuffleHandExtra: MsgShuffleHandExtra) => {
export default async (
container: Container,
shuffleHandExtra: MsgShuffleHandExtra,
) => {
const context = container.context;
playEffect(AudioActionType.SOUND_SHUFFLE);
const { cards: codes, player: controller, zone } = shuffleHandExtra;
// 本质上是要将手卡/额外卡组的sequence变成和codes一样的顺序
const cards = cardStore.at(zone, controller);
const cards = context.cardStore.at(zone, controller);
const hash = new Map(codes.map((code) => [code, new Array()]));
codes.forEach((code, sequence) => {
hash.get(code)?.push(sequence);
......
import { ygopro } from "@/api";
import { cardStore } from "@/stores";
import { callCardMove } from "@/ui/Duel/PlayMat/Card";
import MsgShuffleSetCard = ygopro.StocGameMessage.MsgShuffleSetCard;
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
// 后端传过来的`from_locations`的列表是切洗前场上卡的location,它们在列表里面按照切洗后的顺序排列
export default async (shuffleSetCard: MsgShuffleSetCard) => {
export default async (
container: Container,
shuffleSetCard: MsgShuffleSetCard,
) => {
playEffect(AudioActionType.SOUND_SHUFFLE);
const context = container.context;
const from_locations = shuffleSetCard.from_locations;
const overlay_locations = shuffleSetCard.overlay_locations;
if (from_locations.length === 0) {
......@@ -24,7 +28,11 @@ export default async (shuffleSetCard: MsgShuffleSetCard) => {
Promise.all(
Array.from({ length: count }).map(async (_, i) => {
const from = from_locations[i];
const target = cardStore.at(from.zone, from.controller, from.sequence);
const target = context.cardStore.at(
from.zone,
from.controller,
from.sequence,
);
if (target) {
// 设置code为0,洗切后的code会由`UpdateData`指定
target.code = 0;
......@@ -38,7 +46,7 @@ export default async (shuffleSetCard: MsgShuffleSetCard) => {
const overlay_location = overlay_locations[i];
if (overlay_location.zone > 0) {
// 如果没有超量素材,后端会全传0
for (const overlay of cardStore.findOverlay(
for (const overlay of context.cardStore.findOverlay(
from.zone,
from.controller,
from.sequence,
......
import { ygopro } from "@/api";
import { fetchEsHintMeta } from "@/stores";
import { Container } from "@/container";
export default (_: ygopro.StocGameMessage.MsgSpSummoned) => {
fetchEsHintMeta({ originMsg: 1606 });
import { fetchEsHintMeta } from "./util";
export default (
container: Container,
_: ygopro.StocGameMessage.MsgSpSummoned,
) => {
fetchEsHintMeta({ context: container.context, originMsg: 1606 });
};
import { ygopro } from "@/api";
import { fetchEsHintMeta } from "@/stores";
import { Container } from "@/container";
export default (spSummoning: ygopro.StocGameMessage.MsgSpSummoning) => {
import { fetchEsHintMeta } from "./util";
export default (
container: Container,
spSummoning: ygopro.StocGameMessage.MsgSpSummoning,
) => {
// const card = fetchCard(spSummoning.code);
// if (card.data.type && card.data.type & TYPE_TOKEN) {
// playEffect(AudioActionType.SOUND_TOKEN);
......@@ -9,6 +14,7 @@ export default (spSummoning: ygopro.StocGameMessage.MsgSpSummoning) => {
// playEffect(AudioActionType.SOUND_SPECIAL_SUMMON);
// }
fetchEsHintMeta({
context: container.context,
originMsg: "「[?]」特殊召唤宣言时",
cardID: spSummoning.code,
});
......
......@@ -5,13 +5,7 @@ import { ygopro } from "@/api";
import { useConfig } from "@/config";
import { Container } from "@/container";
import { sleep } from "@/infra";
import {
cardStore,
matStore,
replayStore,
RoomStage,
SideStage,
} from "@/stores";
import { replayStore, RoomStage, SideStage } from "@/stores";
import { replayStart } from "@/ui/Match/ReplayModal";
import { genCard } from "../utils";
......@@ -23,7 +17,7 @@ export default async (
) => {
const context = container.context;
// 先初始化`matStore`
matStore.selfType = start.playerType;
context.matStore.selfType = start.playerType;
if (context.sideStore.stage !== SideStage.NONE) {
// 更新Side状态
......@@ -34,12 +28,12 @@ export default async (
context.roomStore.stage = RoomStage.DUEL_START;
}
matStore.initInfo.set(0, {
context.matStore.initInfo.set(0, {
life: start.life1,
deckSize: start.deckSize1,
extraSize: start.extraSize1,
});
matStore.initInfo.set(1, {
context.matStore.initInfo.set(1, {
life: start.life2,
deckSize: start.deckSize2,
extraSize: start.extraSize2,
......@@ -88,7 +82,7 @@ export default async (
),
);
cardStore.inner.push(...cards);
context.cardStore.inner.push(...cards);
// note: 额外卡组的卡会在对局开始后通过`UpdateData` msg更新
......
import { ygopro } from "@/api";
import { fetchEsHintMeta } from "@/stores";
import { Container } from "@/container";
export default (_: ygopro.StocGameMessage.MsgSummoned) => {
fetchEsHintMeta({ originMsg: 1604 });
import { fetchEsHintMeta } from "./util";
export default (
container: Container,
_: ygopro.StocGameMessage.MsgSummoned,
) => {
fetchEsHintMeta({ context: container.context, originMsg: 1604 });
};
import { ygopro } from "@/api";
import { fetchEsHintMeta } from "@/stores";
import { Container } from "@/container";
export default (summoning: ygopro.StocGameMessage.MsgSummoning) => {
import { fetchEsHintMeta } from "./util";
export default (
container: Container,
summoning: ygopro.StocGameMessage.MsgSummoning,
) => {
/* 因为现在Neos动画架构的问题,这里播放音效的话会滞后于移动动画,
* 因此这里先注释掉,等解决掉上述问题后再加上召唤的音效。
* */
// playEffect(AudioActionType.SOUND_SUMMON);
fetchEsHintMeta({
context: container.context,
originMsg: "「[?]」通常召唤宣言时",
cardID: summoning.code,
});
......
import { ygopro } from "@/api";
import { fetchEsHintMeta } from "@/stores";
import { Container } from "@/container";
export default (_swap: ygopro.StocGameMessage.MsgSwap) => {
fetchEsHintMeta({ originMsg: 1602 });
import { fetchEsHintMeta } from "./util";
export default (
container: Container,
_swap: ygopro.StocGameMessage.MsgSwap,
) => {
fetchEsHintMeta({ context: container.context, originMsg: 1602 });
};
import { ygopro } from "@/api";
import { cardStore } from "@/stores";
import { callCardMove } from "@/ui/Duel/PlayMat/Card";
import MsgSwapGraveDeck = ygopro.StocGameMessage.MsgSwapGraveDeck;
import { Container } from "@/container";
const { DECK, GRAVE } = ygopro.CardZone;
export default async (swapGraveDeck: MsgSwapGraveDeck) => {
export default async (
container: Container,
swapGraveDeck: MsgSwapGraveDeck,
) => {
const context = container.context;
const player = swapGraveDeck.player;
const deck = cardStore.at(DECK, player);
const grave = cardStore.at(GRAVE, player);
const deck = context.cardStore.at(DECK, player);
const grave = context.cardStore.at(GRAVE, player);
for (const card of deck) {
card.location.zone = GRAVE;
......
import { sendTimeConfirm, ygopro } from "@/api";
import { Container } from "@/container";
import { matStore } from "@/stores";
export default function handleTimeLimit(
container: Container,
timeLimit: ygopro.StocTimeLimit,
) {
matStore.timeLimits.set(timeLimit.player, timeLimit.left_time);
if (matStore.isMe(timeLimit.player)) {
const context = container.context;
context.matStore.timeLimits.set(timeLimit.player, timeLimit.left_time);
if (context.matStore.isMe(timeLimit.player)) {
sendTimeConfirm(container.conn);
}
}
import { fetchStrings, Region, ygopro } from "@/api";
import { sleep } from "@/infra";
import { matStore } from "@/stores";
import MsgToss = ygopro.StocGameMessage.MsgToss;
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
export default async (toss: MsgToss) => {
export default async (container: Container, toss: MsgToss) => {
const context = container.context;
const player = toss.player;
const tossType = toss.toss_type;
const prefix = fetchStrings(Region.System, matStore.isMe(player) ? 102 : 103);
const prefix = fetchStrings(
Region.System,
context.matStore.isMe(player) ? 102 : 103,
);
for (const x of toss.res) {
if (tossType === MsgToss.TossType.DICE) {
playEffect(AudioActionType.SOUND_DICE);
matStore.tossResult = prefix + fetchStrings(Region.System, 1624) + x;
context.matStore.tossResult =
prefix + fetchStrings(Region.System, 1624) + x;
} else if (tossType === MsgToss.TossType.COIN) {
playEffect(AudioActionType.SOUND_COIN);
matStore.tossResult =
context.matStore.tossResult =
prefix +
fetchStrings(Region.System, 1623) +
fetchStrings(Region.System, 61 - x);
......
import { ygopro } from "@/api";
import { useConfig } from "@/config";
import { matStore } from "@/stores";
import { Container } from "@/container";
const NeosConfig = useConfig();
export default (unimplemented: ygopro.StocGameMessage.MsgUnimplemented) => {
export default (
container: Container,
unimplemented: ygopro.StocGameMessage.MsgUnimplemented,
) => {
if (!NeosConfig.unimplementedWhiteList.includes(unimplemented.command)) {
matStore.unimplemented = unimplemented.command;
container.context.matStore.unimplemented = unimplemented.command;
}
};
import { ygopro } from "@/api";
import { Container } from "@/container";
import { AudioActionType, playEffect } from "@/infra/audio";
import { cardStore } from "@/stores";
type MsgUpdateCounter = ygopro.StocGameMessage.MsgUpdateCounter;
export default (updateCounter: MsgUpdateCounter) => {
export default (container: Container, updateCounter: MsgUpdateCounter) => {
const context = container.context;
const { location, count, action_type: counterType } = updateCounter;
const target = cardStore.find(location); // 不太确定这个后面能不能相应,我不好说
const target = context.cardStore.find(location); // 不太确定这个后面能不能相应,我不好说
if (target) {
switch (counterType) {
case ygopro.StocGameMessage.MsgUpdateCounter.ActionType.ADD: {
......
import { fetchCard, ygopro } from "@/api";
import { cardStore } from "@/stores";
import { callCardMove } from "@/ui/Duel/PlayMat/Card";
import MsgUpdateData = ygopro.StocGameMessage.MsgUpdateData;
import { TYPE_TOKEN } from "@/common";
import { Container } from "@/container";
export default async (updateData: MsgUpdateData) => {
export default async (container: Container, updateData: MsgUpdateData) => {
const { player: controller, zone, actions } = updateData;
if (controller !== undefined && zone !== undefined && actions !== undefined) {
const field = cardStore.at(zone, controller);
const field = container.context.cardStore.at(zone, controller);
for (const action of actions) {
const sequence = action.location?.sequence;
if (typeof sequence !== "undefined") {
......
import { ygopro } from "@/api";
import { fetchEsHintMeta, matStore } from "@/stores";
import MsgUpdateHp = ygopro.StocGameMessage.MsgUpdateHp;
import { Container } from "@/container";
import { AudioActionType, changeScene, playEffect } from "@/infra/audio";
export default (msgUpdateHp: MsgUpdateHp) => {
import { fetchEsHintMeta } from "./util";
export default (container: Container, msgUpdateHp: MsgUpdateHp) => {
const context = container.context;
if (msgUpdateHp.type_ === MsgUpdateHp.ActionType.DAMAGE) {
playEffect(AudioActionType.SOUND_DAMAGE);
fetchEsHintMeta({ originMsg: "玩家收到伤害时" }); // TODO: i18n
matStore.initInfo.of(msgUpdateHp.player).life -= msgUpdateHp.value;
fetchEsHintMeta({ context, originMsg: "玩家收到伤害时" }); // TODO: i18n
context.matStore.initInfo.of(msgUpdateHp.player).life -= msgUpdateHp.value;
} else if (msgUpdateHp.type_ === MsgUpdateHp.ActionType.RECOVER) {
playEffect(AudioActionType.SOUND_RECOVER);
fetchEsHintMeta({ originMsg: "玩家生命值回复时" }); // TODO: i18n
matStore.initInfo.of(msgUpdateHp.player).life += msgUpdateHp.value;
fetchEsHintMeta({ context, originMsg: "玩家生命值回复时" }); // TODO: i18n
context.matStore.initInfo.of(msgUpdateHp.player).life += msgUpdateHp.value;
}
if (matStore.initInfo.me.life > matStore.initInfo.op.life * 2) {
if (
context.matStore.initInfo.me.life >
context.matStore.initInfo.op.life * 2
) {
changeScene(AudioActionType.BGM_ADVANTAGE);
}
if (matStore.initInfo.me.life * 2 < matStore.initInfo.op.life) {
if (
context.matStore.initInfo.me.life * 2 <
context.matStore.initInfo.op.life
) {
changeScene(AudioActionType.BGM_DISADVANTAGE);
}
};
import { ygopro } from "@/api";
const { MZONE, SZONE, HAND } = ygopro.CardZone;
import { fetchStrings } from "@/api";
import { Region } from "@/api";
import { fetchCard } from "@/api/cards";
import { Context } from "@/container";
export function isAllOnField(locations: ygopro.CardLocation[]): boolean {
const isOnField = (location: ygopro.CardLocation) => {
......@@ -53,3 +57,41 @@ export function argmax<T>(arr: T[], getValue: (item: T) => number): number {
return maxIndex;
}
export const fetchEsHintMeta = async ({
context,
originMsg,
location,
cardID,
}: {
context: Context;
originMsg: string | number;
location?: ygopro.CardLocation;
cardID?: number;
}) => {
const newOriginMsg =
typeof originMsg === "string"
? originMsg
: fetchStrings(Region.System, originMsg);
const cardMeta = cardID ? fetchCard(cardID) : undefined;
let esHint = newOriginMsg;
if (cardMeta?.text.name) {
esHint = esHint.replace("[?]", cardMeta.text.name);
}
if (location) {
const fieldMeta = context.cardStore.at(
location.zone,
location.controller,
location.sequence,
);
if (fieldMeta?.meta.text.name) {
esHint = esHint.replace("[?]", fieldMeta.meta.text.name);
}
}
context.matStore.hint.esHint = esHint;
};
import { ygopro } from "@/api";
import { cardStore } from "@/stores";
import { Container } from "@/container";
import { showWaiting } from "@/ui/Duel/Message";
export default (_wait: ygopro.StocGameMessage.MsgWait) => {
for (const card of cardStore.inner) {
export default (
container: Container,
_wait: ygopro.StocGameMessage.MsgWait,
) => {
for (const card of container.context.cardStore.inner) {
card.idleInteractivities = [];
}
showWaiting(true);
......
import { fetchStrings, Region, ygopro } from "@/api";
import { matStore } from "@/stores";
import { displayEndModal } from "@/ui/Duel/Message";
import MsgWin = ygopro.StocGameMessage.MsgWin;
import { Container } from "@/container";
import { AudioActionType, changeScene } from "@/infra/audio";
export default async (win: MsgWin) => {
export default async (container: Container, win: MsgWin) => {
const context = container.context;
const { win_player, reason } = win;
await displayEndModal(
matStore.isMe(win_player),
context.matStore.isMe(win_player),
fetchStrings(Region.Victory, `0x${reason.toString(16)}`),
);
if (matStore.isMe(win_player)) {
if (context.matStore.isMe(win_player)) {
changeScene(AudioActionType.BGM_WIN);
} else {
changeScene(AudioActionType.BGM_LOSE);
......
......@@ -100,7 +100,7 @@ async function _handle(
break;
}
case "stoc_duel_end": {
handleDuelEnd(pb);
handleDuelEnd(container, pb);
break;
}
case "stoc_game_msg": {
......
import { ygopro } from "@/api";
import { matStore } from "@/stores";
import { Container } from "@/container";
export default function handleDuelEnd(_pb: ygopro.YgoStocMsg) {
matStore.duelEnd = true;
export default function handleDuelEnd(
container: Container,
_pb: ygopro.YgoStocMsg,
) {
container.context.matStore.duelEnd = true;
}
import type { ygopro } from "@/api";
import { fetchCard, getCardStr } from "@/api/cards";
import { cardStore } from "@/stores";
import { Context } from "@/container";
import type { Option } from "@/ui/Duel/Message";
const helper = async (
context: Context,
{
code,
location,
......@@ -26,7 +27,7 @@ const helper = async (
mustSelect?: boolean,
) => {
const { controller, zone, sequence } = location;
const target = cardStore.at(zone, controller, sequence);
const target = context.cardStore.at(zone, controller, sequence);
// 这里可能直接用target.meta即可,不用再查一遍DB
// 但是ygopro后端传回来了code,感觉这里会有些坑,因此求稳这样写
......@@ -63,6 +64,7 @@ const helper = async (
};
export const fetchCheckCardMeta = async (
context: Context,
cards: {
code: number;
location: ygopro.CardLocation;
......@@ -79,6 +81,7 @@ export const fetchCheckCardMeta = async (
const selectables: Option[] = [];
for (const card of cards) {
await helper(
context,
card,
selecteds,
mustSelects,
......
......@@ -94,6 +94,3 @@ export class CardStore implements NeosStore {
}
export const cardStore = proxy(new CardStore());
// @ts-ignore
window.cardStore = cardStore;
import { Region, type ygopro } from "@/api";
import { Region } from "@/api";
import { DESCRIPTION_LIMIT, fetchStrings, getStrings } from "@/api";
import { fetchCard } from "@/api/cards";
import { cardStore } from "@/stores/cardStore";
import { matStore } from "../store";
......@@ -38,39 +37,3 @@ export const fetchSelectHintMeta = ({
matStore.hint.esHint = esHint;
}
};
export const fetchEsHintMeta = async ({
originMsg,
location,
cardID,
}: {
originMsg: string | number;
location?: ygopro.CardLocation;
cardID?: number;
}) => {
const newOriginMsg =
typeof originMsg === "string"
? originMsg
: fetchStrings(Region.System, originMsg);
const cardMeta = cardID ? fetchCard(cardID) : undefined;
let esHint = newOriginMsg;
if (cardMeta?.text.name) {
esHint = esHint.replace("[?]", cardMeta.text.name);
}
if (location) {
const fieldMeta = cardStore.at(
location.zone,
location.controller,
location.sequence,
);
if (fieldMeta?.meta.text.name) {
esHint = esHint.replace("[?]", fieldMeta.meta.text.name);
}
}
matStore.hint.esHint = esHint;
};
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