import {Command} from "@colyseus/command"; import {Client, Room} from "colyseus"; 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 { 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 [key, val] of tmpActionMap) { if (typeof val == 'number') { giveUpCount++; } } if (giveUpCount >= playerCount) { // 所有人都放弃了, 则取消定时, 直接进入下一轮 if (this.room.mainClock && 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); // @ts-ignore cards = tmpActionMap.get(pid); break; } } else { isFirst = false; } } /** * 3 种情况直接进入选择随从轮 * 1. 下家出牌 * 2. tmpActionMap中数据等于 playerCount * 3. timeUp * 否则继续等待 */ // 吃牌逻辑 if (player != null && (isFirst || timeUp)) { // 如果有吃牌计时的话,停止吃牌计时 if (this.room.mainClock && 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()]; } } }