109 lines
4.2 KiB
TypeScript
109 lines
4.2 KiB
TypeScript
import {Command} from "@colyseus/command";
|
|
import {CardGameState} from "../schema/CardGameState";
|
|
import {GameStateConst} from "../../constants/GameStateConst";
|
|
import {singleton} from "../../common/Singleton";
|
|
import {GameEnv} from "../../cfg/GameEnv";
|
|
import {debugRoom} from "../../common/Debug";
|
|
import {TurnEndCommand} from "./TurnEndCommand";
|
|
import {Player} from "../schema/Player";
|
|
import arrUtil from "../../utils/array.util";
|
|
import {Card} from "../schema/Card";
|
|
|
|
/**
|
|
* 根据条件决定吃牌玩家, 并执行吃牌逻辑
|
|
*/
|
|
|
|
|
|
export class EatConfirmCommand extends Command<CardGameState, { timeUp: boolean }> {
|
|
|
|
execute({timeUp} = this.payload) {
|
|
let giveUpCount = 0;
|
|
const playerCount = this.room.maxClients - 1;
|
|
const sessionIds = [...this.state.players.keys()];
|
|
// 将当前轮玩家移至第一位
|
|
let pids = arrUtil.moveElement(sessionIds, -sessionIds.indexOf(this.state.currentTurn));
|
|
|
|
let tmpActionMap = this.state.tmpActionMap;
|
|
for (let [, val] of tmpActionMap) {
|
|
if (typeof val == 'number') {
|
|
giveUpCount++;
|
|
}
|
|
}
|
|
if (giveUpCount >= playerCount) {
|
|
// 所有人都放弃了, 则取消定时, 直接进入下一轮
|
|
if (this.room.mainClock?.active) {
|
|
this.room.mainClock.clear();
|
|
}
|
|
return [new TurnEndCommand()];
|
|
}
|
|
|
|
let player:Player;
|
|
let cards: string[] = [];
|
|
let isFirst = true;
|
|
// 所有死亡玩家已在吃牌开始的时候至为放弃, 所以这里可以不用考虑死亡玩家
|
|
for (let i = 1; i < pids.length; i ++) {
|
|
// 获取第一个不放弃的玩家
|
|
let pid = pids[i];
|
|
if (tmpActionMap.has(pid)) {
|
|
if (typeof tmpActionMap.get(pid) != 'number') {
|
|
player = this.state.players.get(pid);
|
|
cards = tmpActionMap.get(pid) as string[];
|
|
break;
|
|
}
|
|
} else {
|
|
isFirst = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 3 种情况直接进入选择随从轮
|
|
* 1. 下家出牌
|
|
* 2. tmpActionMap中数据等于 playerCount
|
|
* 3. timeUp
|
|
* 否则继续等待
|
|
*/
|
|
// 吃牌逻辑
|
|
if (player != null && (isFirst || timeUp)) {
|
|
// 如果有吃牌计时的话,停止吃牌计时
|
|
if (this.room.mainClock?.active) {
|
|
this.room.mainClock.clear();
|
|
}
|
|
for (let id of cards) {
|
|
this.state.cards.set(id + '', player.cards.get(id + ''));
|
|
player.cards.delete(id + '');
|
|
player.cardSet.delete(id + '');
|
|
}
|
|
let cardArr: Card[] = [...this.state.cards.values()];
|
|
this.state.gameState = GameStateConst.STATE_PICK_PET;
|
|
let time = singleton(GameEnv).playerActTime * 1000 + player.extraTime;
|
|
let self = this;
|
|
|
|
// 开启选随从计时, 计时结束后结束当前轮
|
|
this.room.mainClock = this.clock.setTimeout(function () {
|
|
player.extraTime = 0;
|
|
self.room.mainClock.clear();
|
|
debugRoom('选随从或者法术时间到, 自动出牌, 自动进入下一轮');
|
|
self.room.dispatcher.dispatch(new TurnEndCommand());
|
|
}, time);
|
|
let fromPlayer = this.state.players.get(this.state.currentTurn);
|
|
if (fromPlayer.id !== player.id) {
|
|
this.room.battleMan.onCardLinkOver(player, cardArr, fromPlayer);
|
|
} else {
|
|
this.room.battleMan.onCardLinkOver(player, cardArr);
|
|
}
|
|
// 成功后广播吃牌成功消息
|
|
this.room.broadcast('eat_card_s2c', {player: player.id, errocode: 0, errmsg: ''});
|
|
// 向其他玩家发送吃卡失败的消息
|
|
for (let [key, val] of tmpActionMap) {
|
|
if (typeof val != 'number' && key !== player.id) {
|
|
let client = this.room.getClient(key);
|
|
client.send('eat_card_s2c', {errcode: 9, errmsg: '吃卡失败'});
|
|
}
|
|
}
|
|
} else if (!player && timeUp) {
|
|
return [new TurnEndCommand()];
|
|
}
|
|
|
|
}
|
|
}
|