コード例 #1
0
ファイル: grid_map.cs プロジェクト: lizhongwow/SceneTest
    //    {
    //    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;
    }