Commit b85b3cab authored by timel's avatar timel

feat: valtio store logic 50%

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