重构代码
This commit is contained in:
parent
cc15c95ca3
commit
68cebfdb7b
@ -1,16 +1,14 @@
|
||||
import {Command} from "@colyseus/command";
|
||||
import {CardGameState} from "../schema/CardGameState";
|
||||
import gameUtil from "../../utils/game.util";
|
||||
import {Client} from "colyseus";
|
||||
import {NextSubCommand} from "./NextSubCommand";
|
||||
import {GameStateConst} from "../../constants/GameStateConst";
|
||||
import {GameEnv} from "../../cfg/GameEnv";
|
||||
import {debugRoom, error} from "../../common/Debug";
|
||||
import {TurnEndCommand} from "./TurnEndCommand";
|
||||
import {Card} from "../schema/Card";
|
||||
import {Wait} from "./Wait";
|
||||
import {CardType} from "../../cfg/enums/CardType";
|
||||
import {StateTypeEnum} from "../enums/StateTypeEnum";
|
||||
import { Command } from '@colyseus/command'
|
||||
import { CardGameState } from '../schema/CardGameState'
|
||||
import gameUtil from '../../utils/game.util'
|
||||
import { Client } from 'colyseus'
|
||||
import { GameStateConst } from '../../constants/GameStateConst'
|
||||
import { GameEnv } from '../../cfg/GameEnv'
|
||||
import { debugRoom, error } from '../../common/Debug'
|
||||
import { TurnEndCommand } from './TurnEndCommand'
|
||||
import { Card } from '../schema/Card'
|
||||
import { Wait } from './Wait'
|
||||
import { StateTypeEnum } from '../enums/StateTypeEnum'
|
||||
|
||||
/**
|
||||
* 出牌
|
||||
@ -19,116 +17,141 @@ import {StateTypeEnum} from "../enums/StateTypeEnum";
|
||||
* type: 1, 到时间后, 自动的抽牌
|
||||
*/
|
||||
export class DiscardCommand extends Command<CardGameState, { client: Client, cards: [string], target?: string, dtype: number }> {
|
||||
// validate({ client, cards } = this.payload) {
|
||||
// const player = this.state.players.get(client.sessionId);
|
||||
// return player !== undefined && gameUtil.checkCardsExists(player.cards, cards);
|
||||
// }
|
||||
// validate({ client, cards } = this.payload) {
|
||||
// const player = this.state.players.get(client.sessionId);
|
||||
// return player !== undefined && gameUtil.checkCardsExists(player.cards, cards);
|
||||
// }
|
||||
|
||||
async execute({ client, cards , target, dtype} = this.payload) {
|
||||
const player = this.state.players.get(client.sessionId);
|
||||
if (!player) {
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 1, errmsg: 'player不存在'});
|
||||
return;
|
||||
}
|
||||
let tmpCards = [];
|
||||
for (let id of cards) {
|
||||
if (player.cards.has(id + '')) {
|
||||
if (!player.cards.get(id + '').number) {
|
||||
error(`${player.id} 的手牌 ${id} 数据有问题`);
|
||||
continue;
|
||||
}
|
||||
tmpCards.push(player.cards.get(id + '').clone());
|
||||
} else {
|
||||
error(`${player.id} 出的牌 ${id} 在手牌中不存在`)
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 2, errmsg: `要出的牌 ${id} 在手牌中不存在`});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.state.currentTurn != client.sessionId) {
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 3, errmsg: '不是当前轮'});
|
||||
return;
|
||||
}
|
||||
let targetCard
|
||||
if (target) {
|
||||
if (this.state.cards.size > 1) {
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 6, errmsg: '不符合吃牌规则'});
|
||||
return;
|
||||
}
|
||||
if (!this.state.cards.has(target + '')) {
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 5, errmsg: '找不到要吃的牌'});
|
||||
return;
|
||||
}
|
||||
targetCard = this.state.cards.values().next().value.clone()
|
||||
let targetPlayer = this.state.players.get(targetCard.owner)
|
||||
targetPlayer?.cardQueue.clear()
|
||||
tmpCards.push(targetCard)
|
||||
if (!gameUtil.checkDiscard(tmpCards, new GameEnv().otherEatCount)) {
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 4, errmsg: '出牌不符合规则'});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!gameUtil.checkDiscard(tmpCards, new GameEnv().selfEatCount)) {
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 4, errmsg: '出牌不符合规则'});
|
||||
return;
|
||||
}
|
||||
for (let [key, val] of this.state.cards) {
|
||||
this.state.cards.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//停止出牌计时, 并更新player.extraTime;
|
||||
let elapsedTime = this.room.stopSchedule('draw_card');
|
||||
if (elapsedTime >= 0) {
|
||||
let maxTime = new GameEnv().maxDiscardTime * 1000;
|
||||
let count = elapsedTime - maxTime;
|
||||
let newCount = player.extraTime - Math.min(count, 0);
|
||||
player.extraTime = Math.max(newCount, 0);
|
||||
}
|
||||
for (let card of tmpCards) {
|
||||
this.state.cards.set(card.id + '', card);
|
||||
player.cardQueue.push(card);
|
||||
gameUtil.deleteCardFromPlayer(player, card.id);
|
||||
}
|
||||
/**
|
||||
* 这说明是当前轮正常出牌,
|
||||
* 如果出一张牌的话, 进入胡牌轮
|
||||
* 否则直接进入选随从轮
|
||||
*/
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 0, cards: cards, type: dtype})
|
||||
if (cards.length === 1) {
|
||||
let cardArr: Card[] = [...this.state.cards.values()];
|
||||
let time =this.room.battleMan.onCardDiscarded(player, cardArr[0])
|
||||
await this.delay(time);
|
||||
// 20210219 修改: 出单张牌后直接进入下个玩家的出牌时间
|
||||
// if (cardArr[0].type == CardType.general || cardArr[0].type == CardType.variable_unit) {
|
||||
// return [new NextSubCommand()];
|
||||
// } else {
|
||||
// return [new Wait().setPayload(new GameEnv().emptyRoundTime), new TurnEndCommand()];
|
||||
// }
|
||||
return [new Wait().setPayload(new GameEnv().emptyRoundTime), new TurnEndCommand()];
|
||||
} else {
|
||||
let cardArr: Card[] = [...this.state.cards.values()];
|
||||
let self = this;
|
||||
let cardMsg: any = {player: player.id, errcode: 0, errmsg: ''}
|
||||
if (targetCard) {
|
||||
cardMsg.target = targetCard.owner
|
||||
}
|
||||
this.room.broadcast('eat_card_s2c', cardMsg, {except: client});
|
||||
cardMsg.cards = cards;
|
||||
this.room.send(client,'eat_card_s2c', cardMsg);
|
||||
let delay = this.room.battleMan.onCardLinkOver(player, cardArr);
|
||||
player.statData.inc(StateTypeEnum.EATCOUNT, 1);
|
||||
await this.delay(delay);
|
||||
let time = new GameEnv().playerActTime * 1000 + player.extraTime;
|
||||
this.state.updateGameState(GameStateConst.STATE_PICK_PET);
|
||||
// 开启选随从计时, 计时结束后结束当前轮
|
||||
let timeOverSelectPet = function () {
|
||||
player.extraTime = 0;
|
||||
debugRoom('选随从或者法术时间到, 自动出牌, 自动进入下一轮');
|
||||
self.room.dispatcher.dispatch(new TurnEndCommand());
|
||||
}
|
||||
this.room.beginSchedule(time, timeOverSelectPet, `select_pet`);
|
||||
}
|
||||
async execute({ client, cards, target, dtype } = this.payload) {
|
||||
const player = this.state.players.get(client.sessionId)
|
||||
if (!player) {
|
||||
this.room.send(client, 'discard_card_s2c', {
|
||||
errcode: 1,
|
||||
errmsg: 'player不存在'
|
||||
})
|
||||
return
|
||||
}
|
||||
let tmpCards = []
|
||||
for (let id of cards) {
|
||||
if (player.cards.has(id + '')) {
|
||||
if (!player.cards.get(id + '').number) {
|
||||
error(`${ player.id } 的手牌 ${ id } 数据有问题`)
|
||||
continue
|
||||
}
|
||||
tmpCards.push(player.cards.get(id + '').clone())
|
||||
} else {
|
||||
error(`${ player.id } 出的牌 ${ id } 在手牌中不存在`)
|
||||
this.room.send(client, 'discard_card_s2c', {
|
||||
errcode: 2,
|
||||
errmsg: `要出的牌 ${ id } 在手牌中不存在`
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
if (this.state.currentTurn != client.sessionId) {
|
||||
this.room.send(client, 'discard_card_s2c', {
|
||||
errcode: 3,
|
||||
errmsg: '不是当前轮'
|
||||
})
|
||||
return
|
||||
}
|
||||
let targetCard
|
||||
if (target) {
|
||||
if (this.state.cards.size > 1) {
|
||||
this.room.send(client, 'discard_card_s2c', {
|
||||
errcode: 6,
|
||||
errmsg: '不符合吃牌规则'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.state.cards.has(target + '')) {
|
||||
this.room.send(client, 'discard_card_s2c', {
|
||||
errcode: 5,
|
||||
errmsg: '找不到要吃的牌'
|
||||
})
|
||||
return
|
||||
}
|
||||
targetCard = this.state.cards.values().next().value.clone()
|
||||
let targetPlayer = this.state.players.get(targetCard.owner)
|
||||
targetPlayer?.cardQueue.clear()
|
||||
tmpCards.push(targetCard)
|
||||
if (!gameUtil.checkDiscard(tmpCards, new GameEnv().otherEatCount)) {
|
||||
this.room.send(client, 'discard_card_s2c', {
|
||||
errcode: 4,
|
||||
errmsg: '出牌不符合规则'
|
||||
})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (!gameUtil.checkDiscard(tmpCards, new GameEnv().selfEatCount)) {
|
||||
this.room.send(client, 'discard_card_s2c', {
|
||||
errcode: 4,
|
||||
errmsg: '出牌不符合规则'
|
||||
})
|
||||
return
|
||||
}
|
||||
for (let [key, val] of this.state.cards) {
|
||||
this.state.cards.delete(key)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//停止出牌计时, 并更新player.extraTime;
|
||||
let elapsedTime = this.room.stopSchedule('draw_card')
|
||||
if (elapsedTime >= 0) {
|
||||
let maxTime = new GameEnv().maxDiscardTime * 1000
|
||||
let count = elapsedTime - maxTime
|
||||
let newCount = player.extraTime - Math.min(count, 0)
|
||||
player.extraTime = Math.max(newCount, 0)
|
||||
}
|
||||
for (let card of tmpCards) {
|
||||
this.state.cards.set(card.id + '', card)
|
||||
player.cardQueue.push(card)
|
||||
gameUtil.deleteCardFromPlayer(player, card.id)
|
||||
}
|
||||
/**
|
||||
* 这说明是当前轮正常出牌,
|
||||
* 如果出一张牌的话, 进入胡牌轮
|
||||
* 否则直接进入选随从轮
|
||||
*/
|
||||
this.room.send(client, 'discard_card_s2c', {
|
||||
errcode: 0,
|
||||
cards: cards,
|
||||
type: dtype
|
||||
})
|
||||
if (cards.length === 1) {
|
||||
let cardArr: Card[] = [...this.state.cards.values()]
|
||||
let time = this.room.battleMan.onCardDiscarded(player, cardArr[0])
|
||||
await this.delay(time)
|
||||
// 20210219 修改: 出单张牌后直接进入下个玩家的出牌时间
|
||||
// if (cardArr[0].type == CardType.general || cardArr[0].type == CardType.variable_unit) {
|
||||
// return [new NextSubCommand()];
|
||||
// } else {
|
||||
// return [new Wait().setPayload(new GameEnv().emptyRoundTime), new TurnEndCommand()];
|
||||
// }
|
||||
return [new Wait().setPayload(new GameEnv().emptyRoundTime), new TurnEndCommand()]
|
||||
} else {
|
||||
let cardArr: Card[] = [...this.state.cards.values()]
|
||||
let self = this
|
||||
let cardMsg: any = { player: player.id, errcode: 0, errmsg: '' }
|
||||
if (targetCard) {
|
||||
cardMsg.target = targetCard.owner
|
||||
}
|
||||
this.room.broadcast('eat_card_s2c', cardMsg, { except: client })
|
||||
cardMsg.cards = cards
|
||||
this.room.send(client, 'eat_card_s2c', cardMsg)
|
||||
let delay = this.room.battleMan.onCardLinkOver(player, cardArr)
|
||||
player.statData.inc(StateTypeEnum.EATCOUNT, 1)
|
||||
await this.delay(delay)
|
||||
let time = new GameEnv().playerActTime * 1000 + player.extraTime
|
||||
this.state.updateGameState(GameStateConst.STATE_PICK_PET)
|
||||
// 开启选随从计时, 计时结束后结束当前轮
|
||||
let timeOverSelectPet = function () {
|
||||
player.extraTime = 0
|
||||
debugRoom('选随从或者法术时间到, 自动出牌, 自动进入下一轮')
|
||||
self.room.dispatcher.dispatch(new TurnEndCommand())
|
||||
}
|
||||
this.room.beginSchedule(time, timeOverSelectPet, `select_pet`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,361 +1,361 @@
|
||||
import {Card} from "../rooms/schema/Card";
|
||||
import { Card } from '../rooms/schema/Card'
|
||||
|
||||
import {Player} from "../rooms/schema/Player";
|
||||
import {BaseConst} from "../constants/BaseConst";
|
||||
import {SystemCardCfg} from "../cfg/parsers/SystemCardCfg";
|
||||
import {EffectCardCfg} from "../cfg/parsers/EffectCardCfg";
|
||||
import { Player } from '../rooms/schema/Player'
|
||||
import { BaseConst } from '../constants/BaseConst'
|
||||
import { SystemCardCfg } from '../cfg/parsers/SystemCardCfg'
|
||||
import { EffectCardCfg } from '../cfg/parsers/EffectCardCfg'
|
||||
import { cardLog, debugRoom, error } from '../common/Debug'
|
||||
import {Room} from "colyseus";
|
||||
import {PlayerStateConst} from "../constants/PlayerStateConst";
|
||||
import {GameEnv} from "../cfg/GameEnv";
|
||||
import {CardGameState} from "../rooms/schema/CardGameState";
|
||||
import {CardType} from "../cfg/enums/CardType";
|
||||
import {EffectType} from "../cfg/enums/EffectType";
|
||||
import { Room } from 'colyseus'
|
||||
import { PlayerStateConst } from '../constants/PlayerStateConst'
|
||||
import { GameEnv } from '../cfg/GameEnv'
|
||||
import { CardGameState } from '../rooms/schema/CardGameState'
|
||||
import { CardType } from '../cfg/enums/CardType'
|
||||
import { EffectType } from '../cfg/enums/EffectType'
|
||||
|
||||
let gameUtil = {
|
||||
/**
|
||||
* 游戏开始时, 初始化卡组
|
||||
*/
|
||||
initCardQue(beginNum: number) {
|
||||
let cards: Card[] = [];
|
||||
let numCfgMap: Map<number, SystemCardCfg> = global.$cfg.get(BaseConst.SYSTEMCARD);
|
||||
let effCfgMap: Map<number, EffectCardCfg> = global.$cfg.get(BaseConst.EFFECTCARD);
|
||||
/**
|
||||
* 游戏开始时, 初始化卡组
|
||||
*/
|
||||
initCardQue(beginNum: number) {
|
||||
let cards: Card[] = []
|
||||
let numCfgMap: Map<number, SystemCardCfg> = global.$cfg.get(BaseConst.SYSTEMCARD)
|
||||
let effCfgMap: Map<number, EffectCardCfg> = global.$cfg.get(BaseConst.EFFECTCARD)
|
||||
|
||||
let countMap: Map<number, number> = new Map();
|
||||
let localId = beginNum;
|
||||
for (let [, cfg] of numCfgMap) {
|
||||
for (let i = 0; i < cfg.count; i++) {
|
||||
let [effid, effType] = this.getRandomEffect(cfg.weightArr, effCfgMap, countMap);
|
||||
let type = cfg.type_id;
|
||||
// 如果效果的type_id为11, 说明是自选随从卡, 则将card的type改为11
|
||||
if (effType == EffectType.variable_unit) {
|
||||
type = CardType.variable_unit;
|
||||
}
|
||||
let card = new Card(localId++, cfg.point, type, effid);
|
||||
cards.push(card);
|
||||
}
|
||||
let countMap: Map<number, number> = new Map()
|
||||
let localId = beginNum
|
||||
for (let [, cfg] of numCfgMap) {
|
||||
for (let i = 0; i < cfg.count; i++) {
|
||||
let [effid, effType] = this.getRandomEffect(cfg.weightArr, effCfgMap, countMap)
|
||||
let type = cfg.type_id
|
||||
// 如果效果的type_id为11, 说明是自选随从卡, 则将card的type改为11
|
||||
if (effType == EffectType.variable_unit) {
|
||||
type = CardType.variable_unit
|
||||
}
|
||||
|
||||
cards.randomSort();
|
||||
return cards;
|
||||
},
|
||||
initSampleCards(beginNum: number) {
|
||||
let cardArr = [[1, 1, 20012, 1], [2, 3, 20102, 11], [3, 4, 20032, 1], [4, 10, 20102, 11], [5, 10, 20042, 1], [6, 1, 20012, 1], [7, 3, 20102, 11], [8, 4, 20032, 1], [9, 5, 20102, 11], [10, 6, 20102, 11], [11, 1, 20012, 1], [12, 5, 20102, 11], [13, 5, 20032, 1], [14, 5, 20102, 11], [15, 5, 20102, 11], [16, 6, 20102, 11], [17, 1, 20012, 1], [18, 3, 20102, 11], [19, 5, 20102, 11], [20, 7, 20102, 11], [21, 8, 20042, 1], [22, 10, 20102, 11], [23, 4, 20102, 11], [24, 7, 20052, 1], [25, 3, 20102, 11], [26, 7, 20052, 1], [27, 6, 20072, 1], [28, 1, 20052, 1], [29, 5, 20102, 11], [30, 4, 20052, 1], [31, 0, 20112, 2], [32, 5, 20102, 11], [33, 5, 20062, 1], [34, 2, 20102, 11], [35, 4, 20062, 1], [36, 1, 20072, 1], [37, 1, 20102, 11], [38, 1, 20062, 1], [39, 9, 20042, 1], [40, 0, 20112, 2], [41, 6, 20102, 11], [42, 8, 20072, 1], [43, 0, 20112, 2], [44, 0, 20112, 2], [45, 0, 20112, 2], [46, 0, 20112, 2], [47, 0, 20112, 2], [48, 0, 20112, 2], [49, 10, 20042, 1], [50, 0, 20112, 2], [51, 5, 20102, 11], [52, 5, 20082, 1], [53, 5, 20102, 11], [54, 5, 20052, 1], [55, 0, 20122, 3], [56, 0, 20122, 3], [57, 0, 20122, 3], [58, 0, 20122, 3], [59, 0, 20122, 3], [60, 0, 20122, 3], [61, 0, 20122, 3], [62, 0, 20122, 3], [63, 0, 20112, 2], [64, 0, 20112, 2], [65, 0, 20112, 2], [66, 0, 20112, 2], [67, 0, 20112, 2], [68, 0, 20112, 2]]
|
||||
let cards: Card[] = [];
|
||||
for (let i = cardArr.length - 1; i >=0; i--) {
|
||||
let subarr = cardArr[i]
|
||||
let card = new Card(subarr[0], subarr[1], subarr[3], subarr[2])
|
||||
cards.push(card)
|
||||
}
|
||||
debugRoom(cards)
|
||||
return cards
|
||||
},
|
||||
/**
|
||||
* 随机生成一张指定效果的卡
|
||||
* @param effectId
|
||||
* @param preCardId
|
||||
* @param options
|
||||
*/
|
||||
generateCardWithEffect(effectId: number, preCardId: number, options?: any): Card {
|
||||
let numCfgMap: Map<number, SystemCardCfg> = global.$cfg.get(BaseConst.SYSTEMCARD);
|
||||
const effectMap = global.$cfg.get(BaseConst.EFFECTCARD);
|
||||
let cfgs = [];
|
||||
const effectCfg = effectMap.get(effectId);
|
||||
if (!effectCfg) {
|
||||
return null;
|
||||
}
|
||||
if (effectCfg.type_id == EffectType.unit) {
|
||||
let point = Math.random2(1, 11) | 0;
|
||||
return new Card(preCardId + 1, point, CardType.variable_unit, effectId);
|
||||
} else {
|
||||
for (let [, cfg] of numCfgMap) {
|
||||
if (cfg.weight.indexOf(effectId + '') >= 0) {
|
||||
cfgs.push(cfg);
|
||||
}
|
||||
}
|
||||
let cfg: SystemCardCfg = cfgs.randomOne();
|
||||
return new Card(preCardId + 1, cfg.point, cfg.type_id, effectId);
|
||||
}
|
||||
|
||||
},
|
||||
/**
|
||||
* 获取随机的随从
|
||||
* @param player
|
||||
*/
|
||||
getRandomServant(player: Player) {
|
||||
let total = 0;
|
||||
let tmpArr: number[][] = [];
|
||||
for (let [id, weight] of player.unitCfgs) {
|
||||
total += weight;
|
||||
tmpArr.push([parseInt(id), total]);
|
||||
}
|
||||
let num = Math.random() * total;
|
||||
let result;
|
||||
for (let data of tmpArr) {
|
||||
if (data[1] >= num) {
|
||||
result = data[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* 根据配表中的权重, 获取一个效果卡的id
|
||||
* @param weightArr 配表中的权重列表
|
||||
* @param effCfgMap 配表中的所有效果卡的配置
|
||||
* @param countMap 当前已生成的效果卡数量
|
||||
*/
|
||||
getRandomEffect(weightArr: number[][], effCfgMap: Map<number, EffectCardCfg>, countMap: Map<number, number>): number[] {
|
||||
let total = 0;
|
||||
let tmpArr: number[][] = [];
|
||||
for (let data of weightArr) {
|
||||
total += data[1];
|
||||
tmpArr.push([data[0], total]);
|
||||
}
|
||||
let num = Math.random() * total;
|
||||
let effid;
|
||||
let effType;
|
||||
for (let data of tmpArr) {
|
||||
if (data[1] >= num) {
|
||||
let count = countMap.has(data[0]) ? countMap.get(data[0]) : 0;
|
||||
if (count < effCfgMap.get(data[0]).count) {
|
||||
effid = effCfgMap.get(data[0]).id;
|
||||
effType = effCfgMap.get(data[0]).type_id;
|
||||
countMap.set(effid, count + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!effid) {
|
||||
for (let [id, count] of countMap) {
|
||||
if (count < effCfgMap.get(id).count) {
|
||||
effid = id;
|
||||
effType = effCfgMap.get(effid).type_id;
|
||||
countMap.set(effid, count + 1);
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!effid) {
|
||||
error('生成卡组时, 无法匹配效果卡, 请确认效果卡的最大数量是否等于点数卡总数')
|
||||
}
|
||||
return [effid, effType];
|
||||
},
|
||||
/**
|
||||
* 检查目标数组中的卡id是否在存在
|
||||
* @param cardMap
|
||||
* @param cardIds
|
||||
*/
|
||||
checkCardsExists(cardMap: Map<string, Card>, cardIds: Array<string>) {
|
||||
let result = true;
|
||||
for (let id of cardIds) {
|
||||
if (!cardMap.has(id + '')) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* 抽卡
|
||||
* @param room
|
||||
* @param cardArr
|
||||
* @param player
|
||||
* @param count
|
||||
* @param fromplayer
|
||||
* @param extData 指定卡的效果
|
||||
*/
|
||||
drawCard(room: Room, cardArr: Card[], player: Player, count: number, fromplayer?: Player, extData?: {}): Card[] {
|
||||
let cards: Card[] = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
let card = cardArr.pop();
|
||||
if (extData) {
|
||||
// @ts-ignore
|
||||
extData['effect'] && (card.effect = extData['effect']);
|
||||
// @ts-ignore
|
||||
extData['type'] && (card.type = extData['type']);
|
||||
// @ts-ignore
|
||||
extData['number'] && (card.number = extData['number']);
|
||||
}
|
||||
cards.push(card);
|
||||
}
|
||||
this.addCardToPlayer(room, player, cards, fromplayer);
|
||||
return cards;
|
||||
},
|
||||
/**
|
||||
* 随机移除n张手牌
|
||||
* @param player
|
||||
* @param count
|
||||
*/
|
||||
removeCard(player: Player, count: number): Card[] {
|
||||
let cards: Card[] = [];
|
||||
let cardArr: Card[] = [...player.cards.values()];
|
||||
cards = cardArr.randomGet(count);
|
||||
this.deleteCardFromPlayer(player, cards);
|
||||
return cards;
|
||||
},
|
||||
/**
|
||||
* 从玩家手牌中删除指定的卡
|
||||
* @param player
|
||||
* @param cards
|
||||
*/
|
||||
deleteCardFromPlayer(player: Player, cards: Card[] | string[] | number[] | number | string) {
|
||||
let deleteOne = function (cardId: string) {
|
||||
if (player.cards.has(cardId)) {
|
||||
if (cardLog.enabled) {
|
||||
let card = player.cards.get(cardId);
|
||||
cardLog(`delete: ${player.id} ${card.id} ${card.effect} ${card.type} `)
|
||||
}
|
||||
player.cards.delete(cardId);
|
||||
player.cardSet.delete(cardId);
|
||||
}
|
||||
}
|
||||
if (typeof cards == 'number' || typeof cards == 'string') {
|
||||
const cardId = cards + '';
|
||||
deleteOne(cardId);
|
||||
} else {
|
||||
for (let card of cards) {
|
||||
let cardId = '';
|
||||
if (typeof card == 'string') {
|
||||
cardId = card;
|
||||
} else if (typeof card == 'number') {
|
||||
cardId = card + '';
|
||||
} else {
|
||||
cardId = (card as Card).id + '';
|
||||
}
|
||||
deleteOne(cardId);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
pushInPlayerCards(player: Player, cards: Card[]) {
|
||||
const effectMap = global.$cfg.get(BaseConst.EFFECTCARD);
|
||||
let realCards: Card[] = []
|
||||
for (let card of cards) {
|
||||
if (!card) {
|
||||
continue
|
||||
}
|
||||
// 如果card的type == 11, 说明是自选随从卡, 则替换成玩家牌组中的卡
|
||||
if (card.type == CardType.variable_unit && effectMap.get(card.effect).type_id == EffectType.variable_unit) {
|
||||
card.effect = this.getRandomServant(player);
|
||||
}
|
||||
card.owner = player.id
|
||||
realCards.push(card)
|
||||
player.cards.set(card.id + '', card);
|
||||
player.cardSet.add(card.id + '');
|
||||
}
|
||||
cardLog(`add: ${player.id} ${realCards.map(o => [o.id, o.effect, o.type])}`)
|
||||
},
|
||||
/**
|
||||
* 往玩家的卡组里添加卡
|
||||
* @param room
|
||||
* @param player
|
||||
* @param cards
|
||||
* @param fromplayer
|
||||
*/
|
||||
addCardToPlayer(room: Room, player: Player, cards: Card[], fromplayer?: Player) {
|
||||
this.pushInPlayerCards(player, cards);
|
||||
player.countTotal += cards.length;
|
||||
let time = room.battleMan.onCardGetted(player, cards, fromplayer);
|
||||
cardLog(`addCardToPlayer add time: ${time}`);
|
||||
},
|
||||
/**
|
||||
* 更换相同数量的卡
|
||||
* @param cardArr
|
||||
* @param player
|
||||
* @param targetCards
|
||||
*/
|
||||
changeCard(cardArr: Card[], player: Player, targetCards: Card[]): Card[] {
|
||||
const effectMap = global.$cfg.get(BaseConst.EFFECTCARD);
|
||||
let cards: Card[] = [];
|
||||
let tmpCards: Card[] = [];
|
||||
for (let card of targetCards) {
|
||||
tmpCards.push(card.clone());
|
||||
}
|
||||
this.deleteCardFromPlayer(player, targetCards);
|
||||
cardArr.randomInsert(tmpCards);
|
||||
let count = targetCards.length;
|
||||
for (let i = 0; i < count; i++) {
|
||||
cards.push(cardArr.pop());
|
||||
}
|
||||
this.pushInPlayerCards(player, cards);
|
||||
return cards;
|
||||
},
|
||||
/**
|
||||
* 检查出牌是否符合规则
|
||||
* @param cardsLst
|
||||
* @param maxCount
|
||||
*/
|
||||
checkDiscard(cardsLst: Card[], maxCount: number) {
|
||||
if (cardsLst.length == 0 || cardsLst.length == 2) {
|
||||
return false
|
||||
} else if (cardsLst.length == 1) {
|
||||
return true;
|
||||
}
|
||||
let numSet: number[] = [];
|
||||
cardsLst.forEach(function (value) {
|
||||
if (value.type == CardType.general || value.type == CardType.variable_unit) {
|
||||
numSet.push(value.number);
|
||||
}
|
||||
});
|
||||
if (numSet.length === 1) {
|
||||
return true;
|
||||
}
|
||||
if (numSet.length < maxCount) {
|
||||
return false;
|
||||
}
|
||||
numSet.sort((a, b) => {
|
||||
return a - b;
|
||||
});
|
||||
let preNum;
|
||||
let sequence = true; //是否是顺序
|
||||
let same = true; //是否是相同
|
||||
for (let num of numSet) {
|
||||
if (preNum) {
|
||||
if (num !== (preNum + 1) && sequence) {
|
||||
sequence = false;
|
||||
}
|
||||
if (num !== preNum && same) {
|
||||
same = false;
|
||||
}
|
||||
if (!sequence && !same) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
preNum = num;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
/**
|
||||
* 结算时计算总的ap
|
||||
* @param player
|
||||
*/
|
||||
calcTotalAp(player: Player) {
|
||||
let result = 0;
|
||||
if (!player) {
|
||||
return result;
|
||||
}
|
||||
for (let [pid, pet] of player.pets) {
|
||||
result += pet.ap;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
checkGameEnd(state: CardGameState) {
|
||||
let deadCount0 = 0;
|
||||
let deadCount1 = 0;
|
||||
for (let [, player] of state.players) {
|
||||
if (player.team == 0 && player.state == PlayerStateConst.PLAYER_DEAD ) {
|
||||
deadCount0 ++;
|
||||
} else if (player.team == 1 && player.state == PlayerStateConst.PLAYER_DEAD ){
|
||||
deadCount1 ++;
|
||||
}
|
||||
}
|
||||
const roundNum = new GameEnv().duelRoundNum;
|
||||
const totalRound = roundNum * new GameEnv().maxDuelNum;
|
||||
return (deadCount0 == 2 || deadCount1 == 2) || (state.round >= totalRound - 1);
|
||||
let card = new Card(localId++, cfg.point, type, effid)
|
||||
cards.push(card)
|
||||
}
|
||||
}
|
||||
|
||||
cards.randomSort()
|
||||
return cards
|
||||
},
|
||||
initSampleCards(beginNum: number) {
|
||||
let cardArr = [[1, 1, 20012, 1], [2, 3, 20102, 11], [3, 4, 20032, 1], [4, 10, 20102, 11], [5, 10, 20042, 1], [6, 1, 20012, 1], [7, 3, 20102, 11], [8, 4, 20032, 1], [9, 5, 20102, 11], [10, 6, 20102, 11], [11, 1, 20012, 1], [12, 5, 20102, 11], [13, 5, 20032, 1], [14, 5, 20102, 11], [15, 5, 20102, 11], [16, 6, 20102, 11], [17, 1, 20012, 1], [18, 3, 20102, 11], [19, 5, 20102, 11], [20, 7, 20102, 11], [21, 8, 20042, 1], [22, 10, 20102, 11], [23, 4, 20102, 11], [24, 7, 20052, 1], [25, 3, 20102, 11], [26, 7, 20052, 1], [27, 6, 20072, 1], [28, 1, 20052, 1], [29, 5, 20102, 11], [30, 4, 20052, 1], [31, 0, 20112, 2], [32, 5, 20102, 11], [33, 5, 20062, 1], [34, 2, 20102, 11], [35, 4, 20062, 1], [36, 1, 20072, 1], [37, 1, 20102, 11], [38, 1, 20062, 1], [39, 9, 20042, 1], [40, 0, 20112, 2], [41, 6, 20102, 11], [42, 8, 20072, 1], [43, 0, 20112, 2], [44, 0, 20112, 2], [45, 0, 20112, 2], [46, 0, 20112, 2], [47, 0, 20112, 2], [48, 0, 20112, 2], [49, 10, 20042, 1], [50, 0, 20112, 2], [51, 5, 20102, 11], [52, 5, 20082, 1], [53, 5, 20102, 11], [54, 5, 20052, 1], [55, 0, 20122, 3], [56, 0, 20122, 3], [57, 0, 20122, 3], [58, 0, 20122, 3], [59, 0, 20122, 3], [60, 0, 20122, 3], [61, 0, 20122, 3], [62, 0, 20122, 3], [63, 0, 20112, 2], [64, 0, 20112, 2], [65, 0, 20112, 2], [66, 0, 20112, 2], [67, 0, 20112, 2], [68, 0, 20112, 2]]
|
||||
let cards: Card[] = []
|
||||
for (let i = cardArr.length - 1; i >= 0; i--) {
|
||||
let subarr = cardArr[i]
|
||||
let card = new Card(subarr[0], subarr[1], subarr[3], subarr[2])
|
||||
cards.push(card)
|
||||
}
|
||||
debugRoom(cards)
|
||||
return cards
|
||||
},
|
||||
/**
|
||||
* 随机生成一张指定效果的卡
|
||||
* @param effectId
|
||||
* @param preCardId
|
||||
* @param options
|
||||
*/
|
||||
generateCardWithEffect(effectId: number, preCardId: number, options?: any): Card {
|
||||
let numCfgMap: Map<number, SystemCardCfg> = global.$cfg.get(BaseConst.SYSTEMCARD)
|
||||
const effectMap = global.$cfg.get(BaseConst.EFFECTCARD)
|
||||
let cfgs = []
|
||||
const effectCfg = effectMap.get(effectId)
|
||||
if (!effectCfg) {
|
||||
return null
|
||||
}
|
||||
if (effectCfg.type_id == EffectType.unit) {
|
||||
let point = Math.random2(1, 11) | 0
|
||||
return new Card(preCardId + 1, point, CardType.variable_unit, effectId)
|
||||
} else {
|
||||
for (let [, cfg] of numCfgMap) {
|
||||
if (cfg.weight.indexOf(effectId + '') >= 0) {
|
||||
cfgs.push(cfg)
|
||||
}
|
||||
}
|
||||
let cfg: SystemCardCfg = cfgs.randomOne()
|
||||
return new Card(preCardId + 1, cfg.point, cfg.type_id, effectId)
|
||||
}
|
||||
|
||||
},
|
||||
/**
|
||||
* 获取随机的随从
|
||||
* @param player
|
||||
*/
|
||||
getRandomServant(player: Player) {
|
||||
let total = 0
|
||||
let tmpArr: number[][] = []
|
||||
for (let [id, weight] of player.unitCfgs) {
|
||||
total += weight
|
||||
tmpArr.push([parseInt(id), total])
|
||||
}
|
||||
let num = Math.random() * total
|
||||
let result
|
||||
for (let data of tmpArr) {
|
||||
if (data[1] >= num) {
|
||||
result = data[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
},
|
||||
/**
|
||||
* 根据配表中的权重, 获取一个效果卡的id
|
||||
* @param weightArr 配表中的权重列表
|
||||
* @param effCfgMap 配表中的所有效果卡的配置
|
||||
* @param countMap 当前已生成的效果卡数量
|
||||
*/
|
||||
getRandomEffect(weightArr: number[][], effCfgMap: Map<number, EffectCardCfg>, countMap: Map<number, number>): number[] {
|
||||
let total = 0
|
||||
let tmpArr: number[][] = []
|
||||
for (let data of weightArr) {
|
||||
total += data[1]
|
||||
tmpArr.push([data[0], total])
|
||||
}
|
||||
let num = Math.random() * total
|
||||
let effid
|
||||
let effType
|
||||
for (let data of tmpArr) {
|
||||
if (data[1] >= num) {
|
||||
let count = countMap.has(data[0]) ? countMap.get(data[0]) : 0
|
||||
if (count < effCfgMap.get(data[0]).count) {
|
||||
effid = effCfgMap.get(data[0]).id
|
||||
effType = effCfgMap.get(data[0]).type_id
|
||||
countMap.set(effid, count + 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!effid) {
|
||||
for (let [id, count] of countMap) {
|
||||
if (count < effCfgMap.get(id).count) {
|
||||
effid = id
|
||||
effType = effCfgMap.get(effid).type_id
|
||||
countMap.set(effid, count + 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!effid) {
|
||||
error('生成卡组时, 无法匹配效果卡, 请确认效果卡的最大数量是否等于点数卡总数')
|
||||
}
|
||||
return [effid, effType]
|
||||
},
|
||||
/**
|
||||
* 检查目标数组中的卡id是否在存在
|
||||
* @param cardMap
|
||||
* @param cardIds
|
||||
*/
|
||||
checkCardsExists(cardMap: Map<string, Card>, cardIds: Array<string>) {
|
||||
let result = true
|
||||
for (let id of cardIds) {
|
||||
if (!cardMap.has(id + '')) {
|
||||
result = false
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
},
|
||||
/**
|
||||
* 抽卡
|
||||
* @param room
|
||||
* @param cardArr
|
||||
* @param player
|
||||
* @param count
|
||||
* @param fromplayer
|
||||
* @param extData 指定卡的效果
|
||||
*/
|
||||
drawCard(room: Room, cardArr: Card[], player: Player, count: number, fromplayer?: Player, extData?: {}): Card[] {
|
||||
let cards: Card[] = []
|
||||
for (let i = 0; i < count; i++) {
|
||||
let card = cardArr.pop()
|
||||
if (extData) {
|
||||
// @ts-ignore
|
||||
extData['effect'] && (card.effect = extData['effect'])
|
||||
// @ts-ignore
|
||||
extData['type'] && (card.type = extData['type'])
|
||||
// @ts-ignore
|
||||
extData['number'] && (card.number = extData['number'])
|
||||
}
|
||||
cards.push(card)
|
||||
}
|
||||
this.addCardToPlayer(room, player, cards, fromplayer)
|
||||
return cards
|
||||
},
|
||||
/**
|
||||
* 随机移除n张手牌
|
||||
* @param player
|
||||
* @param count
|
||||
*/
|
||||
removeCard(player: Player, count: number): Card[] {
|
||||
let cards: Card[] = []
|
||||
let cardArr: Card[] = [...player.cards.values()]
|
||||
cards = cardArr.randomGet(count)
|
||||
this.deleteCardFromPlayer(player, cards)
|
||||
return cards
|
||||
},
|
||||
/**
|
||||
* 从玩家手牌中删除指定的卡
|
||||
* @param player
|
||||
* @param cards
|
||||
*/
|
||||
deleteCardFromPlayer(player: Player, cards: Card[] | string[] | number[] | number | string) {
|
||||
let deleteOne = function (cardId: string) {
|
||||
if (player.cards.has(cardId)) {
|
||||
if (cardLog.enabled) {
|
||||
let card = player.cards.get(cardId)
|
||||
cardLog(`delete: ${ player.id } ${ card.id } ${ card.effect } ${ card.type } `)
|
||||
}
|
||||
player.cards.delete(cardId)
|
||||
player.cardSet.delete(cardId)
|
||||
}
|
||||
}
|
||||
if (typeof cards == 'number' || typeof cards == 'string') {
|
||||
const cardId = cards + ''
|
||||
deleteOne(cardId)
|
||||
} else {
|
||||
for (let card of cards) {
|
||||
let cardId = ''
|
||||
if (typeof card == 'string') {
|
||||
cardId = card
|
||||
} else if (typeof card == 'number') {
|
||||
cardId = card + ''
|
||||
} else {
|
||||
cardId = (card as Card).id + ''
|
||||
}
|
||||
deleteOne(cardId)
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
pushInPlayerCards(player: Player, cards: Card[]) {
|
||||
const effectMap = global.$cfg.get(BaseConst.EFFECTCARD)
|
||||
let realCards: Card[] = []
|
||||
for (let card of cards) {
|
||||
if (!card) {
|
||||
continue
|
||||
}
|
||||
// 如果card的type == 11, 说明是自选随从卡, 则替换成玩家牌组中的卡
|
||||
if (card.type == CardType.variable_unit && effectMap.get(card.effect).type_id == EffectType.variable_unit) {
|
||||
card.effect = this.getRandomServant(player)
|
||||
}
|
||||
card.owner = player.id
|
||||
realCards.push(card)
|
||||
player.cards.set(card.id + '', card)
|
||||
player.cardSet.add(card.id + '')
|
||||
}
|
||||
cardLog(`add: ${ player.id } ${ realCards.map(o => [o.id, o.effect, o.type]) }`)
|
||||
},
|
||||
/**
|
||||
* 往玩家的卡组里添加卡
|
||||
* @param room
|
||||
* @param player
|
||||
* @param cards
|
||||
* @param fromplayer
|
||||
*/
|
||||
addCardToPlayer(room: Room, player: Player, cards: Card[], fromplayer?: Player) {
|
||||
this.pushInPlayerCards(player, cards)
|
||||
player.countTotal += cards.length
|
||||
let time = room.battleMan.onCardGetted(player, cards, fromplayer)
|
||||
cardLog(`addCardToPlayer add time: ${ time }`)
|
||||
},
|
||||
/**
|
||||
* 更换相同数量的卡
|
||||
* @param cardArr
|
||||
* @param player
|
||||
* @param targetCards
|
||||
*/
|
||||
changeCard(cardArr: Card[], player: Player, targetCards: Card[]): Card[] {
|
||||
const effectMap = global.$cfg.get(BaseConst.EFFECTCARD)
|
||||
let cards: Card[] = []
|
||||
let tmpCards: Card[] = []
|
||||
for (let card of targetCards) {
|
||||
tmpCards.push(card.clone())
|
||||
}
|
||||
this.deleteCardFromPlayer(player, targetCards)
|
||||
cardArr.randomInsert(tmpCards)
|
||||
let count = targetCards.length
|
||||
for (let i = 0; i < count; i++) {
|
||||
cards.push(cardArr.pop())
|
||||
}
|
||||
this.pushInPlayerCards(player, cards)
|
||||
return cards
|
||||
},
|
||||
/**
|
||||
* 检查出牌是否符合规则
|
||||
* @param cardsLst
|
||||
* @param maxCount
|
||||
*/
|
||||
checkDiscard(cardsLst: Card[], maxCount: number) {
|
||||
if (cardsLst.length == 0 || cardsLst.length == 2) {
|
||||
return false
|
||||
} else if (cardsLst.length == 1) {
|
||||
return true
|
||||
}
|
||||
let numSet: number[] = []
|
||||
cardsLst.forEach(function (value) {
|
||||
if (value.type == CardType.general || value.type == CardType.variable_unit) {
|
||||
numSet.push(value.number)
|
||||
}
|
||||
})
|
||||
if (numSet.length === 1) {
|
||||
return true
|
||||
}
|
||||
if (numSet.length < maxCount) {
|
||||
return false
|
||||
}
|
||||
numSet.sort((a, b) => {
|
||||
return a - b
|
||||
})
|
||||
let preNum
|
||||
let sequence = true //是否是顺序
|
||||
let same = true //是否是相同
|
||||
for (let num of numSet) {
|
||||
if (preNum) {
|
||||
if (num !== (preNum + 1) && sequence) {
|
||||
sequence = false
|
||||
}
|
||||
if (num !== preNum && same) {
|
||||
same = false
|
||||
}
|
||||
if (!sequence && !same) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
preNum = num
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
/**
|
||||
* 结算时计算总的ap
|
||||
* @param player
|
||||
*/
|
||||
calcTotalAp(player: Player) {
|
||||
let result = 0
|
||||
if (!player) {
|
||||
return result
|
||||
}
|
||||
for (let [pid, pet] of player.pets) {
|
||||
result += pet.ap
|
||||
}
|
||||
return result
|
||||
},
|
||||
|
||||
checkGameEnd(state: CardGameState) {
|
||||
let deadCount0 = 0
|
||||
let deadCount1 = 0
|
||||
for (let [, player] of state.players) {
|
||||
if (player.team == 0 && player.state == PlayerStateConst.PLAYER_DEAD) {
|
||||
deadCount0++
|
||||
} else if (player.team == 1 && player.state == PlayerStateConst.PLAYER_DEAD) {
|
||||
deadCount1++
|
||||
}
|
||||
}
|
||||
const roundNum = new GameEnv().duelRoundNum
|
||||
const totalRound = roundNum * new GameEnv().maxDuelNum
|
||||
return (deadCount0 == 2 || deadCount1 == 2) || (state.round >= totalRound - 1)
|
||||
}
|
||||
|
||||
}
|
||||
export default gameUtil;
|
||||
export default gameUtil
|
||||
|
Loading…
x
Reference in New Issue
Block a user