Пример #1
0
    //    {
    //    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;
    }
Пример #2
0
        public static MapUnitState add_state_to_pl(long cur_clock_tm, IBaseUnit target, tres_conf state, IBaseUnit frm_sprite, int per, bool bremark = true)
        {
            if (target.isdie() || target.isghost())
            {
                // TO DO : 考虑有些技能能作用于尸体
                return null;
            }

            var pl = target.get_pack_data();

            var state_desc = Utility.get_skil_state_desc(state.tar_state);
            if (state_desc == null)
            {
                // Err: state not exist;
                Utility.trace_err("persist_game add state[" + state.tar_state + "] to[" + pl.iid + "], state not exist!\n");
                return null;
            }

            var state_tm = state.state_tm;
            //sys.trace(sys.SLT_DETAIL, "state_tm before["+state_tm+"]\n");

            var mul = 1000;
            var add = 0;
            //        if (0 in pl.stat_red)
            //{
            //            mul += pl.stat_red[0].mul;
            //            add += pl.stat_red[0].add;
            //        }
            //        if (state.tar_state in pl.stat_red)
            //{
            //            mul += pl.stat_red[state.tar_state].mul;
            //            add += pl.stat_red[state.tar_state].add;
            //        }

            //sys.trace(sys.SLT_DETAIL, "mul["+mul+"] add["+add+"]\n");

            state_tm = (state_tm * 1000 / mul - add);
            if (state_tm < 1) state_tm = 1;
            //sys.trace(sys.SLT_DETAIL, "state_tm after["+state_tm+"]\n");

            var new_end_tm = cur_clock_tm + state_tm * 100;
            //sys.trace(sys.SLT_DETAIL, "new_end_tm["+new_end_tm+"]\n");

            var remove_stateids = new List<int>();

            if (pl.states != null)
            {
                if (state_desc.max_cnt > 0)
                {
                    // 判断状态数量
                    var own_cnt = 0;
                    foreach (var val in pl.states.state_par)
                    {
                        if (val.id == state.tar_state)
                        {
                            ++own_cnt;

                            if (own_cnt >= state_desc.max_cnt)
                            {
                                // 超过最大数量限制,不在增加状态
                                return null;
                            }
                        }
                    }
                    if (own_cnt == 0)
                    {
                        //替换掉低级的
                        if (state_desc.unique != null)
                        {
                            for (var idx = 0; idx < pl.states.state_par.Count; ++idx)
                            {
                                var val = pl.states.state_par[idx];

                                if (val.desc.unique == null)
                                    continue;

                                if (state_desc.unique.uni_tp != val.desc.unique.uni_tp)
                                {
                                    continue;
                                }

                                if (state_desc.unique.uni_prior > val.desc.unique.uni_prior)
                                {
                                    pl.states.state_par.RemoveAt(idx);
                                    --idx;
                                    remove_stateids.push(val.desc.id);
                                }
                            }
                        }
                    }
                }
                else if (state_desc.unique != null)
                {
                    // 判断独有状态,根据独有类型实施替换

                    for (var idx = 0; idx < pl.states.state_par.Count; ++idx)
                    {
                        var val = pl.states.state_par[idx];

                        if (val.desc.unique == null)
                            continue;

                        if (state_desc.unique.uni_tp != val.desc.unique.uni_tp)
                        {
                            continue;
                        }

                        if (state_desc.unique.uni_prior > val.desc.unique.uni_prior)
                        {
                            if (new_end_tm > val.end_tm)
                            {
                                pl.states.state_par.RemoveAt(idx);
                                --idx;
                                remove_stateids.push(val.desc.id);
                            }
                            else
                            {
                                return null;
                            }
                        }
                        else if (state_desc.unique.uni_prior > val.desc.unique.uni_prior)
                        {
                            pl.states.state_par.RemoveAt(idx);
                            --idx;
                            remove_stateids.push(val.desc.id);
                        }
                        else
                        {
                            return null;
                        }
                    }
                }
            }

            var i = 0;
            for (; i < state_desc.s_states.Count; ++i)
            {
                int state_tp = state_desc.s_states[i].tp;
                if ((state_tp & (int)pl_state_type.PST_CANT_MOVE) == (int)pl_state_type.PST_CANT_MOVE)
                {
                    // stop sprite & broadcast msg
                    grid_map.update_pl_move(target, cur_clock_tm);

                    if (pl.moving != null)
                    {
                        // 停止移动
                        //var data = { tm = cur_clock_tm, iid = pl.iid, x = pl.x, y = pl.y, face = pl.face };
                        // send stop move msg to clients
                        //target.gmap.broadcast_map_rpc(10, data);
                        //target.broad_cast_zone_msg_and_self(10, data);

                        //delete pl.moving;
                        pl.moving = null;
                    }
                }
                if ((state_tp & (int)pl_state_type.PST_CANT_CAST_SKILL) == (int)pl_state_type.PST_CANT_CAST_SKILL)
                {
                    if (pl.holding != null)
                    {//先 停止聚气
                        if (target.gmap != null)
                        {
                            target.gmap.update_skill_holding(target, pl, 0);
                        }
                    }

                    if (pl.casting != null)
                    {
                        // 停止施法
                        //var data = { iid = pl.iid };
                        // send cancel_casting_res to clients
                        //target.broad_cast_zone_msg_and_self(29, data);

                        //delete pl.casting;
                        pl.casting = null;
                    }
                }
            }

            if (pl.states == null)
                pl.states = new UnitState();


            IMapUnit frm_pl = null;
            int frm_iid = 0;

            if (frm_sprite != null)
            {
                frm_pl = frm_sprite.get_pack_data();
                frm_iid = frm_pl.iid;
            }

            MapUnitState obj = new MapUnitState()
            {
                id = state.tar_state,
                par = (int)(state.state_par * per / 1000.0),
                start_tm = cur_clock_tm,
                end_tm = new_end_tm,
                desc = state_desc,
                frm_iid = frm_iid,
                per = per,
                attadj = new Dictionary<string, int>(),
            };

            pl.states.state_par.push(obj);

            // 首次添加定时状态
            if (state_desc.timer != null)
            {
                obj.tm_elapsed = 0;

                var timer = state_desc.timer;
                if (timer.add_stat != null)
                {
                    int tar_state = timer.add_stat.tar_state;
                    if (tar_state != state_desc.id)
                    {
                        var state_obj = add_state_to_pl(cur_clock_tm, target, timer.add_stat, frm_sprite, per, false);
                        if (state_obj != null)
                        {
                            // broadcast add state msg;
                            //target.broad_cast_zone_msg_and_self(24, { iid = pl.iid, states =[state_obj]});
                        }
                    }

                    if (timer.dmg != null)
                    {
                        if (timer.trang != null)
                        {

                            apply_rang_eff(cur_clock_tm, target, new Point2D(pl.x, pl.y), new List<tres_conf>() { timer.dmg.convert2tres() }, timer.trang, 0, obj.par);
                        }
                        else
                        {
                            grid_map.apply_dmg_on_pl(target, frm_sprite, timer.dmg.convert2damage(), cur_clock_tm, obj.par);
                        }

                    }

                    // 增加直接回蓝、回血功能
                    //            if ("dd" in state_desc.timer)
                    //{
                    //                apply_direct_dmg_on_pl(target, frm_sprite, state_desc.timer.dd[0], cur_clock_tm, obj.par);
                    //            }

                    if (target.isdie() || target.isghost())
                    {
                        // TO DO : 考虑有些技能能作用于尸体
                        return null;
                    }
                }

                if (state_desc.absorbdmg != null)
                {
                    obj.absorbed = 0;
                    obj.maxdmg = (state_desc.absorbdmg.maxdmg * obj.par / 1000);
                }

                if (state_desc.atkcnt != null)
                {
                    obj.atkedcnt = 0;
                }

                //if(frm_sprite && "hate" in state_desc && frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer)
                if (frm_sprite != null && state_desc.hate > 0)
                {
                    target.onhate(frm_sprite, state_desc.hate);
                }

                if (remove_stateids.Count > 0)
                {
                    // broadcast rmv_state msg
                    //target.broad_cast_zone_msg_and_self(31, { iid = pl.iid, ids = remove_stateids});
                }
            }

            if (bremark)
            {
                _remark_pl_state(target, pl);
            }

            return obj;
        }
