增加可以连续出牌的逻辑

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 {
/**
*
* @param {boolean} advMode
* @return {boolean}
* @param opt
*/
public canEat(advMode: boolean) {
public canEat(opt: {advMode: boolean}) {
let result = false
if (advMode && new GameEnv().canEatAdv) {
if (opt.advMode && new GameEnv().canEatAdv) {
result = true
} else if (!advMode && new GameEnv().canEatBase) {
} else if (!opt.advMode && new GameEnv().canEatBase) {
result = true
}
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;
/**
* room.mainClock设定任务
* mainClock任何时候只有一个可执行的任务
*
* @param millisecond
* @param handler
* @param name
@ -247,15 +246,20 @@ declare module 'colyseus' {
beginSchedule(millisecond: number, handler: Function, name: string): void;
/**
* room.mainClock的任务
* mainClock任何时候只有一个可执行的任务
*
* @param name
*
*/
stopSchedule(name: string): number;
/**
*
*/
pauseSchedule(name: string): number;
/**
*
*/
resumeSchedule(name: string): number;
/**
* room.mainClock增加n秒
* n秒
* @param name
* @param millisecond
* @param reason

View File

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

View File

@ -45,7 +45,7 @@ export class RobotClient implements Client {
addListeners() {
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 {
@ -114,7 +114,8 @@ export class RobotClient implements Client {
private gameTurnUpdate(currentValue: string, previousValue: string) {
let self = this
self.myTurn = currentValue === self.sessionId
let pid = currentValue.split(':')[0]
self.myTurn = pid === self.sessionId
if (!this.active) {
return
}
@ -140,7 +141,7 @@ export class RobotClient implements Client {
@wait('maxDiscardTime')
private async discard() {
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) {
targetCard = [...this.svrstate.cards.values()][0]
}

View File

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

View File

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

View File

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

View File

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

View File

@ -4,6 +4,10 @@ import { Client } from 'colyseus'
import { TurnEndCommand } from './TurnEndCommand'
import { GameEnv } from '../../cfg/GameEnv'
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)
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")
currentTurn: string;
/**
* currentTurn的字段,
* 格式: playerId:eatCount
* @type {string}
*/
@type("string")
playerTurn: string;
/**
* currentTurn当中当前玩家吃牌次数
* @type {number}
*/
@type("number")
eatCount: number;
/**
* , gameState==3
*/
@ -76,10 +89,14 @@ export class CardGameState extends Schema {
this.$listeners?.gameState?.invoke(val, preVal);
}
updateGameTurn(val: string) {
updateGameTurn(val: string, eatCount: number) {
let preVal = this.currentTurn;
this.currentTurn = val;
this.eatCount = eatCount;
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() {

View File

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