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 {error} from "../common/Debug"; import {Room} from "colyseus"; import {PlayerStateConst} from "../constants/PlayerStateConst"; import {GameEnv} from "../cfg/GameEnv"; import {GameResultCommand} from "../rooms/commands/GameResultCommand"; import {CardGameState} from "../rooms/schema/CardGameState"; let gameUtil = { /** * 游戏开始时, 初始化卡组 */ initCardQue() { let cards: Card[] = []; let numCfgMap: Map = global.$cfg.get(BaseConst.SYSTEMCARD); let effCfgMap: Map = global.$cfg.get(BaseConst.EFFECTCARD); let countMap: Map = new Map(); let localId = 1; 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 == 11) { type = 11; } let card = new Card(localId++, cfg.point, type, effid); cards.push(card); } } cards.randomSort(); return cards; }, /** * 随机生成一张指定效果的卡 * @param effectId * @param preCardId * @param options */ generateCardWithEffect(effectId: number, preCardId: number, options?: any): Card { let numCfgMap: Map = global.$cfg.get(BaseConst.SYSTEMCARD); let cfgs = []; 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([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, countMap: Map): 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, cardIds: Array) { 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[]) { 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 + ''; } if (player.cards.has(cardId)) { player.cards.delete(cardId); player.cardSet.delete(cardId); } } }, /** * 往玩家的卡组里添加卡 * @param room * @param player * @param cards * @param fromplayer */ addCardToPlayer(room: Room, player: Player, cards: Card[], fromplayer?: Player) { for (let card of cards) { // 如果card的type == 11, 说明是自选随从卡, 则替换成玩家牌组中的卡 if (card.type == 11) { card.effect = this.getRandomServant(player); } player.cards.set(card.id + '', card); player.cardSet.add(card.id + ''); } player.countTotal += cards.length; room.battleMan.onCardGetted(player, cards, fromplayer); }, /** * 更换相同数量的卡 * @param cardArr * @param player * @param targetCards */ changeCard(cardArr: Card[], player: Player, targetCards: Card[]): Card[] { let cards: Card[] = []; for (let card of targetCards) { player.cards.delete(card.id + ''); player.cardSet.delete(card.id + ''); } cardArr.randomInsert(targetCards); let count = targetCards.length; for (let i = 0; i < count; i++) { let card = cardArr.pop(); if (card.type == 11) { card.effect = this.getRandomServant(player); } cards.push(card); player.cards.set(card.id + '', card); player.cardSet.add(card.id + ''); } return cards; }, /** * 检查出牌是否符合规则 * @param cardsLst */ checkDiscard(cardsLst: Card[]) { 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.number < 11) { numSet.push(value.number); } }); if (numSet.length === 1) { return true; } if (numSet.length < 3) { 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;