Пример #3
0
    public void apply_direct_dmg_on_pl(IBaseUnit tar_sprite, IBaseUnit frm_sprite, Variant damage, long cur_clock_tm, int per)
    {
        // TO DO : 优化: per = 1000时不需要计算增益

        var tar_pl = tar_sprite.get_pack_data();

        // 取不到状态添加对象情况下,本函数frm_sprite可能为空,则需要默认的计算参数
        var pl = default(IMapUnit);

        if (frm_sprite != null)
        {
            pl = frm_sprite.get_pack_data();
            pl.last_atk_tm = cur_clock_tm; // 触发普通攻击cd
        }

        //Utility.trace_info("apply_dmg_on_pl frm_sprite:["+frm_sprite+"] per["+per+"]\n");
        //sys.dumpobj(pl);

        //var hpchange = {};
        if (tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer)
        {// 玩家 防护值调整
            double dpdmg = 0;
            if (damage.ContainsKey("dp_dmg"))
            {
                dpdmg = (damage["dp_dmg"]._int32 * per / 1000);
            }
            if (damage.ContainsKey("dp_per"))
            {
                dpdmg += (damage["dp_per"]._int32 * per / 100000.0 * tar_pl.max_dp);
            }
            //    if (frm_sprite != null && damage.ContainsKey("dattadj"))
            //    {
            //        foreach (attname, val in damage.dattadj[0] )
            //{
            //            if (attname in pl )
            //    {
            //                dpdmg += (pl[attname] / val);
            //                //sys.trace( sys.SLT_DETAIL, " pl[" + attname + "]= " + pl[attname] + " mpdmg=" + mpdmg + "\n" );
            //            }
            //        }
            //    }

            if (dpdmg != 0)
            {

                tar_pl.dp -= (int)dpdmg;
                if (tar_pl.dp < 0) tar_pl.dp = 0;
                if (tar_pl.dp > tar_pl.max_dp) tar_pl.dp = tar_pl.max_dp;

                //sys.trace( sys.SLT_DETAIL, "dpdmg tar_pl.cid =" + tar_pl.cid + "    tar_pl.dp = " +  tar_pl.dp + "\n");      
                //hpchange.dpadd < - -dpdmg;
            }
        }

        double total_dmg = 0;
        //        if ("hp_dmg" in damage)
        //{
        //            total_dmg = (damage.hp_dmg * per / 1000.0);
        //            //sys.trace( sys.SLT_DETAIL, "per= " + per + " total_dmg=" + total_dmg + "\n" );
        //        }
        //        if ("hp_per" in damage )
        //{
        //            total_dmg += (damage.hp_per * per / 100000.0 * tar_pl.max_hp);
        //        }
        //        if (frm_sprite && ("hattadj" in damage) )
        //{
        //            foreach (attname, val in damage.hattadj[0] )
        //    {
        //                if (attname in pl )
        //        {
        //                    total_dmg += (pl[attname] / val);
        //                    //sys.trace( sys.SLT_DETAIL, " pl[" + attname + "]= " + pl[attname] + " total_dmg=" + total_dmg + "\n" );
        //                }
        //            }
        //        }

        //sys.dumpobj(damage);
        //Utility.trace_info("total_dmg:["+total_dmg+"]\n");
        if (total_dmg != 0)
        {
            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);
                        }
                    }
                }

                // 吸收伤害
                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);
            }

            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;

            //hpchange.hpadd < - -total_dmg;
            //hpchange.die < -tar_pl.hp <= 0;
        }

        //    if (hpchange.Count > 0)
        //    {
        //        // broadcast hpchange msg
        //        hpchange.frm_iid < -pl.iid;
        //        tar_sprite.broad_cast_zone_msg_and_self(26, { iid = tar_pl.iid, hpchange = hpchange});

        //        if ("cid" in tar_pl)
        //{
        //            var tid = team.get_ply_teamid(tar_pl.cid);
        //            if (tid > 0)
        //            {
        //                // 在队伍中,发送队友属性变化消息
        //                team_bcast_rpc_except(tid, 138, { cid = tar_pl.cid, hp = tar_pl.hp, dp = tar_pl.dp}, tar_pl.sid);
        //            }
        //        }

        if (tar_pl.hp <= 0)
        {
            // die!
            tar_sprite.die(frm_sprite);
        }
        //}

        double mpdmg = 0;
        //        if ("mp_dmg" in damage)
        //{
        //            mpdmg = (damage.mp_dmg * per / 1000);
        //        }
        //        if ("mp_per" in damage )
        //{
        //            mpdmg += (damage.mp_per * per / 100000.0 * tar_pl.max_mp);
        //        }
        //        if (frm_sprite && ("mattadj" in damage) )
        //{
        //            foreach (attname, val in damage.mattadj[0] )
        //    {
        //                if (attname in pl )
        //        {
        //                    mpdmg += (pl[attname] / val);
        //                    //sys.trace( sys.SLT_DETAIL, " pl[" + attname + "]= " + pl[attname] + " mpdmg=" + mpdmg + "\n" );
        //                }
        //            }
        //        }

        //Utility.trace_info("mpdmg:["+mpdmg+"]\n");
        //if (mpdmg != 0)
        //{
        //    // 魔法值、怒气值调整
        //    var mpchange_rpc = { };

        //    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;

        //    if (frm_sprite)
        //    {
        //        tar_sprite.onhate(frm_sprite, mpdmg);
        //    }

        //    if (tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer)
        //    {
        //// send mpchange msg
        //::send_rpc(tar_pl.sid, 32, mpchange_rpc);
        //    }
        //}

    }