Commit b85b3cab authored by timel's avatar timel

feat: valtio store logic 50%

parent 2c415f42
import { ygopro } from "@/api/ocgcore/idl/ocgcore"; import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "@/reducers/duel/hintSlice"; import { fetchEsHintMeta } from "@/reducers/duel/hintSlice";
import { AppDispatch } from "@/store"; import { AppDispatch } from "@/store";
import { matStore } from "@/valtioStores";
export default ( export default (
attack: ygopro.StocGameMessage.MsgAttack, attack: ygopro.StocGameMessage.MsgAttack,
...@@ -9,4 +10,8 @@ export default ( ...@@ -9,4 +10,8 @@ export default (
dispatch( dispatch(
fetchEsHintMeta({ originMsg: "「[?]」攻击时", location: attack.location }) fetchEsHintMeta({ originMsg: "「[?]」攻击时", location: attack.location })
); );
matStore.hint.fetchEsHintMeta({
originMsg: "「[?]」攻击时",
location: attack.location,
});
}; };
import { ygopro } from "@/api/ocgcore/idl/ocgcore"; import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "@/reducers/duel/hintSlice"; import { fetchEsHintMeta } from "@/reducers/duel/hintSlice";
import { AppDispatch } from "@/store"; import { AppDispatch } from "@/store";
import { matStore } from "@/valtioStores";
export default ( export default (
_: ygopro.StocGameMessage.MsgAttackDisabled, _: ygopro.StocGameMessage.MsgAttackDisabled,
dispatch: AppDispatch dispatch: AppDispatch
) => { ) => {
dispatch(fetchEsHintMeta({ originMsg: "攻击被无效时" })); dispatch(fetchEsHintMeta({ originMsg: "攻击被无效时" }));
matStore.hint.fetchEsHintMeta({ originMsg: "攻击被无效时" });
}; };
import { ygopro } from "@/api/ocgcore/idl/ocgcore"; import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "@/reducers/duel/hintSlice"; import { fetchEsHintMeta } from "@/reducers/duel/hintSlice";
import { AppDispatch } from "@/store"; import { AppDispatch } from "@/store";
import { matStore } from "@/valtioStores";
export default ( export default (
chaining: ygopro.StocGameMessage.MsgChaining, chaining: ygopro.StocGameMessage.MsgChaining,
dispatch: AppDispatch dispatch: AppDispatch
...@@ -9,4 +9,8 @@ export default ( ...@@ -9,4 +9,8 @@ export default (
dispatch( dispatch(
fetchEsHintMeta({ originMsg: "「[?]」被发动时", cardID: chaining.code }) fetchEsHintMeta({ originMsg: "「[?]」被发动时", cardID: chaining.code })
); );
matStore.hint.fetchEsHintMeta({
originMsg: "「[?]」被发动时",
cardID: chaining.code,
});
}; };
...@@ -2,9 +2,7 @@ import { ygopro } from "@/api/ocgcore/idl/ocgcore"; ...@@ -2,9 +2,7 @@ import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { fetchHandsMeta } from "@/reducers/duel/handsSlice"; import { fetchHandsMeta } from "@/reducers/duel/handsSlice";
import { fetchEsHintMeta } from "@/reducers/duel/hintSlice"; import { fetchEsHintMeta } from "@/reducers/duel/hintSlice";
import { AppDispatch } from "@/store"; import { AppDispatch } from "@/store";
import { valtioStore } from "@/valtioStores"; import { matStore } from "@/valtioStores";
const { matStore } = valtioStore;
export default ( export default (
draw: ygopro.StocGameMessage.MsgDraw, draw: ygopro.StocGameMessage.MsgDraw,
...@@ -13,5 +11,6 @@ export default ( ...@@ -13,5 +11,6 @@ export default (
dispatch(fetchEsHintMeta({ originMsg: "玩家抽卡时" })); dispatch(fetchEsHintMeta({ originMsg: "玩家抽卡时" }));
dispatch(fetchHandsMeta({ controler: draw.player, codes: draw.cards })); dispatch(fetchHandsMeta({ controler: draw.player, codes: draw.cards }));
matStore.hint.fetchEsHintMeta({ originMsg: "玩家抽卡时" });
matStore.hands.add(draw.player, draw.cards); matStore.hands.add(draw.player, draw.cards);
}; };
import { ygopro } from "@/api/ocgcore/idl/ocgcore"; import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "@/reducers/duel/hintSlice"; import { fetchEsHintMeta } from "@/reducers/duel/hintSlice";
import { AppDispatch } from "@/store"; import { AppDispatch } from "@/store";
import { matStore } from "@/valtioStores";
export default ( export default (
_: ygopro.StocGameMessage.MsgFlipSummoned, _: ygopro.StocGameMessage.MsgFlipSummoned,
dispatch: AppDispatch dispatch: AppDispatch
) => { ) => {
dispatch(fetchEsHintMeta({ originMsg: 1608 })); dispatch(fetchEsHintMeta({ originMsg: 1608 }));
matStore.hint.fetchEsHintMeta({ originMsg: 1608 });
}; };
import { ygopro } from "@/api/ocgcore/idl/ocgcore"; import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "@/reducers/duel/hintSlice"; import { fetchEsHintMeta } from "@/reducers/duel/hintSlice";
import { AppDispatch } from "@/store"; import { AppDispatch } from "@/store";
import { matStore } from "@/valtioStores";
export default ( export default (
flipSummoning: ygopro.StocGameMessage.MsgFlipSummoning, flipSummoning: ygopro.StocGameMessage.MsgFlipSummoning,
...@@ -12,4 +13,8 @@ export default ( ...@@ -12,4 +13,8 @@ export default (
cardID: flipSummoning.code, cardID: flipSummoning.code,
}) })
); );
matStore.hint.fetchEsHintMeta({
originMsg: "「[?]」反转召唤宣言时",
cardID: flipSummoning.code,
});
}; };
...@@ -43,6 +43,8 @@ import onMsgUpdateHp from "./updateHp"; ...@@ -43,6 +43,8 @@ import onMsgUpdateHp from "./updateHp";
import onMsgWait from "./wait"; import onMsgWait from "./wait";
import onMsgWin from "./win"; import onMsgWin from "./win";
import { matStore } from "@/valtioStores";
const ActiveList = [ const ActiveList = [
"select_idle_cmd", "select_idle_cmd",
"select_place", "select_place",
...@@ -62,6 +64,7 @@ export default function handleGameMsg(pb: ygopro.YgoStocMsg) { ...@@ -62,6 +64,7 @@ export default function handleGameMsg(pb: ygopro.YgoStocMsg) {
if (ActiveList.includes(msg.gameMsg)) { if (ActiveList.includes(msg.gameMsg)) {
dispatch(setWaiting(false)); dispatch(setWaiting(false));
matStore.waiting = false;
} }
switch (msg.gameMsg) { switch (msg.gameMsg) {
......
...@@ -5,22 +5,31 @@ import { ...@@ -5,22 +5,31 @@ import {
fetchSelectHintMeta, fetchSelectHintMeta,
} from "@/reducers/duel/hintSlice"; } from "@/reducers/duel/hintSlice";
import { AppDispatch } from "@/store"; import { AppDispatch } from "@/store";
import { matStore } from "@/valtioStores";
import MsgHint = ygopro.StocGameMessage.MsgHint; import MsgHint = ygopro.StocGameMessage.MsgHint;
export default (hint: MsgHint, dispatch: AppDispatch) => { export default (hint: MsgHint, dispatch: AppDispatch) => {
switch (hint.hint_type) { switch (hint.hint_type) {
case MsgHint.HintType.HINT_EVENT: { case MsgHint.HintType.HINT_EVENT: {
dispatch(fetchEsHintMeta({ originMsg: hint.hint_data })); dispatch(fetchEsHintMeta({ originMsg: hint.hint_data }));
matStore.hint.fetchEsHintMeta({ originMsg: hint.hint_data });
break; break;
} }
case MsgHint.HintType.HINT_MESSAGE: { case MsgHint.HintType.HINT_MESSAGE: {
dispatch(fetchCommonHintMeta(hint.hint_data)); dispatch(fetchCommonHintMeta(hint.hint_data));
matStore.hint.fetchCommonHintMeta(hint.hint_data);
break; break;
} }
case MsgHint.HintType.HINT_SELECTMSG: { case MsgHint.HintType.HINT_SELECTMSG: {
dispatch( dispatch(
fetchSelectHintMeta({ selectHintData: hint.hint_data, esHint: "" }) fetchSelectHintMeta({ selectHintData: hint.hint_data, esHint: "" })
); );
matStore.hint.fetchSelectHintMeta({
selectHintData: hint.hint_data,
esHint: "",
});
break; break;
} }
default: { default: {
......
...@@ -2,6 +2,8 @@ import { ygopro } from "@/api/ocgcore/idl/ocgcore"; ...@@ -2,6 +2,8 @@ import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { updatePhase } from "@/reducers/duel/mod"; import { updatePhase } from "@/reducers/duel/mod";
import { AppDispatch } from "@/store"; import { AppDispatch } from "@/store";
import { matStore, type PhaseName } from "@/valtioStores";
export default ( export default (
newPhase: ygopro.StocGameMessage.MsgNewPhase, newPhase: ygopro.StocGameMessage.MsgNewPhase,
dispatch: AppDispatch dispatch: AppDispatch
...@@ -11,4 +13,11 @@ export default ( ...@@ -11,4 +13,11 @@ export default (
ygopro.StocGameMessage.MsgNewPhase.PhaseType[newPhase.phase_type] ygopro.StocGameMessage.MsgNewPhase.PhaseType[newPhase.phase_type]
) )
); );
// ts本身还没有这么智能,所以需要手动指定类型
const currentPhase = ygopro.StocGameMessage.MsgNewPhase.PhaseType[
newPhase.phase_type
] as PhaseName;
matStore.phase.currentPhase = currentPhase;
}; };
...@@ -2,10 +2,13 @@ import { ygopro } from "@/api/ocgcore/idl/ocgcore"; ...@@ -2,10 +2,13 @@ import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import { updateTurn } from "@/reducers/duel/mod"; import { updateTurn } from "@/reducers/duel/mod";
import { AppDispatch } from "@/store"; import { AppDispatch } from "@/store";
import { matStore } from "@/valtioStores";
export default ( export default (
newTurn: ygopro.StocGameMessage.MsgNewTurn, newTurn: ygopro.StocGameMessage.MsgNewTurn,
dispatch: AppDispatch dispatch: AppDispatch
) => { ) => {
const player = newTurn.player; const player = newTurn.player;
dispatch(updateTurn(player)); dispatch(updateTurn(player));
matStore.currentPlayer = player;
}; };
...@@ -3,7 +3,7 @@ import { fetchEsHintMeta } from "@/reducers/duel/hintSlice"; ...@@ -3,7 +3,7 @@ import { fetchEsHintMeta } from "@/reducers/duel/hintSlice";
import { setMagicPosition, setMonsterPosition } from "@/reducers/duel/mod"; import { setMagicPosition, setMonsterPosition } from "@/reducers/duel/mod";
import { AppDispatch } from "@/store"; import { AppDispatch } from "@/store";
import MsgPosChange = ygopro.StocGameMessage.MsgPosChange; import MsgPosChange = ygopro.StocGameMessage.MsgPosChange;
import { matStore } from "@/valtioStores";
export default (posChange: MsgPosChange, dispatch: AppDispatch) => { export default (posChange: MsgPosChange, dispatch: AppDispatch) => {
const cardInfo = posChange.card_info; const cardInfo = posChange.card_info;
...@@ -16,6 +16,9 @@ export default (posChange: MsgPosChange, dispatch: AppDispatch) => { ...@@ -16,6 +16,9 @@ export default (posChange: MsgPosChange, dispatch: AppDispatch) => {
position: posChange.cur_position, position: posChange.cur_position,
}) })
); );
matStore.monsters.at(cardInfo.controler)[
cardInfo.sequence
].location.position = posChange.cur_position;
break; break;
} }
...@@ -27,6 +30,9 @@ export default (posChange: MsgPosChange, dispatch: AppDispatch) => { ...@@ -27,6 +30,9 @@ export default (posChange: MsgPosChange, dispatch: AppDispatch) => {
position: posChange.cur_position, position: posChange.cur_position,
}) })
); );
matStore.magics.at(cardInfo.controler)[
cardInfo.sequence
].location.position = posChange.cur_position;
break; break;
} }
......
...@@ -2,7 +2,7 @@ export * from "./types"; ...@@ -2,7 +2,7 @@ export * from "./types";
import { proxy } from "valtio"; import { proxy } from "valtio";
import { fetchCard } from "@/api/cards"; import { fetchCard, type CardMeta } from "@/api/cards";
import { ygopro } from "@/api/ocgcore/idl/ocgcore"; import { ygopro } from "@/api/ocgcore/idl/ocgcore";
import type { import type {
...@@ -11,7 +11,7 @@ import type { ...@@ -11,7 +11,7 @@ import type {
CardsBothSide, CardsBothSide,
DuelFieldState, DuelFieldState,
InitInfo, InitInfo,
PlayMatState, MatState,
} from "./types"; } from "./types";
import { InteractType } from "./types"; import { InteractType } from "./types";
import { DESCRIPTION_LIMIT, fetchStrings, getStrings } from "@/api/strings"; import { DESCRIPTION_LIMIT, fetchStrings, getStrings } from "@/api/strings";
...@@ -45,7 +45,7 @@ const genBlock = ( ...@@ -45,7 +45,7 @@ const genBlock = (
}; };
}; };
const initInfo: PlayMatState["initInfo"] = proxy({ const initInfo: MatState["initInfo"] = proxy({
me: { me: {
masterRule: "UNKNOWN", masterRule: "UNKNOWN",
life: -1, // 特地设置一个不可能的值 life: -1, // 特地设置一个不可能的值
...@@ -66,12 +66,13 @@ const initInfo: PlayMatState["initInfo"] = proxy({ ...@@ -66,12 +66,13 @@ const initInfo: PlayMatState["initInfo"] = proxy({
}, },
}); });
const hint: PlayMatState["hint"] = proxy({ const hint: MatState["hint"] = proxy({
code: -1, code: -1,
fetchCommonHintMeta: (hintData: number) => { fetchCommonHintMeta: (code: number) => {
return fetchStrings("!system", hintData); hint.code = code;
hint.msg = fetchStrings("!system", code);
}, },
fetchSelectHintMeta: async (selectHintData: number, esHint?: string) => { fetchSelectHintMeta: async ({ selectHintData, esHint }) => {
let selectHintMeta = ""; let selectHintMeta = "";
if (selectHintData > DESCRIPTION_LIMIT) { if (selectHintData > DESCRIPTION_LIMIT) {
// 针对`MSG_SELECT_PLACE`的特化逻辑 // 针对`MSG_SELECT_PLACE`的特化逻辑
...@@ -83,28 +84,41 @@ const hint: PlayMatState["hint"] = proxy({ ...@@ -83,28 +84,41 @@ const hint: PlayMatState["hint"] = proxy({
} else { } else {
selectHintMeta = await getStrings(selectHintData); selectHintMeta = await getStrings(selectHintData);
} }
return {
selectHintMeta, hint.code = selectHintData;
esHint, if (hint.code > DESCRIPTION_LIMIT) {
}; // 针对`MSG_SELECT_PLACE`的特化逻辑
hint.msg = selectHintMeta;
} else {
hint.esSelectHint = selectHintMeta;
hint.esHint = esHint;
}
}, },
fetchEsHintMeta: async ( fetchEsHintMeta: async ({ originMsg, location, cardID }) => {
_originMsg: string | number, const newOriginMsg =
location?: ygopro.CardLocation, typeof originMsg === "string"
cardID?: number ? originMsg
) => { : fetchStrings("!system", originMsg);
const originMsg =
typeof _originMsg === "string"
? _originMsg
: fetchStrings("!system", _originMsg);
if (cardID) { const cardMeta = cardID ? await fetchCard(cardID) : undefined;
const cardMeta = await fetchCard(cardID);
return { originMsg, cardMeta, location }; let esHint = newOriginMsg;
} else {
return { originMsg, location }; if (cardMeta?.text.name) {
esHint = esHint.replace("[?]", cardMeta.text.name);
}
if (location) {
const fieldMeta = matStore
.getZone(location.location)
.at(location.controler)
.at(location.sequence);
if (fieldMeta?.occupant?.text.name) {
esHint = esHint.replace("[?]", fieldMeta.occupant.text.name);
}
} }
hint.esHint = esHint;
}, },
}); });
...@@ -201,11 +215,35 @@ const wrap = <T extends DuelFieldState>( ...@@ -201,11 +215,35 @@ const wrap = <T extends DuelFieldState>(
return res; return res;
}; };
/**
* zone -> matStore
*/
const getZone = (zone: ygopro.CardZone) => {
switch (zone) {
case ygopro.CardZone.MZONE:
return matStore.monsters;
case ygopro.CardZone.SZONE:
return matStore.magics;
case ygopro.CardZone.HAND:
return matStore.hands;
case ygopro.CardZone.DECK:
return matStore.decks;
case ygopro.CardZone.GRAVE:
return matStore.graveyards;
case ygopro.CardZone.REMOVED:
return matStore.banishedZones;
case ygopro.CardZone.EXTRA:
return matStore.extraDecks;
default:
console.error("in error", zone);
return matStore.extraDecks;
}
};
/** /**
* 💡 决斗盘状态仓库,本文件核心, * 💡 决斗盘状态仓库,本文件核心,
* 具体介绍可以点进`PlayMatState`去看 * 具体介绍可以点进`PlayMatState`去看
*/ */
export const matStore = proxy<PlayMatState>({ export const matStore: MatState = proxy<MatState>({
magics: wrap(genBlock(ygopro.CardZone.SZONE, 6), ygopro.CardZone.SZONE), magics: wrap(genBlock(ygopro.CardZone.SZONE, 6), ygopro.CardZone.SZONE),
monsters: wrap(genBlock(ygopro.CardZone.MZONE, 7), ygopro.CardZone.MZONE), monsters: wrap(genBlock(ygopro.CardZone.MZONE, 7), ygopro.CardZone.MZONE),
graveyards: wrap({ me: [], op: [] }, ygopro.CardZone.GRAVE), graveyards: wrap({ me: [], op: [] }, ygopro.CardZone.GRAVE),
...@@ -234,6 +272,8 @@ export const matStore = proxy<PlayMatState>({ ...@@ -234,6 +272,8 @@ export const matStore = proxy<PlayMatState>({
result: ygopro.StocGameMessage.MsgWin.ActionType.UNKNOWN, result: ygopro.StocGameMessage.MsgWin.ActionType.UNKNOWN,
waiting: false, waiting: false,
unimplemented: 0, unimplemented: 0,
// methods
getZone,
}); });
/** /**
......
...@@ -44,7 +44,7 @@ export interface CardsBothSide<T extends DuelFieldState> extends BothSide<T> { ...@@ -44,7 +44,7 @@ export interface CardsBothSide<T extends DuelFieldState> extends BothSide<T> {
clearPlaceInteractivity: (controller: number, sequence: number) => void; clearPlaceInteractivity: (controller: number, sequence: number) => void;
} }
export interface PlayMatState { export interface MatState {
selfType: number; selfType: number;
initInfo: BothSide<InitInfo> & { initInfo: BothSide<InitInfo> & {
...@@ -79,7 +79,7 @@ export interface PlayMatState { ...@@ -79,7 +79,7 @@ export interface PlayMatState {
unimplemented: number; // 未处理的`Message` unimplemented: number; // 未处理的`Message`
// remove: (player: number, sequence: number) => void; getZone: (zone: ygopro.CardZone) => CardsBothSide<DuelFieldState>; // 是否在某个区域
} }
export interface InitInfo { export interface InitInfo {
...@@ -164,27 +164,23 @@ export interface HintState { ...@@ -164,27 +164,23 @@ export interface HintState {
} }
// 和hint相关的方法 // 和hint相关的方法
export interface HintMethods { export interface HintMethods {
fetchCommonHintMeta: (hintData: number) => string; fetchCommonHintMeta: (hintData: number) => void;
fetchSelectHintMeta: ( fetchSelectHintMeta: (args: {
selectHintData: number, selectHintData: number;
esHint?: string
) => Promise<{
selectHintMeta: string;
esHint?: string; esHint?: string;
}>; }) => Promise<void>;
fetchEsHintMeta: ( fetchEsHintMeta: (args: {
originMsg: string | number, originMsg: string | number;
location?: ygopro.CardLocation,
cardID?: number
) => Promise<{
originMsg: string;
cardMeta?: CardMeta;
location?: ygopro.CardLocation; location?: ygopro.CardLocation;
}>; cardID?: number;
}) => Promise<void>;
} }
export type PhaseName =
keyof typeof ygopro.StocGameMessage.MsgNewPhase.PhaseType;
export interface PhaseState { export interface PhaseState {
currentPhase: string; // TODO 当前的阶段 应该改成enum currentPhase: PhaseName; // TODO 当前的阶段 应该改成enum
enableBp: boolean; // 允许进入战斗阶段 enableBp: boolean; // 允许进入战斗阶段
enableM2: boolean; // 允许进入M2阶段 enableM2: boolean; // 允许进入M2阶段
enableEp: boolean; // 允许回合结束 enableEp: boolean; // 允许回合结束
......
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