增加可以连续出牌的逻辑
This commit is contained in:
parent
83d8343a0e
commit
a2a53cfd42
@ -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
18
src/global.d.ts
vendored
@ -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
|
||||
|
@ -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]
|
||||
}
|
||||
|
@ -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]
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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: '当前游戏不允许吃牌'
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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()]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user