예제 #1
0
    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;
    }
예제 #2
0
        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;
        }