card_svr/src/rooms/commands/GameResultCommand.ts

232 lines
8.0 KiB
TypeScript

import {Command} from "@colyseus/command";
import {CardGameState} from "../schema/CardGameState";
import {GameStateConst} from "../../constants/GameStateConst";
import {PlayerStateConst} from "../../constants/PlayerStateConst";
import {Pet} from "../schema/Pet";
import {GameEnv} from "../../cfg/GameEnv";
import {debugRoom, error} from "../../common/Debug";
import gameUtil from "../../utils/game.util";
import {Card} from "../schema/Card";
import {MapSchema, SetSchema} from "@colyseus/schema";
import {StateTypeEnum} from "../enums/StateTypeEnum";
import axios from "axios";
import {Config} from "../../cfg/Config";
let config: Config = require('../../../config/config.json');
/**
* 游戏结束
*/
export class GameResultCommand extends Command<CardGameState, {}> {
async execute() {
// 计算最终结果
let hp0 = 0;
let hp1 = 0;
let ap0 = 0;
let ap1 = 0;
let petAp0 = 0;
let petAp1 = 0;
let resultArr = [];
for (let [, player] of this.state.players) {
let data = {
id: player.id,
team: player.team,
hp: player.hp,
alive: player.state != PlayerStateConst.PLAYER_DEAD,
ap: gameUtil.calcTotalAp(player)
};
resultArr.push(data);
if (player.team == 0) {
hp0 += player.hp;
if (player.state != PlayerStateConst.PLAYER_DEAD) {
ap0 += data.ap;
for (let [,pet] of player.pets) {
petAp0 += (pet.ap + pet.extAp);
}
}
}
if (player.team == 1) {
hp1 += player.hp;
if (player.state != PlayerStateConst.PLAYER_DEAD) {
ap1 += data.ap;
for (let [,pet] of player.pets) {
petAp1 += (pet.ap + pet.extAp);
}
}
}
}
let winner = -1; // 平局
if (hp0 > hp1) {
winner = 0;
} else if (hp0 < hp1) {
winner = 1;
} else {
if (ap0 > ap1) {
winner = 0;
} else if (ap0 < ap1){
winner = 1;
} else {
if (petAp0 > petAp1) {
winner = 0;
} else if (petAp0 < petAp1) {
winner = 1;
}
}
}
let resultData: any = {
winner: winner,
results: resultArr
};
let resultMap: Map<StateTypeEnum, [string, number]> = new Map();
for (let [, player] of this.state.players) {
for (let [type, val] of player.statData) {
if (resultMap.has(type)) {
let current = resultMap.get(type);
if (current[1] < val) {
resultMap.set(type, [player.id, val]);
}
} else {
resultMap.set(type, [player.id, val]);
}
}
}
let statics: any = [];
for (let [type, val] of resultMap) {
statics.push({
type,
player: val[0],
val: val[1]
})
}
resultData[statics] = statics;
let self = this;
this.room.bGameResult(resultData);
this.state.updateGameState(GameStateConst.STATE_GAME_OVER);
//启动定时, 时间到后, 踢出没离开且没点重玩的玩家, 并将房间设为非private
let resultTimeOver = async function () {
// 踢出没离开并没点击重新开始的玩家
debugRoom(`restart_schedule 倒计时结束, 有 ${self.state.restartCount} 人点击重玩`)
if (self.state.restartCount == 0) {
// 没有任何人点重新开始, 则解散房间
await self.room.disconnect();
} else if (self.state.restartCount < self.room.maxClients){
// 如果点击重开的玩家少于房间最大人数, 则把房间设为公开, 等待其他玩家匹配进来
for (let [,player] of self.state.players) {
if (player.state !== PlayerStateConst.PLAYER_NORMAL) {
let client = self.room.getClient(player);
debugRoom(`清除没点击重新开始的玩家 ${client.sessionId}`);
client.leave();
}
}
self.state.updateGameState(GameStateConst.STATE_WAIT_JOIN);
await self.room.unlock();
await self.room.setPrivate(false);
//开启匹配定时, 长时间没匹配到人的话, 添加机器人
let timeOutWaitingPlayer = function () {
let count = self.room.maxClients - self.room.clientCount();
if (count > 0) {
for (let i = 0; i < count; i++) {
self.room.addRobot();
}
}
}
let time = new GameEnv().waitingPlayerTime * 1000;
self.room.beginSchedule(time, timeOutWaitingPlayer, 'waiting_player');
} else { // 如果4个人都点击了重开, 理论上不存在这种情况
error(`所有人都点击了重新开始, 为啥还没开始游戏???`);
}
}
let time = new GameEnv().gameResultTime * 1000;
this.room.beginSchedule(time, resultTimeOver, 'restart_schedule');
self.reportGameResult(resultData.winner);
this.resetAllState();
}
/**
* 重置所有状态
*/
resetAllState() {
this.state.restartCount = 0;
this.state.updateGameTurn( undefined);
this.state.subTurn = undefined;
this.state.round = 0;
this.state.cardQueue.length = 0;
this.state.cards.clear();
this.state.cards = new MapSchema<Card>();
for (let [,player] of this.state.players) {
player.cards.clear();
player.cards = new MapSchema<Card>()
player.cardSet.clear();
player.statData.clear();
player.petData.clear();
player.cardSet = new SetSchema<string>();
player.countTotal = 0;
player.countPresent = 0;
for(let [,pet] of player.pets) {
this.resetPet(pet);
}
}
this.room.battleMan.onGameEnd();
}
resetPet(pet: Pet) {
pet.state = 0;
pet.ap = 0;
pet.id = undefined;
pet.extAp = 0;
pet.harmReduce = 0;
pet.skills.length = 0;
pet.extSkills.length = 0;
}
reportGameResult(winner: number) {
let data: any = {
roomid: this.room.roomId,
round: this.state.round,
winner: winner,
season: 0,
}
let players: any[] = [];
let i = 0;
for (let [, player] of this.state.players) {
let cards = [...player.unitCfgs.keys()];
let dataObj: any = {};
for (let [key,val] of player.statData) {
dataObj[key] = val;
}
players.push({
accountid: player.accountId,
playerid: player.id,
index: i ++,
team: player.team,
heroid: player.heroId,
statdata: dataObj,
cards: cards
});
}
data.players = players;
let dataStr = JSON.stringify(data);
let reqConfig = {
method: 'post',
url: `${config.info_svr}/record/save`,
headers: {
'Content-Type': 'application/json',
},
data : dataStr
};
// @ts-ignore
axios(reqConfig)
.then(function (response) {
debugRoom(JSON.stringify(response.data));
})
.catch(function (err) {
error(err);
});
}
}