card_svr/src/rooms/RoomExtMethod.ts
2021-01-18 19:38:27 +08:00

271 lines
11 KiB
TypeScript

import {Room} from "colyseus";
import gameUtil from "../utils/game.util";
import {debugRoom, error} from "../common/Debug";
import {PlayerStateConst} from "../constants/PlayerStateConst";
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";
/**
* 一些常用的方法
*/
Object.defineProperties(Room.prototype, {
drawCardFromPlayer: {
value: function (srcplayer: string, dstplayer: string, count: number): number {
debugRoom(`玩家 ${srcplayer}${dstplayer}${count} 张卡`);
let player1 = this.state.players.get(dstplayer);
let player0: Player = this.state.players.get(srcplayer);
/**
* 首先取目标玩家手牌数和偷牌数量的最小值
* 然后取目标玩家的手牌数和配置中玩家手牌数的差值
* 取以上2值的最小值为实际偷牌数量
*/
let realCount = Math.min(player1.cards.size, count);
let maxCount = new GameEnv().maxCardNum;
realCount = Math.min(realCount, maxCount - player0.cards.size);
let tmpCards = gameUtil.removeCard(player1, realCount);
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,
dstplayer,
cards: cardIds
};
this.bStealCard(msgData, {except: client, afterNextPatch: true});
let sMsgData = {
srcplayer,
dstplayer,
cards: tmpCards
}
this.sStealCard(client, sMsgData);
return tmpCards.length;
}
},
giveUpCard: {
value: function (dstplayer: string, count: number, fromplayer?: string){
let player = this.state.players.get(dstplayer);
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,
cards: cardIds
};
this.bRemoveCard(msgData);
return tmpCards.length;
}
},
/**
* 补卡, 并广播消息
* @param dstplayer 目标玩家
* @param count 补多少张, 该值和max_count至少一个不为0
* @param max_count 补到多少张, 如果count和max_count都不为0, 则抽 Math.min(count, (max_count - 当前手牌数))
* @param source 0: 正常抽卡, 1: 技能, 9: GM
* @param fromplayer
*/
addCard: {
value: function ( dstplayer: string, count: number, max_count: number, source: number = 0, fromplayer?: string, extData?: {}): number {
let maxCountCfg = new GameEnv().maxCardNum;
let maxCount = Math.min(maxCountCfg, max_count);
let player = this.state.players.get(dstplayer);
let curCount = player.cards.size;
if (count > 0) {
if (maxCount > 0) {
count = Math.min(count, maxCount - curCount);
} else {
count = Math.min(count, maxCountCfg - curCount);
}
} else if (maxCount > 0){
count = maxCount - curCount;
} else {
error("补卡方法的参数有问题, count和max_count都为0");
return 0;
}
let player2 = fromplayer ? this.state.players.get(fromplayer) : null;
let cards = gameUtil.drawCard(this, this.state.cardQueue, player, count, player2, extData);
if (source == 1 && player2 && player2.id != player.id) {
player2.statData.inc(StateTypeEnum.ACOUNT, cards.length);
}
let client = this.getClient(dstplayer);
let sData = {
player: dstplayer,
cards: cards,
source: source
};
this.sDrawCard(client, sData);
let cardIds = cards.map(card => card.id);
let bData = {
player: dstplayer,
cards: cardIds,
source: source
};
this.bDrawCard(bData, {except: client});
return cardIds.length;
}
},
updateHp: {
value: function (dstplayer: string, hp: number, reason?: string, fromplayer?: string): number {
let player = this.state.players.get(dstplayer);
if (!player) {
error(`updateHp 未找到玩家 ${dstplayer}`);
return 0;
}
if (player.state === PlayerStateConst.PLAYER_DEAD) {
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, Math.min(-hp, player.hp));
player.statData.inc(StateTypeEnum.TDMG, Math.min(-hp, player.hp));
}
debugRoom(`更新血量: ${player.id} ${player.hp} -> ${hp}, reason: ${reason}`);
if (dstHp <= 0) {
dstHp = 0;
this.dispatcher.dispatch(new PlayDeadCommand(), {player: player});
}
player.hp = dstHp;
}
return player.hp;
}
},
/**
* 更新随从信息
* @param data
*/
updatePet: {
value: function (datas: PetInfo[], fromplayer?: string): void {
let playerSet: Set<string> = new Set();
for (let obj of datas) {
let pid = obj.player;
playerSet.add(pid);
let player = this.state.players.get(pid);
let pet = player.pets.get(obj.pos + '');
pet.id = obj.id;
pet.ap = obj.ap;
pet.extAp = obj.extAp;
pet.harmReduce = obj.harmReduce;
pet.skills.length = 0;
pet.state = (obj.ap > 0 || obj.pos == 0) ? 1: 2;
pet.effectCount = obj.effectCount;
pet.point = obj.point;
pet.em = obj.em;
pet.silence = obj.silence;
pet.hps = obj.hps;
if (obj.skills) {
pet.skills.length = 0;
for (let s of obj.skills) {
pet.skills.push(s);
}
}
if (obj.extSkills) {
pet.extSkills.length = 0;
for (let s of obj.extSkills) {
pet.extSkills.push(s);
}
}
if (obj.buffs) {
pet.buffs.length = 0;
for (let s of obj.buffs) {
pet.buffs.push(s);
}
}
}
this.broadcast("pet_update_s2c", {data: [...playerSet]}, {afterNextPatch: true});
}
},
/**
* 更新随从信息, 统计用
* @param datas
* @param fromplayer
*/
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 (!player || !targetPlayer) {
error(`updatePetStat, player or targetPlayer is null ${!!player} ${!!targetPlayer}`);
}
debugRoom(`updatePetStat, val change, old: ${valOld}, new: ${valNew}`);
if (valNew < valOld) {
player?.statData.inc(StateTypeEnum.DMG, valOld - valNew);
targetPlayer?.statData.inc(StateTypeEnum.TDMG, valOld - valNew);
}
}
}
},
/**
* 为一个玩家生产n张指定效果id的卡, 并加入手牌
* @param effectId
* @param count
* @param player
*/
generateCard: {
value: function ({player, count, effectId, fromplayer, options}
: {player: string | Player, count: number, effectId: number, fromplayer?: string | Player, options?: any}): number {
let tmpCards = [];
let maxCount = new GameEnv().maxCardNum;
let dstplayer;
if (typeof player == 'string') {
dstplayer = this.state.players.get(player);
} else {
dstplayer = player;
}
let realCount = Math.min(count, maxCount - dstplayer.cards.size);
for (let i = 0; i < realCount; i++) {
let cardId = 1000 + (this.state.maxCardId ++ );
let card = gameUtil.generateCardWithEffect(effectId, cardId, options);
if (card) {
tmpCards.push(card);
}
}
if (tmpCards.length == 0) {
error(`生成卡牌时, 无法获取对应的effect配置, ${dstplayer.id}, ${effectId}, ${realCount}`)
return 0;
}
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 = {
player: dstplayer.id,
cards: tmpCards,
source: 1
};
this.sDrawCard(client, sData);
let cardIds = tmpCards.map(card => card.id);
let bData = {
player: dstplayer.id,
cards: cardIds,
source: 1
};
this.bDrawCard(bData, {except: client});
return realCount;
}
}
});