コード例 #1
0
ファイル: oldSkill.cs プロジェクト: lizhongwow/SceneTest
        public static bool apply_skill_eff_to(long now, IBaseUnit from, IBaseUnit target, skill_state_conf sk_res,
            int aff, int percentage)
        {
            if (target.isghost() || target.isdie())
                return false;

            if (target.ignore_dmg())
                return false;

            if (sk_res.rate > 0)
            {
                if (new Random().Next(0, 100) > sk_res.rate)
                    return false;
            }

            if (target.has_state(pl_state_type.PST_SKILL_AVOID))
                return false;

            if (from.iid != target.iid)
            {
                if (!skill_conf.skill_target_type_validation(aff, skill_aff_type.SAT_ENERMY))
                {
                    if (from.can_atk(target))
                        return false;

                    if (from.isaily(target))
                    {
                        if (!skill_conf.skill_target_type_validation(aff, skill_aff_type.SAT_ALLY))
                            return false;
                    }
                    else
                    {
                        if (!skill_conf.skill_target_type_validation(aff, skill_aff_type.SAT_MID))
                            return false;
                    }
                }
                else
                {
                    if (from.Is_Player())
                    {
                        if (target.Is_Player())
                        {
                            if (target.get_pack_data().in_pczone || from.get_pack_data().in_pczone)
                                return false;

                            if (!from.can_atk(target))
                                return false;
                        }
                        else if (target.Is_Monster())
                        {
                            if (target.owner_ply != null)
                            {
                                if (target.owner_ply.iid == from.iid)
                                    return false;

                                if (target.owner_ply.get_pack_data().in_pczone || from.get_pack_data().in_pczone)
                                    return false;

                                if (!from.can_atk(target))
                                    return false;
                            }
                        }
                    }
                    else
                    {
                        if (!from.can_atk(target))
                            return false;
                    }
                }
            }
            else
            {
                if(!skill_conf.skill_target_type_validation(aff,skill_aff_type.SAT_SELF))
                    return false;
            }

            if (from.Is_Player())
            {
                if(target.can_atk(from))
                    target.atk_by(from);
            }

            if (sk_res.nodmg == 0)
            {
                //TODO do damage
            }

            if (sk_res.rmv_stat > 0)
                rmv_stat_from_pl_by_gb(sk_res.rmv_stat,target);

            if(sk_res.rmv_1_stat >0)
                rmv_1_stat_from_pl_by_gb(sk_res.rmv_1_stat,target);

            if (sk_res.tar_state > 0)
            {
                IBaseUnit_State state = add_state_to_pl(now, target, sk_res, from, 100);
            }

            if (sk_res.force_move_dir != -1)
            {
                int dir = sk_res.force_move_dir;
                if (sk_res.force_move_dir == 2)
                    dir = new Random().Next(0, 2);

                int delta_x = target.x - from.x;
                int delta_y = target.y - from.y;

                if (delta_x != 0 || delta_y != 0)
                {
                    Point2D vec=new Point2D(delta_x,delta_y);
                    vec = Utility.normalize_vec2(vec);

                    delta_x = (int)(sk_res.force_move_rang*vec.x);
                    delta_y = (int) (sk_res.force_move_rang*vec.y);

                    if (sk_res.force_move_dir == 0)
                    {
                        target.x += delta_x;
                        target.y += delta_y;
                    }
                    else
                    {
                        target.x -= delta_x;
                        target.y -= delta_y;
                    }
                }

                target.get_pack_data().moving = null;
                target.get_pack_data().casting = null;
                target.get_pack_data().last_mvpts = null;
            }

            return true;
        }
コード例 #2
0
ファイル: grid_map.cs プロジェクト: lizhongwow/SceneTest
    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);
            //    }
        }
    }
