608 lines
19 KiB
TypeScript
608 lines
19 KiB
TypeScript
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<ncount;i++){
|
|
this._subskill._trigger(subparam, cb);
|
|
}
|
|
}
|
|
};
|
|
|
|
_trigger(param: SkillParam, cb?: any) {
|
|
//触发buff效果
|
|
let res = TriggerManager.onTrigger(this, param);
|
|
|
|
this._currCount++;
|
|
|
|
if (!this._start) {
|
|
this._start = true;
|
|
}
|
|
|
|
cb && cb(this, param, res);
|
|
|
|
this._cb && this._cb(this, param, res);
|
|
|
|
this._triggerSubSkill(param, cb);
|
|
};
|
|
|
|
trigger(param: SkillParam, cb?: any) {
|
|
let ncount = this.getFinalValue(EnhanceCustomType.RELEASE_TIMES, this._data.release_times,
|
|
this._data.release_timesmax, param.edd_cnt, param.cardpoint);
|
|
if(ncount == 0){
|
|
ncount = 1;
|
|
}
|
|
for(let i=0; i<ncount;i++){
|
|
this._trigger(param, cb);
|
|
}
|
|
};
|
|
|
|
checkTrigger(tg_type: TriggerType, tg_value: any, tg_target: SkillParam, cb?: any) {
|
|
if (tg_type == TriggerType.ROUND_START_MYSELF) {
|
|
this._roundCount++;
|
|
if (this._start) {
|
|
this._startround++;
|
|
}
|
|
}
|
|
if(this._tgctrl.checkTrigger(tg_type, tg_value, this._owner, (cdt: CondDecideType, v: number)=>{
|
|
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;
|
|
};
|
|
};
|