Commit 426b4473 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/new_phase' into 'main'

Feat/new phase

See merge request !28
parents 4ff2f37c ff75a890
Pipeline #18313 passed with stages
in 2 minutes and 19 seconds
Subproject commit f4278cdb78436dd2fd2a521f825c7498eef7b65d Subproject commit 2006e72d50bfb10cf78573eb6327a3e8ded39133
...@@ -3100,7 +3100,7 @@ export namespace ygopro { ...@@ -3100,7 +3100,7 @@ export namespace ygopro {
} }
} }
export class StocGameMessage extends pb_1.Message { export class StocGameMessage extends pb_1.Message {
#one_of_decls: number[][] = [[1, 2, 3]]; #one_of_decls: number[][] = [[1, 2, 3, 4]];
constructor( constructor(
data?: data?:
| any[] | any[]
...@@ -3109,16 +3109,25 @@ export namespace ygopro { ...@@ -3109,16 +3109,25 @@ export namespace ygopro {
start?: StocGameMessage.MsgStart; start?: StocGameMessage.MsgStart;
draw?: never; draw?: never;
new_turn?: never; new_turn?: never;
new_phase?: never;
} }
| { | {
start?: never; start?: never;
draw?: StocGameMessage.MsgDraw; draw?: StocGameMessage.MsgDraw;
new_turn?: never; new_turn?: never;
new_phase?: never;
} }
| { | {
start?: never; start?: never;
draw?: never; draw?: never;
new_turn?: StocGameMessage.MsgNewTurn; new_turn?: StocGameMessage.MsgNewTurn;
new_phase?: never;
}
| {
start?: never;
draw?: never;
new_turn?: never;
new_phase?: StocGameMessage.MsgNewPhase;
} }
)) ))
) { ) {
...@@ -3141,6 +3150,9 @@ export namespace ygopro { ...@@ -3141,6 +3150,9 @@ export namespace ygopro {
if ("new_turn" in data && data.new_turn != undefined) { if ("new_turn" in data && data.new_turn != undefined) {
this.new_turn = data.new_turn; this.new_turn = data.new_turn;
} }
if ("new_phase" in data && data.new_phase != undefined) {
this.new_phase = data.new_phase;
}
} }
} }
get start() { get start() {
...@@ -3182,16 +3194,30 @@ export namespace ygopro { ...@@ -3182,16 +3194,30 @@ export namespace ygopro {
get has_new_turn() { get has_new_turn() {
return pb_1.Message.getField(this, 3) != null; return pb_1.Message.getField(this, 3) != null;
} }
get new_phase() {
return pb_1.Message.getWrapperField(
this,
StocGameMessage.MsgNewPhase,
4
) as StocGameMessage.MsgNewPhase;
}
set new_phase(value: StocGameMessage.MsgNewPhase) {
pb_1.Message.setOneofWrapperField(this, 4, this.#one_of_decls[0], value);
}
get has_new_phase() {
return pb_1.Message.getField(this, 4) != null;
}
get gameMsg() { get gameMsg() {
const cases: { const cases: {
[index: number]: "none" | "start" | "draw" | "new_turn"; [index: number]: "none" | "start" | "draw" | "new_turn" | "new_phase";
} = { } = {
0: "none", 0: "none",
1: "start", 1: "start",
2: "draw", 2: "draw",
3: "new_turn", 3: "new_turn",
4: "new_phase",
}; };
return cases[pb_1.Message.computeOneofCase(this, [1, 2, 3])]; return cases[pb_1.Message.computeOneofCase(this, [1, 2, 3, 4])];
} }
static fromObject(data: { static fromObject(data: {
start?: ReturnType<typeof StocGameMessage.MsgStart.prototype.toObject>; start?: ReturnType<typeof StocGameMessage.MsgStart.prototype.toObject>;
...@@ -3199,6 +3225,9 @@ export namespace ygopro { ...@@ -3199,6 +3225,9 @@ export namespace ygopro {
new_turn?: ReturnType< new_turn?: ReturnType<
typeof StocGameMessage.MsgNewTurn.prototype.toObject typeof StocGameMessage.MsgNewTurn.prototype.toObject
>; >;
new_phase?: ReturnType<
typeof StocGameMessage.MsgNewPhase.prototype.toObject
>;
}): StocGameMessage { }): StocGameMessage {
const message = new StocGameMessage({}); const message = new StocGameMessage({});
if (data.start != null) { if (data.start != null) {
...@@ -3210,6 +3239,11 @@ export namespace ygopro { ...@@ -3210,6 +3239,11 @@ export namespace ygopro {
if (data.new_turn != null) { if (data.new_turn != null) {
message.new_turn = StocGameMessage.MsgNewTurn.fromObject(data.new_turn); message.new_turn = StocGameMessage.MsgNewTurn.fromObject(data.new_turn);
} }
if (data.new_phase != null) {
message.new_phase = StocGameMessage.MsgNewPhase.fromObject(
data.new_phase
);
}
return message; return message;
} }
toObject() { toObject() {
...@@ -3219,6 +3253,9 @@ export namespace ygopro { ...@@ -3219,6 +3253,9 @@ export namespace ygopro {
new_turn?: ReturnType< new_turn?: ReturnType<
typeof StocGameMessage.MsgNewTurn.prototype.toObject typeof StocGameMessage.MsgNewTurn.prototype.toObject
>; >;
new_phase?: ReturnType<
typeof StocGameMessage.MsgNewPhase.prototype.toObject
>;
} = {}; } = {};
if (this.start != null) { if (this.start != null) {
data.start = this.start.toObject(); data.start = this.start.toObject();
...@@ -3229,6 +3266,9 @@ export namespace ygopro { ...@@ -3229,6 +3266,9 @@ export namespace ygopro {
if (this.new_turn != null) { if (this.new_turn != null) {
data.new_turn = this.new_turn.toObject(); data.new_turn = this.new_turn.toObject();
} }
if (this.new_phase != null) {
data.new_phase = this.new_phase.toObject();
}
return data; return data;
} }
serialize(): Uint8Array; serialize(): Uint8Array;
...@@ -3243,6 +3283,10 @@ export namespace ygopro { ...@@ -3243,6 +3283,10 @@ export namespace ygopro {
writer.writeMessage(3, this.new_turn, () => writer.writeMessage(3, this.new_turn, () =>
this.new_turn.serialize(writer) this.new_turn.serialize(writer)
); );
if (this.has_new_phase)
writer.writeMessage(4, this.new_phase, () =>
this.new_phase.serialize(writer)
);
if (!w) return writer.getResultBuffer(); if (!w) return writer.getResultBuffer();
} }
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): StocGameMessage { static deserialize(bytes: Uint8Array | pb_1.BinaryReader): StocGameMessage {
...@@ -3275,6 +3319,14 @@ export namespace ygopro { ...@@ -3275,6 +3319,14 @@ export namespace ygopro {
StocGameMessage.MsgNewTurn.deserialize(reader)) StocGameMessage.MsgNewTurn.deserialize(reader))
); );
break; break;
case 4:
reader.readMessage(
message.new_phase,
() =>
(message.new_phase =
StocGameMessage.MsgNewPhase.deserialize(reader))
);
break;
default: default:
reader.skipField(); reader.skipField();
} }
...@@ -3716,5 +3768,105 @@ export namespace ygopro { ...@@ -3716,5 +3768,105 @@ export namespace ygopro {
return MsgNewTurn.deserialize(bytes); return MsgNewTurn.deserialize(bytes);
} }
} }
export class MsgNewPhase extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(
data?:
| any[]
| {
phase_type?: StocGameMessage.MsgNewPhase.PhaseType;
}
) {
super();
pb_1.Message.initialize(
this,
Array.isArray(data) ? data : [],
0,
-1,
[],
this.#one_of_decls
);
if (!Array.isArray(data) && typeof data == "object") {
if ("phase_type" in data && data.phase_type != undefined) {
this.phase_type = data.phase_type;
}
}
}
get phase_type() {
return pb_1.Message.getFieldWithDefault(
this,
1,
StocGameMessage.MsgNewPhase.PhaseType.UNKNOWN
) as StocGameMessage.MsgNewPhase.PhaseType;
}
set phase_type(value: StocGameMessage.MsgNewPhase.PhaseType) {
pb_1.Message.setField(this, 1, value);
}
static fromObject(data: {
phase_type?: StocGameMessage.MsgNewPhase.PhaseType;
}): MsgNewPhase {
const message = new MsgNewPhase({});
if (data.phase_type != null) {
message.phase_type = data.phase_type;
}
return message;
}
toObject() {
const data: {
phase_type?: StocGameMessage.MsgNewPhase.PhaseType;
} = {};
if (this.phase_type != null) {
data.phase_type = this.phase_type;
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.phase_type != StocGameMessage.MsgNewPhase.PhaseType.UNKNOWN)
writer.writeEnum(1, this.phase_type);
if (!w) return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): MsgNewPhase {
const reader =
bytes instanceof pb_1.BinaryReader
? bytes
: new pb_1.BinaryReader(bytes),
message = new MsgNewPhase();
while (reader.nextField()) {
if (reader.isEndGroup()) break;
switch (reader.getFieldNumber()) {
case 1:
message.phase_type = reader.readEnum();
break;
default:
reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): MsgNewPhase {
return MsgNewPhase.deserialize(bytes);
}
}
export namespace MsgNewPhase {
export enum PhaseType {
UNKNOWN = 0,
DRAW = 1,
STANDBY = 2,
MAIN1 = 3,
BATTLE_START = 4,
BATTLE_STEP = 5,
DAMAGE = 6,
DAMAGE_GAL = 7,
BATTLE = 8,
MAIN2 = 9,
END = 10,
}
}
} }
} }
const OFFSET_UINT8 = 1; const OFFSET_UINT8 = 1;
const OFFSET_INT8 = 1; const OFFSET_INT8 = 1;
const OFFSET_UINT16 = 2;
const OFFSET_UINT32 = 4; const OFFSET_UINT32 = 4;
export class BufferReader { export class BufferReader {
...@@ -27,6 +28,13 @@ export class BufferReader { ...@@ -27,6 +28,13 @@ export class BufferReader {
return ret; return ret;
} }
readUint16(): number {
const ret = this.dataView.getUint16(this.offset, this.littleEndian);
this.offset += OFFSET_UINT16;
return ret;
}
readUint32(): number { readUint32(): number {
const ret = this.dataView.getUint32(this.offset, this.littleEndian); const ret = this.dataView.getUint32(this.offset, this.littleEndian);
this.offset += OFFSET_UINT32; this.offset += OFFSET_UINT32;
......
...@@ -26,3 +26,4 @@ export const STOC_GAME_MSG = 1; ...@@ -26,3 +26,4 @@ export const STOC_GAME_MSG = 1;
export const MSG_START = 4; export const MSG_START = 4;
export const MSG_DRAW = 90; export const MSG_DRAW = 90;
export const MSG_NEW_TURN = 40; export const MSG_NEW_TURN = 40;
export const MSG_NEW_PHASE = 41;
...@@ -9,6 +9,7 @@ import * as GAME_MSG from "../../protoDecl"; ...@@ -9,6 +9,7 @@ import * as GAME_MSG from "../../protoDecl";
import MsgStartAdapter from "./start"; import MsgStartAdapter from "./start";
import MsgDrawAdapter from "./draw"; import MsgDrawAdapter from "./draw";
import MsgNewTurnAdapter from "./newTurn"; import MsgNewTurnAdapter from "./newTurn";
import MsgNewPhaseAdapter from "./newPhase";
/* /*
* STOC GameMsg * STOC GameMsg
...@@ -49,6 +50,11 @@ export default class GameMsgAdapter implements StocAdapter { ...@@ -49,6 +50,11 @@ export default class GameMsgAdapter implements StocAdapter {
break; break;
} }
case GAME_MSG.MSG_NEW_PHASE: {
gameMsg.new_phase = MsgNewPhaseAdapter(gameData);
break;
}
default: { default: {
console.log("Unhandled GameMessage function=", func); console.log("Unhandled GameMessage function=", func);
......
import { ygopro } from "../../../idl/ocgcore";
import { BufferReader } from "../../bufferIO";
const LITTLE_ENDIAN = true;
/*
* Msg New Phase
*
* @param phase: uint16 - 下一个阶段
*
* @usage - 服务端告诉前端下一个阶段
* */
export default (data: Uint8Array) => {
const reader = new BufferReader(data, LITTLE_ENDIAN);
const phase = reader.readUint16();
let phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.UNKNOWN;
switch (phase) {
case 0x01: {
phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.DRAW;
break;
}
case 0x02: {
phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.STANDBY;
break;
}
case 0x04: {
phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.MAIN1;
break;
}
case 0x08: {
phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.BATTLE_START;
break;
}
case 0x10: {
phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.BATTLE_STEP;
break;
}
case 0x20: {
phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.DAMAGE;
break;
}
case 0x40: {
phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.DAMAGE_GAL;
break;
}
case 0x80: {
phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.BATTLE;
break;
}
case 0x100: {
phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.MAIN2;
break;
}
case 0x200: {
phaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType.END;
break;
}
default: {
break;
}
}
return new ygopro.StocGameMessage.MsgNewPhase({
phase_type: phaseType,
});
};
...@@ -12,6 +12,7 @@ import { ...@@ -12,6 +12,7 @@ import {
meHandsCase, meHandsCase,
} from "./handsSlice"; } from "./handsSlice";
import { newTurnImpl } from "./turnSlice"; import { newTurnImpl } from "./turnSlice";
import { newPhaseImpl } from "./phaseSlice";
import { RootState } from "../../store"; import { RootState } from "../../store";
export interface DuelState { export interface DuelState {
...@@ -20,6 +21,7 @@ export interface DuelState { ...@@ -20,6 +21,7 @@ export interface DuelState {
meHands?: Hands; // 自己的手牌 meHands?: Hands; // 自己的手牌
opHands?: Hands; // 对手的手牌 opHands?: Hands; // 对手的手牌
currentPlayer?: number; // 当前的操作方 currentPlayer?: number; // 当前的操作方
currentPhase?: string; // 当前的阶段
} }
const initialState: DuelState = {}; const initialState: DuelState = {};
...@@ -33,14 +35,21 @@ const duelSlice = createSlice({ ...@@ -33,14 +35,21 @@ const duelSlice = createSlice({
meAddHands: meAddHandsImpl, meAddHands: meAddHandsImpl,
opAddHands: opAddHandsImpl, opAddHands: opAddHandsImpl,
updateTurn: newTurnImpl, updateTurn: newTurnImpl,
updatePhase: newPhaseImpl,
}, },
extraReducers(builder) { extraReducers(builder) {
meHandsCase(builder); meHandsCase(builder);
}, },
}); });
export const { meInfoInit, opInfoInit, meAddHands, opAddHands, updateTurn } = export const {
duelSlice.actions; meInfoInit,
opInfoInit,
meAddHands,
opAddHands,
updateTurn,
updatePhase,
} = duelSlice.actions;
export const selectDuelHsStart = (state: RootState) => { export const selectDuelHsStart = (state: RootState) => {
return state.duel.meInitInfo != null; return state.duel.meInitInfo != null;
}; };
......
import { PayloadAction, CaseReducer } from "@reduxjs/toolkit";
import { RootState } from "../../store";
import { DuelState } from "./mod";
export const newPhaseImpl: CaseReducer<DuelState, PayloadAction<string>> = (
state,
action
) => {
state.currentPhase = action.payload;
};
export const selectCurrentPhase = (state: RootState) => state.duel.currentPhase;
...@@ -3,6 +3,7 @@ import { store } from "../../store"; ...@@ -3,6 +3,7 @@ import { store } from "../../store";
import onMsgStart from "./start"; import onMsgStart from "./start";
import onMsgDraw from "./draw"; import onMsgDraw from "./draw";
import onMsgNewTurn from "./newTurn"; import onMsgNewTurn from "./newTurn";
import onMsgNewPhase from "./newPhase";
export default function handleGameMsg(pb: ygopro.YgoStocMsg) { export default function handleGameMsg(pb: ygopro.YgoStocMsg) {
const dispatch = store.dispatch; const dispatch = store.dispatch;
...@@ -30,6 +31,13 @@ export default function handleGameMsg(pb: ygopro.YgoStocMsg) { ...@@ -30,6 +31,13 @@ export default function handleGameMsg(pb: ygopro.YgoStocMsg) {
break; break;
} }
case "new_phase": {
const newPhase = msg.new_phase;
onMsgNewPhase(newPhase, dispatch);
break;
}
default: { default: {
console.log("Unhandled GameMsg=" + msg.gameMsg); console.log("Unhandled GameMsg=" + msg.gameMsg);
......
import { ygopro } from "../../api/ocgcore/idl/ocgcore";
import { AppDispatch } from "../../store";
import { updatePhase } from "../../reducers/duel/mod";
export default (
newPhase: ygopro.StocGameMessage.MsgNewPhase,
dispatch: AppDispatch
) => {
dispatch(updatePhase(newPhase.phase_type.toString()));
};
...@@ -19,6 +19,7 @@ import renderField from "./field"; ...@@ -19,6 +19,7 @@ import renderField from "./field";
import * as CONFIG from "../../../config/ui"; import * as CONFIG from "../../../config/ui";
import { Card } from "../../../api/cards"; import { Card } from "../../../api/cards";
import { selectCurrentPlayer } from "../../../reducers/duel/turnSlice"; import { selectCurrentPlayer } from "../../../reducers/duel/turnSlice";
import { selectCurrentPhase } from "../../../reducers/duel/phaseSlice";
// CONFIG // CONFIG
...@@ -36,6 +37,7 @@ export default class SimpleDuelPlateImpl implements IDuelPlate { ...@@ -36,6 +37,7 @@ export default class SimpleDuelPlateImpl implements IDuelPlate {
}; };
const hands = useAppSelector(this.handsSelector || defaultHandsSelector); const hands = useAppSelector(this.handsSelector || defaultHandsSelector);
const currentPlayer = useAppSelector(selectCurrentPlayer); const currentPlayer = useAppSelector(selectCurrentPlayer);
const currentPhase = useAppSelector(selectCurrentPhase);
// ----- WebGL渲染 ----- // ----- WebGL渲染 -----
const canvasRef = useRef<HTMLCanvasElement>(null); const canvasRef = useRef<HTMLCanvasElement>(null);
...@@ -107,6 +109,8 @@ export default class SimpleDuelPlateImpl implements IDuelPlate { ...@@ -107,6 +109,8 @@ export default class SimpleDuelPlateImpl implements IDuelPlate {
// 当前操作玩家 // 当前操作玩家
console.log(`currentPlayer:` + currentPlayer); console.log(`currentPlayer:` + currentPlayer);
// 当前阶段
console.log(`currentPhase:` + currentPhase);
// 渲染循环 // 渲染循环
engine.runRenderLoop(() => { engine.runRenderLoop(() => {
......
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