import { SkillCfg } from "cfg/parsers/SkillCfg"; import { SKillEffectData } from "message/SkillInfo"; import CfgMan from "../CfgMan"; import { PetHandler } from "../Handler/PetHandler"; import { PlayerHandler } from "../Handler/PlayerHandler"; import { CondDecideType, EnhanceCustomType, GameCampType, GameUnitType, SkillEffectType, SkillEffectValueType, SkillRangeUnitType, SkillType, TriggerType } from "./SkillConst"; import { SkillParam, SkillTarget } from "./SkillParam"; import { TriggerCtrl } from "./TriggerCtrl"; import TriggerManager from "./TriggerMan"; export class Skill { _currCount: number; _roundCount: number; _startround: number; _delayround: number; _id: number; _data: SkillCfg; _type: any; _param: number; _tgctrl: TriggerCtrl; _man: any; _owner: PlayerHandler; _start: boolean; _cb: any; halo_v: number = -1; rd: number = 0; private _subskill: Skill; // LIFE-CYCLE CALLBACKS: // onLoad () {}; // start () {}; // update (dt) {}; init(skillid: number, skilldata: SkillCfg, manager: any) { this._currCount = 0; // 当前计数 this._roundCount = 0; // 回合数 this._startround = 0; // 触发后回合数 this._delayround = 0; // 延迟回合数 this._id = skillid; this._data = skilldata; this._type = skilldata.skill_typeid; // todo: 根据bufftype处理paramlst this._param = TriggerManager.handleEffectParam(this._type, skilldata.eff_num); this._tgctrl = TriggerManager.addSkillTrigger(this._id, skilldata.tigger_typeid, skilldata.cond_typeid, skilldata.cond_rangeid, skilldata.cond_num); this._man = manager; }; triggerType() { return this._data.tigger_typeid; }; skillname() { return this._data.name; }; clear() { this._id = 0; this._data = null; }; removeSelf() { }; isSkill() { return true; }; isOver() { return false; }; isSame(id: number) { return this._id == id; }; isBornSkill(){ return this._type == SkillType.BORN; }; isDieSkill(){ return this._type == SkillType.DEAD; }; isHaloSkill(){ return this._type == SkillType.HALO; }; isTauntSkill(){ return this._data.effect_typeid == SkillEffectType.TAUNT; }; isTransEffCardSkill(){ return this._data.effect_typeid == SkillEffectType.CARD_CHG_EN; }; isHurtSkill(){ return this._data.effect_typeid == SkillEffectType.HURT_POWER || this._data.effect_typeid == SkillEffectType.HURT_ALL; }; isAttackSkill(){ return this._data.effect_typeid == SkillEffectType.ATTACK; }; isRebornSkill(){ return this._data.effect_typeid == SkillEffectType.REBORN; }; isSingleTarget(){ switch(this._data.rangeid){ case SkillRangeUnitType.ALL: case SkillRangeUnitType.ALL_EXSELF: return false; default: return true; } }; isAllTarget(){ return this._data.rangeid == SkillRangeUnitType.ALL; }; isInRange(srcpet: PetHandler, dstpet: PetHandler){ switch(this._data.rangeid){ case SkillRangeUnitType.SELF: return srcpet == dstpet; case SkillRangeUnitType.SINGLE: return false; case SkillRangeUnitType.OTHER: return false; case SkillRangeUnitType.ALL: return true; case SkillRangeUnitType.ALL_EXSELF: return srcpet != dstpet; default: return false; } }; // 是否能影响自己 isEffSelfPet(srcpet: PetHandler, dstpet: PetHandler){ if(this._data.friendlyid != GameCampType.SELF){ return false; } let tgok = false; switch(this._data.targetid){ case GameUnitType.BATTLEUNIT: tgok = this.isInRange(srcpet, dstpet); break; case GameUnitType.HERO: tgok = dstpet._isHero; break; case GameUnitType.PET: if(!dstpet._isHero){ tgok = this.isInRange(srcpet, dstpet); } break; default: break; } return tgok; }; getTargets(param: SkillParam): SkillTarget[]{ return this._owner._owner.getSkillTargets(this, param); }; getEnhanceValue(param: SkillParam): number{ return CfgMan.calcEnhanceValue(this._data.edd_effid, this._data.edd_effnum, param.edd_cnt, param.cardpoint); }; getEffValue(ac?: number, ap?: number, sp?: number): number{ let nmin = CfgMan.calcEffctValueEx(EnhanceCustomType.EFF_VALUE, this._data.eff_numtypeid, this._data.num_signid, this._data.eff_num, ap, sp); let nmax = CfgMan.calcEffctValueEx(EnhanceCustomType.EFF_VALUE, this._data.eff_numtypeid, this._data.num_signid, this._data.eff_nummax, ap, sp); return this.getFinalValue(EnhanceCustomType.EFF_VALUE, nmin, nmax, ac, ap, sp); }; getFinalValue(vtype:EnhanceCustomType, nmin: number, nmax: number, ac:number, ap: number, sp: number = 0): number{ let n = 0; if(CfgMan.canEnhanceValue(vtype, this._data.edd_effid)){ n = CfgMan.randomEffValue(nmin, nmax, this._data.edd_effid, this._data.eddeffnum_signid, this._data.edd_effnum, ac); }else{ n = CfgMan.roundV(nmin, nmax); } return n; }; getHaloValue(): number{ if(!this.isHaloSkill()){ return 0; } if(this.halo_v < 0){ this.halo_v = this.getEffValue(); } return this.halo_v; }; addHaloValue(v: number): number{ if(this.halo_v < 0){ this.halo_v = this.getEffValue(); } if(this.halo_v > 0){ let tmp = this.halo_v; this.halo_v += v; if(this.halo_v < 0){ this.halo_v = 0; return -tmp; }else{ return v; } } return 0; }; resetHaloValue(){ this.halo_v = -1; }; _triggerSubSkill(param: SkillParam, cb?: any){ if(this._data.quoteskillid && !this._subskill){ this._subskill = this._owner.newSkill(this._data.quoteskillid); } if(this._subskill){ let subparam = this._data.skill_users? param.clone(): param; if(this._data.skill_users){ let tmpplayer = subparam.srcplayer; let tmppet = subparam.srcpet; subparam.srcplayer = subparam.dstplayer; subparam.srcpet = subparam.dstpet; subparam.dstpet = tmppet; subparam.dstplayer = tmpplayer; } let ncount = this.getFinalValue(EnhanceCustomType.QUOTE_TIMES, this._data.quotecard_times, this._data.quotecard_timesmax, param.edd_cnt, param.cardpoint); if(ncount == 0){ ncount = 1; } for(let i=0; i{ if(this.isTotalCardSkill()){ if(cdt == CondDecideType.EQUAL){ this._owner.addTotalCard(-v); }else if(cdt == CondDecideType.GREATER){ this._owner.resetTotalCard(); } } })){ this.trigger(tg_target, cb); return 1; }else{ return 0; } }; handleCard(efftype: SkillEffectType, effvalue: number, tgt: SkillTarget){ let res = effvalue; switch(efftype){ case SkillEffectType.CARD_ADD: if(tgt.dsttype == GameUnitType.PLAYER){ let n = (tgt.dst as PlayerHandler).addCard(res, tgt.srcplayer); if(n >= 0){ tgt.success(efftype, n); }else{ tgt.fail(efftype, n); } }else{ tgt.fail(efftype, -1); } break; case SkillEffectType.CARD_ADD_LIMIT: if(tgt.dsttype == GameUnitType.PLAYER){ let n = (tgt.dst as PlayerHandler).addCardLimit(res, tgt.srcplayer); if(n >= 0){ tgt.success(efftype, n); }else{ tgt.fail(efftype, -1); } }else{ tgt.fail(efftype, -1); } break; case SkillEffectType.CARD_STEAL: if(tgt.dsttype == GameUnitType.PLAYER){ let n = tgt.srcplayer.stealCard((tgt.dst as PlayerHandler), res); if(n >= 0){ tgt.success(efftype, n); }else{ tgt.fail(efftype, -1); } }else{ tgt.fail(efftype, -1); } break; case SkillEffectType.CARD_CHG_EN: //todo: 暂不处理 break; case SkillEffectType.CARD_GETDIRECT: if(tgt.dsttype == GameUnitType.PLAYER){ let cardid = this._data.quotecardid; let n = (tgt.dst as PlayerHandler).addDirectCard(cardid, res, tgt.srcplayer); if(n >= 0){ tgt.success(efftype, n); }else{ tgt.fail(efftype, -1); } }else{ tgt.fail(efftype, -1); } break; default: break; } }; handlePower(efftype: SkillEffectType, effvalue: number, tgt: SkillTarget){ switch(efftype){ case SkillEffectType.POWER_ENHANCE: case SkillEffectType.POWEREX_ENHANCE: if(tgt.dsttype != GameUnitType.NONE && tgt.dsttype != GameUnitType.PLAYER){ let n = efftype == SkillEffectType.POWER_ENHANCE? (tgt.dst as PetHandler).addBaseAP(effvalue): (tgt.dst as PetHandler).addExAP(effvalue, this); tgt.success(efftype, n); }else{ tgt.fail(efftype, -1); } break; case SkillEffectType.HURT_POWER: case SkillEffectType.HURT_ALL: let effv = this.EMV(effvalue); if(tgt.dsttype != GameUnitType.NONE && tgt.dsttype != GameUnitType.PLAYER){ let n = (tgt.dst as PetHandler).beHurt(effv); tgt.success(efftype, n); }else{ tgt.fail(efftype, -1); } break; default: break; } }; handleHP(effvalue: number, tgt: SkillTarget){ let efftype = SkillEffectType.HURT_HP; if(tgt.dsttype == GameUnitType.PLAYER || tgt.dsttype == GameUnitType.HERO){ let effv = this.EMV(effvalue); let n = tgt.dst.addHP(effv); tgt.success(efftype, n); }else{ tgt.fail(efftype, -1); } }; summon(efftype: SkillEffectType, exparam: SkillParam, tgt: SkillTarget){ switch(efftype){ case SkillEffectType.SUMMON_NPC: { let ncount = this.getFinalValue(EnhanceCustomType.QUOTE_TIMES, this._data.quoteunit_times, this._data.quoteunit_timesmax, exparam.edd_cnt, exparam.cardpoint); if(ncount == 0){ ncount = 1; } let obj = tgt.srcpet? tgt.srcpet: tgt.srcplayer; let n = obj.summonPet(this._data.quoteunitid, ncount, exparam); if(n >= 0){ tgt.success(efftype, n); }else{ tgt.fail(efftype, -1); } } break; case SkillEffectType.SUMMON_SKILL: { let ncount = this.getFinalValue(EnhanceCustomType.QUOTE_TIMES, this._data.quoteskill_times, this._data.quoteskill_timesmax, exparam.edd_cnt, exparam.cardpoint); if(ncount == 0){ ncount = 1; } let obj = tgt.srcpet? tgt.srcpet: tgt.srcplayer; let res = obj.useSkill(this._data.quoteskillid, ncount, exparam); if(res){ tgt.success(efftype, res.length); }else{ tgt.fail(efftype, -1); } } break; case SkillEffectType.SKILL_GET: { let ncount = this.getFinalValue(EnhanceCustomType.GET_TIMES, this._data.getskill_times, this._data.getskill_timesmax, exparam.edd_cnt, exparam.cardpoint); if(ncount == 0){ ncount = 1; } let obj; if(this._data.skill_owners){ obj = tgt.dst; }else{ obj = tgt.srcpet? tgt.srcpet: tgt.srcplayer; } let n = obj? obj.addSkill(this._data.getskillid, ncount): 0; if(n){ tgt.success(efftype, this._data.getskillid); }else{ tgt.fail(efftype, -1); } } break; default: break; } }; taunt(tgt:SkillTarget){ let efftype = SkillEffectType.TAUNT; if(tgt.dsttype != GameUnitType.NONE && tgt.dsttype != GameUnitType.PLAYER){ (tgt.dst as PetHandler).taunt(); tgt.success(efftype, 1); }else{ tgt.fail(efftype, -1); } }; addBuff(efftype: SkillEffectType, effvalue: number, tgt: SkillTarget){ }; reduceHurt(effvalue: number, tgt: SkillTarget){ let efftype = SkillEffectType.HURT_REDUCE; if(tgt.dsttype != GameUnitType.NONE && tgt.dsttype != GameUnitType.PLAYER){ let n = (tgt.dst as PetHandler).addReduceHurt(effvalue); tgt.success(efftype, n); }else{ tgt.fail(efftype, -1); } }; enhanceMagic(effvalue: number, tgt: SkillTarget){ let efftype = SkillEffectType.ENHANCE_MAGIC; if(tgt.dsttype != GameUnitType.NONE){ let obj = tgt.dst; let n = obj.addEM(effvalue); if(n >= 0){ tgt.success(efftype, n); }else{ tgt.fail(efftype, n); } }else{ tgt.fail(efftype, -1); } }; EMV(effvalue: number){ if(this._type != SkillType.MAGIC){ return effvalue; } let ev = this._owner.getEM(); return effvalue + ev; }; reborn(tgt: SkillTarget){ let efftype = SkillEffectType.REBORN; if(tgt.dsttype != GameUnitType.NONE){ let res = tgt.dst.reborn(); if(res){ tgt.success(efftype, 1); }else{ tgt.fail(efftype, -1); } }else{ tgt.fail(efftype, -1); } }; silent(effvalue: number, tgt: SkillTarget){ let efftype = SkillEffectType.REBORN; if(tgt.dsttype != GameUnitType.NONE){ let res = tgt.dst.beSilent(effvalue); if(res){ tgt.success(efftype, res); }else{ tgt.fail(efftype, -1); } }else{ tgt.fail(efftype, -1); } }; attack(effvalue: number, tgt: SkillTarget, param: SkillParam){ let efftype = SkillEffectType.ATTACK; if(tgt.dsttype == GameUnitType.HERO || tgt.dsttype == GameUnitType.PET){ let obj = tgt.srcpet? tgt.srcpet: tgt.srcplayer; let v = effvalue; let res = obj.attack((tgt.dst as PetHandler), param, v); if(res){ tgt.success(efftype, res); // if(this._data.quoteskillid){ // let dp = this._data.skill_users? param.clone(): param; // if(this._data.skill_users){ // dp.srcpet = param.dstpet; // dp.srcplayer = param.dstplayer; // dp.dstpet = param.srcpet; // dp.dstplayer = param.srcplayer; // } // let pet = tgt.srcpet; // if(!pet && tgt.srcplayer){ // pet = tgt.srcplayer._self; // } // (tgt.dst as PetHandler).attack(pet, dp, 0, true); // } }else{ tgt.fail(efftype, -1); } }else{ tgt.fail(efftype, -1); } }; attack_back(effvalue: number, tgt: SkillTarget, param: SkillParam){ let efftype = SkillEffectType.ATTACK_BACK; if(tgt.dsttype == GameUnitType.HERO || tgt.dsttype == GameUnitType.PET){ let obj = tgt.srcpet? tgt.srcpet: tgt.srcplayer; let v = effvalue; let res = obj.attack((tgt.dst as PetHandler), param, v, true); if(res){ tgt.success(efftype, res); }else{ tgt.fail(efftype, -1); } }else{ tgt.fail(efftype, -1); } }; setOwner(owner: PlayerHandler) { this._owner = owner; }; setTriggerCallback(cb: any) { this._cb = cb; }; isTotalCardSkill(){ return this._tgctrl._cond.isTempTotalCard(); }; clone() { let obj = new Skill(); obj._currCount = 0; // 当前计数 obj._roundCount = 0; // 回合数 obj._startround = 0; // 触发后回合数 obj._delayround = 0; // 延迟回合数 obj._id = this._id; obj._data = this._data; obj._type = this._type; obj._param = this._param; obj._tgctrl = this._tgctrl; return obj; }; };