import { Player } from "../../schema/Player"; import { PetHandler } from "./PetHandler"; import { HeroCfg } from "../../../cfg/parsers/HeroCfg"; import { BattleHandler } from "./BattleHandler"; import CfgMan from "../CfgMan"; import { Pet } from "rooms/schema/Pet"; import { CondDecideType, CondType, EffectCardType, GameUnitType, SkillType, TriggerType } from "../skill/SkillConst"; import { UnitCfg } from "cfg/parsers/UnitCfg"; import { Skill } from "../skill/Skill"; import { SkillParam, SkillTarget } from "../skill/SkillParam"; import SkillMan from "../skill/SkillMan"; import { Card } from "rooms/schema/Card"; import arrUtil from "utils/array.util"; import { SKillEffectData } from "message/SkillInfo"; export class PlayerHandler { public _player: Player; public _playercfg: HeroCfg; public _self: PetHandler; public _unitcfg: UnitCfg; public _pets: PetHandler[] = []; public _owner: BattleHandler; public _friend: PlayerHandler; _totalcc: number = 0; private _totalem: number = 0; public init(aplayer: Player, owner: BattleHandler){ this._owner = owner; this._player = aplayer; this._playercfg = CfgMan.findPlayerCfg(this._player.heroId); this._self = new PetHandler(); this._self.init(null, this, 0); this._self._isHero = true; let lst = this._playercfg.ex_skill? [this._playercfg.ex_skill]: null; let ps = new SkillParam(0, 0, 0, this, this._self, null, null); this._self.loadData(this._playercfg.herounit_id, ps, lst); this._unitcfg = this._playercfg && CfgMan.findUnitCfg(this._playercfg.herounit_id); }; public clear(){ this._self = null; this._pets.length = 0; }; public getCurrCardCount(){ return this._player.cards.size; }; public getTotalCardCount(ct: CondDecideType, v: number): number{ if(ct == CondDecideType.EQUAL && this._totalcc > v){ return v; } return this._totalcc; }; public getId(): string{ return this._player.id + ''; }; public newPet(): PetHandler { let res = null; let pr = null; let n = 0; for(let [key, obj] of this._player.pets){ if(n != 0){ if(obj.state == 0 || obj.state == 2){ res = obj; break; } } ++n; } if(res){ pr = new PetHandler; pr.init(res, this, n); this._pets.push(pr); } return pr; }; public delPet(pet: PetHandler){ if(!pet){ return; } this.onEMChanged(pet._enmagic);//删除法强 pet.clear(); let idx = this._pets.indexOf(pet); (idx >= 0) && this._pets.splice(idx, 1); this._owner.onDelPetNotify(pet); }; public getPet(pet: Pet): PetHandler{ return this._pets.find((item:PetHandler)=>{ return item._pet == pet; }); }; public findPet(pos: number): PetHandler{ if(pos < 0){ return null; } if(pos == 0){ return this._self; } return this._pets.find((item:PetHandler)=>{ return item._idx == pos; }) }; public exportAllPets(skill: Skill, param: SkillParam, expet: PetHandler, dst: SkillTarget[]): SkillTarget[]{ if(!dst){ return null; } let ct = skill._data.targetid; switch(ct){ case GameUnitType.BATTLEUNIT: let lst = this._pets.reverse(); lst.forEach(element => { if(expet != element){ dst.push(new SkillTarget(skill, param.srcplayer, param.srcpet, element, GameUnitType.PET)); } }); (expet != this._self) && dst.push(new SkillTarget(skill, param.srcplayer, param.srcpet, this._self, GameUnitType.HERO)); break; case GameUnitType.HERO: (expet != this._self) && dst.push(new SkillTarget(skill, param.srcplayer, param.srcpet, this._self, GameUnitType.HERO)); break; case GameUnitType.PET: lst.forEach(element => { if(expet != element){ dst.push(new SkillTarget(skill, param.srcplayer, param.srcpet, element, GameUnitType.PET)); } }); break; default: break; } return dst; }; public useCard(obj: SkillParam, oldpos?: number) { let cfg = CfgMan.findEffCardCfg(obj.cardid); if(!cfg){ return false; } let lst = []; cfg.quoteskill1id && lst.push(cfg.quoteskill1id); cfg.quoteskill2id && lst.push(cfg.quoteskill2id); cfg.quoteskill3id && lst.push(cfg.quoteskill3id); cfg.quoteskill4id && lst.push(cfg.quoteskill4id); let oldpet = this.findPet(oldpos); if(oldpet == this._self){ oldpet = null; } if(cfg.type_id == EffectCardType.NPC || cfg.type_id == EffectCardType.NPC_CUSTOM){ let exap = 0; if(oldpet){ exap = oldpet.totalAP(); this.delPet(oldpet); } let pet = this.newPet(); if(!pet){ return false; } obj.srcpet = pet; if(!obj.dstpet){ if(obj.dstplayer && obj.dstplayer.isMyPet(pet)){ obj.dstpet = pet; } } pet.loadData(cfg.stageunit_id, obj, lst, exap); }else if(cfg.type_id == EffectCardType.MAGIC){ if(oldpet && CfgMan.hasSummonPetSkill(lst)){ this.delPet(oldpet); } this.useSkills(lst, obj); } }; public useSkills(skills: number[], obj: SkillParam) { skills && skills.forEach((item: number)=>{ this.useSkill(item, 1, obj); }); }; public useSkill(skillid: number, count: number, obj: SkillParam): SkillTarget[]{ return this.handleSkill(skillid, count, obj, this._self); }; public newSkill(skillid: number): Skill{ let obj = SkillMan.getSkill(skillid); if(obj){ obj.setOwner(this); } return obj; }; public addSkill(skillid: number, count: number = 1): Skill[]{ return this._self.addSkill(skillid, count); }; public handleSkill(skillid: number, count: number, param: SkillParam, pet: PetHandler):SkillTarget[]{ let cfg = CfgMan.findSkillCfg(skillid); if(!cfg){ return null; } let lst: Skill[] = []; if(cfg.skill_typeid == SkillType.MAGIC){ for(let i = 0; i < count; i++){ let sk = this.newSkill(skillid); lst.push(sk); } // this._owner.onSkillResultNotify(lst); }else { let bhalo = false; let bchged = false; for(let i = 0; i < count; i++){ let sl = pet.addSkill(skillid); if(sl && sl.length > 0){ bchged = true; sl.forEach((obj: Skill)=>{ if(obj.isBornSkill()){ lst.push(obj); }else if(obj.isDieSkill()){ //nothing to do }else if(obj.isHaloSkill()){ //only handle halo, not handle skill bhalo = true; }else{ lst.push(obj); } }); } } if(bhalo){ this.onHaloAdd(pet, true); } if(bchged){ pet.dataChanged(); } } return this.simpleCheckSkills(lst, pet, param); }; public summonPet(petid: number, count: number = 1, exparam: SkillParam):number{ let n = -1; for(let i = 0; i < count; i++){ let pet = this.newPet(); if(!pet){ break; } n++; pet.loadData(petid, exparam); } return n; }; public addCard(count: number, from?: PlayerHandler): number{ return this._owner.onPlayerAddCardNotify(this, count, 0, from); }; public addCardLimit(maxcount: number, from?: PlayerHandler): number{ return this._owner.onPlayerAddCardNotify(this, 0, maxcount, from); }; public addDirectCard(cardid: number, count: number, from?: PlayerHandler){ return this._owner.onPlayerAddDirectCardNotify(this, count, cardid, from); }; public stealCard(dstplayer: PlayerHandler, count: number): number{ return this._owner.onPlayerStealCardNotify(this, dstplayer, count); }; public addHP(value: number): number{ return this._owner.onPlayerAddHPNotify(this, value); }; public getHP(){ return this._player.hp; }; public addEM(value: number): number{ return this._self.addEM(value); }; public getEM(): number{ return this._totalem; }; public onEMChanged(value: number){ if(value == 0){ return; } this._totalem += value; if(this._totalem < 0){ this._totalem = 0; } }; public totalAP(){ return this._self.totalAP(); }; public setFriend(aplayer: PlayerHandler){ this._friend = aplayer; }; public die(){ this.clear(); //todo: }; public reborn(){ return this._self.reborn(); }; public attack(apet: PetHandler, param: SkillParam, ev: number, isAtkBack: boolean = false){ return this._self.attack(apet, param, ev, isAtkBack); }; public beSilent(count: number){ return this._self.beSilent(count); }; public canBeKill(subhp: number): boolean{ if(subhp >= 0){ return false; } let hp = this.getHP(); return (hp + subhp <= 0); }; public isAlive(): boolean{ return this._player.state != 2; }; public onPetBorned(apet: PetHandler, param: SkillParam){ this._owner.onAddPetNotify(apet); this.onEMChanged(apet._enmagic);//增加法强 // 战吼 if(!apet.isSilent()){ this.simpleCheckSkills(apet._bornSkills, apet, param); } }; public onPetDied(apet: PetHandler): boolean{ // 遗愿 if(!apet.isSilent()){ this.simpleCheckSkills(apet._dieSkills); } if(apet.isDead()){ this.delPet(apet); } return true; }; public onPetChanged(apet: PetHandler){ this._owner.onUpdatePetNotify(apet); }; public onHaloAdd(apet: PetHandler, only_checkother: boolean = false){ let lst: PetHandler[] = []; if(only_checkother){ this._pets.forEach((obj: PetHandler)=>{ if(apet.addEffHalo(obj)){ lst.push(obj); } }); if(this._self != apet){ if(apet.addEffHalo(this._self)){ lst.push(this._self); } } }else{ apet.addEffHalo(apet); this._pets.forEach((obj: PetHandler)=>{ if(obj != apet){ obj.addEffHalo(apet); if(apet.addEffHalo(obj)){ lst.push(obj); } } }); if(this._self != apet){ this._self.addEffHalo(apet); if(apet.addEffHalo(this._self)){ lst.push(this._self); } } } this._owner.onUpdatePetsNotify(lst); }; public onHaloRemove(apet: PetHandler){ let lst: PetHandler[] = []; this._pets.forEach((obj: PetHandler)=>{ if(apet != obj){ if(obj.removeEffHalo(apet)){ lst.push(obj); } } }); if(this._self != apet){ if(this._self.removeEffHalo(apet)){ lst.push(this._self); } } this._owner.onUpdatePetsNotify(lst); }; onAttackBefore(apet: PetHandler, sp?: SkillParam){ this.singleCheckSkills(apet, TriggerType.BEFORE_ATTACK, null, sp); }; onBeAttack(apet: PetHandler, sp?: SkillParam){ this.singleCheckSkills(apet, TriggerType.BE_ATTACK, null, sp); }; onBeHurt(apet: PetHandler, value: number){ this.singleCheckSkills(apet, TriggerType.BE_HURT, value); }; public isMyPet(apet: PetHandler){ if(apet == this._self){ return true; } return this._pets.includes(apet); }; public findTauntPet(): PetHandler{ if(this._self && this._self.isTaunt()){ return this._self; } return this._pets.find((item: PetHandler) =>{ return item.isTaunt(); }); }; public findAllTauntPets(lst: PetHandler[], expet?: PetHandler): number{ if(!lst){ return -1; } let ncnt = 0; if(this._self && this._self.isTaunt() && this._self != expet){ lst.push(this._self); ncnt++; } this._pets.forEach((item: PetHandler) =>{ if(item.isTaunt() && this._self != expet){ lst.push(item); ncnt++; } }); return ncnt; }; public findAllPets(lst: PetHandler[], expet?: PetHandler): number{ if(!lst){ return -1; } let ncnt = 0; if(this._self && this._self != expet){ lst.push(this._self); ncnt++; } this._pets.forEach((item: PetHandler) =>{ if(this._self != expet){ lst.push(item); ncnt++; } }); return ncnt; }; public hasTransEffCardSkill(): boolean{ if(!this._self){ return false; } let obj = this._self._skills.find((val: Skill)=>{ return val.isTransEffCardSkill(); }); return !!obj; }; public getTransEffCardRate(): number{ if(!this._self){ return 0; } let obj = this._self._skills.find((val: Skill)=>{ return val.isTransEffCardSkill(); }); return obj? obj.getEffValue(): 0; }; onCardLinkReady(fromplayer: PlayerHandler){ this.checkSkills(TriggerType.CARD_LINK_BEFORE); }; onCardLinkEnd(linkcards: Card[], fromplayer: PlayerHandler){ this.checkSkills(TriggerType.CARD_LINK_AFTER, fromplayer); }; onCardDroped(dropcards: Card[], srcplayer: PlayerHandler){ this.checkSkills(TriggerType.CARD_DROP_MYROUND); }; onCardDiscarded(discardcard: Card){ this.checkSkills(TriggerType.CARD_DISCARD_MYROUND); }; onCardGetted(getcards: Card[], srcplayer: PlayerHandler){ getcards && (this._totalcc += getcards.length); this.checkSkills(TriggerType.CARD_GETTED); }; onUseCardEnd(sp: SkillParam){ this.checkSkills(TriggerType.CARD_USED, 0, sp); }; onRoundStart(){ this.checkSkills(TriggerType.ROUND_START_MYSELF); }; onRoundEnd(){ this.checkSkills(TriggerType.ROUND_END_MYSELF); }; checkSkills(tgttype: TriggerType, tgtvalue?: any, tgtsp?: SkillParam){ let sp = tgtsp; if(!sp){ sp = new SkillParam(0, 0, 0, this, this._self, null, null); } let reslst: SkillTarget[] = []; this._self.checkSkills(tgttype, tgtvalue, sp, (skill: Skill, ap: SkillParam, res: SkillTarget[])=>{ if(res){ reslst = reslst.concat(res); }else{ let st = new SkillTarget(skill); st.LoadParam(sp); reslst.push(st); } }); this._pets.forEach((item: PetHandler) => { sp.srcpet = item; item.checkSkills(tgttype, tgtvalue, sp, (skill: Skill, ap: SkillParam, res: SkillTarget[])=>{ if(res){ reslst = reslst.concat(res); }else{ let st = new SkillTarget(skill); st.LoadParam(sp); reslst.push(st); } }); }); this._owner.onSkillResultNotify(reslst); }; singleCheckSkills(apet: PetHandler, tgttype: TriggerType, tgtvalue?: any, tgtsp?: SkillParam){ let sp = tgtsp; if(!sp){ sp = new SkillParam(0, 0, 0, this, apet, null, null); } let reslst: SkillTarget[] = []; apet.checkSkills(tgttype, tgtvalue, sp, (skill: Skill, ap: SkillParam, res: SkillTarget[])=>{ if(res){ reslst = reslst.concat(res); }else{ let st = new SkillTarget(skill); st.LoadParam(sp); reslst.push(st); } }); this._owner.onSkillResultNotify(reslst); }; simpleCheckSkills(skills: Skill[], apet?: PetHandler, param?: SkillParam): SkillTarget[]{ let sp = param? param: new SkillParam(0, 0, 0, this, apet, this, apet); if(sp && sp.cardid == 0 && apet){ if(!sp.edd_cnt){ sp.edd_cnt = apet._orignEffCnt; } if(!sp.cardpoint){ sp.cardpoint = apet._orignCardPoint; } } let reslst: SkillTarget[] = []; skills.forEach((item: Skill)=>{ item.checkTrigger(TriggerType.NO_COND, 0, sp, (skill: Skill, ap: SkillParam, res: SkillTarget[])=>{ if(res){ reslst = reslst.concat(res); }else{ let st = new SkillTarget(skill); st.LoadParam(sp); reslst.push(st); } }); }); this._owner.onSkillResultNotify(reslst); return reslst; }; resetTotalCard(){ this._totalcc = 0; }; addTotalCard(v: number){ this._totalcc += v; } }