Commit fb466b56 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/surrender' into 'main'

Feat/surrender

See merge request !143
parents 70518c92 20b60179
Pipeline #20767 passed with stages
in 14 minutes and 2 seconds
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><path d="M0 0h512v512H0z" fill="#000" fill-opacity="1"></path><g class="" transform="translate(0,0)" style=""><path d="M19.75 14.438c59.538 112.29 142.51 202.35 232.28 292.718l3.626 3.75.063-.062c21.827 21.93 44.04 43.923 66.405 66.25-18.856 14.813-38.974 28.2-59.938 40.312l28.532 28.53 68.717-68.717c42.337 27.636 76.286 63.646 104.094 105.81l28.064-28.06c-42.47-27.493-79.74-60.206-106.03-103.876l68.936-68.938-28.53-28.53c-11.115 21.853-24.413 42.015-39.47 60.593-43.852-43.8-86.462-85.842-130.125-125.47-.224-.203-.432-.422-.656-.625C183.624 122.75 108.515 63.91 19.75 14.437zm471.875 0c-83.038 46.28-154.122 100.78-221.97 161.156l22.814 21.562 56.81-56.812 13.22 13.187-56.438 56.44 24.594 23.186c61.802-66.92 117.6-136.92 160.97-218.72zm-329.53 125.906l200.56 200.53c-4.36 4.443-8.84 8.793-13.405 13.032L148.875 153.53l13.22-13.186zm-76.69 113.28l-28.5 28.532 68.907 68.906c-26.29 43.673-63.53 76.414-106 103.907l28.063 28.06c27.807-42.164 61.758-78.174 104.094-105.81l68.718 68.717 28.53-28.53c-20.962-12.113-41.08-25.5-59.937-40.313 17.865-17.83 35.61-35.433 53.157-52.97l-24.843-25.655-55.47 55.467c-4.565-4.238-9.014-8.62-13.374-13.062l55.844-55.844-24.53-25.374c-18.28 17.856-36.602 36.06-55.158 54.594-15.068-18.587-28.38-38.758-39.5-60.625z" fill="#fff" fill-opacity="1"></path></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><path d="M0 0h512v512H0z" fill="#000" fill-opacity="1"></path><g class="" transform="translate(0,0)" style=""><path d="M228.576 26.213v207.32h54.848V26.214h-54.848zm-28.518 45.744C108.44 96.58 41 180.215 41 279.605c0 118.74 96.258 215 215 215 118.74 0 215-96.26 215-215 0-99.39-67.44-183.025-159.057-207.647v50.47c64.6 22.994 110.85 84.684 110.85 157.177 0 92.117-74.676 166.794-166.793 166.794-92.118 0-166.794-74.678-166.794-166.795 0-72.494 46.25-134.183 110.852-157.178v-50.47z" fill="#fff" fill-opacity="1"></path></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><path d="M0 0h512v512H0z" fill="#000" fill-opacity="1"></path><g class="" transform="translate(0,0)" style=""><path d="M101.938 19.938c-8.837 0-15.813 6.978-15.813 15.812 0 7.358 4.84 13.427 11.563 15.25l23.134 55.4c-12.618 7.364-23.065 19.85-30.17 37.528L64.22 163.75l11.218 14.938 8.177-6.135c31.722-21.112 72.4-39.987 110.12-49.975l27.327-4.078-2.78-18.5-33.294 4.982c-13.01-4.957-25.152-7.096-36.113-6.607-3.67.164-7.202.62-10.6 1.334l-23.088-55.304c1.6-2.48 2.532-5.436 2.532-8.656 0-8.837-6.945-15.813-15.782-15.813zM178.81 147c-17.714 6.11-35.908 13.923-52.875 22.656l68.407 165.03 14.625-7.842 28.28-38.75L178.812 147zm169.094 111.53l-68.125 3.033-56.967 78-1.25 1.718-1.875 1.033-65.313 35.03-28.47 117.188h345.25l-15-63.686-165.56-54.688 5.874-17.75 89.905 29.688-38.47-129.563z" fill="#fff" fill-opacity="1"></path></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><path d="M0 0h512v512H0z" fill="#000" fill-opacity="1"></path><g class="" transform="translate(0,0)" style=""><path d="M145.3 23.89L89.27 257.7c5.62-4.9 12.93-5.8 19.63-4.4l54-225.21zm37 6.1l-57 231.41c1 .8 1.9 1.8 2.7 2.7 39.2-14 117.2-32 127.1 32.2 15.2 99.1 96.8 135.8 148.9 114.8-27.8-99.6 87.6-116.8 70.7-205.1 0 0-111 26.4-131.6-90.6-23.5-58.14-101.6-103.33-160.8-85.41zM101.4 270.9c-6.91 22.3-10.68 51.2.6 67.9 5.4 30.1 34 51.5 49.4 57.5-12.2 4.6-24.8 2.8-35.4-3.3-5.6 11.4-18.71 17.5-29.76 21 7.21 8.8 15.46 16.7 23.96 22.4 4.3 18.2 7.3 41.8 12.7 56.9h114.7c-31.7-18.6-56.8-42-61.3-69.9 8.6-18.2 10.5-46.2-.5-70.9-14.8-22.7-54.9-22.9-61.1-48.3-2.5-11.2 5.2-40.6-13.3-33.3zm-41.38 13c-7.17 1.5-11.98 8.3-10.24 14.7 8.66 1 17.82 2.2 26.53 3.8.38-4.1 1-8.2 1.73-12-6.18-2.5-12.48-4.8-18.02-6.5zm-16.91 32.2c-7.45 1.7-10.55 12.4-3.69 15.7 13.81.8 28.8 2.6 40.96 4.9-2-5-3.24-10.1-3.9-15.3-10.35-2.2-22.62-4.3-33.37-5.3zm-3.18 33.5c-8.95 5.5.2 16.2 4.7 18 15.57 2 29.64 2.7 41.1-1.8 4.51-2.5 4.29-4.4 2.89-8.3-16.82-3.7-33.26-6.4-48.69-7.9zm57.96 29.7c-12.54 8.9-32.12 8.5-44.89 7.4 1.64 6 7.89 9 10.92 10.2 9.37 3.7 22.37-1.1 33.47-8.4 3.21-2.7 4.51-8.7.5-9.2zm-45.46 32.2l-13.18 54.9 17.5 4.2 13-54.3c-6.59-.5-11.94-2.1-17.32-4.8z" fill="#fff" fill-opacity="1"></path></g></svg>
\ No newline at end of file
neos-protobuf @ 3383e74b
Subproject commit 6434c30b91cc28627fff3a7266c69b5b4e83d3aa
Subproject commit 3383e74b3f523574a91d4d41fa3a7a3602728cda
......@@ -61,6 +61,11 @@
"footer": {
"height": 80
}
},
"status": {
"avatarSize": 40,
"meAvatarColor": "#0e63e1",
"opAvatarColor": "#e10e68"
}
}
}
......@@ -61,6 +61,11 @@
"footer": {
"height": 80
}
},
"status": {
"avatarSize": 40,
"meAvatarColor": "#0e63e1",
"opAvatarColor": "#e10e68"
}
}
}
......@@ -363,7 +363,7 @@ export namespace ygopro {
}
}
export class YgoCtosMsg extends pb_1.Message {
#one_of_decls: number[][] = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]];
#one_of_decls: number[][] = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]];
constructor(
data?:
| any[]
......@@ -380,6 +380,7 @@ export namespace ygopro {
ctos_time_confirm?: never;
ctos_response?: never;
ctos_chat?: never;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
......@@ -393,6 +394,7 @@ export namespace ygopro {
ctos_time_confirm?: never;
ctos_response?: never;
ctos_chat?: never;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
......@@ -406,6 +408,7 @@ export namespace ygopro {
ctos_time_confirm?: never;
ctos_response?: never;
ctos_chat?: never;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
......@@ -419,6 +422,7 @@ export namespace ygopro {
ctos_time_confirm?: never;
ctos_response?: never;
ctos_chat?: never;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
......@@ -432,6 +436,7 @@ export namespace ygopro {
ctos_time_confirm?: never;
ctos_response?: never;
ctos_chat?: never;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
......@@ -445,6 +450,7 @@ export namespace ygopro {
ctos_time_confirm?: never;
ctos_response?: never;
ctos_chat?: never;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
......@@ -458,6 +464,7 @@ export namespace ygopro {
ctos_time_confirm?: never;
ctos_response?: never;
ctos_chat?: never;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
......@@ -471,6 +478,7 @@ export namespace ygopro {
ctos_time_confirm?: never;
ctos_response?: never;
ctos_chat?: never;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
......@@ -484,6 +492,7 @@ export namespace ygopro {
ctos_time_confirm?: CtosTimeConfirm;
ctos_response?: never;
ctos_chat?: never;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
......@@ -497,6 +506,7 @@ export namespace ygopro {
ctos_time_confirm?: never;
ctos_response?: CtosGameMsgResponse;
ctos_chat?: never;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
......@@ -510,6 +520,21 @@ export namespace ygopro {
ctos_time_confirm?: never;
ctos_response?: never;
ctos_chat?: CtosChat;
ctos_surrender?: never;
}
| {
ctos_player_info?: never;
ctos_join_game?: never;
ctos_update_deck?: never;
ctos_hs_ready?: never;
ctos_hs_start?: never;
ctos_hs_not_ready?: never;
ctos_hand_result?: never;
ctos_tp_result?: never;
ctos_time_confirm?: never;
ctos_response?: never;
ctos_chat?: never;
ctos_surrender?: CtosSurrender;
}
))
) {
......@@ -562,6 +587,9 @@ export namespace ygopro {
if ("ctos_chat" in data && data.ctos_chat != undefined) {
this.ctos_chat = data.ctos_chat;
}
if ("ctos_surrender" in data && data.ctos_surrender != undefined) {
this.ctos_surrender = data.ctos_surrender;
}
}
}
get ctos_player_info() {
......@@ -695,6 +723,19 @@ export namespace ygopro {
get has_ctos_chat() {
return pb_1.Message.getField(this, 11) != null;
}
get ctos_surrender() {
return pb_1.Message.getWrapperField(
this,
CtosSurrender,
12
) as CtosSurrender;
}
set ctos_surrender(value: CtosSurrender) {
pb_1.Message.setOneofWrapperField(this, 12, this.#one_of_decls[0], value);
}
get has_ctos_surrender() {
return pb_1.Message.getField(this, 12) != null;
}
get msg() {
const cases: {
[index: number]:
......@@ -709,7 +750,8 @@ export namespace ygopro {
| "ctos_tp_result"
| "ctos_time_confirm"
| "ctos_response"
| "ctos_chat";
| "ctos_chat"
| "ctos_surrender";
} = {
0: "none",
1: "ctos_player_info",
......@@ -723,9 +765,13 @@ export namespace ygopro {
9: "ctos_time_confirm",
10: "ctos_response",
11: "ctos_chat",
12: "ctos_surrender",
};
return cases[
pb_1.Message.computeOneofCase(this, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
pb_1.Message.computeOneofCase(
this,
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
)
];
}
static fromObject(data: {
......@@ -740,6 +786,7 @@ export namespace ygopro {
ctos_time_confirm?: ReturnType<typeof CtosTimeConfirm.prototype.toObject>;
ctos_response?: ReturnType<typeof CtosGameMsgResponse.prototype.toObject>;
ctos_chat?: ReturnType<typeof CtosChat.prototype.toObject>;
ctos_surrender?: ReturnType<typeof CtosSurrender.prototype.toObject>;
}): YgoCtosMsg {
const message = new YgoCtosMsg({});
if (data.ctos_player_info != null) {
......@@ -787,6 +834,9 @@ export namespace ygopro {
if (data.ctos_chat != null) {
message.ctos_chat = CtosChat.fromObject(data.ctos_chat);
}
if (data.ctos_surrender != null) {
message.ctos_surrender = CtosSurrender.fromObject(data.ctos_surrender);
}
return message;
}
toObject() {
......@@ -808,6 +858,7 @@ export namespace ygopro {
typeof CtosGameMsgResponse.prototype.toObject
>;
ctos_chat?: ReturnType<typeof CtosChat.prototype.toObject>;
ctos_surrender?: ReturnType<typeof CtosSurrender.prototype.toObject>;
} = {};
if (this.ctos_player_info != null) {
data.ctos_player_info = this.ctos_player_info.toObject();
......@@ -842,6 +893,9 @@ export namespace ygopro {
if (this.ctos_chat != null) {
data.ctos_chat = this.ctos_chat.toObject();
}
if (this.ctos_surrender != null) {
data.ctos_surrender = this.ctos_surrender.toObject();
}
return data;
}
serialize(): Uint8Array;
......@@ -892,6 +946,10 @@ export namespace ygopro {
writer.writeMessage(11, this.ctos_chat, () =>
this.ctos_chat.serialize(writer)
);
if (this.has_ctos_surrender)
writer.writeMessage(12, this.ctos_surrender, () =>
this.ctos_surrender.serialize(writer)
);
if (!w) return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): YgoCtosMsg {
......@@ -977,6 +1035,12 @@ export namespace ygopro {
() => (message.ctos_chat = CtosChat.deserialize(reader))
);
break;
case 12:
reader.readMessage(
message.ctos_surrender,
() => (message.ctos_surrender = CtosSurrender.deserialize(reader))
);
break;
default:
reader.skipField();
}
......@@ -2552,6 +2616,57 @@ export namespace ygopro {
return CtosChat.deserialize(bytes);
}
}
export class CtosSurrender extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {}) {
super();
pb_1.Message.initialize(
this,
Array.isArray(data) ? data : [],
0,
-1,
[],
this.#one_of_decls
);
if (!Array.isArray(data) && typeof data == "object") {
}
}
static fromObject(data: {}): CtosSurrender {
const message = new CtosSurrender({});
return message;
}
toObject() {
const data: {} = {};
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 (!w) return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): CtosSurrender {
const reader =
bytes instanceof pb_1.BinaryReader
? bytes
: new pb_1.BinaryReader(bytes),
message = new CtosSurrender();
while (reader.nextField()) {
if (reader.isEndGroup()) break;
switch (reader.getFieldNumber()) {
default:
reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): CtosSurrender {
return CtosSurrender.deserialize(bytes);
}
}
export class CtosGameMsgResponse extends pb_1.Message {
#one_of_decls: number[][] = [[1, 2, 3, 4, 5, 6, 7, 8, 9]];
constructor(
......
import { ygopro } from "../../idl/ocgcore";
import { YgoProPacket } from "../packet";
import { CTOS_SURRENDER } from "../protoDecl";
/*
* CTOS SURRENDER
*
* @param - null
*
* @usage - 告知服务端当前玩家投降
*
* */
export default class CtosSurrender extends YgoProPacket {
constructor(_: ygopro.YgoCtosMsg) {
super(1, CTOS_SURRENDER, new Uint8Array(0));
}
}
......@@ -12,6 +12,7 @@ export const CTOS_TP_RESULT = 4;
export const CTOS_TIME_CONFIRM = 21;
export const CTOS_RESPONSE = 1;
export const CTOS_CHAT = 22;
export const CTOS_SURRENDER = 0x14;
export const STOC_JOIN_GAME = 18;
export const STOC_CHAT = 25;
......
......@@ -13,6 +13,7 @@ import HsStartAdapter from "./ocgAdapter/ctos/ctosHsStart";
import HandResult from "./ocgAdapter/ctos/ctosHandResult";
import TpResult from "./ocgAdapter/ctos/ctosTpResult";
import TimeConfirm from "./ocgAdapter/ctos/ctosTimeConfirm";
import Surrender from "./ocgAdapter/ctos/ctosSurrender";
import GameMsgResponse from "./ocgAdapter/ctos/ctosGameMsgResponse/mod";
import Chat from "./ocgAdapter/ctos/ctosChat";
......@@ -120,6 +121,15 @@ export function sendTimeConfirm() {
socketMiddleWare({ cmd: socketCmd.SEND, payload });
}
export function sendSurrender() {
const surrender = new ygopro.YgoCtosMsg({
ctos_surrender: new ygopro.CtosSurrender({}),
});
const payload = new Surrender(surrender).serialize();
socketMiddleWare({ cmd: socketCmd.SEND, payload });
}
export function sendChat(message: string) {
const chat = new ygopro.YgoCtosMsg({
ctos_chat: new ygopro.CtosChat({ message }),
......
import { PayloadAction, CaseReducer } from "@reduxjs/toolkit";
import { RootState } from "../../store";
import { DuelState } from "./mod";
import { judgeSelf } from "./util";
export const newTurnImpl: CaseReducer<DuelState, PayloadAction<number>> = (
state,
......@@ -9,5 +10,5 @@ export const newTurnImpl: CaseReducer<DuelState, PayloadAction<number>> = (
state.currentPlayer = action.payload;
};
export const selectCurrentPlayer = (state: RootState) =>
state.duel.currentPlayer;
export const selectCurrentPlayerIsMe = (state: RootState) =>
judgeSelf(state.duel.currentPlayer!, state.duel);
......@@ -33,6 +33,7 @@ const footerStyle: React.CSSProperties = {
textAlign: "center",
height: layoutConfig.footer.height,
color: "#fff",
paddingLeft: `${layoutConfig.sider.width}px`,
};
const NeosLayout = (props: {
......
import React, { useEffect, useRef } from "react";
import React from "react";
import { Engine, Scene } from "react-babylonjs";
import { ReactReduxContext, Provider } from "react-redux";
import * as BABYLON from "@babylonjs/core";
......@@ -25,24 +25,16 @@ import DuelTimeLine from "./timeLine";
import { Row } from "antd";
import SendBox from "./sendBox";
import PlayerStatus from "./status";
import { useAppSelector } from "../../hook";
import {
selectMeInitInfo,
selectOpInitInfo,
} from "../../reducers/duel/initInfoSlice";
// Ref: https://github.com/brianzinn/react-babylonjs/issues/126
const NeosDuel = () => {
const meInfo = useAppSelector(selectMeInitInfo);
const opInfo = useAppSelector(selectOpInitInfo);
return (
<>
<NeosLayout
sider={<NeosSider />}
header={<PlayerStatus userName="UserName" hp={opInfo?.life || 0} />}
header={<PlayerStatus />}
content={<NeosCanvas />}
footer={<PlayerStatus userName="UserName" hp={meInfo?.life || 0} />}
footer={<Phase />}
/>
<CardModal />
<CardListModal />
......@@ -84,7 +76,6 @@ const NeosCanvas = () => (
<Cemeteries />
<Exclusion />
<Field />
<Phase />
<Ground />
</Provider>
</Scene>
......
import React from "react";
import React, { useState } from "react";
import { store } from "../../store";
import { useAppSelector } from "../../hook";
import {
......@@ -10,59 +10,49 @@ import {
import {
sendSelectBattleCmdResponse,
sendSelectIdleCmdResponse,
sendSurrender,
} from "../../api/ocgcore/ocgHelper";
import {
clearHandsIdleInteractivity,
clearMagicIdleInteractivities,
clearMonsterIdleInteractivities,
clearAllIdleInteractivities,
setEnableBp,
setEnableEp,
setEnableM2,
} from "../../reducers/duel/mod";
import { Button2D } from "./2d";
import { Button, Modal, Space } from "antd";
import Icon from "@ant-design/icons";
import { ReactComponent as BattleSvg } from "../../../neos-assets/crossed-swords.svg";
import { ReactComponent as Main2Svg } from "../../../neos-assets/sword-in-stone.svg";
import { ReactComponent as EpSvg } from "../../../neos-assets/power-button.svg";
import { ReactComponent as SurrenderSvg } from "../../../neos-assets/truce.svg";
const Bp = () => {
const dispatch = store.dispatch;
const enable = useAppSelector(selectEnableBp);
const onClick = () => {
// 清除一堆东西的互动性
dispatch(clearHandsIdleInteractivity(0));
dispatch(clearHandsIdleInteractivity(1));
dispatch(clearMonsterIdleInteractivities(0));
dispatch(clearMonsterIdleInteractivities(1));
dispatch(clearMagicIdleInteractivities(0));
dispatch(clearMagicIdleInteractivities(1));
sendSelectIdleCmdResponse(6);
dispatch(setEnableBp(false));
};
return <Button2D text="bp" left={-200} enable={enable} onClick={onClick} />;
};
const M2 = () => {
const dispatch = store.dispatch;
const enable = useAppSelector(selectEnableM2);
const onClick = () => {
// 清除一堆东西的互动性
dispatch(clearHandsIdleInteractivity(0));
dispatch(clearHandsIdleInteractivity(1));
dispatch(clearMonsterIdleInteractivities(0));
dispatch(clearMonsterIdleInteractivities(1));
dispatch(clearMagicIdleInteractivities(0));
dispatch(clearMagicIdleInteractivities(1));
sendSelectBattleCmdResponse(2);
dispatch(setEnableM2(false));
};
const IconSize = "150%";
const SpaceSize = 16;
return <Button2D text="m2" left={0} enable={enable} onClick={onClick} />;
const PhaseButton = (props: {
text: string;
enable: boolean;
onClick: () => void;
icon?: React.ReactNode;
}) => {
return (
<Button
icon={props.icon}
disabled={!props.enable}
onClick={props.onClick}
size="large"
>
{props.text}
</Button>
);
};
const Ep = () => {
const Phase = () => {
const dispatch = store.dispatch;
const enable = useAppSelector(selectEnableEp);
const enableBp = useAppSelector(selectEnableBp);
const enableM2 = useAppSelector(selectEnableM2);
const enableEp = useAppSelector(selectEnableEp);
const currentPhase = useAppSelector(selectCurrentPhase);
const [modalOpen, setModalOpen] = useState(false);
const response =
currentPhase === "BATTLE_START" ||
......@@ -73,35 +63,83 @@ const Ep = () => {
? 3
: 7;
const onClick = (response: number) => () => {
// 清除一堆东西的互动性
dispatch(clearHandsIdleInteractivity(0));
dispatch(clearHandsIdleInteractivity(1));
dispatch(clearMonsterIdleInteractivities(0));
dispatch(clearMonsterIdleInteractivities(1));
dispatch(clearMagicIdleInteractivities(0));
dispatch(clearMagicIdleInteractivities(1));
const onBp = () => {
dispatch(clearAllIdleInteractivities(0));
dispatch(clearAllIdleInteractivities(0));
sendSelectIdleCmdResponse(6);
dispatch(setEnableBp(false));
};
const onM2 = () => {
dispatch(clearAllIdleInteractivities(0));
dispatch(clearAllIdleInteractivities(0));
sendSelectBattleCmdResponse(2);
dispatch(setEnableM2(false));
};
const onEp = () => {
dispatch(clearAllIdleInteractivities(0));
dispatch(clearAllIdleInteractivities(0));
sendSelectIdleCmdResponse(response);
dispatch(setEnableEp(false));
};
const onSurrender = () => {
setModalOpen(true);
};
return (
<Button2D
text="ep"
left={200}
enable={enable}
onClick={onClick(response)}
/>
<Space wrap size={SpaceSize}>
<PhaseButton
icon={<Icon component={BattleSvg} style={{ fontSize: IconSize }} />}
enable={enableBp}
text="战斗阶段"
onClick={onBp}
/>
<PhaseButton
icon={<Icon component={Main2Svg} style={{ fontSize: IconSize }} />}
enable={enableM2}
text="主要阶段2"
onClick={onM2}
/>
<PhaseButton
icon={<Icon component={EpSvg} style={{ fontSize: IconSize }} />}
enable={enableEp}
text="结束回合"
onClick={onEp}
/>
<PhaseButton
icon={<Icon component={SurrenderSvg} style={{ fontSize: IconSize }} />}
enable={true}
text="投降"
onClick={onSurrender}
/>
<Modal
title="是否确认要投降?"
open={modalOpen}
closable={false}
footer={
<>
<Button
onClick={() => {
sendSurrender();
setModalOpen(false);
}}
>
Yes
</Button>
<Button
onClick={() => {
setModalOpen(false);
}}
>
No
</Button>
</>
}
/>
</Space>
);
};
const Phase = () => (
<>
<Bp />
<M2 />
<Ep />
</>
);
export default Phase;
import React from "react";
import { UserOutlined, BackwardOutlined } from "@ant-design/icons";
import { Avatar, Space, Statistic } from "antd";
import { UserOutlined } from "@ant-design/icons";
import { Avatar } from "antd";
import { CheckCard } from "@ant-design/pro-components";
import NeosConfig from "../../../neos.config.json";
import { useAppSelector } from "../../hook";
import {
selectMeInitInfo,
selectOpInitInfo,
} from "../../reducers/duel/initInfoSlice";
import { selectCurrentPlayerIsMe } from "../../reducers/duel/turnSlice";
const spaceSize = 20;
const Config = NeosConfig.ui.status;
const avatarSize = 40;
const ME_VALUE = "myself";
const OP_VALUE = "opponent";
const PlayerStatus = (props: { userName: string; hp: number }) => (
<Space size={spaceSize} direction="horizontal">
<Space wrap size={spaceSize}>
<Avatar size={avatarSize} icon={<UserOutlined />} />
</Space>
<Space wrap size={spaceSize}>
{props.userName}
</Space>
<Space wrap size={spaceSize}>
<Statistic title="Hp" value={props.hp} />
</Space>
<Space wrap size={spaceSize}>
<Avatar
size={avatarSize}
style={{ color: "red" }}
icon={<BackwardOutlined />}
const PlayerStatus = () => {
const meInfo = useAppSelector(selectMeInitInfo);
const opInfo = useAppSelector(selectOpInitInfo);
const myTurn = useAppSelector(selectCurrentPlayerIsMe);
return (
<CheckCard.Group
bordered
style={{ height: `${NeosConfig.ui.layout.header.height}` }}
value={myTurn ? ME_VALUE : OP_VALUE}
>
<CheckCard
avatar={
<Avatar
size={avatarSize}
style={{ backgroundColor: Config.opAvatarColor }}
icon={<UserOutlined />}
/>
}
title={OP_VALUE}
description={`Lp: ${opInfo?.life || 0}`}
value={OP_VALUE}
style={{
position: "absolute",
left: `${NeosConfig.ui.layout.sider.width}px`,
}}
/>
<CheckCard
avatar={
<Avatar
size={avatarSize}
style={{ backgroundColor: Config.meAvatarColor }}
icon={<UserOutlined />}
/>
}
title={ME_VALUE}
description={`Lp: ${meInfo?.life || 0}`}
value={ME_VALUE}
style={{
position: "absolute",
right: "0px",
}}
/>
</Space>
</Space>
);
</CheckCard.Group>
);
};
export default PlayerStatus;
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