// { // level = 1, // atktp = atk_type.ATKTP_ATK, // atk_min = 100, // atk_max = 100, // matk_min = 100, // matk_max = 100, // atk_rate = 1000, // 命中率 // miss_rate = 0, // 闪避 // pkatkrate = 100, // pkmisrate = 100, // criatk = 0, // criatk_debuffs = 0, //暴击抵抗,相对 criatk 的抵抗 ,千分比, 算法:受到暴击击的概率降低xx // cridmg = 0, // exatk = 0, // exatk_debuffs = 0, // 卓越一击率抵抗, 相对 exatk 的抵抗 ,千分比, 算法:受到卓越一击的概率降低xx // exdmg = 0, // dobrate = 0, // igdef_rate = 0, // igdef_rate_debuffs = 0, // 抵抗无视防御几率 // def_red = 0, // dmg_red = 0, // atk_dmg_mul = 0, // igdmg_red = 0, // 无视伤害减免几率,千分比 // igatk_dmg_mul = 0,// 无视伤害增益几率,千分比 // hpsuck = 0, // 每次攻击吸收生命值 // hpsuck_dmgmul = 0, // 每次攻击吸收生命值增加伤害比例 // addResist = [0,0,0,0,0,0,0], // 属性攻击 // clansred = 0, // iid = 0, //}; // damage { noratk: } ?? public static Variant apply_dmg_on_pl_ex(IBaseUnit tar_sprite, IBaseUnit frm_sprite, damage damage, long cur_clock_tm, int per, bool wpnatk = false, bool direct_dmg = false) { // TO DO : 优化: per = 1000时不需要计算增益 //direct_dmg 默认伤害....? 技能伤害, 追击伤害, 有miss几率 //wpnatk 是否默认攻击 //::g_dump( "apply_dmg [ damage ] ===>>>> ", damage ) ; //::g_dump( "apply_dmg [ flags ] ===>>>> ", { wpnatk = wpnatk, direct_dmg = direct_dmg } ) ; if (frm_sprite != null) { frm_sprite.on_hurt(tar_sprite); } tar_sprite.on_be_hurt(frm_sprite); var tar_pl = tar_sprite.get_pack_data(); // 取不到状态添加对象情况下,本函数frm_sprite可能为空,则需要默认的计算参数 var pl = default(IMapUnit);// g_dmg_calc_def_pl; if (frm_sprite != null) { pl = frm_sprite.get_pack_data(); pl.last_atk_tm = cur_clock_tm; // 触发普通攻击cd } var ret = new Variant(); ret["hited"] = 3; ret["criatk"] = 0; ret["dmg"] = 0; ret["dobdmg"] = false; ret["isdie"] = false; ret["frm_iid"] = pl.iid; ret["to_iid"] = tar_pl.iid; // 计算玩家 VS NPC 等级调整伤害 //var dmg_per_add = 0; var is_pvp = true; if (frm_sprite != null) { if (frm_sprite.get_sprite_type() == map_sprite_type.MstMonster) { is_pvp = false; } } if (tar_sprite.get_sprite_type() == map_sprite_type.MstMonster) { is_pvp = false; } // miss check var bAllMiss = false; if (direct_dmg) { if (is_pvp) { // pvp var atk_rate = 100 * (pl.pkatkrate / (pl.pkatkrate + tar_pl.pkmisrate)/* * (pl.level/(pl.level + tar_pl.level))*/); var lvl_dist = tar_pl.level - pl.level; if (lvl_dist >= 300) { atk_rate -= 15; } else if (lvl_dist >= 200) { atk_rate -= 10; } else if (lvl_dist >= 100) { atk_rate -= 5; } var judg = Utility.random(0, 100); if (judg > atk_rate) { // miss ret["hited"] = 1; return ret; } } else { // pve var atk_rate = 100.0 * (pl.atk_rate - tar_pl.miss_rate) / pl.atk_rate; if (atk_rate < 5) { if (atk_rate < 0) { bAllMiss = true; } atk_rate = 5; } var judg = Utility.random(0, 100); if (judg > atk_rate) { // miss ret["hited"] = 1; return ret; } } } double targetDef = tar_pl.def; if (is_pvp) targetDef += tar_pl.pkdef; targetDef = (targetDef - targetDef * (pl.def_red / 1000.0)); var igdef_rate = pl.igdef_rate - tar_pl.igdef_rate_debuffs; if (igdef_rate > 0) { var judg = Utility.random(0, 1000); if (judg < igdef_rate) { targetDef = 0; ret["criatk"] = 1; // 无视防御 } } //Utility.trace_info("apply_dmg_on_pl frm_sprite:["+frm_sprite+"] per["+per+"]\n"); //sys.dumpobj(pl); //var combat_conf = get_general_combat_conf(); double total_dmg = 0; // TO DO : 计算伤害 damage 是否是物理伤害 if (pl.atktp == atk_type.ATKTP_MATK && !wpnatk && (damage.plyatk != 1)) { //pl.atktp == atk_type.ATKTP_MATK 是 魔攻攻击分类角色 // !wpnatk 不是默认攻击 // (!("plyatk" in damage) || damage.plyatk!=1) 不是物理攻击 // 根据魔法攻击计算伤害 int dmg_min = damage.dmg_min + pl.matk_min * damage.noratk; int dmg_max = damage.dmg_max + pl.matk_max * damage.noratk; if (is_pvp && pl.pkmatk != 0) {//pvp魔法攻击增加 dmg_min += pl.pkmatk; dmg_max += pl.pkmatk; } if (damage.attr >= 0) {// 属性攻击 dmg_min += pl.addResist[damage.attr]; dmg_max += pl.addResist[damage.attr]; } // TO DO : 根据装备武器不同来计算伤害 //if(direct_dmg && frm_sprite) //{ // //frm_sprite.get_equip_by_pos(6); // 获取装备的武器 //} double dmg = 0; var dmg_calced = false; if (damage.noratk > 0 && (pl.criatk - pl.criatk_debuffs > 0 || pl.exatk - pl.exatk_debuffs > 0)) { var judg = Utility.random(0, 1000); if (judg < pl.exatk - pl.exatk_debuffs) {//卓越一击几率 dmg = dmg_max - targetDef; dmg += dmg_max * (0.2 + pl.exper_add / 1000.0); dmg += pl.exdmg; ret["criatk"] = 2; // 卓越一击 dmg_calced = true; } else { judg = Utility.random(0, 1000); if (judg < pl.criatk - pl.criatk_debuffs) {// 会心一击几率 dmg = dmg_max - targetDef; dmg += pl.cridmg; ret["criatk"] = 3; // 会心一击 dmg_calced = true; } } } if (!dmg_calced) { dmg = Utility.random(dmg_min, dmg_max + 1); //if(is_pvp) //{ // dmg = dmg - (targetDef*tar_sprite.game_conf.pvp_def_per/100.0); //} //else //{ // dmg = dmg - targetDef; //} } if (frm_sprite != null && frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { //// 技能攻击,技能额外加成 //int dmg_mul = damage["noratk"]; //var baseatt_conf = frm_sprite.carr_gen_conf.baseatt[0]; //if( ("inte2atk" in baseatt_conf) && baseatt_conf.inte2atk != 0 ) //{ // dmg_mul += pl.inte/(pl.inte+baseatt_conf.inte2atk); //} ////sys.trace( sys.SLT_DETAIL, "atk_type.ATKTP_MATK dmg_mul=" + dmg_mul + " baseatt_conf.inte2atk =" + baseatt_conf.inte2atk + "\n") //dmg = dmg * dmg_mul; } if (dmg <= 0) { dmg = 1; } total_dmg += dmg; } else { // 根据攻击力计算伤害 var skil_dmg_min = damage.dmg_min + pl.atk_min; var skil_dmg_max = damage.dmg_max + pl.atk_max; if (is_pvp && pl.pkatk != 0) { skil_dmg_min += pl.pkatk; skil_dmg_max += pl.pkatk; } if (damage.attr >= 0) { skil_dmg_min += pl.addResist[damage.attr]; skil_dmg_max += pl.addResist[damage.attr]; } double dmg = 0; var dmg_calced = false; if (damage.noratk > 0 && (pl.criatk - pl.criatk_debuffs > 0 || pl.exatk - pl.exatk_debuffs > 0)) { var judg = Utility.random(0, 1000); if (judg < pl.exatk - pl.exatk_debuffs) { dmg = skil_dmg_max; dmg += skil_dmg_max * (0.2 + pl.exper_add / 1000.0); dmg += pl.cridmg; dmg += pl.exdmg; ret["criatk"] = 2; // 卓越一击 dmg_calced = true; } else { judg = Utility.random(0, 1000); if (judg < pl.criatk - pl.criatk_debuffs) { dmg = skil_dmg_max; dmg += pl.cridmg; ret["criatk"] = 3; // 会心一击 dmg_calced = true; } } } if (!dmg_calced) { dmg = Utility.random(skil_dmg_min, skil_dmg_max + 1); } //if(is_pvp) //{ // dmg = dmg - (targetDef*tar_sprite.game_conf.pvp_def_per/100.0); //} //else //{ // dmg = dmg - targetDef; //} if (!wpnatk && frm_sprite != null && frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { // 物理技能攻击,技能额外加成 var dmg_mul = damage.noratk; //var baseatt_conf = frm_sprite.carr_gen_conf.baseatt[0]; //if( ("inte2atk" in baseatt_conf) && baseatt_conf.inte2atk != 0 ) //{ // dmg_mul += pl.inte/(pl.inte+baseatt_conf.inte2atk); //} //sys.trace( sys.SLT_DETAIL, "atk_type.ATKTP_ATK dmg_mul=" + dmg_mul + "\n") dmg = dmg * dmg_mul; } if (dmg <= 0) { dmg = 1; } total_dmg += dmg; } if (bAllMiss) {//pve中 攻击者攻击几率 小于 被攻击者 miss几率时,攻击减益到30% total_dmg = (total_dmg * 30) / 100; } if (tar_pl.dmg_red != 1) {//伤害减免 if (pl.igdmg_red <= 0) { //无视伤害减免几率 total_dmg = (total_dmg * tar_pl.dmg_red); } else { var judg = Utility.random(0, 1000); if (judg >= pl.igdmg_red) { total_dmg = (total_dmg * tar_pl.dmg_red); } } } if (is_pvp && tar_pl.pkdmg_red != 1) { //pvp 伤害减免 total_dmg = (total_dmg * tar_pl.pkdmg_red); } var tlevel = pl.level / 10; if (total_dmg >= 0 && total_dmg < tlevel) { if (tlevel < 1) { tlevel = 1; } total_dmg = tlevel; } // TO DO : sprite damage, 小精灵伤害 if (direct_dmg) { // 计算生命损耗伤害加成 if (frm_sprite != null && pl.hpsuck > 0) { // 损耗自己生命 if (pl.hp > pl.hpsuck) { pl.hp -= pl.hpsuck; if (pl.hp < 0) pl.hp = 0; // broadcast hpchange msg //frm_sprite.broad_cast_zone_msg_and_self(26, {iid=pl.iid, hpchange={hpadd=-pl.hpsuck, die=(pl.hp <= 0), frm_iid=pl.iid}}); //if(pl.cid >0) //{ // var tid = team.get_ply_teamid(pl.cid); // if(tid > 0) // { // // 在队伍中,发送队友属性变化消息 // team_bcast_rpc_except(tid, 138, {cid=pl.cid, hp=pl.hp}, pl.sid); // } //} if (pl.hpsuck_dmgmul > 0) { // 增加攻击伤害 total_dmg = total_dmg * ((1000.0 + pl.hpsuck_dmgmul) / 1000.0); } } } var atk_dmg_mul = pl.atk_dmg_mul; if (pl.igatk_dmg_mul > 0) { //无视伤害增益几率 var judg = Utility.random(0, 1000); if (judg < pl.igatk_dmg_mul) { atk_dmg_mul = 0; } } if (is_pvp) { total_dmg += (total_dmg * ((atk_dmg_mul + pl.pkatk_dmg_mul) / 1000.0)); } else { total_dmg += (total_dmg * (atk_dmg_mul / 1000.0)); } //// 计算技能伤害的属性加成值 //if(damage.ContainsKey("attdmg_mul")) //{ // foreach(var attdmg in damage["attdmg_mul"]) // { // var val = 0; // if(attdmg.name in pl) // { // val = pl[attdmg.name]; // } // total_dmg *= ((attdmg.base + val * attdmg.val ) / attdmg.basediv); // } //} //if("attdmg_add" in damage) //{ // foreach(attdmg in damage.attdmg_add) // { // var val = 0; // if(attdmg.name in pl) // { // val = pl[attdmg.name]; // } // total_dmg += ((attdmg.base + val * attdmg.val ) / attdmg.basediv); // } //} //if((tar_sprite.get_sprite_type()==map_sprite_type.MstMonster) && tar_pl.clanatt_eff) //{ // // 需要计算副本中帮派科技伤害减免 // var clanper = 1000 - tar_pl.clanred + pl.clansred; // //Utility.trace_info("calc clanatt total_dmg["+total_dmg+"] clanper["+clanper+"] pl.clansred["+pl.clansred+"] tar_pl.clanred["+tar_pl.clanred+"]\n"); // total_dmg = (total_dmg * ((clanper)/1000.0)); // //Utility.trace_info("calc clanatt total_dmg["+total_dmg+"]\n"); //} // TO DO : 吸蓝 mpsteal } total_dmg += damage.hp_dmg; total_dmg = (total_dmg * (per / 1000.0)); //sys.dumpobj(damage); //Utility.trace_info("total_dmg:["+total_dmg+"]\n"); if (total_dmg.CompareTo(0) > 0) { var real_atk_dmg = total_dmg; if (total_dmg > 0) { if (frm_sprite != null) { tar_sprite.onhate(frm_sprite, total_dmg); tar_sprite.ondmg(frm_sprite, total_dmg); if (frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { if (frm_sprite.gmap.blvlmap) { frm_sprite.gmap.worldsvr.on_dmg(frm_sprite, tar_sprite, total_dmg); } } if (direct_dmg) { frm_sprite.calc_weapon_dura(total_dmg); // 计算装备耐久损耗 frm_sprite.on_make_direct_dmg(); } } if (direct_dmg) { tar_sprite.calc_eqp_dura(total_dmg); // 计算装备耐久损耗 // 计算双倍伤害 if (pl.dobrate > 0) { var judg = Utility.random(0, 1000); if (judg < pl.dobrate) { total_dmg += total_dmg; ret["dobdmg"] = true; } } } // 吸收伤害 total_dmg = pl_absorb_dmg(tar_sprite, tar_pl, total_dmg); // 魔法抵扣生命 total_dmg = pl_hpdmg_2_mpdmg(tar_sprite, tar_pl, total_dmg); // 伤害链接 pl_dmg_link(tar_sprite, tar_pl, total_dmg); } if (is_pvp && total_dmg > 0) { var pkignore_dp = false;//无视dp var pkigdp_rate = pl.pkigdp_rate - tar_pl.pkigdp_rate_debuffs; if (pkigdp_rate > 0) { var judg = Utility.random(0, 1000); pkignore_dp = judg < pkigdp_rate; } if (!pkignore_dp) { if (tar_pl.dp < total_dmg) { var dp_dmg = tar_pl.dp; tar_pl.dp = 0; //剩余值 10倍作用于hp total_dmg = ((total_dmg - dp_dmg));//*tar_sprite.game_conf.ply_hp_dmg_factor); tar_pl.hp -= (int)total_dmg; if (tar_pl.hp < 0) tar_pl.hp = 0; ret["dp_dmg"] = dp_dmg; } else { tar_pl.dp -= (int)total_dmg; if (tar_pl.dp > tar_pl.max_dp) tar_pl.dp = tar_pl.max_dp; ret["dp_dmg"] = total_dmg; total_dmg = 0; } } else { //剩余值 10倍作用于hp total_dmg = (total_dmg * 10);//tar_sprite.game_conf.ply_hp_dmg_factor); tar_pl.hp -= (int)total_dmg; if (tar_pl.hp < 0) tar_pl.hp = 0; } //sys.trace( sys.SLT_DETAIL, "tar_pl.cid =" + tar_pl.cid + " tar_pl.dp = " + tar_pl.dp + " tar_pl.hp = " + tar_pl.hp + "\n"); } else { tar_pl.hp -= (int)total_dmg; if (tar_pl.hp < 0) tar_pl.hp = 0; if (tar_pl.hp > tar_pl.max_hp) tar_pl.hp = tar_pl.max_hp; } // broadcast hpchange msg //tar_sprite.broad_cast_zone_msg_and_self(26, {iid=tar_pl.iid, hpchange={hpadd=-total_dmg, die=(tar_pl.hp <= 0), frm_iid=pl.iid}}); ret["isdie"] = (tar_pl.hp <= 0); ret["dmg"] = total_dmg; //if(tar_pl.cid >0) //{ // var tid = team.get_ply_teamid(tar_pl.cid); // if(tid > 0) // { // // 在队伍中,发送队友属性变化消息 // if( is_pvp ) // { // team_bcast_rpc_except(tid, 138, {cid=tar_pl.cid, hp=tar_pl.hp, dp=tar_pl.dp}, tar_pl.sid); // } // else // { // team_bcast_rpc_except(tid, 138, {cid=tar_pl.cid, hp=tar_pl.hp}, tar_pl.sid); // } // } //} if (tar_pl.hp <= 0) { // die! tar_sprite.die(frm_sprite); } //目标死亡,本次伤害不反弹 if (frm_sprite != null && real_atk_dmg > 0 && tar_pl.iid != pl.iid && tar_pl.hp > 0) { // 反弹伤害 double dmg = 0; if (tar_pl.rev_dmg_mul > 0) { dmg = (real_atk_dmg * ((tar_pl.rev_dmg_mul) / 1000.0)); if (dmg <= 0) dmg = 1; } if (tar_pl.rev_atk > 0) { var judg = Utility.random(0, 1000); if (judg < tar_pl.rev_atk) { dmg += real_atk_dmg; } } //if(is_pvp) //{ // dmg = (dmg * combat_conf.pk_dmg_per/100); //} if (dmg > 0) { // 吸收伤害 dmg = pl_absorb_dmg(frm_sprite, pl, dmg); // 魔法抵扣生命 dmg = pl_hpdmg_2_mpdmg(frm_sprite, pl, dmg); frm_sprite.onhate(tar_sprite, dmg); frm_sprite.ondmg(tar_sprite, dmg); //var frm_hpchange = {frm_iid=tar_pl.iid} if (is_pvp) { //sys.trace( sys.SLT_DETAIL, "pl.dp =" + pl.dp + "pl.hp = "+ pl.hp + "\n"); if (pl.dp < dmg) { var dp_dmg = pl.dp; pl.dp = 0; //剩余值 10倍作用于hp dmg = ((dmg - dp_dmg));//*tar_sprite.game_conf.ply_hp_dmg_factor); pl.hp -= (int)dmg; if (pl.hp < 0) pl.hp = 0; //frm_hpchange.dpadd <- -dp_dmg; //frm_hpchange.hpadd <- -dmg; //frm_hpchange.die <- pl.hp <= 0; } else { pl.dp -= (int)dmg; //frm_hpchange.dpadd <- -dmg; } //sys.dumpobj( frm_hpchange ); } else { pl.hp -= (int)dmg; if (pl.hp < 0) pl.hp = 0; //frm_hpchange.hpadd <- -dmg; //frm_hpchange.die <- pl.hp <= 0; } // broadcast hpchange msg //frm_sprite.broad_cast_zone_msg_and_self(26, {iid=pl.iid, hpchange=frm_hpchange}); //if(pl.cid > 0) ////if("cid" in pl) //{ // var tid = team.get_ply_teamid(pl.cid); // if(tid > 0) // { // // 在队伍中,发送队友属性变化消息 // if ( is_pvp ) // { // team_bcast_rpc_except(tid, 138, {cid=pl.cid, hp=pl.hp, dp=pl.dp}, pl.sid); // } // else // { // team_bcast_rpc_except(tid, 138, {cid=pl.cid, hp=pl.hp}, pl.sid); // } // } //} if (pl.hp <= 0) { // 被弹死了 frm_sprite.die(tar_sprite); } } } } // 魔法值、怒气值调整 var mpchanged = false; //var mpchange_rpc = {}; if (damage.mp_dmg != 0) { var mpdmg = (damage.mp_dmg * per / 1000); tar_pl.mp -= mpdmg; if (tar_pl.mp < 0) tar_pl.mp = 0; if (tar_pl.mp > tar_pl.max_mp) tar_pl.mp = tar_pl.max_mp; //mpchange_rpc.mpadd <- -mpdmg; mpchanged = true; if (frm_sprite != null) { tar_sprite.onhate(frm_sprite, mpdmg); } } if (mpchanged && tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { // send mpchange msg //::send_rpc(tar_pl.sid, 32, mpchange_rpc); } return ret; }