Commit ddd5f1ac authored by Chunchi Che's avatar Chunchi Che

Merge branch 'optimize/move' into 'main'

Optimize/move

See merge request !75
parents d521a1cd 25910ff5
Pipeline #19515 passed with stages
in 3 minutes and 10 seconds
...@@ -22,7 +22,6 @@ export const initDeckImpl: CaseReducer< ...@@ -22,7 +22,6 @@ export const initDeckImpl: CaseReducer<
location: { location: {
controler: player, controler: player,
location: ygopro.CardZone.DECK, location: ygopro.CardZone.DECK,
sequence: i,
}, },
idleInteractivities: [], idleInteractivities: [],
}); });
......
...@@ -20,7 +20,6 @@ export const initFieldImpl: CaseReducer<DuelState, PayloadAction<number>> = ( ...@@ -20,7 +20,6 @@ export const initFieldImpl: CaseReducer<DuelState, PayloadAction<number>> = (
inner: { inner: {
location: { location: {
controler: player, controler: player,
sequence: 0,
location: ygopro.CardZone.ONFIELD, location: ygopro.CardZone.ONFIELD,
}, },
idleInteractivities: [], idleInteractivities: [],
...@@ -31,7 +30,6 @@ export const initFieldImpl: CaseReducer<DuelState, PayloadAction<number>> = ( ...@@ -31,7 +30,6 @@ export const initFieldImpl: CaseReducer<DuelState, PayloadAction<number>> = (
inner: { inner: {
location: { location: {
controler: player, controler: player,
sequence: 0,
location: ygopro.CardZone.ONFIELD, location: ygopro.CardZone.ONFIELD,
}, },
idleInteractivities: [], idleInteractivities: [],
......
...@@ -12,7 +12,6 @@ export interface CardState { ...@@ -12,7 +12,6 @@ export interface CardState {
location: { location: {
controler: number; controler: number;
location?: number; location?: number;
sequence: number;
position?: ygopro.CardPosition; position?: ygopro.CardPosition;
overlay_sequence?: number; overlay_sequence?: number;
}; // 位置信息 }; // 位置信息
...@@ -97,12 +96,11 @@ export function extendOccupant<T extends DuelFieldState>( ...@@ -97,12 +96,11 @@ export function extendOccupant<T extends DuelFieldState>(
position?: ygopro.CardPosition position?: ygopro.CardPosition
) { ) {
if (state) { if (state) {
for (const item of state.inner) { const target = state.inner.find((_, idx) => idx == sequence);
if (item.location.sequence == sequence) { if (target) {
item.occupant = newMeta; target.occupant = newMeta;
if (position) { if (position) {
item.location.position = position; target.location.position = position;
}
} }
} }
} }
...@@ -114,10 +112,9 @@ export function extendMeta<T extends DuelFieldState>( ...@@ -114,10 +112,9 @@ export function extendMeta<T extends DuelFieldState>(
sequence: number sequence: number
) { ) {
if (state) { if (state) {
for (const item of state.inner) { const target = state.inner.find((_, idx) => idx == sequence);
if (item.location.sequence == sequence) { if (target) {
item.occupant = newMeta; target.occupant = newMeta;
}
} }
} }
} }
...@@ -129,9 +126,9 @@ export function extendPlaceInteractivity<T extends DuelFieldState>( ...@@ -129,9 +126,9 @@ export function extendPlaceInteractivity<T extends DuelFieldState>(
zone: ygopro.CardZone zone: ygopro.CardZone
) { ) {
if (state) { if (state) {
for (let item of state.inner) { const target = state.inner.find((_, idx) => idx == sequence);
if (item.location.sequence == sequence) { if (target) {
item.placeInteractivities = { target.placeInteractivities = {
interactType: InteractType.PLACE_SELECTABLE, interactType: InteractType.PLACE_SELECTABLE,
response: { response: {
controler, controler,
...@@ -141,7 +138,6 @@ export function extendPlaceInteractivity<T extends DuelFieldState>( ...@@ -141,7 +138,6 @@ export function extendPlaceInteractivity<T extends DuelFieldState>(
}; };
} }
} }
}
} }
export function clearPlaceInteractivities<T extends DuelFieldState>( export function clearPlaceInteractivities<T extends DuelFieldState>(
...@@ -153,3 +149,34 @@ export function clearPlaceInteractivities<T extends DuelFieldState>( ...@@ -153,3 +149,34 @@ export function clearPlaceInteractivities<T extends DuelFieldState>(
} }
} }
} }
export function removeCard<T extends DuelFieldState>(
state: T | undefined,
sequence: number
) {
if (state) {
state.inner = state.inner.filter((_, idx) => idx != sequence);
}
}
export function removeOccupant<T extends DuelFieldState>(
state: T | undefined,
sequence: number
) {
if (state) {
const target = state.inner.find((_, idx) => idx == sequence);
if (target) {
target.occupant = undefined;
}
}
}
export function insertCard<T extends DuelFieldState>(
state: T | undefined,
sequence: number,
card: CardState
) {
if (state) {
state.inner.splice(sequence, 0, card);
}
}
...@@ -8,7 +8,14 @@ import { DuelState } from "./mod"; ...@@ -8,7 +8,14 @@ import { DuelState } from "./mod";
import { RootState } from "../../store"; import { RootState } from "../../store";
import { fetchCard, CardMeta } from "../../api/cards"; import { fetchCard, CardMeta } from "../../api/cards";
import { judgeSelf } from "./util"; import { judgeSelf } from "./util";
import { Interactivity, DuelFieldState } from "./generic"; import {
Interactivity,
DuelFieldState,
removeCard,
createAsyncMetaThunk,
insertCard,
extendMeta,
} from "./generic";
import { ygopro } from "../../api/ocgcore/idl/ocgcore"; import { ygopro } from "../../api/ocgcore/idl/ocgcore";
export interface HandState extends DuelFieldState {} export interface HandState extends DuelFieldState {}
...@@ -35,6 +42,56 @@ export const fetchHandsMeta = createAsyncThunk( ...@@ -35,6 +42,56 @@ export const fetchHandsMeta = createAsyncThunk(
} }
); );
// 清空手牌互动性
export const clearHandsIdleInteractivityImpl: CaseReducer<
DuelState,
PayloadAction<number>
> = (state, action) => {
const player = action.payload;
const hands = judgeSelf(player, state) ? state.meHands : state.opHands;
if (hands) {
for (let hand of hands.inner) {
hand.idleInteractivities = [];
}
}
};
// 添加手牌互动性
export const addHandsIdleInteractivityImpl: CaseReducer<
DuelState,
PayloadAction<{
player: number;
sequence: number;
interactivity: Interactivity<number>;
}>
> = (state, action) => {
const player = action.payload.player;
const hands = judgeSelf(player, state) ? state.meHands : state.opHands;
if (hands) {
const sequence = action.payload.sequence;
const interactivity = action.payload.interactivity;
hands.inner[sequence].idleInteractivities.push(interactivity);
}
};
// 删除手牌
export const removeHandImpl: CaseReducer<
DuelState,
PayloadAction<[number, number]>
> = (state, action) => {
const controler = action.payload[0];
const sequence = action.payload[1];
const hands = judgeSelf(controler, state) ? state.meHands : state.opHands;
removeCard(hands, sequence);
};
export const insertHandMeta = createAsyncMetaThunk("duel/insertHandMeta");
export const handsCase = (builder: ActionReducerMapBuilder<DuelState>) => { export const handsCase = (builder: ActionReducerMapBuilder<DuelState>) => {
builder.addCase(fetchHandsMeta.pending, (state, action) => { builder.addCase(fetchHandsMeta.pending, (state, action) => {
// Meta结果没返回之前先更新手牌`ID` // Meta结果没返回之前先更新手牌`ID`
...@@ -82,60 +139,33 @@ export const handsCase = (builder: ActionReducerMapBuilder<DuelState>) => { ...@@ -82,60 +139,33 @@ export const handsCase = (builder: ActionReducerMapBuilder<DuelState>) => {
} }
} }
}); });
};
// 清空手牌互动性 builder.addCase(insertHandMeta.pending, (state, action) => {
export const clearHandsIdleInteractivityImpl: CaseReducer< const controler = action.meta.arg.controler;
DuelState, const sequence = action.meta.arg.sequence;
PayloadAction<number> const code = action.meta.arg.code;
> = (state, action) => {
const player = action.payload;
const hands = judgeSelf(player, state) ? state.meHands : state.opHands; const hands = judgeSelf(controler, state) ? state.meHands : state.opHands;
if (hands) {
for (let hand of hands.inner) {
hand.idleInteractivities = [];
}
}
};
// 添加手牌互动性
export const addHandsIdleInteractivityImpl: CaseReducer<
DuelState,
PayloadAction<{
player: number;
sequence: number;
interactivity: Interactivity<number>;
}>
> = (state, action) => {
const player = action.payload.player;
const hands = judgeSelf(player, state) ? state.meHands : state.opHands; insertCard(hands, sequence, {
if (hands) { occupant: { id: code, data: {}, text: {} },
location: { controler },
idleInteractivities: [],
});
});
builder.addCase(insertHandMeta.fulfilled, (state, action) => {
const controler = action.payload.controler;
const sequence = action.payload.sequence; const sequence = action.payload.sequence;
const interactivity = action.payload.interactivity; const meta = action.payload.meta;
hands.inner[sequence].idleInteractivities.push(interactivity);
}
};
// 删除手牌
export const removeHandImpl: CaseReducer<
DuelState,
PayloadAction<[number, number]>
> = (state, action) => {
const controler = action.payload[0];
const sequence = action.payload[1];
const hands = judgeSelf(controler, state) ? state.meHands : state.opHands; const hands = judgeSelf(controler, state) ? state.meHands : state.opHands;
if (hands) {
hands.inner = hands.inner.filter( extendMeta(hands, meta, sequence);
(card) => card.location.sequence != sequence });
);
}
}; };
// 在特定位置增加手牌
export const selectMeHands = (state: RootState) => export const selectMeHands = (state: RootState) =>
state.duel.meHands || { inner: [] }; state.duel.meHands || { inner: [] };
export const selectOpHands = (state: RootState) => export const selectOpHands = (state: RootState) =>
......
...@@ -13,6 +13,7 @@ import { ...@@ -13,6 +13,7 @@ import {
extendOccupant, extendOccupant,
extendPlaceInteractivity, extendPlaceInteractivity,
clearPlaceInteractivities, clearPlaceInteractivities,
removeOccupant,
} from "./generic"; } from "./generic";
export interface MagicState extends DuelFieldState {} export interface MagicState extends DuelFieldState {}
...@@ -127,6 +128,18 @@ export const magicCase = (builder: ActionReducerMapBuilder<DuelState>) => { ...@@ -127,6 +128,18 @@ export const magicCase = (builder: ActionReducerMapBuilder<DuelState>) => {
}); });
}; };
// 删除魔法陷阱
export const removeMagicImpl: CaseReducer<
DuelState,
PayloadAction<{ controler: number; sequence: number }>
> = (state, action) => {
const controler = action.payload.controler;
const magics = judgeSelf(controler, state) ? state.meMagics : state.opMagics;
removeOccupant(magics, action.payload.sequence);
};
export const selectMeMagics = (state: RootState) => export const selectMeMagics = (state: RootState) =>
state.duel.meMagics || { inner: [] }; state.duel.meMagics || { inner: [] };
export const selectOpMagics = (state: RootState) => export const selectOpMagics = (state: RootState) =>
......
...@@ -46,6 +46,7 @@ import { ...@@ -46,6 +46,7 @@ import {
initMonstersImpl, initMonstersImpl,
addMonsterPlaceInteractivitiesImpl, addMonsterPlaceInteractivitiesImpl,
clearMonsterPlaceInteractivitiesImpl, clearMonsterPlaceInteractivitiesImpl,
removeMonsterImpl,
monsterCase, monsterCase,
} from "./monstersSlice"; } from "./monstersSlice";
import { import {
...@@ -53,6 +54,7 @@ import { ...@@ -53,6 +54,7 @@ import {
initMagicsImpl, initMagicsImpl,
addMagicPlaceInteractivitiesImpl, addMagicPlaceInteractivitiesImpl,
clearMagicPlaceInteractivitiesImpl, clearMagicPlaceInteractivitiesImpl,
removeMagicImpl,
magicCase, magicCase,
} from "./magicSlice"; } from "./magicSlice";
import { CemeteryState, initCemeteryImpl, cemeteryCase } from "./cemeretySlice"; import { CemeteryState, initCemeteryImpl, cemeteryCase } from "./cemeretySlice";
...@@ -135,11 +137,13 @@ const duelSlice = createSlice({ ...@@ -135,11 +137,13 @@ const duelSlice = createSlice({
initMonsters: initMonstersImpl, initMonsters: initMonstersImpl,
addMonsterPlaceInteractivities: addMonsterPlaceInteractivitiesImpl, addMonsterPlaceInteractivities: addMonsterPlaceInteractivitiesImpl,
clearMonsterPlaceInteractivities: clearMonsterPlaceInteractivitiesImpl, clearMonsterPlaceInteractivities: clearMonsterPlaceInteractivitiesImpl,
removeMonster: removeMonsterImpl,
// 魔法陷阱区相关`Reducer` // 魔法陷阱区相关`Reducer`
initMagics: initMagicsImpl, initMagics: initMagicsImpl,
addMagicPlaceInteractivities: addMagicPlaceInteractivitiesImpl, addMagicPlaceInteractivities: addMagicPlaceInteractivitiesImpl,
clearMagicPlaceInteractivities: clearMagicPlaceInteractivitiesImpl, clearMagicPlaceInteractivities: clearMagicPlaceInteractivitiesImpl,
removeMagic: removeMagicImpl,
// 墓地相关`Reducer` // 墓地相关`Reducer`
initCemetery: initCemeteryImpl, initCemetery: initCemeteryImpl,
...@@ -201,9 +205,11 @@ export const { ...@@ -201,9 +205,11 @@ export const {
initMonsters, initMonsters,
addMonsterPlaceInteractivities, addMonsterPlaceInteractivities,
clearMonsterPlaceInteractivities, clearMonsterPlaceInteractivities,
removeMonster,
initMagics, initMagics,
addMagicPlaceInteractivities, addMagicPlaceInteractivities,
clearMagicPlaceInteractivities, clearMagicPlaceInteractivities,
removeMagic,
removeHand, removeHand,
initCemetery, initCemetery,
setCardListModalIsOpen, setCardListModalIsOpen,
......
...@@ -13,6 +13,7 @@ import { ...@@ -13,6 +13,7 @@ import {
extendOccupant, extendOccupant,
extendPlaceInteractivity, extendPlaceInteractivity,
clearPlaceInteractivities, clearPlaceInteractivities,
removeOccupant,
} from "./generic"; } from "./generic";
export interface MonsterState extends DuelFieldState {} export interface MonsterState extends DuelFieldState {}
...@@ -137,6 +138,20 @@ export const monsterCase = (builder: ActionReducerMapBuilder<DuelState>) => { ...@@ -137,6 +138,20 @@ export const monsterCase = (builder: ActionReducerMapBuilder<DuelState>) => {
}); });
}; };
// 删除怪兽
export const removeMonsterImpl: CaseReducer<
DuelState,
PayloadAction<{ controler: number; sequence: number }>
> = (state, action) => {
const controler = action.payload.controler;
const monsters = judgeSelf(controler, state)
? state.meMonsters
: state.opMonsters;
removeOccupant(monsters, action.payload.sequence);
};
export const selectMeMonsters = (state: RootState) => export const selectMeMonsters = (state: RootState) =>
state.duel.meMonsters || { inner: [] }; state.duel.meMonsters || { inner: [] };
export const selectOpMonsters = (state: RootState) => export const selectOpMonsters = (state: RootState) =>
......
...@@ -2,9 +2,14 @@ import { ygopro } from "../../api/ocgcore/idl/ocgcore"; ...@@ -2,9 +2,14 @@ import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import MsgMove = ygopro.StocGameMessage.MsgMove; import MsgMove = ygopro.StocGameMessage.MsgMove;
import { AppDispatch } from "../../store"; import { AppDispatch } from "../../store";
import { fetchMonsterMeta } from "../../reducers/duel/monstersSlice"; import { fetchMonsterMeta } from "../../reducers/duel/monstersSlice";
import { removeHand } from "../../reducers/duel/mod"; import {
removeHand,
removeMagic,
removeMonster,
} from "../../reducers/duel/mod";
import { fetchMagicMeta } from "../../reducers/duel/magicSlice"; import { fetchMagicMeta } from "../../reducers/duel/magicSlice";
import { fetchCemeteryMeta } from "../../reducers/duel/cemeretySlice"; import { fetchCemeteryMeta } from "../../reducers/duel/cemeretySlice";
import { insertHandMeta } from "../../reducers/duel/handsSlice";
export default (move: MsgMove, dispatch: AppDispatch) => { export default (move: MsgMove, dispatch: AppDispatch) => {
const code = move.code; const code = move.code;
...@@ -18,6 +23,20 @@ export default (move: MsgMove, dispatch: AppDispatch) => { ...@@ -18,6 +23,20 @@ export default (move: MsgMove, dispatch: AppDispatch) => {
break; break;
} }
case ygopro.CardZone.MZONE: {
dispatch(
removeMonster({ controler: from.controler, sequence: from.sequence })
);
break;
}
case ygopro.CardZone.SZONE: {
dispatch(
removeMagic({ controler: from.controler, sequence: from.sequence })
);
break;
}
default: { default: {
console.log(`Unhandled zone type ${from.location}`); console.log(`Unhandled zone type ${from.location}`);
break; break;
...@@ -60,6 +79,13 @@ export default (move: MsgMove, dispatch: AppDispatch) => { ...@@ -60,6 +79,13 @@ export default (move: MsgMove, dispatch: AppDispatch) => {
break; break;
} }
case ygopro.CardZone.HAND: {
dispatch(
insertHandMeta({ controler: to.controler, sequence: to.sequence, code })
);
break;
}
default: { default: {
console.log(`Unhandled zone type ${to.location}`); console.log(`Unhandled zone type ${to.location}`);
......
...@@ -14,6 +14,7 @@ const Field = () => { ...@@ -14,6 +14,7 @@ const Field = () => {
{meField ? ( {meField ? (
<FixedSlot <FixedSlot
state={meField} state={meField}
sequence={0}
position={fieldPosition(0)} position={fieldPosition(0)}
rotation={CONFIG.CardSlotRotation(false)} rotation={CONFIG.CardSlotRotation(false)}
/> />
...@@ -23,6 +24,7 @@ const Field = () => { ...@@ -23,6 +24,7 @@ const Field = () => {
{opField ? ( {opField ? (
<FixedSlot <FixedSlot
state={opField} state={opField}
sequence={0}
position={fieldPosition(1)} position={fieldPosition(1)}
rotation={CONFIG.CardSlotRotation(true)} rotation={CONFIG.CardSlotRotation(true)}
/> />
......
...@@ -18,6 +18,7 @@ const shape = CONFIG.CardSlotShape(); ...@@ -18,6 +18,7 @@ const shape = CONFIG.CardSlotShape();
const FixedSlot = (props: { const FixedSlot = (props: {
state: CardState; state: CardState;
sequence: number;
position: BABYLON.Vector3; position: BABYLON.Vector3;
rotation: BABYLON.Vector3; rotation: BABYLON.Vector3;
deffenseRotation?: BABYLON.Vector3; deffenseRotation?: BABYLON.Vector3;
...@@ -67,7 +68,7 @@ const FixedSlot = (props: { ...@@ -67,7 +68,7 @@ const FixedSlot = (props: {
return ( return (
<plane <plane
name={`fixedslot-${props.state.location.sequence}`} name={`fixedslot-${props.sequence}`}
ref={planeRef} ref={planeRef}
width={shape.width} width={shape.width}
height={shape.height} height={shape.height}
...@@ -83,7 +84,7 @@ const FixedSlot = (props: { ...@@ -83,7 +84,7 @@ const FixedSlot = (props: {
edgesColor={edgesColor} edgesColor={edgesColor}
> >
<standardMaterial <standardMaterial
name={`fixedslot-mat-${props.state.location.sequence}`} name={`fixedslot-mat-${props.sequence}`}
diffuseTexture={ diffuseTexture={
props.state.occupant props.state.occupant
? faceDown ? faceDown
......
...@@ -19,21 +19,23 @@ const Magics = () => { ...@@ -19,21 +19,23 @@ const Magics = () => {
return ( return (
<> <>
{zip(meMagics, meMagicPositions).map(([magic, position]) => { {zip(meMagics, meMagicPositions).map(([magic, position], sequence) => {
return ( return (
<FixedSlot <FixedSlot
state={magic} state={magic}
key={magic.location.sequence} key={sequence}
sequence={sequence}
position={position} position={position}
rotation={CONFIG.CardSlotRotation(false)} rotation={CONFIG.CardSlotRotation(false)}
/> />
); );
})} })}
{zip(opMagics, opMagicPositions).map(([magic, position]) => { {zip(opMagics, opMagicPositions).map(([magic, position], sequence) => {
return ( return (
<FixedSlot <FixedSlot
state={magic} state={magic}
key={magic.location.sequence} key={sequence}
sequence={sequence}
position={position} position={position}
rotation={CONFIG.CardSlotRotation(true)} rotation={CONFIG.CardSlotRotation(true)}
/> />
...@@ -49,9 +51,7 @@ const magicPositions = (player: number, magics: CardState[]) => { ...@@ -49,9 +51,7 @@ const magicPositions = (player: number, magics: CardState[]) => {
const y = shape.depth / 2 + CONFIG.Floating; const y = shape.depth / 2 + CONFIG.Floating;
const z = player == 0 ? -2.6 : 2.6; const z = player == 0 ? -2.6 : 2.6;
return magics.map( return magics.map((_, sequence) => new BABYLON.Vector3(x(sequence), y, z));
(magic) => new BABYLON.Vector3(x(magic.location.sequence), y, z)
);
}; };
export default Magics; export default Magics;
...@@ -22,28 +22,34 @@ const Monsters = () => { ...@@ -22,28 +22,34 @@ const Monsters = () => {
return ( return (
<> <>
{zip(meMonsters, meMonsterPositions).map(([monster, position], idx) => { {zip(meMonsters, meMonsterPositions).map(
([monster, position], sequence) => {
return ( return (
<FixedSlot <FixedSlot
state={monster} state={monster}
key={idx} key={sequence}
sequence={sequence}
position={position} position={position}
rotation={CONFIG.CardSlotRotation(false)} rotation={CONFIG.CardSlotRotation(false)}
deffenseRotation={CONFIG.CardSlotDefenceRotation()} deffenseRotation={CONFIG.CardSlotDefenceRotation()}
/> />
); );
})} }
{zip(opMonsters, opMonsterPositions).map(([monster, position], idx) => { )}
{zip(opMonsters, opMonsterPositions).map(
([monster, position], sequence) => {
return ( return (
<FixedSlot <FixedSlot
state={monster} state={monster}
key={idx} key={sequence}
sequence={sequence}
position={position} position={position}
rotation={CONFIG.CardSlotRotation(true)} rotation={CONFIG.CardSlotRotation(true)}
deffenseRotation={CONFIG.CardSlotDefenceRotation()} deffenseRotation={CONFIG.CardSlotDefenceRotation()}
/> />
); );
})} }
)}
<ExtraMonsters /> <ExtraMonsters />
<ExtraMonsters /> <ExtraMonsters />
</> </>
...@@ -86,9 +92,7 @@ const monsterPositions = (player: number, monsters: CardState[]) => { ...@@ -86,9 +92,7 @@ const monsterPositions = (player: number, monsters: CardState[]) => {
const y = shape.depth / 2 + CONFIG.Floating; const y = shape.depth / 2 + CONFIG.Floating;
const z = player == 0 ? -1.35 : 1.35; const z = player == 0 ? -1.35 : 1.35;
return monsters.map( return monsters.map((_, sequence) => new BABYLON.Vector3(x(sequence), y, z));
(monster) => new BABYLON.Vector3(x(monster.location.sequence), y, z)
);
}; };
export default Monsters; export default Monsters;
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