コード例 #3
0
ファイル: skills.cs プロジェクト: lizhongwow/SceneTest
        //public static bool apply_skill_eff_to(long cur_clock_tm, IBaseUnit from, IBaseUnit target, dmg dmg, int aff, int skill_id, int percentage)
        //{
        //    tres sk_res = new tres();
        //    sk_res.rate = 100;

        //    return apply_skill_eff_to(cur_clock_tm, from, target, sk_res, aff, skill_id, percentage);

        //}

        public static bool apply_skill_eff_to(long cur_clock_tm, IBaseUnit from, IBaseUnit target, tres_conf sk_res, int aff, int skill_id, int percentage)
        {

            var dflag = true;
            if (target.isdie() || target.isghost())
            {
                // TO DO : 考虑有些技能能作用于尸体
                if (dflag) Utility.debug(" !apply_skill_eff_to  false 1");
                return false;
            }

            if (target.ignore_dmg())
            {
                if (dflag) Utility.debug(" !apply_skill_eff_to  false 2");
                return false;
            }

            //if ( "rate" in sk_res )
            if (sk_res.rate > 0)
            {
                if (Utility.random(0, 100) > sk_res.rate)
                {
                    if (dflag) Utility.debug(" !apply_skill_eff_to  false 3");
                    return false;
                }
            }

            var to_pl = target.get_pack_data();
            var frm_pl = from.get_pack_data();

            //var rpc_data = new Variant();
            //rpc_data["hited"] = 3;
            //rpc_data["sid"] = skill_id;
            //rpc_data["frm_iid"] = frm_pl.iid;
            //rpc_data["to_iid"] = to_pl.iid;

            if (target.has_state(pl_state_type.PST_SKILL_AVOID))
            {
                // 目标技能免疫
                // send single_skill_res msg to clients
                //rpc_data["hited"] = 0;//免疫
                //target.broad_cast_zone_msg_and_self(22, rpc_data);
                if (dflag) Utility.debug(" !apply_skill_eff_to  false 4");
                return false;
            }

            //if(from.get_sprite_type() == map_sprite_type.MST_MONSTER && target.get_sprite_type() == map_sprite_type.MST_MONSTER)
            //{
            //    return false; // 一家人不打一家人
            //}

            // TO DO : 根据aff判断敌人、盟友关系从而确定是否受此状态影响

            game_err_code check_res = Utility.check_target_type(from, target, aff, target.gmap.pk_seting);
            if (check_res != game_err_code.RES_OK)
                return false;

            if (from.get_sprite_type() == map_sprite_type.MstPlayer)
            {
                if (target.can_atk(from))
                {
                    target.atk_by(from);
                }
            }

            //if(sk_res.hp_dmg != 0)
            //{
            //    rpc_data.hp_dmg <- {};
            //    rpc_data.hp_dmg.hp_dmg <- sk_res.hp_dmg;

            //    to_pl.hp -= sk_res.hp_dmg;

            //    if(to_pl.hp > to_pl.max_hp)
            //    {
            //        to_pl.hp = to_pl.max_hp;
            //    }
            //}
            //if(sk_res.mp_dmg != 0)
            //{
            //    rpc_data.mp_dmg <- {};
            //    rpc_data.mp_dmg.mp_dmg <- sk_res.mp_dmg;

            //    to_pl.mp -= sk_res.mp_dmg;

            //    if(to_pl.mp > to_pl.max_mp)
            //    {
            //        to_pl.mp = to_pl.max_mp;
            //    }
            //}

            Utility.debug("apply_skill_eff_to try apply_dmg_on_pl!");

            //no_dmg  不计算伤害
            if (sk_res.no_dmg == 0)
            {
                var ret = grid_map.apply_dmg_on_pl(target, from, sk_res.convert2damage(), cur_clock_tm, percentage, true);
                Utility.debug("!apply_skill_eff_to apply_dmg_on_pl:" + ret);
                if (ret["hited"]._int32 != 3)
                {
                    // 未命中
                    // send single_skill_res msg to clients
                    //rpc_data["hited"] = ret["hited"];
                    //target.broad_cast_zone_msg_and_self(22, rpc_data);
                    if (dflag) Utility.debug(" !apply_skill_eff_to  false 20");
                    return false;
                }
            }


            //sys.trace(sys.SLT_DETAIL, "sk_res.rmv_stat ["+sk_res.rmv_stat+"]\n");

            if (sk_res.rmv_stat > 0)
            {
                int rmv_stat = sk_res.rmv_stat;

                if (to_pl.states != null)
                {
                    //sys.dumpobj(to_pl.states);
                    // 移除所有状态
                    rmv_stat_from_pl_by_gb(rmv_stat, target, to_pl);
                }
            }

            if (sk_res.rmv_1stat > 0)
            {
                if (to_pl.states != null)

                {
                    // 移除一个状态
                    rmv_1stat_from_pl_by_gb(sk_res.rmv_1stat, target, to_pl);
                }
            }

            if (sk_res.tar_state > 0)
            {
                int tar_state = sk_res.tar_state;
                var add_stat = true;
                if (sk_res.stat_rat > 0)
                {
                    // 有几率触发技能效果
                    var judg = Utility.random(0, 100);
                    if (judg > sk_res.stat_rat)
                    {
                        //sys.trace(sys.SLT_DETAIL, "stat_rat["+sk_res.stat_rat+"] < judg["+judg+"]\n");
                        if (dflag) Utility.debug(" !apply_skill_eff_to  false 21");
                        add_stat = false;
                    }
                }

                if (add_stat)
                {
                    // add state eff to character
                    var state_obj = add_state_to_pl(cur_clock_tm, target, sk_res, from, percentage);
                    if (state_obj != null)
                    {
                        // rpc_data.states < -state_obj;
                        //rpc_data.states <- {};
                        //rpc_data.states.id <- state_obj.id;
                        //rpc_data.states.par <- state_obj.par;
                        //rpc_data.states.start_tm <-state_obj.start_tm;
                        //rpc_data.states.end_tm <- state_obj.end_tm;
                    }
                }
            }

            if (sk_res.cd_red != null)
            {
                // 减少cd
                //var skcds = [];

                foreach (var cd_red in sk_res.cd_red)
                {
                    int sktp = cd_red.sktp;
                    int cd_reduce = (cd_red.red_tm * percentage / 10);
                    if (sktp == 0)
                    {


                        foreach (int sk_key in to_pl.skill_cd.Keys)
                        {
                            //cd -= (sk_res.cd_red.red_tm * 100 * per / 1000);
                            to_pl.skill_cd[sk_key] -= cd_reduce;

                            //skcds.push({ sktp = sktp, cdtm = cd - cur_clock_tm});
                        }
                    }
                    else if (to_pl.skill_cd.ContainsKey(sktp))
                    {
                        to_pl.skill_cd[sktp] -= cd_reduce;

                        //skcds.push({ sktp = cd_red.sktp, cdtm = to_pl.skill_cd[cd_red.sktp] - cur_clock_tm});
                    }
                }

                //        if (skcds.len() > 0)
                //        {
                //// send self_attchange msg
                //::send_rpc(to_pl.sid, 32, { skcds = skcds});
                //        }
            }

            if (!to_pl.cfmv)
            {
                if (sk_res.fmv != null)
                {
                    var judge = Utility.random(0, 100);
                    int fmv_rate = sk_res.fmv.rate;
                    int fmv_dir = sk_res.fmv.dir;
                    int fmv_rang = sk_res.fmv.rang;
                    if (judge < fmv_rate)
                    {
                        var dir = fmv_dir;
                        if (dir == 2)
                        {//随机前后
                            dir = Utility.random(0, 2);
                        }
                        // 迫使目标移动
                        if (dir == 0)
                        {
                            // 远离自己的方向
                            var dist_x = to_pl.x - frm_pl.x;
                            var dist_y = to_pl.y - frm_pl.y;

                            if ((dist_x != 0) || (dist_y != 0))
                            {
                                var vec = Utility.normalize_vec2(dist_x, dist_y);

                                var from_x = to_pl.x;
                                var from_y = to_pl.y;
                                to_pl.x += (int)(vec.x * fmv_rang);
                                to_pl.y += (int)(vec.y * fmv_rang);

                                var dest_pos = target.gmap.valpoint_on_vector(to_pl.x, to_pl.y, from_x, from_y, vec);

                                var to_grid_pos = target.gmap.get_grid_by_pt(dest_pos.x, dest_pos.y);
                                //if(!to_grid_pos || (dest_pos.x < 0) || (dest_pos.y < 0))
                                //{
                                //    // 目标坐标非法,出错
                                //    Utility.trace_err("fmv frm_pl.x["+frm_pl.x+"] frm_pl.y["+frm_pl.y+"] from_x["+from_x+"] y["+from_y+"] to_pl.x["+to_pl.x+"] to_pl.y["+to_pl.y+"] dest_pos.x["+dest_pos.x+"] dest_pos.y["+dest_pos.y+"] vec:\n");
                                //    sys.dumpobj(vec);
                                //}

                                to_pl.x = (int)dest_pos.x;
                                to_pl.y = (int)dest_pos.y;

                                //sys.trace(sys.SLT_DETAIL, "fmv to_pl.x["+to_pl.x+"] ["+to_pl.y+"]\n");

                                if (target.get_sprite_type() == map_sprite_type.MstPlayer && !target.is_in_lvl)
                                {
                                    to_pl.lx = to_pl.x;
                                    to_pl.ly = to_pl.y;
                                }
                            }
                        }
                        else if (dir == 1)
                        {
                            // 靠近自己的方向
                            var dist_x = frm_pl.x - to_pl.x;
                            var dist_y = frm_pl.y - to_pl.y;

                            if ((dist_x != 0) || (dist_y != 0))
                            {
                                var dist2 = dist_x * dist_x + dist_y * dist_y;
                                var vec = Utility.normalize_vec2(dist_x, dist_y);

                                if (fmv_rang == 0 || fmv_rang * fmv_rang >= dist2)
                                {
                                    // 拉近到自己身边一格
                                    var from_x = to_pl.x;
                                    var from_y = to_pl.y;

                                    to_pl.x = (int)(frm_pl.x - vec.x * game_const.map_grid_pixel);
                                    to_pl.y = (int)(frm_pl.y - vec.y * game_const.map_grid_pixel);

                                    var dest_pos = target.gmap.valpoint_on_vector(to_pl.x, to_pl.y, from_x, from_y, vec);
                                    to_pl.x = (int)dest_pos.x;
                                    to_pl.y = (int)dest_pos.y;

                                    if (target.get_sprite_type() == map_sprite_type.MstPlayer && !target.is_in_lvl)
                                    {
                                        to_pl.lx = to_pl.x;
                                        to_pl.ly = to_pl.y;
                                    }
                                }
                                else
                                {
                                    var from_x = to_pl.x;
                                    var from_y = to_pl.y;
                                    to_pl.x += (int)(vec.x * fmv_rang);
                                    to_pl.y += (int)(vec.y * fmv_rang);

                                    var dest_pos = target.gmap.valpoint_on_vector(to_pl.x, to_pl.y, from_x, from_y, vec);
                                    to_pl.x = (int)dest_pos.x;
                                    to_pl.y = (int)dest_pos.y;

                                    if (target.get_sprite_type() == map_sprite_type.MstPlayer && !target.is_in_lvl)
                                    {
                                        to_pl.lx = to_pl.x;
                                        to_pl.ly = to_pl.y;
                                    }
                                }
                            }
                        }
                    }

                    if (to_pl.moving != null)
                    {
                        // 停止移动
                        //var data = { tm = cur_clock_tm, iid = to_pl.iid, x = to_pl.x, y = to_pl.y, face = to_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 to_pl.moving;
                        to_pl.moving = null;
                    }

                    to_pl.last_mvpts = null;

                    //rpc_data.fmv < - { to_x = to_pl.x, to_y = to_pl.y, dir = sk_res.fmv.dir};

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

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

            //var gmap = target.gmap;

            //if(to_pl.hp <= 0)
            //{
            //    // die!
            //    to_pl.hp = 0;
            //    target.die(from);

            //    rpc_data.isdie = true;
            //}

            // send single_skill_res msg to clients
            //gmap.broadcast_map_rpc(22, rpc_data);
            //target.broad_cast_zone_msg_and_self(22, rpc_data);

            return true;
        }
コード例 #4
0
ファイル: grid_map.cs プロジェクト: lizhongwow/SceneTest
    //当单位配置中 keepdist = 1 时,攻击时将尽量保持与目标间的距离为自己的攻击距离
    public static void update_keep_atk_range(IBaseUnit sprite, long tm_elasped_s)
    {
        var pl = sprite.get_pack_data();
        if (pl.atking == null)
        {
            return;
        }

        if (sprite.has_state(pl_state_type.PST_CANT_MOVE))
        {
            // can't move
            return;
        }

        var gmap = sprite.gmap;

        if (gmap.has_sprite_by_iid(pl.atking.tar_iid))
        {
            //Utility.trace_err("monster["+this.mondata.iid+"] atking tar_iid[" + this.mondata.atking.tar_iid +"] cur tm[" +cur_clock_tm+"] last_trace_tm ["+ last_trace_target_tm +"] \n");

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

            double dist_x = pl.x - tar_pl.x;
            double dist_y = pl.y - tar_pl.y;
            var dist2 = dist_x * dist_x + dist_y * dist_y;
            var dist = Math.Sqrt(dist2);
            var atk_rang2 = pl.atkrange * pl.atkrange;


            // 处于最佳攻击距离
            var best_atk_rang = pl.atkrange;
            if (dist.CompareTo(best_atk_rang) <= 0)
            {
                //Utility.trace_info("atk_trace stop:"+dist2+"="+atk_rang2+"\n");
                if (pl.moving != null)
                {
                    //// 停止移动
                    ////var cur_grid_pos  = {x=(pl.x/game_const.map_grid_pixel), y=(pl.y/game_const.map_grid_pixel)}
                    //var data = {tm=sys.clock_time()- pl.atking.trace_tm_left, iid=pl.iid, x=pl.x, y=pl.y, face=pl.face};
                    //// send stop move msg to clients
                    ////gmap.broadcast_map_rpc(10, data);
                    //sprite.broad_cast_zone_msg_and_self(10, data);

                    //delete pl.moving;
                    pl.moving = null;
                }
            }
            else
            {
                //if(dist > best_atk_rang)
                //{
                //    Utility.trace_info("atk_trace:"+dist+">"+best_atk_rang+"\n");
                //}
                //else if(dist < best_atk_rang)
                //{
                //    Utility.trace_info("atk_trace:"+dist+"<"+best_atk_rang+"\n");
                //}
                // 保持距离
                //var cur_pos = gmap.get_grid_by_pt(pl.x, pl.y);
                //var tar_pos = gmap.get_grid_by_pt(tar_pl.x, tar_pl.y);
                //var k = (best_atk_rang / dist);
                //var best_pos = {};
                //best_pos.x <- (tar_pos.x + (cur_pos.x - tar_pos.x) * k);
                //best_pos.y <- (tar_pos.y + (cur_pos.y - tar_pos.y) * k);

                // 计算和目标之间的角度atan(a),范围为[-PI/2, PI/2],为了获得整个圆周的范围,当(x<0)时角度为:PI+atan(a)
                /*      
                 *      |
                 * (-,-)|(+,-)
                 * -----O------>X
                 * (-,+)|(+,+)
                 *      |
                 *      \/Y
                 */
                double alpha = 0;
                if (dist != 0)
                {
                    alpha = Math.PI / 2;
                    if (dist_x != 0)
                    {
                        alpha = Math.Atan((dist_y / dist_x));
                        if (dist_x < 0)
                        {
                            alpha += Math.PI;
                        }
                    }
                    else if (dist_y < 0)
                    {
                        alpha = -Math.PI / 2;
                    }
                }
                //Utility.trace_info("atan("+dist_y+"/"+dist_x+"="+k+")="+alpha+"\n");
                // 在最佳攻击距离圈上选取最近可达点
                var new_pos = gmap.valpoint_on_round(tar_pl.x, tar_pl.y, best_atk_rang, alpha);
                if (new_pos != null)
                {
                    new_pos = gmap.get_grid_by_pt(new_pos.x, new_pos.y);
                    sprite._move_to(new_pos.x, new_pos.y);
                }
                //Utility.trace_info("keep range pos:("+tar_pos.x+","+tar_pos.y+","+best_atk_rang+")->("+new_pos.x+","+new_pos.y+")\n");
            }
        }
    }
コード例 #5
0
ファイル: grid_map.cs プロジェクト: lizhongwow/SceneTest
    public static void update_pl_follow_tracing(IBaseUnit sprite, long cur_clock_tm)
    {
        var pl = sprite.get_pack_data();
        if (pl.follow == null)
        {
            return;
        }

        if (sprite.has_state(pl_state_type.PST_CANT_MOVE))
        {
            // can't move
            return;
        }

        var gmap = sprite.gmap;

        if (gmap.map_sprites.ContainsKey(pl.follow.tar_iid))
        {
            _update_pl_tracing(sprite, pl.follow.ToVariant(), pl.follow.frang, pl.follow.trang, cur_clock_tm);
        }
        else
        {
            //delete pl.follow;
            pl.follow = null;
        }
    }
コード例 #6
0
ファイル: grid_map.cs プロジェクト: lizhongwow/SceneTest
    public static void update_pl_atk_tracing(IBaseUnit sprite, long cur_clock_tm)
    {
        // attack target

        // TO DO : 追击问题?
        // 追击情况下,攻击者的移动以被攻击者的位置为目标,当被攻击者移动时,攻击者的路径将随时变化,如何同步才能保证客户端与服务器位置同步且通信效率最优?

        var pl = sprite.get_pack_data();
        if (pl.atking != null)
        {
            return;
        }

        if (sprite.has_state(pl_state_type.PST_CANT_MOVE))
        {
            // can't move
            return;
        }

        var gmap = sprite.gmap;

        if (gmap.map_sprites.ContainsKey(pl.atking.tar_iid))
        {
            var atkrang = gmap.map_sprites[pl.atking.tar_iid].get_pack_data().size + pl.atkrange + pl.size;
            atkrang = atkrang * atkrang;
            _update_pl_tracing(sprite, pl.atking.ToVariant(), atkrang, atkrang, cur_clock_tm);
        }
        else
        {
            //delete pl.atking;
            pl.atking = null;
        }
    }
コード例 #7
0
ファイル: grid_map.cs プロジェクト: lizhongwow/SceneTest
    public static int update_pl_move(IBaseUnit sprite, long cur_clock_tm)
    {
        var pl = sprite.get_pack_data();

        bool dflag = true;

        if (pl.moving == null)
            return 0;


        //// for Debug...
        //if(sprite.get_sprite_type() == map_sprite_type.MstMonster)
        //{
        //    return;
        //}

        if (sprite.has_state(pl_state_type.PST_CANT_MOVE))
        {
            // can't move

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

            if (dflag) Utility.debug("update_pl_move pl_state_type.PST_CANT_MOVE!!");

            pl.moving = null;
            //delete pl.moving;
            return 0;
        }

        if (pl.moving.pts != null)
        {
            if (dflag) Utility.debug("update_pl_move pts  in pl.moving!!");
            return _update_pl_pt_move(sprite, cur_clock_tm);
        }

        return _update_pl_ori_move(sprite, cur_clock_tm);
    }
コード例 #8
0
ファイル: oldGrid_Map.cs プロジェクト: lizhongwow/SceneTest
        public cast_skill_res _cast_skill(long now, Dictionary<string, string> rpc, skill_type skill_type,
            IBaseUnit caster, IBaseUnit target, bool precast = false, Point2D to_pos = null)
        {
            if (caster.isghost())
                return new cast_skill_res() { res = game_err_code.YOU_ARE_GHOST };

            IMapUnit pl = caster.get_pack_data();
            if (pl.atking != null)
                return new cast_skill_res() { res = game_err_code.SKIL_ALREADY_CASTING_SKILL };

            if (pl.jumping != null)
                return new cast_skill_res(game_err_code.SKIL_CANT_CAST_WHEN_JUMP);

            int skill_id = Convert.ToInt32(rpc["sid"]);


            if (pl.holding != null && pl.holding.sid != skill_id)
                return new cast_skill_res(game_err_code.SKIL_ALREADY_HOLDING_SKILL);

            skill_conf skillConf = Utility.GetSkillConf(skill_id);
            if (skillConf == null)
                return new cast_skill_res(game_err_code.SKIL_NOT_EXIST);

            if (!skillConf.igccstate)
            {
                if (caster.has_state(pl_state_type.PST_CANT_CAST_SKILL))
                    return new cast_skill_res(game_err_code.SKIL_CANT_CAST);
            }

            if (skillConf.tar_tp != (int)skill_type)
                return new cast_skill_res(game_err_code.SKIL_CAST_TARGET_TYPE_ERR);

            int skill_level = caster.get_skil_data(skill_id);
            if (skill_level <= 0)
            {
                skill_level = this.get_map_skill(skill_id);
                if (skill_level <= 0)
                    return new cast_skill_res(game_err_code.SKIL_NOT_LEARN);
            }

            if (target != null)
            {
                IMapUnit tar_pl = target.get_pack_data();
                if (tar_pl.invisible > pl.invisible)
                    return new cast_skill_res(game_err_code.SKIL_TARGET_NOT_AVALIBLE);

                if (skillConf.tar_tp == (int)skill_type.ST_TARGET)
                {
                    if (caster.iid != target.iid)
                    {
                        if (!skillConf.Is_Target_Enermy())
                        {
                            if (caster.can_atk(target))
                                return new cast_skill_res(game_err_code.SKIL_INVALIDE_TAREGET);

                            bool isaly = caster.isaily(target);
                            if (isaly)
                            {
                                if (!skillConf.Is_Target_ALAI())
                                    return new cast_skill_res(game_err_code.SKIL_INVALIDE_TAREGET);
                            }
                            else
                            {
                                if (!skillConf.Is_Target_MID())
                                    return new cast_skill_res(game_err_code.SKIL_INVALIDE_TAREGET);
                            }
                        }
                        else if (caster.Is_Player())
                        {
                            if (target.Is_Player())
                            {
                                if (this.pk_seting == map_pk_setting_type.MPST_PEACE)
                                    return new cast_skill_res(game_err_code.CANT_PK_IN_PEACE_MAP);

                                if (pl.in_pczone || tar_pl.in_pczone)
                                    return new cast_skill_res(game_err_code.CANT_PK_IN_PEACE_ZONE);

                                if (this.pk_seting == map_pk_setting_type.MPST_NORMAL)
                                {
                                    if (!target.can_atk_direct())
                                        if (!caster.can_atk(target))
                                            return new cast_skill_res(game_err_code.NULL);
                                }
                                else
                                {
                                    if (!caster.can_atk(target))
                                        return new cast_skill_res(game_err_code.NULL);
                                }
                            }
                            else if (target.Is_Monster())
                            {
                                if (target.owner_ply != null)
                                {
                                    IBaseUnit owner_sprite = target.owner_ply;
                                    IMapUnit owner_pl = owner_sprite.get_pack_data();

                                    if (owner_sprite.iid == caster.iid)
                                        return new cast_skill_res(game_err_code.CANT_ATTACK_SELF_PET);

                                    if (this.pk_seting == map_pk_setting_type.MPST_PEACE)
                                        return new cast_skill_res(game_err_code.CANT_PK_IN_PEACE_MAP);

                                    if (pl.in_pczone || owner_pl.in_pczone)
                                        return new cast_skill_res(game_err_code.CANT_PK_IN_PEACE_ZONE);

                                    if (this.pk_seting == map_pk_setting_type.MPST_NORMAL)
                                    {
                                        if (!owner_sprite.can_atk_direct())
                                            if (!caster.can_atk(owner_sprite))
                                                return new cast_skill_res(game_err_code.NULL);
                                    }
                                    else
                                    {
                                        if (!caster.can_atk(owner_sprite))
                                            return new cast_skill_res(game_err_code.NULL);
                                    }
                                }
                                else
                                {
                                    if (!caster.can_atk(target))
                                        return new cast_skill_res(game_err_code.NULL);
                                }
                            }
                            else
                            {
                                if (!skillConf.Is_Target_SELF())
                                    return new cast_skill_res(game_err_code.SKIL_INVALIDE_TAREGET);
                            }
                        }
                    }
                }
            }

            skill_lv_conf skill_level_conf = skillConf.GetSkillLevelConf(skill_level);
            if (null == skill_level_conf)
                return new cast_skill_res(game_err_code.SKIL_LVL_ERR);

            if (caster.Is_Skill_In_CD(skill_id, now))
                return new cast_skill_res(game_err_code.SKIL_CD_NOT_REACH);

            if (pl.moving != null)
                update_pl_move(caster, now);

            int cast_rang = pl.size + pl.atkrange;
            if (skillConf.cast_rang > 0)
                cast_rang += skillConf.cast_rang;

            if (to_pos != null)
            {
                if (target != null)
                {
                    cast_rang += target.get_pack_data().size;
                    if (target.get_pack_data().moving != null)
                        update_pl_move(target, now);
                }

                if (skill_level_conf.jump == null && skill_level_conf.teleport == null)
                {
                    double d_x = to_pos.x - caster.x;
                    double d_y = to_pos.y - caster.y;
                    long rang = cast_rang + 45;
                    if (d_x * d_x + d_y * d_y > rang * rang)
                        return new cast_skill_res(game_err_code.SKIL_CAST_RANG_ERR);
                }
            }

            if (precast && skillConf.cast_tm > 0)
            {
                pl.moving = null;

                pl.casting = new casting() { end_tm = now + skillConf.cast_tm * 100, tar_tp = (int)skill_type, rpc = rpc };

                return new cast_skill_res(game_err_code.RES_OK);
            }

            if (skillConf.hold_tm < 0)
            {
                if (pl.holding != null)
                    pl.holding = null;
                else
                {
                    pl.moving = null;

                    pl.holding = new holding() { tar_tp = (int)skill_type, rpc = rpc, start_tm = now, end_tm = now + skillConf.hold_tm * 100 };

                    return new cast_skill_res(game_err_code.RES_OK);
                }
            }

            if (pl.invisible > 0)
            {
                oldSkill.rmv_state_from_pl_by_att("invisible", caster);
            }

            caster.Set_Skill_CD(skill_id, now, now + skillConf.cd_tm * 100);

            cast_skill_res res = new cast_skill_res(game_err_code.RES_OK);
            res.rpc_data = new Dictionary<string, string>();

            if (to_pos != null)
            {
                if (skill_level_conf.teleport != null)
                {
                    pl.moving = null;
                    pl.last_mvpts = null;

                    Point2D t_point = Utility.valpoint_on_line(caster, to_pos, skill_level_conf.teleport.rang);

                    if (skill_level_conf.teleport.tm <= 0)
                    {
                        caster.x = (int)t_point.x;
                        caster.y = (int)t_point.y;
                    }
                    else
                    {
                        pl.teleping = new teleping()
                        {
                            dest_x = (int)t_point.x,
                            dest_y = (int)t_point.y,
                            end_tm = now + skill_level_conf.teleport.tm * 100,
                            percent = 100,
                            rpc = rpc,
                            start_tm = now,
                            telep = skill_level_conf.teleport
                        };
                    }
                }
                else if (skill_level_conf.jump != null)
                {
                    pl.moving = null;
                    pl.last_mvpts = null;

                    int sub_len = 0;
                    if (target != null)
                        sub_len = 45;

                    Point2D dest_pos = Utility.valpoint_on_line(caster, to_pos, skill_level_conf.jump.rang, sub_len);

                    double dist_x = dest_pos.x - caster.x;
                    double dist_y = dest_pos.y - caster.y;
                    double rang = Math.Sqrt(dist_x * dist_x + dist_y * dist_y);

                    int jump_tm = (int)(rang * 1000 / skill_level_conf.jump.speed);
                    if (jump_tm <= 0)
                        jump_tm = 1;

                    pl.jumping = new jumping()
                    {
                        dest_x = (int)dest_pos.x,
                        dest_y = (int)dest_pos.y,
                        during_tm = jump_tm,
                        end_tm = now + jump_tm,
                        start_tm = now,
                        jump = skill_level_conf.jump,
                        percent = 100,
                        rpc = rpc,
                        tar_iid = (target == null) ? 0 : target.iid,
                    };

                }


            }

            return res;
        }