card_svr/src/rooms/logic/Handler/BattleHandler.ts
2020-12-11 21:21:51 +08:00

473 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {Player} from "../../schema/Player";
import {Card} from "../../schema/Card";
import {CardGameState} from "../../schema/CardGameState";
import { PlayerHandler } from "./PlayerHandler";
import CfgMan from "../CfgMan";
import { EffectCardType, GameCampType, GameUnitType } from "../skill/SkillConst";
import { Pet } from "rooms/schema/Pet";
import {SkillParam, SkillTarget} from "../skill/SkillParam";
import { Room } from "colyseus";
import { Skill } from "../skill/Skill";
import { PetHandler } from "./PetHandler";
import { SkillInfoMsg } from "message/SkillInfo";
import { PetInfo } from "message/PetInfo";
export class BattleHandler {
private _cs: CardGameState;
private _players: Map<Player, PlayerHandler> = new Map();
_room: Room;
private _cardusing: boolean;
private _sktime: number;
private _gamestart: boolean = false;
public init(cs: CardGameState, room: Room){
this._cs = cs;
this._room = room;
this._gamestart = false;
};
public addPlayer(aplayer: Player): PlayerHandler{
let ph = new PlayerHandler();
ph.init(aplayer, this);
this._players.forEach((item: PlayerHandler) => {
if(item._player.team == aplayer.team && item._player != aplayer){
item._friend = ph;
ph._friend = item;
}
});
this._players.set(aplayer, ph);
return ph;
};
public delPlayer(aplayer: Player){
let ph = this.getPlayer(aplayer);
this._players.forEach((item: PlayerHandler) =>{
if(item._friend == ph){
item._friend = null;
}
});
this._players.delete(aplayer);
};
public getPlayer(aplayer: Player): PlayerHandler{
return aplayer? this._players.get(aplayer): null;
};
public getFriend(aplayer: PlayerHandler): PlayerHandler{
if(aplayer && aplayer._friend){
return aplayer._friend;
}
// 防止出错冗余处理
let res;
for(let [key, obj] of this._players){
if(obj._friend == aplayer){
aplayer._friend = obj;
res = obj;
break;
}
}
return res;
};
public petIsValid(pet: PetHandler, players: PlayerHandler[], ct: GameUnitType): boolean{
if(!players || players.length == 0 || !pet){
return false;
}
let obj = players.find( (item: PlayerHandler) =>{
return item.isMyPet(pet);
});
if(!obj){
return false;
}
switch(ct){
case GameUnitType.BATTLEUNIT:
return true;
case GameUnitType.HERO:
return pet._isHero;
case GameUnitType.PET:
return !pet._isHero;
default:
return false;
}
};
public getFinalTarget(players: PlayerHandler[], apet: PetHandler, ct: GameUnitType,
checktaunt: boolean=false): PetHandler
{
let pet = apet;
let bok = this.petIsValid(pet, players, ct);
if(checktaunt && (!bok || !pet._istaunt)){
for(let i = 0; i < players.length;i++){
let obj = players[i].findTauntPet();
if(obj){
pet = obj;
bok = true;
break;
}
}
}
return bok? pet: null;
};
public getSkillTargets(skill: Skill, param: SkillParam): SkillTarget[]{
let lst: SkillTarget[] = [];
let players = this.getTargetPlayers(skill._data.friendlyid, param.srcplayer, param.dstplayer);
if(players.length > 0){
switch(skill._data.targetid){
case GameUnitType.PLAYER:
players.forEach((item:PlayerHandler)=>{
lst.push(new SkillTarget(skill, param.srcplayer, param.srcpet, item, GameUnitType.PLAYER));
});
break;
case GameUnitType.HERO:
players.forEach((item:PlayerHandler)=>{
lst.push(new SkillTarget(skill, param.srcplayer, param.srcpet, item._self, GameUnitType.HERO));
});
break;
case GameUnitType.BATTLEUNIT:
case GameUnitType.PET:
if(skill.isSingleTarget()){
let pet = this.getFinalTarget(players, param.dstpet, skill._data.targetid,
skill.isHurtPowerSkill());
pet && lst.push(new SkillTarget(skill, param.srcplayer, param.srcpet,
pet, pet._isHero? GameUnitType.HERO: GameUnitType.PET));
}else{
if(skill.isAllTarget()){
players.forEach((item: PlayerHandler)=>{
item.exportAllPets(skill, param, null, lst);
});
}else{
if(param.srcpet){
players.forEach((item: PlayerHandler)=>{
item.exportAllPets(skill, param, param.srcpet, lst);
});
}else{
players.forEach((item: PlayerHandler)=>{
if(item != param.srcplayer){
item.exportAllPets(skill, param, param.srcpet, lst);
}
});
}
}
}
break;
default:
break;
}
}
return lst;
};
public getTargetPlayers(gct: GameCampType, src:PlayerHandler, dst:PlayerHandler): PlayerHandler[]{
let lst: PlayerHandler[] = [];
switch(gct){
case GameCampType.SELF:
if(src && src.isAlive()){
lst.push(src);
}
break;
case GameCampType.FRIEND:
let obj = this.getFriend(src);
if(obj && obj.isAlive()){
lst.push(obj);
}
break;
case GameCampType.MYTEAM:
if(src){
src.isAlive() && lst.push(src);
let obj = this.getFriend(src);
obj && obj.isAlive() && lst.push(obj);
}
break;
case GameCampType.ENEMY:
if(dst && dst != src && dst._friend != src && dst.isAlive()){
lst.push(dst);
}
break;
case GameCampType.ENEMYTEAM:
for(let [key, obj] of this._players){
if(obj != src && obj != src._friend && obj.isAlive()){
lst.push(obj);
}
}
break;
case GameCampType.ALL:
for(let [key, obj] of this._players){
if(obj && obj.isAlive()){
lst.push(obj);
}
}
break;
default:
break;
}
return lst;
};
public beginUseCard(){
this._cardusing = true;
this._sktime = 0;
};
public endUseCard(){
this._cardusing = false;
};
public isUsingCard(){
return this._cardusing;
};
//--------------------对外接口(外部调用)----------------------------
/**
* 使用卡片
* @param obj
*/
public useCard(obj:
{srcplayer: Player, card: number, cardpoint: number, dbpt_cnt: number, eff_cnt: number, dstplayer: Player, dstpet: Pet})
:number{
if(!obj || !obj.card){
return 0;
}
let ph = this.getPlayer(obj.srcplayer);
let dstph = this.getPlayer(obj.dstplayer);
let dstpt = dstph? dstph.getPet(obj.dstpet): null;
if(!ph){
return 0;
}
if(!dstpt && dstph){
dstpt = dstph._self;
}
this.beginUseCard();
let pt = obj.cardpoint;
let cfg = CfgMan.findEffCardCfg(obj.card);
if(cfg && cfg.followdouble && obj.dbpt_cnt){
pt *= (obj.dbpt_cnt + 1);
}
if(!dstph){
dstph = ph;
}
let ps = new SkillParam(obj.card, pt, obj.eff_cnt, ph, null, dstph, dstpt);
ph.useCard(ps);
this.onUseCardEnd(ps);
this.endUseCard();
return this._sktime*1000;
};
/**
* 使用技能
* @param obj
*/
public useSkill(obj:{
srcplayer: Player, skillid: number, dstplayer: Player, dstpet: Pet
}){
};
/**
* 确认玩家是否有换效果牌技能
* @param aplayer
*/
public hasTransEffCardSkill(aplayer: Player): boolean{
let ph = this.getPlayer(aplayer);
return ph && ph.hasTransEffCardSkill();
};
/**
* 获得玩家效果牌转换比率(几张普通卡转一张效果卡)
* @param aplayer
*/
public getTransEffCardRate(aplayer: Player): number{
let ph = this.getPlayer(aplayer);
return ph? ph.getTransEffCardRate(): 0;
};
/**
* 吃牌/胡牌确认[暂不用]
* @param aplayer : 玩家
* @param fromplayer 吃别人的牌,自己胡牌时此参数传空
*/
public onCardLinkReady(aplayer: Player, fromplayer?: Player){
let ph = this.getPlayer(aplayer);
let fromph = this.getPlayer(fromplayer);
ph && ph.onCardLinkReady(fromph);
};
/**
* 吃牌/胡牌结束
* @param aplayer :玩家
* @param linkcards :吃到的牌组信息
*/
public onCardLinkOver(aplayer: Player, linkcards: Card[], fromplayer?: Player){
let ph = this.getPlayer(aplayer);
let fromph = this.getPlayer(fromplayer);
ph && ph.onCardLinkEnd(linkcards, fromph);
};
/**
* 出牌结束(出单张牌)
* @param aplayer : 玩家
* @param card : 单张牌
*/
public onCardDiscarded(aplayer: Player, card: Card){
let ph = this.getPlayer(aplayer);
ph && ph.onCardDiscarded(card);
};
/**
* 使用卡牌结束(暂时自动回调,无需外部触发)
* @param sp :使用卡牌相关操作
*/
public onUseCardEnd(sp: SkillParam){
if(!sp){
return;
}
sp.srcplayer && sp.srcplayer.onUseCardEnd(sp);
};
/**
* 弃牌完成 //TODO:: 弃卡实装后须调用
* @param aplayer :玩家
* @param fromplayer : 谁使玩家弃牌的(自己主动弃牌的传空)
* @param dropcards : 弃掉的牌组
*/
public onCardDroped(aplayer: Player, dropcards: Card[], fromplayer?: Player){
let ph = this.getPlayer(aplayer);
let fromph = this.getPlayer(fromplayer);
ph && ph.onCardDroped(dropcards, fromph);
};
/**
* 获取牌完成
* @param aplayer :玩家
* @param fromplayer : 谁使玩家获得牌的(自己主动获得牌的传空)
* @param dropcards : 获得的牌组
*/
public onCardGetted(aplayer: Player, getcards: Card[], fromplayer?: Player){
if(!this._gamestart){
return;
}
let ph = this.getPlayer(aplayer);
let fromph = this.getPlayer(fromplayer);
ph && ph.onCardGetted(getcards, fromph);
};
/**
* 玩家回合开始
* @param aplayer
*/
public onPlayerRoundStart(aplayer: Player){
if(!this._gamestart){
this._gamestart = true;
}
let ph = this.getPlayer(aplayer);
ph && ph.onRoundStart();
};
/**
* 玩家回合结束
* @param aplayer
*/
public onPlayerRoundEnd(aplayer: Player){
let ph = this.getPlayer(aplayer);
ph && ph.onRoundEnd();
};
/**
* 玩家死亡
* @param aplayer
*/
public onPlayerDead(aplayer: Player){
let ph = this.getPlayer(aplayer);
ph && ph.die();
this.delPlayer(aplayer);
};
// end--------------------------------------------------
// --------------------调用外部接口函数--------------------------
public onAddPetNotify(apet: PetHandler){
return this._room.bAddPet(apet.exportInfoMsg());
};
public onDelPetNotify(apet: PetHandler){
return this._room.bRemovePet(apet.exportRemoveMsg());
};
public onUpdatePetNotify(apet: PetHandler){
return this._room.updatePet([apet.exportInfo()]);
};
public onUpdatePetsNotify(pets: PetHandler[]){
if(!pets || pets.length <= 0){
return;
}
let lst: PetInfo[] = [];
pets.forEach((item: PetHandler)=>{
lst.push(item.exportInfo());
});
return this._room.updatePet(lst);
};
public onPlayerAddCardNotify(aplayer: PlayerHandler, count: number, maxcount: number,
from?: PlayerHandler): number{
return this._room.addCard(aplayer.getId(), count, maxcount, 1, from? from.getId(): null);
};
public onPlayerStealCardNotify(srcplayer: PlayerHandler,
dstplayer: PlayerHandler, count: number): number{
return this._room.drawCardFromPlayer(srcplayer.getId(), dstplayer.getId(), count);
};
public onSkillResultNotify(skillres: SkillTarget[]){
if(!skillres || skillres.length <= 0){
return;
}
let lst: SkillInfoMsg[] = [];
let difflst: SkillTarget[] = [];
skillres.forEach((item: SkillTarget)=>{
lst.push(item.exportData());
if(!difflst.includes(item)){
difflst.push(item);
}
});
let skid = '';
let tm = 0;
difflst.forEach((item: SkillTarget) =>{
tm += item.getLastTime();
skid += item.srcskillid + '|';
});
if(this.isUsingCard()){
this._sktime += tm;
}else{
this._room.addScheduleTime(tm*1000, skid);
}
this._room.bMsgQueue(lst);
};
public onPlayerAddHPNotify(aplayer: PlayerHandler, addhp: number){
return this._room.updateHp(aplayer.getId(), addhp);
}
//end------------------------------------------------
}