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 {
}
}
export class StocGameMessage extends pb_1.Message {
#one_of_decls: number[][] = [[1, 2, 3]];
#one_of_decls: number[][] = [[1, 2, 3, 4]];
constructor(
data?:
| any[]
......@@ -3109,16 +3109,25 @@ export namespace ygopro {
start?: StocGameMessage.MsgStart;
draw?: never;
new_turn?: never;
new_phase?: never;
}
| {
start?: never;
draw?: StocGameMessage.MsgDraw;
new_turn?: never;
new_phase?: never;
}
| {
start?: never;
draw?: never;
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 {
if ("new_turn" in data && data.new_turn != undefined) {
this.new_turn = data.new_turn;
}
if ("new_phase" in data && data.new_phase != undefined) {
this.new_phase = data.new_phase;
}
}
}
get start() {
......@@ -3182,16 +3194,30 @@ export namespace ygopro {
get has_new_turn() {
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() {
const cases: {
[index: number]: "none" | "start" | "draw" | "new_turn";
[index: number]: "none" | "start" | "draw" | "new_turn" | "new_phase";
} = {
0: "none",
1: "start",
2: "draw",
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: {
start?: ReturnType<typeof StocGameMessage.MsgStart.prototype.toObject>;
......@@ -3199,6 +3225,9 @@ export namespace ygopro {
new_turn?: ReturnType<
typeof StocGameMessage.MsgNewTurn.prototype.toObject
>;
new_phase?: ReturnType<
typeof StocGameMessage.MsgNewPhase.prototype.toObject
>;
}): StocGameMessage {
const message = new StocGameMessage({});
if (data.start != null) {
......@@ -3210,6 +3239,11 @@ export namespace ygopro {
if (data.new_turn != null) {
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;
}
toObject() {
......@@ -3219,6 +3253,9 @@ export namespace ygopro {
new_turn?: ReturnType<
typeof StocGameMessage.MsgNewTurn.prototype.toObject
>;
new_phase?: ReturnType<
typeof StocGameMessage.MsgNewPhase.prototype.toObject
>;
} = {};
if (this.start != null) {
data.start = this.start.toObject();
......@@ -3229,6 +3266,9 @@ export namespace ygopro {
if (this.new_turn != null) {
data.new_turn = this.new_turn.toObject();
}
if (this.new_phase != null) {
data.new_phase = this.new_phase.toObject();
}
return data;
}
serialize(): Uint8Array;
......@@ -3243,6 +3283,10 @@ export namespace ygopro {
writer.writeMessage(3, this.new_turn, () =>
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();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): StocGameMessage {
......@@ -3275,6 +3319,14 @@ export namespace ygopro {
StocGameMessage.MsgNewTurn.deserialize(reader))
);
break;
case 4:
reader.readMessage(
message.new_phase,
() =>
(message.new_phase =
StocGameMessage.MsgNewPhase.deserialize(reader))
);
break;
default:
reader.skipField();
}
......@@ -3716,5 +3768,105 @@ export namespace ygopro {
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_INT8 = 1;
const OFFSET_UINT16 = 2;
const OFFSET_UINT32 = 4;
export class BufferReader {
......@@ -27,6 +28,13 @@ export class BufferReader {
return ret;
}
readUint16(): number {
const ret = this.dataView.getUint16(this.offset, this.littleEndian);
this.offset += OFFSET_UINT16;
return ret;
}
readUint32(): number {
const ret = this.dataView.getUint32(this.offset, this.littleEndian);
this.offset += OFFSET_UINT32;
......
......@@ -26,3 +26,4 @@ export const STOC_GAME_MSG = 1;
export const MSG_START = 4;
export const MSG_DRAW = 90;
export const MSG_NEW_TURN = 40;
export const MSG_NEW_PHASE = 41;
......@@ -9,6 +9,7 @@ import * as GAME_MSG from "../../protoDecl";
import MsgStartAdapter from "./start";
import MsgDrawAdapter from "./draw";
import MsgNewTurnAdapter from "./newTurn";
import MsgNewPhaseAdapter from "./newPhase";
/*
* STOC GameMsg
......@@ -49,6 +50,11 @@ export default class GameMsgAdapter implements StocAdapter {
break;
}
case GAME_MSG.MSG_NEW_PHASE: {
gameMsg.new_phase = MsgNewPhaseAdapter(gameData);
break;
}
default: {
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 {
meHandsCase,
} from "./handsSlice";
import { newTurnImpl } from "./turnSlice";
import { newPhaseImpl } from "./phaseSlice";
import { RootState } from "../../store";
export interface DuelState {
......@@ -20,6 +21,7 @@ export interface DuelState {
meHands?: Hands; // 自己的手牌
opHands?: Hands; // 对手的手牌
currentPlayer?: number; // 当前的操作方
currentPhase?: string; // 当前的阶段
}
const initialState: DuelState = {};
......@@ -33,14 +35,21 @@ const duelSlice = createSlice({
meAddHands: meAddHandsImpl,
opAddHands: opAddHandsImpl,
updateTurn: newTurnImpl,
updatePhase: newPhaseImpl,
},
extraReducers(builder) {
meHandsCase(builder);
},
});
export const { meInfoInit, opInfoInit, meAddHands, opAddHands, updateTurn } =
duelSlice.actions;
export const {
meInfoInit,
opInfoInit,
meAddHands,
opAddHands,
updateTurn,
updatePhase,
} = duelSlice.actions;
export const selectDuelHsStart = (state: RootState) => {
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";
import onMsgStart from "./start";
import onMsgDraw from "./draw";
import onMsgNewTurn from "./newTurn";
import onMsgNewPhase from "./newPhase";
export default function handleGameMsg(pb: ygopro.YgoStocMsg) {
const dispatch = store.dispatch;
......@@ -30,6 +31,13 @@ export default function handleGameMsg(pb: ygopro.YgoStocMsg) {
break;
}
case "new_phase": {
const newPhase = msg.new_phase;
onMsgNewPhase(newPhase, dispatch);
break;
}
default: {
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";
import * as CONFIG from "../../../config/ui";
import { Card } from "../../../api/cards";
import { selectCurrentPlayer } from "../../../reducers/duel/turnSlice";
import { selectCurrentPhase } from "../../../reducers/duel/phaseSlice";
// CONFIG
......@@ -36,6 +37,7 @@ export default class SimpleDuelPlateImpl implements IDuelPlate {
};
const hands = useAppSelector(this.handsSelector || defaultHandsSelector);
const currentPlayer = useAppSelector(selectCurrentPlayer);
const currentPhase = useAppSelector(selectCurrentPhase);
// ----- WebGL渲染 -----
const canvasRef = useRef<HTMLCanvasElement>(null);
......@@ -107,6 +109,8 @@ export default class SimpleDuelPlateImpl implements IDuelPlate {
// 当前操作玩家
console.log(`currentPlayer:` + currentPlayer);
// 当前阶段
console.log(`currentPhase:` + currentPhase);
// 渲染循环
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