import {Client, Room} from "colyseus.js"; import {error, robotLog as log, robotLog as debug} from "../common/Debug"; import {GameStateConst} from "../constants/GameStateConst"; import {Player} from "../rooms/schema/Player"; import assistantUtil from "../utils/assistant.util"; import {delay, wait} from "../decorators/cfg"; export class Robot { host: string; roomId: string; room: Room; sessionId: string; client: Client; myTurn: boolean = false; player: Player; constructor(host: string, roomId: string) { this.host = host; this.roomId = roomId; this.client = new Client(host); } async connect() { try { this.room = await this.client.joinById(this.roomId, {rank: 1, accountid: 'robot'}); this.addListeners(); this.sessionId = this.room.sessionId; this.setReady(); return this.room.sessionId; } catch (err) { error(`error join room ${this.host}, ${this.roomId}`) } } async reConnect(sessionId: string) { try { this.room = await this.client.reconnect(this.roomId, sessionId); this.addListeners(); this.sessionId = this.room.sessionId; return this.room.sessionId; } catch (err) { error(`error reConnect room ${this.host}, ${this.roomId}, sessionId: ${sessionId}`); } } addListeners() { let self = this; this.room.onMessage("*", (type, data) => { switch (type) { case 'draw_card_s2c': // if (data.player == self.sessionId) { // self.cards = self.cards.concat(data.cards); // } break; case 'player_ready_s2c': break; case 'eat_card_s2c': if (data.errcode == 0 && data.player == self.sessionId) { debug(`eat_success: ${self.sessionId}`); self.selectPet(); } break; } }); this.room.onLeave(function () { debug("LEFT ROOM", arguments); self.room.removeAllListeners(); self.room.leave(); }); /** * 监听房间状态的变更, state含有当前房间游戏的所有公共信息, 任何值的更改都会触发该方法 * */ this.room.onStateChange(function (state) { self.player = state.players.get(self.sessionId); // self.players = state.players; }); // 也可以监听state下某个特定值的变更, 比如下面是监听 当前轮的clientid this.room.state.listen("currentTurn", (currentValue: string) => { self.myTurn = currentValue === this.sessionId; if (self.myTurn) { self.discard(); } }); this.room.state.listen("subTurn", (currentValue: string, previousValue: string) => { // self.mySubTurn = currentValue === self.sessionId; // if (self.mySubTurn) { // setTimeout(self.giveup.bind(self), self.delay); // } }); // 监听游戏状态的改变 this.room.state.listen("gameState", (currentValue: number, previousValue: number) => { switch (currentValue) { case GameStateConst.DETERMINE_TURN: // console.log('比大小阶段'); //TODO: 随机分牌比大小阶段, 需要 break; case GameStateConst.CHANGE_HERO: // console.log('英雄选择阶段'); self.selectHero(); break; case GameStateConst.STATE_CHANGE_CARD: // console.log('开局换卡阶段'); self.changeCard(); break; case GameStateConst.STATE_BEGIN_EAT: if (!self.myTurn) { self.eatOrGiveUp(); } break; case GameStateConst.STATE_ROUND_RESULT: console.log('结算轮'); break; } }); } private reply(messageType: string, message: any) { this.room.send(messageType, message); } // >>>>>>>>>>>>>>>>>> begin /** * 开局选择英雄 * @private */ @wait('pickHeroTime') private async selectHero() { let data = assistantUtil.randomHero(); this.reply('select_hero_c2s', data); } /** * 开局准备 * @private */ @delay(2) private async setReady() { this.reply('play_ready_c2s', ''); } /** * 开局换牌 * @private */ @wait('cardChangeTime') private async changeCard() { let cardIds: number[] = []; this.reply('change_card_c2s', { cards: cardIds }); } /** * 出牌 * @private */ @wait('maxDiscardTime') private async discard() { let self = this; let cardArr = [...self.player.cards.values()]; let cards = assistantUtil.checkTriple(cardArr); if (!cards) { return; } let cardIds = cards.map(o => o.id); log(`discard: ${self.sessionId} ${cardIds}`); self.reply('discard_card_c2s', { cards: cardIds }); } /** * 吃牌或者放弃 * @private */ @wait('maxEatTime') private async eatOrGiveUp() { let targetCard = [...this.room.state.cards.values()][0]; let cardArr = [...this.player.cards.values()]; let tmpCards = assistantUtil.checkTriple(cardArr, targetCard); let next = this.giveup.bind(this); if (tmpCards.length > 1 && targetCard.type === 1) { let cardIds: number[] = []; for (let card of tmpCards) { if (card.id !== targetCard.id) { cardIds.push(card.id); } } next = this.eatCard.bind(this, cardIds, targetCard.id); } next.apply(this); } /** * 吃牌 * @param cardIds * @param target * @private */ private eatCard(cardIds: number[], target: number) { log(`eta_card: ${this.sessionId} ${cardIds} -> ${target}`); this.reply('eat_card_c2s', { cards: cardIds, target }); } /** * 放弃吃牌 * @private */ private giveup() { this.reply('give_up_eat_c2s', {}); } /** * 选择一个法术或者一个随从 * @private */ @wait('playerActTime') private async selectPet() { let data = await assistantUtil.selectPet(this.player, this.room.state); if (data) { this.reply('select_pet_c2s', data); } } }