增加可以连续出牌的逻辑

This commit is contained in:
zhl 2021-03-02 13:55:56 +08:00
parent 83d8343a0e
commit a2a53cfd42
11 changed files with 157 additions and 64 deletions

View File

@ -5,18 +5,34 @@ import { GameEnv } from './GameEnv'
export class RoomOptions { export class RoomOptions {
/** /**
* *
* @param {boolean} advMode
* @return {boolean} * @return {boolean}
* @param opt
*/ */
public canEat(advMode: boolean) { public canEat(opt: {advMode: boolean}) {
let result = false let result = false
if (advMode && new GameEnv().canEatAdv) { if (opt.advMode && new GameEnv().canEatAdv) {
result = true result = true
} else if (!advMode && new GameEnv().canEatBase) { } else if (!opt.advMode && new GameEnv().canEatBase) {
result = true result = true
} }
return result return result
} }
/**
*
* //TODO: 根据配表判断
* @param opt
*/
public multipleEat(opt?: any) {
return true
}
/**
* ,
* @param opt
*/
public autoDiscard(opt?: any) {
return true
}
} }

18
src/global.d.ts vendored
View File

@ -238,8 +238,7 @@ declare module 'colyseus' {
updatePetStat(datas: PetInfo[], fromplayer?: string): void; updatePetStat(datas: PetInfo[], fromplayer?: string): void;
/** /**
* room.mainClock设定任务 *
* mainClock任何时候只有一个可执行的任务
* @param millisecond * @param millisecond
* @param handler * @param handler
* @param name * @param name
@ -247,15 +246,20 @@ declare module 'colyseus' {
beginSchedule(millisecond: number, handler: Function, name: string): void; beginSchedule(millisecond: number, handler: Function, name: string): void;
/** /**
* room.mainClock的任务 *
* mainClock任何时候只有一个可执行的任务
*
* @param name
*/ */
stopSchedule(name: string): number; stopSchedule(name: string): number;
/**
*
*/
pauseSchedule(name: string): number;
/**
*
*/
resumeSchedule(name: string): number;
/** /**
* room.mainClock增加n秒 * n秒
* @param name * @param name
* @param millisecond * @param millisecond
* @param reason * @param reason

View File

@ -80,8 +80,9 @@ export class Robot {
// self.players = state.players; // self.players = state.players;
}) })
// 也可以监听state下某个特定值的变更, 比如下面是监听 当前轮的clientid // 也可以监听state下某个特定值的变更, 比如下面是监听 当前轮的clientid
this.room.state.listen('currentTurn', (currentValue: string) => { this.room.state.listen('playerTurn', (currentValue: string) => {
self.myTurn = currentValue === this.sessionId let pid = currentValue.split(':')[0]
self.myTurn = pid === this.sessionId
if (self.myTurn) { if (self.myTurn) {
self.discard() self.discard()
} }
@ -163,7 +164,7 @@ export class Robot {
@wait('maxDiscardTime') @wait('maxDiscardTime')
private async discard() { private async discard() {
let targetCard let targetCard
let canEat = new RoomOptions().canEat(this.room.state.advMode) let canEat = new RoomOptions().canEat({advMode: this.room.state.advMode})
if (this.room.state.cards.size == 1 && canEat) { if (this.room.state.cards.size == 1 && canEat) {
targetCard = [...this.room.state.cards.values()][0] targetCard = [...this.room.state.cards.values()][0]
} }

View File

@ -45,7 +45,7 @@ export class RobotClient implements Client {
addListeners() { addListeners() {
this.listenerState = this.svrstate.listen('gameState', this.gameSateUpdate.bind(this)) this.listenerState = this.svrstate.listen('gameState', this.gameSateUpdate.bind(this))
this.listenerTurn = this.svrstate.listen('currentTurn', this.gameTurnUpdate.bind(this)) this.listenerTurn = this.svrstate.listen('playerTurn', this.gameTurnUpdate.bind(this))
} }
close(code?: number, data?: string): void { close(code?: number, data?: string): void {
@ -114,7 +114,8 @@ export class RobotClient implements Client {
private gameTurnUpdate(currentValue: string, previousValue: string) { private gameTurnUpdate(currentValue: string, previousValue: string) {
let self = this let self = this
self.myTurn = currentValue === self.sessionId let pid = currentValue.split(':')[0]
self.myTurn = pid === self.sessionId
if (!this.active) { if (!this.active) {
return return
} }
@ -140,7 +141,7 @@ export class RobotClient implements Client {
@wait('maxDiscardTime') @wait('maxDiscardTime')
private async discard() { private async discard() {
let targetCard let targetCard
let canEat = new RoomOptions().canEat(this.svrstate.advMode) let canEat = new RoomOptions().canEat({advMode: this.svrstate.advMode})
if (this.svrstate.cards.size == 1 && canEat) { if (this.svrstate.cards.size == 1 && canEat) {
targetCard = [...this.svrstate.cards.values()][0] targetCard = [...this.svrstate.cards.values()][0]
} }

View File

@ -163,7 +163,7 @@ export class GeneralRoom extends Room {
this.dispatcher.dispatch(new OnJoinCommand(), data) this.dispatcher.dispatch(new OnJoinCommand(), data)
} }
//TODO: 掉线逻辑 // 掉线逻辑
async onLeave(client: Client, consented: boolean) { async onLeave(client: Client, consented: boolean) {
if (this.state.gameState === GameStateConst.STATE_GAME_OVER || this.state.gameState === GameStateConst.STATE_WAIT_JOIN) { if (this.state.gameState === GameStateConst.STATE_GAME_OVER || this.state.gameState === GameStateConst.STATE_WAIT_JOIN) {
this.state.players.delete(client.sessionId) this.state.players.delete(client.sessionId)
@ -193,11 +193,19 @@ export class GeneralRoom extends Room {
} }
onDispose() { onDispose() {
for (let [, clock] of this.gameClock) {
clock.clear()
}
this.gameClock.clear() this.gameClock.clear()
this.assistMap.clear() this.assistMap.clear()
this.dispatcher.stop() this.dispatcher.stop()
} }
/**
* player的client实例, 线, assist client
* @param {string | Player} player
* @return {Client}
*/
getClient(player: string | Player): Client { getClient(player: string | Player): Client {
let result: Client let result: Client
let sessionId let sessionId
@ -216,13 +224,16 @@ export class GeneralRoom extends Room {
return result return result
} }
/**
* client数量
* @return {number}
*/
clientCount(): number { clientCount(): number {
return this.clients.length return this.clients.length
} }
/** /**
* room.gameClock设定任务 *
* gameClock任何时候只有一个可执行的任务
* @param millisecond * @param millisecond
* @param handler * @param handler
* @param name * @param name
@ -242,30 +253,60 @@ export class GeneralRoom extends Room {
} }
/** /**
* room.gameClock的任务 *
* gameClock任何时候只有一个可执行的任务
*/ */
stopSchedule(name: string): number { stopSchedule(name: string): number {
debugRoom(`manual stop schedule: ${ name }`) debugRoom(`manual stop schedule: ${ name }`)
if (!this.gameClock.has(name)) { if (!this.gameClock.has(name)) {
return -1 return -1
} else {
let clock = this.gameClock.get(name)
if (!clock.active) {
this.gameClock.delete(name)
return -1
} else {
let time = clock.elapsedTime
clock.clear()
this.gameClock.delete(name)
return time
}
} }
let clock = this.gameClock.get(name)
if (!clock.active) {
this.gameClock.delete(name)
return -1
}
let time = clock.elapsedTime
clock.clear()
this.gameClock.delete(name)
return time
} }
/** /**
* room的gameClock增加n秒 * ,
* @param {string} name
* @return {number}
*/
pauseSchedule(name: string) {
if (!this.gameClock.has(name)) {
return -1
}
let clock = this.gameClock.get(name)
if (!clock.active) {
return -1
}
clock.pause()
return clock.time - clock.elapsedTime
}
/**
* ,
* @param {string} name
* @return {number}
*/
resumeSchedule(name: string) {
if (!this.gameClock.has(name)) {
return -1
}
let clock = this.gameClock.get(name)
if (!clock.active) {
return -1
}
clock.resume()
return clock.time - clock.elapsedTime
}
/**
* n秒
* @param name * @param name
* @param millisecond * @param millisecond
* @param reason * @param reason
@ -303,6 +344,10 @@ export class GeneralRoom extends Room {
await createRobot(data) await createRobot(data)
} }
/**
* assist client, 线
* @param {string} sessionId
*/
addAssistClient(sessionId: string) { addAssistClient(sessionId: string) {
if (!this.assistMap.has(sessionId)) { if (!this.assistMap.has(sessionId)) {
let client = new RobotClient(sessionId, this.state, this['onMessageHandlers']) let client = new RobotClient(sessionId, this.state, this['onMessageHandlers'])
@ -313,7 +358,9 @@ export class GeneralRoom extends Room {
getAssistClient(sessionId: string): RobotClient { getAssistClient(sessionId: string): RobotClient {
return this.assistMap.get(sessionId) return this.assistMap.get(sessionId)
} }
/**
*
*/
getPlayerByIdx(idx: number) { getPlayerByIdx(idx: number) {
for (let [, player] of this.state.players) { for (let [, player] of this.state.players) {
if (player.idx == idx) { if (player.idx == idx) {

View File

@ -58,7 +58,7 @@ export class DiscardCommand extends Command<CardGameState, { client: Client, car
} }
let targetCard let targetCard
if (target) { if (target) {
if (!new RoomOptions().canEat(this.state.advMode)) { if (!new RoomOptions().canEat({advMode: this.state.advMode})) {
this.room.send(client, 'discard_card_s2c', { this.room.send(client, 'discard_card_s2c', {
errcode: 7, errcode: 7,
errmsg: '当前游戏不允许吃牌' errmsg: '当前游戏不允许吃牌'

View File

@ -221,7 +221,7 @@ export class GameResultCommand extends Command<CardGameState, {}> {
*/ */
resetAllState() { resetAllState() {
this.state.restartCount = 0; this.state.restartCount = 0;
this.state.updateGameTurn( undefined); this.state.updateGameTurn( undefined, 0);
this.state.subTurn = undefined; this.state.subTurn = undefined;
this.state.round = 0; this.state.round = 0;
this.state.cardQueue.length = 0; this.state.cardQueue.length = 0;

View File

@ -35,7 +35,7 @@ export class NextTurnCommand extends Command<CardGameState, {}> {
} }
this.state.updateGameTurn((this.state.currentTurn) this.state.updateGameTurn((this.state.currentTurn)
? sessionIds[(sessionIds.indexOf(this.state.currentTurn) + 1) % sessionIds.length] ? sessionIds[(sessionIds.indexOf(this.state.currentTurn) + 1) % sessionIds.length]
: sessionIds[0]); : sessionIds[0], 0);
let player = this.state.players.get(this.state.currentTurn); let player = this.state.players.get(this.state.currentTurn);
player.cardQueue.clear(); player.cardQueue.clear();
if (!player) { if (!player) {

View File

@ -4,6 +4,10 @@ import { Client } from 'colyseus'
import { TurnEndCommand } from './TurnEndCommand' import { TurnEndCommand } from './TurnEndCommand'
import { GameEnv } from '../../cfg/GameEnv' import { GameEnv } from '../../cfg/GameEnv'
import gameUtil from '../../utils/game.util' import gameUtil from '../../utils/game.util'
import { RoomOptions } from '../../cfg/RoomOptions'
import assistantUtil from '../../utils/assistant.util'
import { GameStateConst } from '../../constants/GameStateConst'
import { debugRoom } from '../../common/Debug'
/** /**
* *
@ -94,7 +98,12 @@ export class SelectPetCommand extends Command<CardGameState, {
} }
let time = this.room.battleMan.useCard(data) let time = this.room.battleMan.useCard(data)
await this.delay(time) await this.delay(time)
return [new TurnEndCommand()] if (new RoomOptions().multipleEat() && assistantUtil.checkDiscard([...player.cards.values()]).length > 1) {
this.state.updateGameState(GameStateConst.STATE_BEGIN_DRAW)
this.state.updateGameTurn(player.id, this.state.eatCount + 1)
debugRoom(`more eatcount for player ${player.id}, ${this.state.eatCount}`)
} else {
return [new TurnEndCommand()]
}
} }
} }

View File

@ -21,6 +21,19 @@ export class CardGameState extends Schema {
@type("string") @type("string")
currentTurn: string; currentTurn: string;
/**
* currentTurn的字段,
* 格式: playerId:eatCount
* @type {string}
*/
@type("string")
playerTurn: string;
/**
* currentTurn当中当前玩家吃牌次数
* @type {number}
*/
@type("number")
eatCount: number;
/** /**
* , gameState==3 * , gameState==3
*/ */
@ -76,10 +89,14 @@ export class CardGameState extends Schema {
this.$listeners?.gameState?.invoke(val, preVal); this.$listeners?.gameState?.invoke(val, preVal);
} }
updateGameTurn(val: string) { updateGameTurn(val: string, eatCount: number) {
let preVal = this.currentTurn; let preVal = this.currentTurn;
this.currentTurn = val; this.currentTurn = val;
this.eatCount = eatCount;
this.$listeners?.currentTurn?.invoke(val, preVal); this.$listeners?.currentTurn?.invoke(val, preVal);
let prePlayerTurn = this.playerTurn
this.playerTurn = `${this.currentTurn}:${this.eatCount}`
this.$listeners?.playerTurn?.invoke(this.playerTurn, prePlayerTurn);
} }
get advMode() { get advMode() {

View File

@ -1,5 +1,4 @@
import { Card } from '../rooms/schema/Card' import { Card } from '../rooms/schema/Card'
import arrUtil from './array.util'
import { EffectCardCfg } from '../cfg/parsers/EffectCardCfg' import { EffectCardCfg } from '../cfg/parsers/EffectCardCfg'
import { BaseConst } from '../constants/BaseConst' import { BaseConst } from '../constants/BaseConst'
import { SkillTargetType } from '../rooms/logic/skill/SkillConst' import { SkillTargetType } from '../rooms/logic/skill/SkillConst'
@ -12,11 +11,22 @@ import { CardType } from '../cfg/enums/CardType'
import { GameEnv } from '../cfg/GameEnv' import { GameEnv } from '../cfg/GameEnv'
import { error, robotLog } from '../common/Debug' import { error, robotLog } from '../common/Debug'
import { PlayerStateConst } from '../constants/PlayerStateConst' import { PlayerStateConst } from '../constants/PlayerStateConst'
import { Pet } from '../rooms/schema/Pet'
function pushMapVal(map: Map<number, Card[]>, key: number, value: Card) {
if (map.has(key)) {
let arr = map.get(key)
arr.push(value)
map.set(key, arr)
} else {
map.set(key, [value])
}
}
let assistantUtil = { let assistantUtil = {
/** /**
* *
* @param cardArr * @param cardArr
* @param card * @param card
*/ */
@ -28,23 +38,11 @@ let assistantUtil = {
if (!(c.type == CardType.general || c.type == CardType.variable_unit)) { if (!(c.type == CardType.general || c.type == CardType.variable_unit)) {
continue continue
} }
if (pointMap.has(c.number)) { pushMapVal(pointMap, c.number, c)
let arr = pointMap.get(c.number)
arr.push(c)
pointMap.set(c.number, arr)
} else {
pointMap.set(c.number, [c])
}
cardIdSet.add(c.number) cardIdSet.add(c.number)
} }
if (card && (card.type == CardType.general || card.type == CardType.variable_unit)) { if (card && (card.type == CardType.general || card.type == CardType.variable_unit)) {
if (pointMap.has(card.number)) { pushMapVal(pointMap, card.number, card)
let arr = pointMap.get(card.number)
arr.push(card)
pointMap.set(card.number, arr)
} else {
pointMap.set(card.number, [card])
}
cardIdSet.add(card.number) cardIdSet.add(card.number)
} }
let fetched = false let fetched = false
@ -119,7 +117,7 @@ let assistantUtil = {
} }
return result return result
} else { } else {
return arrUtil.randomGet(cardArr, 1) return [cardArr.randomOne()]
} }
}, },
/** /**
@ -133,7 +131,7 @@ let assistantUtil = {
enemys.push(player) enemys.push(player)
} }
} }
return arrUtil.randomOne(enemys) return enemys.randomOne()
}, },
/** /**
@ -150,9 +148,9 @@ let assistantUtil = {
if (pet.ap > 0 && pet.state == 1) if (pet.ap > 0 && pet.state == 1)
pets.push(pet) pets.push(pet)
} }
let result let result: Pet
if (pets.length > 0) { if (pets.length > 0) {
result = arrUtil.randomOne(pets) result = pets.randomOne()
} }
return result ? result.pos : 0 return result ? result.pos : 0
}, },
@ -264,8 +262,8 @@ let assistantUtil = {
randomHero() { randomHero() {
let heroMap: Map<number, HeroCfg> = global.$cfg.get(BaseConst.HERO) let heroMap: Map<number, HeroCfg> = global.$cfg.get(BaseConst.HERO)
let heroArr = [...heroMap.values()] let heroArr = [...heroMap.values()]
let hero = arrUtil.randomGet(heroArr, 1) let hero: HeroCfg = heroArr.randomOne()
return { heroId: hero[0].id } return { heroId: hero.id }
} }
} }