Commit 124bc90c authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/es_hint' into 'main'

Feat/es hint

See merge request !163
parents 359b0289 58f2cd78
Pipeline #21107 passed with stages
in 13 minutes and 44 seconds
neos-protobuf @ 1648b05d
Subproject commit e477dc8ab6cc6ef898b34499f3e6ecd3b0d99481 Subproject commit 1648b05d2e0bf0fc84c9e98104b8d9ca6a014c1a
...@@ -68,7 +68,8 @@ ...@@ -68,7 +68,8 @@
"opAvatarColor":"#e10e68" "opAvatarColor":"#e10e68"
}, },
"hint":{ "hint":{
"waitingDuration":1.5 "waitingDuration":1.5,
"maxCount": 3
} }
}, },
"unimplementedWhiteList":[ "unimplementedWhiteList":[
......
...@@ -68,7 +68,8 @@ ...@@ -68,7 +68,8 @@
"opAvatarColor":"#e10e68" "opAvatarColor":"#e10e68"
}, },
"hint":{ "hint":{
"waitingDuration":1.5 "waitingDuration":1.5,
"maxCount": 3
} }
}, },
"unimplementedWhiteList":[ "unimplementedWhiteList":[
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -57,5 +57,63 @@ ...@@ -57,5 +57,63 @@
{ "fieldName": "player","fieldType": "uint8" }, { "fieldName": "player","fieldType": "uint8" },
{ "fieldName": "effect_description", "fieldType": "uint32" } { "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" }
]
},
"110": {
"protoType": "attack",
"fields": [
{ "fieldName": "location", "fieldType": "CardLocation" }
]
},
"112": {
"protoType": "attack_disable",
"fields": []
} }
} }
...@@ -20,6 +20,17 @@ const MsgConstructorMap: Map<string, Constructor> = new Map([ ...@@ -20,6 +20,17 @@ const MsgConstructorMap: Map<string, Constructor> = new Map([
["shuffle_hand", ygopro.StocGameMessage.MsgShuffleHand], ["shuffle_hand", ygopro.StocGameMessage.MsgShuffleHand],
["pos_change", ygopro.StocGameMessage.MsgPosChange], ["pos_change", ygopro.StocGameMessage.MsgPosChange],
["select_yes_no", ygopro.StocGameMessage.MsgSelectYesNo], ["select_yes_no", ygopro.StocGameMessage.MsgSelectYesNo],
["set", ygopro.StocGameMessage.MsgSet],
["swap", ygopro.StocGameMessage.MsgSwap],
["summoning", ygopro.StocGameMessage.MsgSummoning],
["summoned", ygopro.StocGameMessage.MsgSummoned],
["flip_summoning", ygopro.StocGameMessage.MsgFlipSummoning],
["flip_summoned", ygopro.StocGameMessage.MsgFlipSummoned],
["sp_summoning", ygopro.StocGameMessage.MsgSpSummoning],
["sp_summoned", ygopro.StocGameMessage.MsgSpSummoned],
["chaining", ygopro.StocGameMessage.MsgChaining],
["attack", ygopro.StocGameMessage.MsgAttack],
["attack_disable", ygopro.StocGameMessage.MsgAttackDisabled],
]); ]);
export interface penetrateType { export interface penetrateType {
......
...@@ -2,97 +2,138 @@ import { createAsyncThunk, ActionReducerMapBuilder } from "@reduxjs/toolkit"; ...@@ -2,97 +2,138 @@ import { createAsyncThunk, ActionReducerMapBuilder } from "@reduxjs/toolkit";
import { DuelState } from "./mod"; import { DuelState } from "./mod";
import { RootState } from "../../store"; import { RootState } from "../../store";
import { DESCRIPTION_LIMIT, fetchStrings, getStrings } from "../../api/strings"; import { DESCRIPTION_LIMIT, fetchStrings, getStrings } from "../../api/strings";
import { judgeSelf } from "./util"; import { findCardByLocation } from "./util";
import { fetchCard } from "../../api/cards"; import { fetchCard } from "../../api/cards";
import { DuelReducer } from "./generic";
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
export interface HintState { export interface HintState {
code: number; code: number;
msg?: string; msg?: string;
esHint?: string;
esSelectHint?: string; esSelectHint?: string;
} }
export const initHintImpl: DuelReducer<void> = (state) => {
state.hint = { code: 0 };
};
export const fetchCommonHintMeta = createAsyncThunk( export const fetchCommonHintMeta = createAsyncThunk(
"duel/fetchCommonHintMeta", "duel/fetchCommonHintMeta",
async (param: [number, number]) => { async (hintData: number) => {
const player = param[0]; return fetchStrings("!system", hintData);
const hintData = param[1];
const hintMeta = fetchStrings("!system", hintData);
const response: [number, string] = [player, hintMeta];
return response;
} }
); );
export const fetchSelectHintMeta = createAsyncThunk( export const fetchSelectHintMeta = createAsyncThunk(
"duel/fetchSelectHintMeta", "duel/fetchSelectHintMeta",
async (param: [number, number]) => { async (param: { selectHintData: number; esHint?: string }) => {
const player = param[0]; const selectHintData = param.selectHintData;
const hintData = param[1];
let hintMeta = ""; let selectHintMeta = "";
if (hintData > DESCRIPTION_LIMIT) { if (selectHintData > DESCRIPTION_LIMIT) {
// 针对`MSG_SELECT_PLACE`的特化逻辑 // 针对`MSG_SELECT_PLACE`的特化逻辑
const cardMeta = await fetchCard(hintData, true); const cardMeta = await fetchCard(selectHintData, true);
hintMeta = fetchStrings("!system", 569).replace( selectHintMeta = fetchStrings("!system", 569).replace(
"[%ls]", "[%ls]",
cardMeta.text.name || "[?]" cardMeta.text.name || "[?]"
); );
} else { } else {
hintMeta = await getStrings(hintData); selectHintMeta = await getStrings(selectHintData);
} }
const response: [number, string] = [player, hintMeta]; return {
return response; selectHintMeta,
esHint: param.esHint,
};
}
);
export const fetchEsHintMeta = createAsyncThunk(
"duel/fetchEsHintMeta",
async (param: {
originMsg: string | number;
location?: ygopro.CardLocation;
cardID?: number;
}) => {
const originMsg =
typeof param.originMsg === "string"
? param.originMsg
: fetchStrings("!system", param.originMsg);
const location = param.location;
if (param.cardID) {
const cardMeta = await fetchCard(param.cardID, true);
return { originMsg, cardMeta, location };
} else {
return { originMsg, location };
}
} }
); );
export const hintCase = (builder: ActionReducerMapBuilder<DuelState>) => { export const hintCase = (builder: ActionReducerMapBuilder<DuelState>) => {
builder.addCase(fetchCommonHintMeta.pending, (state, action) => { builder.addCase(fetchCommonHintMeta.pending, (state, action) => {
const player = action.meta.arg[0]; const code = action.meta.arg;
const code = action.meta.arg[1];
if (judgeSelf(player, state)) { if (state.hint) {
state.meHint = { code }; state.hint.code = code;
} else {
state.opHint = { code };
} }
}); });
builder.addCase(fetchCommonHintMeta.fulfilled, (state, action) => { builder.addCase(fetchCommonHintMeta.fulfilled, (state, action) => {
const player = action.payload[0]; const hintMeta = action.payload;
const hintMeta = action.payload[1];
const hint = judgeSelf(player, state) ? state.meHint : state.opHint; if (state.hint) {
if (hint) { state.hint.msg = hintMeta;
hint.msg = hintMeta;
} }
}); });
builder.addCase(fetchSelectHintMeta.pending, (state, action) => { builder.addCase(fetchSelectHintMeta.pending, (state, action) => {
const player = action.meta.arg[0]; const code = action.meta.arg.selectHintData;
const code = action.meta.arg[1];
if (judgeSelf(player, state)) { if (state.hint) {
state.meHint = { code }; state.hint.code = code;
} else {
state.opHint = { code };
} }
}); });
builder.addCase(fetchSelectHintMeta.fulfilled, (state, action) => { builder.addCase(fetchSelectHintMeta.fulfilled, (state, action) => {
const player = action.payload[0]; const selectHintMsg = action.payload.selectHintMeta;
let hintMsg = action.payload[1]; const esHint = action.payload.esHint;
const hint = judgeSelf(player, state) ? state.meHint : state.opHint; const hint = state.hint;
if (hint) { if (hint) {
if (hint.code > DESCRIPTION_LIMIT) { if (hint.code > DESCRIPTION_LIMIT) {
// 针对`MSG_SELECT_PLACE`的特化逻辑 // 针对`MSG_SELECT_PLACE`的特化逻辑
hint.msg = hintMsg; hint.msg = selectHintMsg;
} else { } else {
hint.esSelectHint = hintMsg; hint.esSelectHint = selectHintMsg;
if (esHint) hint.esHint = esHint;
}
}
});
builder.addCase(fetchEsHintMeta.fulfilled, (state, action) => {
const originMsg = action.payload.originMsg;
const cardMeta = action.payload.cardMeta;
const location = action.payload.location;
const hint = state.hint;
if (hint) {
let esHint = originMsg;
if (cardMeta?.text.name) {
esHint = originMsg.replace("[?]", cardMeta.text.name);
}
if (location) {
const fieldMeta = findCardByLocation(state, location);
if (fieldMeta?.occupant?.text.name) {
esHint = originMsg.replace("[?]", fieldMeta.occupant.text.name);
}
} }
hint.esHint = esHint;
} }
}); });
}; };
export const selectMeHint = (state: RootState) => state.duel.meHint; export const selectHint = (state: RootState) => state.duel.hint;
export const selectOpHint = (state: RootState) => state.duel.opHint;
...@@ -23,7 +23,7 @@ import { ...@@ -23,7 +23,7 @@ import {
setEnableEpImpl, setEnableEpImpl,
} from "./phaseSlice"; } from "./phaseSlice";
import { RootState } from "../../store"; import { RootState } from "../../store";
import { HintState, hintCase } from "./hintSlice"; import { HintState, hintCase, initHintImpl } from "./hintSlice";
import { import {
ModalState, ModalState,
setCardModalIsOpenImpl, setCardModalIsOpenImpl,
...@@ -149,8 +149,7 @@ export interface DuelState { ...@@ -149,8 +149,7 @@ export interface DuelState {
meTimeLimit?: TimeLimit; // 自己的计时 meTimeLimit?: TimeLimit; // 自己的计时
opTimeLimit?: TimeLimit; // 对手的计时 opTimeLimit?: TimeLimit; // 对手的计时
meHint?: HintState; // 自己的提示 hint?: HintState;
opHint?: HintState; // 对手的提示
currentPlayer?: number; // 当前的操作方 currentPlayer?: number; // 当前的操作方
...@@ -296,6 +295,9 @@ const duelSlice = createSlice({ ...@@ -296,6 +295,9 @@ const duelSlice = createSlice({
setSortCardModalIsOpen: setSortCardModalIsOpenImpl, setSortCardModalIsOpen: setSortCardModalIsOpenImpl,
resetSortCardModal: resetSortCardModalImpl, resetSortCardModal: resetSortCardModalImpl,
// 提示相关`Reducer`
initHint: initHintImpl,
// 通用的`Reducer` // 通用的`Reducer`
clearAllIdleInteractivities: clearAllIdleInteractivitiesImpl, clearAllIdleInteractivities: clearAllIdleInteractivitiesImpl,
clearAllPlaceInteractivities: clearAllPlaceInteractivitiesImpl, clearAllPlaceInteractivities: clearAllPlaceInteractivitiesImpl,
...@@ -413,6 +415,7 @@ export const { ...@@ -413,6 +415,7 @@ export const {
clearCheckCounter, clearCheckCounter,
setSortCardModalIsOpen, setSortCardModalIsOpen,
resetSortCardModal, resetSortCardModal,
initHint,
} = duelSlice.actions; } = duelSlice.actions;
export const selectDuelHsStart = (state: RootState) => { export const selectDuelHsStart = (state: RootState) => {
return state.duel.meInitInfo != null; return state.duel.meInitInfo != null;
......
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (
attack: ygopro.StocGameMessage.MsgAttack,
dispatch: AppDispatch
) => {
dispatch(
fetchEsHintMeta({ originMsg: "「[?]」攻击时", location: attack.location })
);
};
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (
_: ygopro.StocGameMessage.MsgAttackDisabled,
dispatch: AppDispatch
) => {
dispatch(fetchEsHintMeta({ originMsg: "攻击被无效时" }));
};
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (
chaining: ygopro.StocGameMessage.MsgChaining,
dispatch: AppDispatch
) => {
dispatch(
fetchEsHintMeta({ originMsg: "「[?]」被发动时", cardID: chaining.code })
);
};
import { ygopro } from "../../api/ocgcore/idl/ocgcore"; import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { AppDispatch } from "../../store"; import { AppDispatch } from "../../store";
import { fetchHandsMeta } from "../../reducers/duel/handsSlice"; import { fetchHandsMeta } from "../../reducers/duel/handsSlice";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
export default ( export default (
draw: ygopro.StocGameMessage.MsgDraw, draw: ygopro.StocGameMessage.MsgDraw,
dispatch: AppDispatch dispatch: AppDispatch
) => { ) => {
dispatch(fetchEsHintMeta({ originMsg: "玩家抽卡时" }));
dispatch(fetchHandsMeta({ controler: draw.player, codes: draw.cards })); dispatch(fetchHandsMeta({ controler: draw.player, codes: draw.cards }));
}; };
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (
_: ygopro.StocGameMessage.MsgFlipSummoned,
dispatch: AppDispatch
) => {
dispatch(fetchEsHintMeta({ originMsg: 1608 }));
};
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (
flipSummoning: ygopro.StocGameMessage.MsgFlipSummoning,
dispatch: AppDispatch
) => {
dispatch(
fetchEsHintMeta({
originMsg: "「[?]」反转召唤宣言时",
cardID: flipSummoning.code,
})
);
};
...@@ -29,6 +29,17 @@ import onMsgSelectTribute from "./selectTribute"; ...@@ -29,6 +29,17 @@ import onMsgSelectTribute from "./selectTribute";
import onMsgUpdateCounter from "./updateCounter"; import onMsgUpdateCounter from "./updateCounter";
import onMsgSelectCounter from "./selectCounter"; import onMsgSelectCounter from "./selectCounter";
import onMsgSortCard from "./sortCard"; import onMsgSortCard from "./sortCard";
import onMsgSet from "./set";
import onMsgSwap from "./swap";
import onMsgAttack from "./attack";
import onMsgAttackDisable from "./attackDisable";
import onMsgChaining from "./chaining";
import onMsgFlipSummoning from "./flipSummoning";
import onMsgFilpSummoned from "./flipSummoned";
import onMsgSpSummoning from "./spSummoning";
import onMsgSpSummoned from "./spSummoned";
import onMsgSummoning from "./summoning";
import onMsgSummoned from "./summoned";
import { setWaiting } from "../../reducers/duel/mod"; import { setWaiting } from "../../reducers/duel/mod";
const ActiveList = [ const ActiveList = [
...@@ -193,6 +204,61 @@ export default function handleGameMsg(pb: ygopro.YgoStocMsg) { ...@@ -193,6 +204,61 @@ export default function handleGameMsg(pb: ygopro.YgoStocMsg) {
break; break;
} }
case "set": {
onMsgSet(msg.set, dispatch);
break;
}
case "swap": {
onMsgSwap(msg.swap, dispatch);
break;
}
case "attack": {
onMsgAttack(msg.attack, dispatch);
break;
}
case "attack_disable": {
onMsgAttackDisable(msg.attack_disable, dispatch);
break;
}
case "chaining": {
onMsgChaining(msg.chaining, dispatch);
break;
}
case "summoning": {
onMsgSummoning(msg.summoning, dispatch);
break;
}
case "summoned": {
onMsgSummoned(msg.summoned, dispatch);
break;
}
case "flip_summoning": {
onMsgFlipSummoning(msg.flip_summoning, dispatch);
break;
}
case "flip_summoned": {
onMsgFilpSummoned(msg.flip_summoned, dispatch);
break;
}
case "sp_summoning": {
onMsgSpSummoning(msg.sp_summoning, dispatch);
break;
}
case "sp_summoned": {
onMsgSpSummoned(msg.sp_summoned, dispatch);
break;
}
case "unimplemented": { case "unimplemented": {
onUnimplemented(msg.unimplemented, dispatch); onUnimplemented(msg.unimplemented, dispatch);
......
...@@ -2,20 +2,25 @@ import { ygopro } from "../../api/ocgcore/idl/ocgcore"; ...@@ -2,20 +2,25 @@ import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { AppDispatch } from "../../store"; import { AppDispatch } from "../../store";
import { import {
fetchCommonHintMeta, fetchCommonHintMeta,
fetchEsHintMeta,
fetchSelectHintMeta, fetchSelectHintMeta,
} from "../../reducers/duel/hintSlice"; } from "../../reducers/duel/hintSlice";
import MsgHint = ygopro.StocGameMessage.MsgHint; import MsgHint = ygopro.StocGameMessage.MsgHint;
export default (hint: MsgHint, dispatch: AppDispatch) => { export default (hint: MsgHint, dispatch: AppDispatch) => {
const player = hint.player;
switch (hint.hint_type) { switch (hint.hint_type) {
case MsgHint.HintType.HINT_EVENT: case MsgHint.HintType.HINT_EVENT: {
dispatch(fetchEsHintMeta({ originMsg: hint.hint_data }));
break;
}
case MsgHint.HintType.HINT_MESSAGE: { case MsgHint.HintType.HINT_MESSAGE: {
dispatch(fetchCommonHintMeta([player, hint.hint_data])); dispatch(fetchCommonHintMeta(hint.hint_data));
break; break;
} }
case MsgHint.HintType.HINT_SELECTMSG: { case MsgHint.HintType.HINT_SELECTMSG: {
dispatch(fetchSelectHintMeta([player, hint.hint_data])); dispatch(
fetchSelectHintMeta({ selectHintData: hint.hint_data, esHint: "" })
);
break; break;
} }
default: { default: {
......
import { ygopro } from "../../api/ocgcore/idl/ocgcore"; import { ygopro } from "../../api/ocgcore/idl/ocgcore";
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;
...@@ -33,4 +34,6 @@ export default (posChange: MsgPosChange, dispatch: AppDispatch) => { ...@@ -33,4 +34,6 @@ export default (posChange: MsgPosChange, dispatch: AppDispatch) => {
console.log(`Unhandled zone ${cardInfo.location}`); console.log(`Unhandled zone ${cardInfo.location}`);
} }
} }
dispatch(fetchEsHintMeta({ originMsg: 1600 }));
}; };
...@@ -84,7 +84,11 @@ export default (selectChain: MsgSelectChain, dispatch: AppDispatch) => { ...@@ -84,7 +84,11 @@ export default (selectChain: MsgSelectChain, dispatch: AppDispatch) => {
}) })
); );
} }
dispatch(fetchSelectHintMeta([player, 203])); dispatch(
fetchSelectHintMeta({
selectHintData: 203,
})
);
dispatch(setCheckCardModalIsOpen(true)); dispatch(setCheckCardModalIsOpen(true));
......
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (_set: ygopro.StocGameMessage.MsgSet, dispatch: AppDispatch) => {
dispatch(fetchEsHintMeta({ originMsg: 1601 }));
};
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (
_: ygopro.StocGameMessage.MsgSpSummoned,
dispatch: AppDispatch
) => {
dispatch(fetchEsHintMeta({ originMsg: 1606 }));
};
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (
spSummoning: ygopro.StocGameMessage.MsgSpSummoning,
dispatch: AppDispatch
) => {
dispatch(
fetchEsHintMeta({
originMsg: "「[?]」特殊召唤宣言时",
cardID: spSummoning.code,
})
);
};
...@@ -8,6 +8,7 @@ import { ...@@ -8,6 +8,7 @@ import {
initCemetery, initCemetery,
initDeck, initDeck,
initExclusion, initExclusion,
initHint,
} from "../../reducers/duel/mod"; } from "../../reducers/duel/mod";
export default ( export default (
...@@ -45,4 +46,5 @@ export default ( ...@@ -45,4 +46,5 @@ export default (
dispatch(initDeck({ player: 1, deskSize: start.deckSize2 })); dispatch(initDeck({ player: 1, deskSize: start.deckSize2 }));
dispatch(initExclusion(0)); dispatch(initExclusion(0));
dispatch(initExclusion(1)); dispatch(initExclusion(1));
dispatch(initHint());
}; };
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (
_: ygopro.StocGameMessage.MsgSummoned,
dispatch: AppDispatch
) => {
dispatch(fetchEsHintMeta({ originMsg: 1604 }));
};
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (
summoning: ygopro.StocGameMessage.MsgSummoning,
dispatch: AppDispatch
) => {
dispatch(
fetchEsHintMeta({
originMsg: "「[?]」通常召唤宣言时",
cardID: summoning.code,
})
);
};
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { AppDispatch } from "../../store";
export default (
_swap: ygopro.StocGameMessage.MsgSwap,
dispatch: AppDispatch
) => {
dispatch(fetchEsHintMeta({ originMsg: 1602 }));
};
import { ygopro } from "../../api/ocgcore/idl/ocgcore"; import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { fetchEsHintMeta } from "../../reducers/duel/hintSlice";
import { updateHp } from "../../reducers/duel/mod"; import { updateHp } from "../../reducers/duel/mod";
import { AppDispatch } from "../../store"; import { AppDispatch } from "../../store";
import MsgUpdateHp = ygopro.StocGameMessage.MsgUpdateHp; import MsgUpdateHp = ygopro.StocGameMessage.MsgUpdateHp;
export default (msgUpdateHp: MsgUpdateHp, dispatch: AppDispatch) => { export default (msgUpdateHp: MsgUpdateHp, dispatch: AppDispatch) => {
if (msgUpdateHp.type_ == MsgUpdateHp.ActionType.DAMAGE) {
dispatch(fetchEsHintMeta({ originMsg: "玩家收到伤害时" })); // TODO: i18n
} else if (msgUpdateHp.type_ == MsgUpdateHp.ActionType.RECOVER) {
dispatch(fetchEsHintMeta({ originMsg: "玩家生命值回复时" })); // TODO: i18n
}
dispatch(updateHp(msgUpdateHp)); dispatch(updateHp(msgUpdateHp));
}; };
...@@ -22,7 +22,7 @@ import { ...@@ -22,7 +22,7 @@ import {
import { ThunderboltOutlined } from "@ant-design/icons"; import { ThunderboltOutlined } from "@ant-design/icons";
import NeosConfig from "../../../neos.config.json"; import NeosConfig from "../../../neos.config.json";
import DragModal from "./dragModal"; import DragModal from "./dragModal";
import { selectMeHint } from "../../reducers/duel/hintSlice"; import { selectHint } from "../../reducers/duel/hintSlice";
const CheckCardModal = () => { const CheckCardModal = () => {
const dispatch = store.dispatch; const dispatch = store.dispatch;
...@@ -34,7 +34,9 @@ const CheckCardModal = () => { ...@@ -34,7 +34,9 @@ const CheckCardModal = () => {
const cancelResponse = useAppSelector(selectCheckCardModalCacnelResponse); const cancelResponse = useAppSelector(selectCheckCardModalCacnelResponse);
const [response, setResponse] = useState<number[]>([]); const [response, setResponse] = useState<number[]>([]);
const defaultValue: number[] = []; const defaultValue: number[] = [];
const selectHint = useAppSelector(selectMeHint)?.esSelectHint || "请选择卡片"; const hint = useAppSelector(selectHint);
const preHintMsg = hint?.esHint || "";
const selectHintMsg = hint?.esSelectHint || "请选择卡片";
// TODO: 这里可以考虑更好地封装 // TODO: 这里可以考虑更好地封装
const sendResponseHandler = ( const sendResponseHandler = (
...@@ -57,7 +59,7 @@ const CheckCardModal = () => { ...@@ -57,7 +59,7 @@ const CheckCardModal = () => {
return ( return (
<DragModal <DragModal
title={`${selectHint} ${min}-${max}`} title={`${preHintMsg} ${selectHintMsg} ${min}-${max}`}
open={isOpen} open={isOpen}
closable={false} closable={false}
footer={ footer={
......
...@@ -20,7 +20,7 @@ import { ...@@ -20,7 +20,7 @@ import {
} from "../../reducers/duel/mod"; } from "../../reducers/duel/mod";
import NeosConfig from "../../../neos.config.json"; import NeosConfig from "../../../neos.config.json";
import DragModal from "./dragModal"; import DragModal from "./dragModal";
import { selectMeHint } from "../../reducers/duel/hintSlice"; import { selectHint } from "../../reducers/duel/hintSlice";
const CheckCardModalV2 = () => { const CheckCardModalV2 = () => {
const dispatch = store.dispatch; const dispatch = store.dispatch;
...@@ -33,30 +33,34 @@ const CheckCardModalV2 = () => { ...@@ -33,30 +33,34 @@ const CheckCardModalV2 = () => {
); );
const selectedOptions = useAppSelector(selectCheckCardModalV2SelectedOptions); const selectedOptions = useAppSelector(selectCheckCardModalV2SelectedOptions);
const responseable = useAppSelector(selectCheckCardModalV2ResponseAble); const responseable = useAppSelector(selectCheckCardModalV2ResponseAble);
const selectHint = useAppSelector(selectMeHint)?.esSelectHint || "请选择卡片"; const hint = useAppSelector(selectHint);
const preHintMsg = hint?.esHint || "";
const selectHintMsg = hint?.esSelectHint || "请选择卡片";
const onFinish = () => { const onFinishOrCancel = () => {
sendSelectUnselectCardResponse({ cancel_or_finish: true }); sendSelectUnselectCardResponse({ cancel_or_finish: true });
dispatch(setCheckCardModalV2IsOpen(false)); dispatch(setCheckCardModalV2IsOpen(false));
dispatch(resetCheckCardModalV2()); dispatch(resetCheckCardModalV2());
dispatch(setCheckCardModalV2ResponseAble(false)); dispatch(setCheckCardModalV2ResponseAble(false));
}; };
const onCancel = () => {
sendSelectUnselectCardResponse({ cancel_or_finish: true });
dispatch(setCheckCardModalV2ResponseAble(false));
};
return ( return (
<DragModal <DragModal
title={`${selectHint} ${min}-${max}`} title={`${preHintMsg} ${selectHintMsg} ${min}-${max}`}
open={isOpen} open={isOpen}
closable={false} closable={false}
footer={ footer={
<> <>
<Button disabled={!finishable || !responseable} onClick={onFinish}> <Button
disabled={!finishable || !responseable}
onClick={onFinishOrCancel}
>
finish finish
</Button> </Button>
<Button disabled={!cancelable || !responseable} onClick={onCancel}> <Button
disabled={!cancelable || !responseable}
onClick={onFinishOrCancel}
>
cancel cancel
</Button> </Button>
</> </>
......
...@@ -12,7 +12,7 @@ import { ...@@ -12,7 +12,7 @@ import {
import NeosConfig from "../../../neos.config.json"; import NeosConfig from "../../../neos.config.json";
import { selectCheckCardModalV3 } from "../../reducers/duel/modal/checkCardModalV3Slice"; import { selectCheckCardModalV3 } from "../../reducers/duel/modal/checkCardModalV3Slice";
import DragModal from "./dragModal"; import DragModal from "./dragModal";
import { selectMeHint } from "../../reducers/duel/hintSlice"; import { selectHint } from "../../reducers/duel/hintSlice";
const CheckCardModalV3 = () => { const CheckCardModalV3 = () => {
const dispatch = store.dispatch; const dispatch = store.dispatch;
...@@ -33,7 +33,9 @@ const CheckCardModalV3 = () => { ...@@ -33,7 +33,9 @@ const CheckCardModalV3 = () => {
.concat(selectedOptions) .concat(selectedOptions)
.map((option) => option.level2) .map((option) => option.level2)
.reduce((sum, current) => sum + current, 0); .reduce((sum, current) => sum + current, 0);
const selectHint = useAppSelector(selectMeHint)?.esSelectHint || "请选择卡片"; const hint = useAppSelector(selectHint);
const preHintMsg = hint?.esHint || "";
const selectHintMsg = hint?.esSelectHint || "请选择卡片";
const responseable = const responseable =
(overflow (overflow
...@@ -52,7 +54,7 @@ const CheckCardModalV3 = () => { ...@@ -52,7 +54,7 @@ const CheckCardModalV3 = () => {
return ( return (
<DragModal <DragModal
title={`${selectHint} ${min}-${max}`} title={`${preHintMsg} ${selectHintMsg} ${min}-${max}`}
open={isOpen} open={isOpen}
closable={false} closable={false}
footer={ footer={
......
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useAppSelector } from "../../hook"; import { useAppSelector } from "../../hook";
import { selectMeHint, selectOpHint } from "../../reducers/duel/hintSlice"; import { selectHint } from "../../reducers/duel/hintSlice";
import { selectCurrentPhase } from "../../reducers/duel/phaseSlice"; import { selectCurrentPhase } from "../../reducers/duel/phaseSlice";
import { notification } from "antd"; import { notification } from "antd";
import { selectDuelResult, selectWaiting } from "../../reducers/duel/mod"; import { selectDuelResult, selectWaiting } from "../../reducers/duel/mod";
...@@ -10,31 +10,23 @@ import MsgWin = ygopro.StocGameMessage.MsgWin; ...@@ -10,31 +10,23 @@ import MsgWin = ygopro.StocGameMessage.MsgWin;
import NeosConfig from "../../../neos.config.json"; import NeosConfig from "../../../neos.config.json";
const HintNotification = () => { const HintNotification = () => {
const meHint = useAppSelector(selectMeHint); const hint = useAppSelector(selectHint);
const opHint = useAppSelector(selectOpHint);
const currentPhase = useAppSelector(selectCurrentPhase); const currentPhase = useAppSelector(selectCurrentPhase);
const waiting = useAppSelector(selectWaiting); const waiting = useAppSelector(selectWaiting);
const result = useAppSelector(selectDuelResult); const result = useAppSelector(selectDuelResult);
const navigate = useNavigate(); const navigate = useNavigate();
const [api, contextHolder] = notification.useNotification(); const [api, contextHolder] = notification.useNotification({
useEffect(() => { maxCount: NeosConfig.ui.hint.maxCount,
if (meHint && meHint.msg) {
api.info({
message: `<我方>${meHint.msg}`,
placement: "bottom",
}); });
}
}, [meHint]);
useEffect(() => { useEffect(() => {
if (opHint && opHint.msg) { if (hint && hint.msg) {
api.info({ api.info({
message: `<对方>${opHint.msg}`, message: `${hint.msg}`,
placement: "top", placement: "bottom",
}); });
} }
}, [opHint]); }, [hint?.msg]);
useEffect(() => { useEffect(() => {
if (currentPhase) { if (currentPhase) {
......
...@@ -9,15 +9,18 @@ import { ...@@ -9,15 +9,18 @@ import {
} from "../../reducers/duel/modal/mod"; } from "../../reducers/duel/modal/mod";
import { setYesNoModalIsOpen } from "../../reducers/duel/mod"; import { setYesNoModalIsOpen } from "../../reducers/duel/mod";
import DragModal from "./dragModal"; import DragModal from "./dragModal";
import { selectHint } from "../../reducers/duel/hintSlice";
const YesNoModal = () => { const YesNoModal = () => {
const dispatch = store.dispatch; const dispatch = store.dispatch;
const isOpen = useAppSelector(selectYesNoModalIsOpen); const isOpen = useAppSelector(selectYesNoModalIsOpen);
const msg = useAppSelector(selectYesNOModalMsg); const msg = useAppSelector(selectYesNOModalMsg);
const hint = useAppSelector(selectHint);
const preHintMsg = hint?.esHint || "";
return ( return (
<DragModal <DragModal
title={msg} title={`${preHintMsg} ${msg}`}
open={isOpen} open={isOpen}
closable={false} closable={false}
footer={ footer={
......
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