Beispiel #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;
    }
Beispiel #2
0
        public static void update_pl_state(long cur_clock_tm, IBaseUnit sprite)
        {
            var pl = sprite.get_pack_data();

            if (pl.states != null)
                return;

            var changed = false;
            //var add_state_rpc = { states =[] };
            //var rmv_state_rpc = { iid = pl.iid, ids =[] }

            var i = 0;
            for (; i < pl.states.state_par.Count; ++i)
            {
                var tm_elapsed = cur_clock_tm - pl.states.state_par[i].start_tm;
                var val = pl.states.state_par[i];
                var rmved = false;

                IBaseUnit frm_sprite = sprite.gmap.get_sprite_by_iid(val.frm_iid);


                if (val.end_tm <= cur_clock_tm)
                {
                    tm_elapsed = val.end_tm - val.start_tm;

                    // time reach, remove
                    pl.states.state_par.RemoveAt(i);
                    --i;
                    changed = true;
                    rmved = true;

                    //rmv_state_rpc.ids.push(val.desc.id);
                }

                // update time change states
                if (tm_elapsed > 500 || rmved)
                {
                    if (!rmved && tm_elapsed > 500)
                    {
                        tm_elapsed = 500;
                    }

                    var j = 0;
                    var desc_s_states = val.desc.s_states;
                    for (; j < desc_s_states.Count; ++j)
                    {
                        var s_state = desc_s_states[j];
                        // update hp change
                        if ((s_state.tp & (int)pl_state_type.PST_HP_TIME_ADD) == (int)pl_state_type.PST_HP_TIME_ADD)
                        {
                            int hp_add = (int)((s_state.par * val.par / 1000.0) * tm_elapsed / 1000.0);
                            //Utility.trace_err("pl.iid [" + pl.iid +"] hp_add ["+hp_add+"] \n");
                            pl.hp += hp_add;
                            if (pl.hp < 0)
                            {
                                pl.hp = 0;

                                // TO DO : die!
                                sprite.die(frm_sprite);

                                //var die_msg_rpc = { iid = pl.iid };
                                //if (frm_sprite)
                                //{
                                //    die_msg_rpc.frm_iid < -val.frm_iid;
                                //}
                                //// broad cast die msg
                                ////sprite.gmap.broadcast_map_rpc(25, die_msg_rpc);
                                //sprite.broad_cast_zone_msg_and_self(25, die_msg_rpc);

                                // player die, no more update
                                return;
                            }
                            else if (pl.hp > pl.max_hp)
                            {
                                pl.hp = pl.max_hp;
                            }
                        }

                        // update mp change
                        if ((s_state.tp & (int)pl_state_type.PST_MP_TIME_ADD) == (int)pl_state_type.PST_MP_TIME_ADD)
                        {
                            int mp_add = (int)((s_state.par * val.par / 1000.0) * tm_elapsed / 1000.0);
                            //Utility.trace_err("pl.iid [" + pl.iid +"] mp_add ["+mp_add+"] \n");
                            pl.mp += mp_add;
                            if (pl.mp < 0)
                            {
                                pl.mp = 0;
                            }
                            else if (pl.mp > pl.max_mp)
                            {
                                pl.mp = pl.max_mp;
                            }
                        }
                    }

                    // 处理定时获得指定状态的状态
                    if (val.desc.timer != null)
                    {
                        var timer = val.desc.timer;
                        val.tm_elapsed += tm_elapsed;

                        int interval = timer.interval;
                        if (val.tm_elapsed >= interval * 100)
                        {
                            val.tm_elapsed -= interval * 100;

                            if (timer.add_stat != null)
                            {
                                var add_stat = timer.add_stat;
                                if (add_stat.tar_state != val.desc.id)
                                {
                                    var state_obj = add_state_to_pl(cur_clock_tm, sprite, add_stat, frm_sprite, val.per, false);
                                    if (state_obj != null)
                                    {
                                        changed = true;
                                        //add_state_rpc.states.push(state_obj);
                                    }

                                }

                                if (timer.dmg != null)
                                {
                                    if (timer.rang != null)
                                    {
                                        apply_rang_eff(cur_clock_tm, sprite, new Point2D(pl.x, pl.y), new List<tres_conf>() { timer.dmg.convert2tres() }, timer.rang, 0, val.par);
                                    }
                                    else
                                    {
                                        grid_map.apply_dmg_on_pl(sprite, frm_sprite, timer.dmg.convert2damage(), cur_clock_tm, val.par);
                                    }

                                }

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

                    val.start_tm += tm_elapsed;
                }

                if (pl.states == null)
                    break;
            }

            if (changed)
            {
                //sys.trace(sys.SLT_DETAIL, "pl.iid [" + pl.iid +"] state changed \n");
                _remark_pl_state(sprite, pl);
            }

            //if (add_state_rpc.states.len() > 0)
            //{
            //    // broadcast add state msg;
            //    add_state_rpc.iid < -pl.iid;
            //    sprite.broad_cast_zone_msg_and_self(24, add_state_rpc);
            //}

            //if (rmv_state_rpc.ids.len() > 0)
            //{
            //    // broadcast rmv_state msg
            //    sprite.broad_cast_zone_msg_and_self(31, rmv_state_rpc);
            //}
        }
Beispiel #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);
        //    }
        //}

    }