コード例 #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
ファイル: skills.cs プロジェクト: lizhongwow/SceneTest
        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
ファイル: 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
    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);
            //    }
        }
    }
コード例 #5
0
ファイル: grid_map.cs プロジェクト: lizhongwow/SceneTest
    public cast_skill_res _cast_skill(long cur_clock_tm, Variant rpc, skill_type tar_tp, IBaseUnit caster, IPoint2D to_pos, IBaseUnit tar_sprite, bool precast)
    {
        var cur_tm_s = DateTime.Now.ToBinary();

        if (caster.isghost())
            return new cast_skill_res(game_err_code.YOU_ARE_GHOST);

        var pl = caster.get_pack_data();
        if (pl.casting != null)
            return new cast_skill_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 = rpc["sid"]._int32;
        //有聚气状态  使用任何技能 将触发它
        if (pl.holding != null && skill_id != pl.holding.rpc["sid"]._int32)
            return new cast_skill_res(game_err_code.SKIL_ALREADY_HOLDING_SKILL);

        var skill_data = Utility.get_skil_skill_desc(skill_id);
        if (skill_data == null)
            return new cast_skill_res(game_err_code.SKIL_NOT_EXIST);

        if (skill_data.tar_tp != (int)tar_tp)
        {
            // Err: skill target type wrong         
            return new cast_skill_res(game_err_code.SKIL_CAST_TARGET_TYPE_ERR);
        }

        // check caster own the skill and get skill level
        var caster_skil_data = caster.get_skil_data(skill_id);
        if (caster_skil_data == null)
        {
            caster_skil_data = this.get_map_skill(skill_id);
            if (caster_skil_data == null)
            {
                return new cast_skill_res(game_err_code.SKIL_NOT_LEARN);
            }
        }

        if (tar_sprite != null)
        {
            var tar_pl = tar_sprite.get_pack_data();
            if (tar_pl.invisible > pl.observer)
            {
                // 看不到目标             
                return new cast_skill_res(game_err_code.SKIL_TARGET_NOT_AVALIBLE);
            }

            if (skill_data.tar_tp == (int)skill_type.ST_TARGET)
            {
                game_err_code check_res = Utility.check_target_type(caster, tar_sprite, skill_data.aff, this.pk_seting);
                if (check_res != game_err_code.RES_OK)
                    return null;
            }
        }

        var skill_level_conf = Utility.get_skil_skill_lvl_desc(skill_id, caster_skil_data.sklvl);
        if (skill_level_conf == null)
        {
            // Err: skill data error          
            Utility.trace_err("persist_game cast skill monster iid[" + pl.iid + "] skill [" + skill_id + "] sklvl[" + caster_skil_data.sklvl + "]  data error\n");
            return new cast_skill_res(game_err_code.SKIL_LVL_ERR);
        }

        if (cur_clock_tm < pl.skill_gen_cd)
        {
            //Utility.trace_err("persist_game cast skill caster [" + caster.get_iid() +"] skill ["+rpc.sid+"] cd not reach\n");         
            return new cast_skill_res(game_err_code.SKIL_CD_NOT_REACH);
        }


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

        // rang check
        var cast_rang = pl.size + pl.atkrange;
        cast_rang += skill_data.cast_rang;

        if (to_pos != null)
        {
            if (tar_sprite != null)
            {
                var tar_pl = tar_sprite.get_pack_data();
                cast_rang += tar_pl.size;
                if (tar_pl.moving != null)
                    update_pl_move(tar_sprite, cur_clock_tm);
            }

            if (skill_level_conf.jump == null && skill_level_conf.teleport == null)
            {
                // 近战技能
                var dist_x = to_pos.x - pl.x;
                var dist_y = to_pos.y - pl.y;
                var rang = cast_rang + 45; // 允许1格误差
                if (dist_x * dist_x + dist_y * dist_y > rang * rang)
                {
                    //Utility.trace_err("persist_game cast skill caster [" + caster.get_iid() +"] skill ["+rpc.sid+"] ground skill out of rang\n");                 
                    return new cast_skill_res(game_err_code.SKIL_CAST_RANG_ERR);
                }
            }
        }

        // 计算吟唱时间
        if (precast && skill_data.cast_tm > 0)
        {
            var cast_tm = skill_data.cast_tm;
            var mul = 0;
            var add = 0;



            cast_tm = (cast_tm * 1000 / (1000 + mul) - add);
            //Utility.trace_info("cast_tm:["+cast_tm+"] \n");

            if (cast_tm > 0)
            {
                // 需要吟唱
                pl.moving = null;

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

                return new cast_skill_res(game_err_code.RES_OK);
            }
        }

        var hold_per = 1;
        if (skill_data.hold_tm > 0)
        {
            var hold_tm = skill_data.hold_tm;
            if (pl.holding != null)
            {
                hold_per = (int)(cur_clock_tm - pl.holding.start_tm) / (hold_tm * 100);
                if (hold_per > 1) hold_per = 1;

                pl.holding = null;
            }
            else
            {
                pl.moving = null;

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

                return new cast_skill_res(game_err_code.RES_OK);
            }
        }

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

        var cd_tm = skill_level_conf.cd;
        var cdmul = 0;

        cd_tm = (cd_tm * 1000 / (1000 + cdmul));
        if (cd_tm < 2) cd_tm = 2;
        //Utility.trace_info("cd_tm:["+cd_tm+"] \n");


        pl.skill_gen_cd = cur_clock_tm + cd_tm * 100;
        pl.skill_gen_cdst = cur_clock_tm;

        //Utility.trace_err("persist_game cast self skill caster [" + caster.get_iid() +"] skill ["+rpc.sid+"] cd ["+pl.skill_cd[skill_data.cdtp]+"]\n");


        var percent = 1000;


        percent = (percent * hold_per);
        if (percent <= 0) percent = 1;

        Variant rpc_data = new Variant();
        rpc["res"] = (int)game_err_code.RES_OK;
        rpc["start_tm"] = rpc["start_tm"];
        rpc["frm_iid"] = pl.iid;
        rpc["sid"] = rpc["sid"];

        cast_skill_res cast_skill_res = new cast_skill_res(game_err_code.RES_OK)
        {
            skill_data = skill_data,
            skill_level_conf = skill_level_conf,
            rpc_data = rpc_data,
            percent = percent
        };

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

                var telep_tm = 0;

                telep_tm = skill_level_conf.teleport.tm * 100;

                var dest_pos = Utility.valpoint_on_line(pl, to_pos, skill_level_conf.teleport.rang);

                if (telep_tm == 0)
                {//立即
                    pl.x = (int)dest_pos.x;
                    pl.y = (int)dest_pos.y;

                    if (caster.get_sprite_type() == map_sprite_type.MstPlayer && !caster.is_in_lvl)
                    {
                        pl.lx = pl.x;
                        pl.ly = pl.y;
                    }
                }
                else
                {
                    pl.teleping = new teleping()
                    {
                        start_tm = cur_clock_tm,
                        end_tm = (cur_clock_tm + telep_tm),
                        telep = skill_level_conf.teleport,
                        rpc = rpc,
                        percent = percent,
                        dest_x = (int)dest_pos.x,
                        dest_y = (int)dest_pos.y
                    };
                }
                //rpc_data.telep < - { to_x = dest_pos.x, to_y = dest_pos.y, tm = telep_tm};
            }
            else if (skill_level_conf.jump != null)
            {
                // 跳跃
                pl.moving = null;
                pl.last_mvpts = null;

                var sub_len = 0;
                if (tar_sprite != null)
                {
                    sub_len = 45;
                }

                var dest_pos = Utility.valpoint_on_line(pl, to_pos, skill_level_conf.jump.jump_rang, sub_len);

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

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

                //pl.x = dest_pos.x;
                //pl.y = dest_pos.y;

                rpc_data["jump"] = new Variant();
                rpc_data["jump"]["tm"] = jump_tm;
                rpc_data["jump"]["to_x"] = dest_pos.x;
                rpc_data["jump"]["to_y"] = dest_pos.y;

                var tar_iid = 0;
                if (tar_sprite != null)
                    tar_iid = tar_sprite.get_pack_data().iid;

                pl.jumping = new jumping()
                {
                    start_tm = cur_clock_tm,
                    during_tm = jump_tm,
                    end_tm = (cur_clock_tm + jump_tm),
                    jump = skill_level_conf.jump,
                    rpc = rpc,
                    percent = percent,
                    dest_x = (int)dest_pos.x,
                    dest_y = (int)dest_pos.y,
                    tar_iid = tar_iid
                };
            }


            //    if ("fly" in  skill_level_conf && skill_level_conf.fly.speed > 0)
            //{
            //        var dest_pos = { x = to_pos.x, y = to_pos.y };
            //        var dist_x = dest_pos.x - pl.x;
            //        var dist_y = dest_pos.y - pl.y;
            //        var rang = Math.Sqrt(dist_x * dist_x + dist_y * dist_y);
            //        if ("toend" in skill_level_conf.fly )
            //    {
            //            var max_rang = skill_level_conf.fly.rang + cast_rang;
            //            dest_pos.x = (dist_x * max_rang / rang + pl.x);
            //            dest_pos.y = (dist_y * max_rang / rang + pl.y);

            //            rang = max_rang;
            //        }

            //        var fly_tm = (rang * 1000 / skill_level_conf.fly.speed);
            //        var fly_end_tm = cur_clock_tm + fly_tm;

            //        var tar_iid = 0;
            //        if (tar_sprite) tar_iid = tar_sprite.get_pack_data().iid;

            //        // 记录飞行道具
            //        this.map_flys.push({ end_tm = fly_end_tm, frm_iid = pl.iid, rpc = rpc, cast_skill_res = cast_skill_res, tar_iid = tar_iid, frm_pos ={ x = pl.x, y = pl.y}, target_pos = dest_pos});

            //        rpc_data.fly < - { tm = fly_tm, to_x = dest_pos.x, to_y = dest_pos.y};
            //    }
        }
        //::g_dump( "cast_skill_res OK:", cast_skill_res );
        return cast_skill_res;
    }
コード例 #6
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;
        }