示例#1
0
    public static void update_pl_atk(IBaseUnit sprite, long cur_clock_tm)
    {
        var pl = sprite.get_pack_data();
        if (pl.atking == null)
            return;

        var cd_tm = sprite.get_atk_cd();

        if (pl.casting != null)
        {
            // 吟唱中,不更新攻击
            _hold_pl_atk(pl, cd_tm, cur_clock_tm);
            return;
        }

        if (pl.holding != null)
        {
            // 聚气中,不更新攻击
            _hold_pl_atk(pl, cd_tm, cur_clock_tm);
            return;
        }

        if (sprite.has_state(pl_state_type.PST_CANT_ATTACK))
        {
            // can't attack
            _hold_pl_atk(pl, cd_tm, cur_clock_tm);
            return;
        }

        //Utility.trace_err("update [" + pl.iid +"] attack \n");

        if (!sprite.gmap.has_sprite_by_iid(pl.atking.tar_iid))
        {
            // 目标不在同一地图
            sprite.cancel_atk();
            // TO DO : send msg
            return;
        }

        var tar_sprite = sprite.gmap.map_sprites[pl.atking.tar_iid];
        var tar_pl = tar_sprite.get_pack_data();

        if (sprite.isghost() || tar_sprite.isghost())
        {
            // 对方是灵魂状态,停止攻击
            sprite.cancel_atk();
            return;
        }

        if (tar_sprite.ignore_dmg())
        {
            _hold_pl_atk(pl, cd_tm, cur_clock_tm);
            return;
        }

        if (cur_clock_tm < pl.skill_gen_cd)
        {
            // 与技能共cd
            _hold_pl_atk(pl, cd_tm, cur_clock_tm);
            return;
        }

        //Utility.trace_err("[" + pl.iid +"] attack ["+pl.atking.tar_iid+"] cur tm: ["+cur_clock_tm+"] atkstarttm["+pl.atking.start_tm+"]\n");

        // TO DO : update face

        var tm_interval = cur_clock_tm - pl.atking.start_tm;

        //Utility.trace_err("[" + pl.iid +"] attack ["+pl.atking.tar_iid+"] tm_interval: ["+tm_interval+"] cd_tm ["+cd_tm+"]\n");

        if (tm_interval < cd_tm)
        {
            // 没到攻击间隔
            return;
        }

        if (tar_pl.invisible > pl.observer)
        {
            // 看不到目标

            if (sprite.get_sprite_type() == map_sprite_type.MstMonster)
            {
                //delete pl.atking; // 停止攻击
                pl.atking = null;
            }
            else
            {
                _hold_pl_atk(pl, cd_tm, cur_clock_tm);
            }

            return;
        }

        //Utility.trace_err("pl.x [" + pl.x +"] pl.y ["+pl.y+"] tar_pl.x: ["+tar_pl.x+"] tar_pl.y: ["+tar_pl.y+"]\n");

        //Utility.trace_err("dist_x [" + dist_x +"] dist_y ["+dist_y+"] atkrange: ["+pl.atkrange+"]\n");

        var dist_x = tar_pl.x - pl.x;
        var dist_y = tar_pl.y - pl.y;
        var range = pl.atkrange + pl.size + tar_pl.size + 32; // 允许1格误差
        if (dist_x * dist_x + dist_y * dist_y > range * range)
        {
            // 不在攻击范围内
            _hold_pl_atk(pl, cd_tm, cur_clock_tm);
            return;
        }

        var atkcnt_trigered = false;
        var added_state = false;
        if (pl.states != null)
        {
            // 检查按攻击次数结算状态
            foreach (var val in pl.states.state_par)
            {
                if (val.atkedcnt < 0 || val.desc.atkcnt == null)
                    continue;

                ++val.atkedcnt;

                //Utility.trace_info("val.atkedcnt["+val.atkedcnt+"] val.desc.atkcnt.cnt["+val.desc.atkcnt.cnt+"]")

                if (val.atkedcnt < val.desc.atkcnt.cnt)
                {
                    continue;
                }

                //sys.dumpobj(val);

                // 触发结算状态
                atkcnt_trigered = true;

                if (val.desc.atkcnt.add_stat > 0)
                {
                    var state_obj = Skill.add_state_to_pl(cur_clock_tm, tar_sprite, new tres_conf(val.desc.atkcnt.add_stat), sprite, val.per, false);
                    if (state_obj != null)
                    {
                        added_state = true;
                        // broadcast add state msg;
                        //tar_sprite.broad_cast_zone_msg_and_self(24, { iid = tar_pl.iid, states =[state_obj]});
                    }
                }

                if (val.desc.atkcnt.dmg > 0)
                {
                    apply_dmg_on_pl(tar_sprite, sprite, new damage() { hp_dmg = val.desc.atkcnt.dmg }, cur_clock_tm, val.par);
                }
            }
        }

        if (pl.invisible > 0)
        {
            // 攻击就现身
            Skill.rmv_state_from_pl_by_att("invisible", sprite, pl);
        }

        //if(sprite.get_sprite_type()==map_sprite_type.MstPlayer)
        //{
        //    // 中断打坐
        //    sprite.try_stop_recover();
        //}

        tar_sprite.atk_by(sprite);

        if (atkcnt_trigered)
        {
            // 触发了攻击次数结算状态,该次攻击失效

            if (added_state)
            {
                Skill._remark_pl_state(tar_sprite, tar_pl);
            }
            if (pl.atking != null)
                pl.atking.start_tm = cur_clock_tm;

            return;
        }

        // 计算攻击次数
        var atk_count = (tm_interval / cd_tm);
        var atk_tm_left = tm_interval % cd_tm;
        var total_dmg = 0;

        pl.atking.start_tm = cur_clock_tm - atk_tm_left;
        pl.last_atk_tm = pl.atking.start_tm;

        pl.skill_gen_cd = pl.atking.start_tm + cd_tm; // 触发技能cd
        pl.skill_gen_cdst = pl.atking.start_tm; // 触发技能cd起始

        var real_cd_tm = pl.skill_gen_cd - cur_clock_tm;
        if (real_cd_tm < 0) real_cd_tm = 0;

        // 判断对象是否攻击免疫
        if (tar_sprite.has_state(pl_state_type.PST_ATK_AVOID))
        {
            // can't be attack
            // send avoid attack msg
            //Utility.trace_err("[" + pl.iid +"] attack ["+pl.atking.tar_iid+"] target avoid attack\n");
            //sprite.broad_cast_zone_msg_and_self(18, { hited = 0, frm_iid = pl.iid, to_iid = pl.atking.tar_iid});
            return;
        }
        //::g_dump( " update_pl_atk()  ===>>>> ", "") ;
        var ret = apply_dmg_on_pl_ex(tar_sprite, sprite, new damage() { dmg_min = 0, dmg_max = 0, noratk = 1, hp_dmg = 0, mp_dmg = 0 }, cur_clock_tm, (int)atk_count * 1000, true, true);

        //ret.atkcount < -atk_count;
        //ret.cdtm < -real_cd_tm;

        // send attack msg
        sprite.broad_cast_zone_msg_and_self(18, ret);
        if (tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer)
        {
            //目标不在视野  需要补发消息
            //    if (!sprite.is_ply_inzone(tar_pl.sid))
            //    {
            //::send_rpc(tar_pl.sid, 18, ret);
            //    }
        }
    }