diff --git a/src/common/Extend.ts b/src/common/Extend.ts index 9d82a79..5413a8c 100644 --- a/src/common/Extend.ts +++ b/src/common/Extend.ts @@ -861,3 +861,25 @@ Object.defineProperties(Array.prototype, { } }); + +interface Map { + /** + * 只针对V为number的Map, 有值的话, 加上V, 没值则直接set + * V为其他类型时, 直接set + * @param key + * @param value + */ + inc?(key: K, value: V): this; +} + +Object.defineProperties(Map.prototype, { + inc: { + value: function (key: K, value: V) { + if (typeof value == 'number') { + this.set(key, (this.get(key) || 0) + value ); + } else { + this.set(key, value); + } + } + } +}); diff --git a/src/rooms/RoomExtMethod.ts b/src/rooms/RoomExtMethod.ts index 640ba26..ee7b6bf 100644 --- a/src/rooms/RoomExtMethod.ts +++ b/src/rooms/RoomExtMethod.ts @@ -6,6 +6,7 @@ import {PetInfo} from "../message/PetInfo"; import {PlayDeadCommand} from "./commands/PlayDeadCommand"; import {GameEnv} from "../cfg/GameEnv"; import {Player} from "./schema/Player"; +import {StateTypeEnum} from "./enums/StateTypeEnum"; /** * 一些常用的方法 @@ -15,7 +16,7 @@ Object.defineProperties(Room.prototype, { value: function (srcplayer: string, dstplayer: string, count: number): number { debugRoom(`玩家 ${srcplayer} 从 ${dstplayer} 偷 ${count} 张卡`); let player1 = this.state.players.get(dstplayer); - let player0 = this.state.players.get(srcplayer); + let player0: Player = this.state.players.get(srcplayer); /** * 首先取目标玩家手牌数和偷牌数量的最小值 * 然后取目标玩家的手牌数和配置中玩家手牌数的差值 @@ -28,6 +29,7 @@ Object.defineProperties(Room.prototype, { gameUtil.addCardToPlayer(this, player0, tmpCards, player1); let cardIds = tmpCards.map(card => card.id); let client = this.getClient(player0); + player0.statData.inc(StateTypeEnum.SCOUNT, tmpCards.length); //广播一个偷卡成功信息, 并私信一个偷卡详情给当前玩家 let msgData = { srcplayer, @@ -50,6 +52,10 @@ Object.defineProperties(Room.prototype, { let tmpCards = gameUtil.removeCard(player, count); let time = this.battleMan.onCardDroped(player, tmpCards); debugRoom(`giveUpCard add time: ${time}`); + let fromP = this.state.players.get(fromplayer); + if (fromP.id != player.id){ + fromP.statData.inc(StateTypeEnum.GCOUNT, tmpCards.length); + } let cardIds = tmpCards.map(card => card.id); let msgData = { player: dstplayer, @@ -64,7 +70,7 @@ Object.defineProperties(Room.prototype, { * @param dstplayer 目标玩家 * @param count 补多少张, 该值和max_count至少一个不为0 * @param max_count 补到多少张, 如果count和max_count都不为0, 则抽 Math.min(count, (max_count - 当前手牌数)) - * @param source 0: 正常抽卡, 1: 技能 + * @param source 0: 正常抽卡, 1: 技能, 9: GM * @param fromplayer */ addCard: { @@ -87,6 +93,9 @@ Object.defineProperties(Room.prototype, { } let player2 = fromplayer ? this.state.players.get(fromplayer) : null; let cards = gameUtil.drawCard(this, this.state.cardQueue, player, count, player2, extData); + if (source == 2 && player2 && player2.id != player.id) { + player2.statData.inc(StateTypeEnum.ACOUNT, cards.length); + } let client = this.getClient(dstplayer); let sData = { player: dstplayer, @@ -115,6 +124,11 @@ Object.defineProperties(Room.prototype, { return 0; } else { let dstHp = player.hp + (hp | 0); + let sourceP = this.state.players.get(fromplayer); + if (sourceP && hp < 0) { + sourceP.statData.inc(StateTypeEnum.DMG, hp); + player.statData.inc(StateTypeEnum.TDMG, hp); + } debugRoom(`更新血量: ${player.id} ${player.hp} -> ${hp}, reason: ${reason}`); if (dstHp <= 0) { dstHp = 0; @@ -177,7 +191,17 @@ Object.defineProperties(Room.prototype, { */ updatePetStat: { value: function (datas: PetInfo[], fromplayer?: string): void { - + let player = this.state.players.get(fromplayer); + for (let data of datas) { + let targetPlayer = this.state.players.get(data.player); + let valOld = targetPlayer.petData.get(data.pos) || 0; + let valNew = data.ap + data.extAp; + targetPlayer.petData.set(data.pos, valNew); + if (valNew < valOld) { + player.statData.inc(StateTypeEnum.DMG, valOld - valNew); + targetPlayer.statData.inc(StateTypeEnum.TDMG, valOld - valNew); + } + } } }, /** @@ -214,9 +238,13 @@ Object.defineProperties(Room.prototype, { let sourcePlayer; if (typeof fromplayer == 'string') { sourcePlayer = this.state.players.get(fromplayer); + if (sourcePlayer.id !== dstplayer.id) { + sourcePlayer.statData.inc(StateTypeEnum.CCOUNT, tmpCards.length); + } } else { sourcePlayer = player; } + gameUtil.addCardToPlayer(this, dstplayer, tmpCards, sourcePlayer); let client = this.getClient(dstplayer); let sData = { diff --git a/src/rooms/commands/DiscardCommand.ts b/src/rooms/commands/DiscardCommand.ts index f36f4bd..72e2dca 100644 --- a/src/rooms/commands/DiscardCommand.ts +++ b/src/rooms/commands/DiscardCommand.ts @@ -10,6 +10,7 @@ import {TurnEndCommand} from "./TurnEndCommand"; import {Card} from "../schema/Card"; import {Wait} from "./Wait"; import {CardType} from "../../cfg/enums/CardType"; +import {StateTypeEnum} from "../enums/StateTypeEnum"; /** * 出牌 @@ -88,6 +89,7 @@ export class DiscardCommand extends Command { let hp1 = 0; let ap0 = 0; let ap1 = 0; + let petAp0 = 0; + let petAp1 = 0; let resultArr = []; for (let [, player] of this.state.players) { let data = { @@ -34,29 +37,66 @@ export class GameResultCommand extends Command { hp0 += player.hp; if (player.state != PlayerStateConst.PLAYER_DEAD) { ap0 += data.ap; + for (let [,pet] of player.pets) { + petAp0 += (pet.ap + pet.extAp); + } } } if (player.team == 1) { hp1 += player.hp; if (player.state != PlayerStateConst.PLAYER_DEAD) { ap1 += data.ap; + for (let [,pet] of player.pets) { + petAp1 += (pet.ap + pet.extAp); + } } } } - let winner = 0; + let winner = -1; // 平局 if (hp0 > hp1) { winner = 0; } else if (hp0 < hp1) { winner = 1; } else { - if (ap0 >= ap1) { + if (ap0 > ap1) { winner = 0; - } else { + } else if (ap0 < ap1){ winner = 1; + } else { + if (petAp0 > petAp1) { + winner = 0; + } else if (petAp0 < petAp1) { + winner = 1; + } } } - let resultData = {winner: winner, results: resultArr}; + let resultData: any = { + winner: winner, + results: resultArr + }; + let resultMap: Map = new Map(); + for (let [, player] of this.state.players) { + for (let [type, val] of player.statData) { + if (resultMap.has(type)) { + let current = resultMap.get(type); + if (current[1] < val) { + resultMap.set(type, [player.id, val]); + } + } else { + resultMap.set(type, [player.id, val]); + } + } + } + let statics: any = []; + for (let [type, val] of resultMap) { + statics.push({ + type, + player: val[0], + val: val[1] + }) + } + resultData[statics] = statics; this.room.bGameResult(resultData); this.state.updateGameState(GameStateConst.STATE_GAME_OVER); //启动定时, 时间到后, 踢出没离开且没点重玩的玩家, 并将房间设为非private @@ -115,6 +155,8 @@ export class GameResultCommand extends Command { player.cards.clear(); player.cards = new MapSchema() player.cardSet.clear(); + player.statData.clear(); + player.petData.clear(); player.cardSet = new SetSchema(); player.countTotal = 0; player.countPresent = 0; diff --git a/src/rooms/commands/TurnEndCommand.ts b/src/rooms/commands/TurnEndCommand.ts index e6c4bb2..ebd6c10 100644 --- a/src/rooms/commands/TurnEndCommand.ts +++ b/src/rooms/commands/TurnEndCommand.ts @@ -1,12 +1,9 @@ import {Command} from "@colyseus/command"; import {CardGameState} from "../schema/CardGameState"; -import {GameEnv} from "../../cfg/GameEnv"; -import {PartResultCommand} from "./PartResultCommand"; import {NextTurnCommand} from "./NextTurnCommand"; -import {PlayerStateConst} from "../../constants/PlayerStateConst"; -import {Wait} from "./Wait"; import {GameResultCommand} from "./GameResultCommand"; import gameUtil from "../../utils/game.util"; +import {StateTypeEnum} from "../enums/StateTypeEnum"; /** * 一轮结束 @@ -29,8 +26,21 @@ export class TurnEndCommand extends Command { // return [new PartResultCommand()]; // } // } - // 判断是否胜利 + // 记录pet的maxap(最高ap) 和 maxsap(最高单体ap) + for (let [,player] of this.state.players) { + let maxAp = player.statData.get(StateTypeEnum.MAXAP) || 0; + let maxsAp = player.statData.get(StateTypeEnum.MAXSAP) || 0; + let totalAp = 0; + for (let [, pet] of player.pets) { + totalAp += (pet.ap || 0 + pet.extAp || 0); + maxsAp = Math.max(maxsAp, (pet.ap || 0 + pet.extAp || 0)); + } + maxAp = Math.max(maxAp, totalAp); + player.statData.set(StateTypeEnum.MAXAP, maxAp); + player.statData.set(StateTypeEnum.MAXSAP, maxsAp); + } + // 判断是否胜利 let result = gameUtil.checkGameEnd(this.state); if (result) { return [new GameResultCommand()]; diff --git a/src/rooms/schema/Player.ts b/src/rooms/schema/Player.ts index 3effda1..0c13a3e 100644 --- a/src/rooms/schema/Player.ts +++ b/src/rooms/schema/Player.ts @@ -3,6 +3,7 @@ import {Pet} from "./Pet"; import {Card} from "./Card"; import {GameEnv} from "../../cfg/GameEnv"; import {PlayerStateConst} from "../../constants/PlayerStateConst"; +import {StateTypeEnum} from "../enums/StateTypeEnum"; export class Player extends Schema { @@ -69,6 +70,14 @@ export class Player extends Schema { * 当前累计抽卡 */ countPresent: number; + /** + * 记录当前局内统计数字 + */ + statData: Map = new Map(); + /** + * 用于记录pet值, 用于统计伤害 + */ + petData: Map = new Map(); /** * 英雄绑定的卡组, 选好英雄后, 从默认配置或玩家卡组(待实现)中获取