Exemple #1
0
        public static void _update_pl_tracing(IBaseUnit sprite, Tracing trace, int frang, int trang, int cur_clock_tm)
        {
            bool can_reach = true;

            IMapUnit pl = sprite.get_pack_data();

            if (trace.trace_tm_left > 0 || cur_clock_tm - sprite.last_trace_target_tm > 500)
            {

            }
        }
Exemple #2
0
    public IBaseUnit new_pet_mon(IBaseUnit ply, map_mon_conf monconf)
    {
        // 分配战斗宠物实例
        IBaseUnit mon = null;
        IMapUnit mondata = null;

        List<IBaseUnit> list = null;
        this.petmon_cache.TryGetValue(monconf.mid, out list);

        if (list == null || list.Count <= 0)
        {
            mon = this.create_monster_byconf(monconf);
            if (mon == null)
            {
                Utility.trace_err("Err: in map [" + this.mapid + "] add_pet_mon mid [" + monconf.mid + "] create error!\n");
                return mon;
            }

            mon.gmap = this;

            mondata = mon.get_pack_data();
            this.map_mons[mondata.iid] = mon;
            this.map_sprites[mondata.iid] = mon;

            list = null;
            if (this.map_mon_bymid.TryGetValue(mondata.mid, out list))
                list.Add(mon);
            else
            {
                list = new List<IBaseUnit>();
                list.Add(mon);
                this.map_mon_bymid[mondata.mid] = list;
            }
        }
        else
        {
            mon = list.pop<IBaseUnit>();
            mondata = mon.get_pack_data();
        }

        IMapUnit pl = ply.get_pack_data();
        var ply_grid = this.get_grid_by_pt(pl.x, pl.y);
        mondata.org_init_x = (int)ply_grid.x;
        mondata.org_init_y = (int)ply_grid.y;
        mon.owner_ply = ply;
        mondata.owner_cid = pl.cid;
        mon.respawn(100, false);

        //var dest_pos = line_find_canwalk_grid(ply_grid.x, ply_grid.y, 3, 9);
        //mon._move_to(dest_pos.x, dest_pos.y);

        return mon;
    }
Exemple #3
0
        public bool isaily(IBaseUnit spr)
        {
            if (spr.get_sprite_type() == map_sprite_type.MstMonster && spr.owner_ply != null)
                spr = spr.owner_ply; // 用主人代替宠物检查敌我关系

            IMapUnit pl = spr.get_pack_data();
            if (pl.iid == this.pinfo.iid)
                return true;

            if (pl.lvlsideid != 0 && pinfo.lvlsideid == pl.lvlsideid)
                return true;

            if (pl.teamid == 0 || pinfo.teamid == 0)
                return false;

            if (pl.teamid == pinfo.teamid)
                return true;

            if (pl.clanid == 0 || pinfo.clanid == 0)
                return false;

            if (pl.clanid == pinfo.clanid)
                return true;

            return false;
        }
Exemple #4
0
        public void die(IBaseUnit killer)
        {
            if (this.dying)
            {
                return;
            }
            this.dying = true;

            long cur_clock_tm = DateTime.Now.ToBinary();
            // 尝试触发死亡ai动作
            this._trig_dying_act(cur_clock_tm);

            // TO DO : player die

            // 中断打坐
            //this.try_stop_recover();

            this.respawn_tm = cur_clock_tm + 30000; // 30 秒后安全复活
            this.pinfo.isdie = true;
            pinfo.atking = null;
            pinfo.moving = null;

            if (pinfo.states != null)
            {
                bool _remark_pl_state = false;
                if (this.pinfo.states.state_par.Count > 0)
                {
                    for (var idx = 0; idx < this.pinfo.states.state_par.Count; ++idx)
                    {
                        var val = this.pinfo.states.state_par[idx];
                        if (val.desc.die_keep == 1)
                            continue;

                        this.pinfo.states.state_par.RemoveAt(idx);
                        --idx;
                        _remark_pl_state = true;
                    }
                }

                //pinfo.states.state = 0;
                //pinfo.states.mov_spd_mul = 1.0;
                //pinfo.states.atk_spd_mul = 1.0;
                //pinfo.states.mp2hp = 0;
                //pinfo.states.dmglnkper = 0;
                //re_calc_cha_data();
                if (_remark_pl_state)
                    Skill._remark_pl_state(this, pinfo);
            }

            if (pinfo.jumping != null)
            {
                // 跳跃中死亡,落在目标点
                pinfo.x = pinfo.jumping.dest_x;
                pinfo.y = pinfo.jumping.dest_y;

                if (!this.is_in_lvl)
                {
                    pinfo.lx = pinfo.x;
                    pinfo.ly = pinfo.y;
                }

                pinfo.jumping = null;
            }

            if (gmap != null)
            {
                if (gmap.blvlmap)
                {
                    //if (this.gmap.worldsvr.is_lvlmis_lvl())
                    //{
                    //    this.allow_respawn_tm = sys.clock_time() + 6000; // 侠客行副本中,必须6秒后复活
                    //}

                    this.gmap.worldsvr.on_ply_die(this);
                }
                else
                {
                    if (gmap.pk_seting != map_pk_setting_type.MPST_PK)
                    {//经验惩罚                       

                    }
                }

                if (killer != null && killer.get_sprite_type() == map_sprite_type.MstMonster)
                {
                    if (killer.owner_ply != null)
                    {
                        killer = killer.owner_ply; // 宠物击杀相当于玩家角色击杀
                    }
                }

                if (killer != null && killer.get_sprite_type() == map_sprite_type.MstPlayer)
                {
                    IMapUnit killer_pl = killer.get_pack_data();
                    //local pkdp = true;
                    if (!gmap.blvlmap)
                    {
                        // 添加仇敌
                        //_add_foes(this, killer.pinfo);

                        //计算pk值 
                        //是否为中立地图
                        if (gmap.pk_seting == map_pk_setting_type.MPST_NORMAL)
                        {
                            if (!this.can_atk_direct())
                            {
                                //自己为正义玩家
                                //sys.dumpobj( defend_tm_map );
                                //sys.trace( sys.SLT_ERR, "killer.pinfo.cid = " + killer.pinfo.cid + "sys.time()" + sys.time() + "\n")
                                int killer_cid = killer_pl.cid;
                                long defend_en_tm = 0;
                                long now_s = DateTime.Now.ToBinary();
                                defend_tm_map.TryGetValue(killer_cid, out defend_en_tm);
                                if (defend_en_tm > 0)
                                {
                                    //自己是正当防卫 则
                                    if (defend_en_tm >= now_s)
                                    {
                                        //增加对方pk值 
                                        int add_val = 1;
                                        int pkv = killer_pl.pk_v;
                                        if (pkv < 0)
                                        {//击杀者 有正义值 则清除
                                            add_val = 1 - pkv;
                                        }
                                        killer.add_pk_v(add_val);
                                    }
                                    else
                                    {
                                        defend_tm_map.Remove(killer_cid);
                                    }
                                }
                            }
                            else
                            {//可直接攻击的玩家
                                if (killer.is_justice())
                                {//击杀者 为正义玩家 降低PK值
                                    killer.sub_pk_v(1, true);
                                }
                            }
                        }
                        this.check_tsk_attribute(true);
                    }
                    else
                    {
                        // 在副本中
                        // 增加击杀值
                        killer_pl.kp++;
                        killer_pl.cur_kp++;

                        this.gmap.worldsvr.on_kp(killer, this);
                    }
                }

                // remove atking from atker
                // TO DO : 增加被锁定列表,死亡后清理被锁定列表中的对象的攻击信息即可
                foreach (var val in gmap.map_sprites.Values)
                {
                    val.on_spr_die(pinfo.iid);
                }
            }

            // 清理助攻列表
            if (this.kp_asist_rec)
            {
                this.beatk_ply_cids.Clear();
            }
        }
Exemple #5
0
        public bool can_atk(IBaseUnit spr)
        {
            if (null != this.owner_ply)
            {
                return this.owner_ply.can_atk(spr);
            }

            if (this.get_sprite_type() == map_sprite_type.MstMonster && null != spr.owner_ply)
                spr = spr.owner_ply;

            IMapUnit pl = spr.get_pack_data();
            if (pl.lvlsideid > 0)
                return this.mondata.lvlsideid != pl.lvlsideid;

            if (this.mondata.lvlsideid == 0 && spr.get_sprite_type() == map_sprite_type.MstMonster)
                return false;

            return true;
        }
Exemple #6
0
        public void ondmg(IBaseUnit atker, int dmg)
        {
            if (!this.shkilawd)
                return;

            if (this.get_sprite_type() == map_sprite_type.MstMonster)
                return;

            int cid = atker.get_pack_data().cid;
            if (this.dmglist.ContainsKey(cid))
                this.dmglist[cid] += dmg;
            else
            {
                this.dmglist[cid] = dmg;
            }

            this.lastdmgtm = DateTime.Now.ToBinary();
        }
Exemple #7
0
        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;
        }
Exemple #8
0
        public static int distance2(IBaseUnit a, IBaseUnit b)
        {
            IMapUnit ma = a.get_pack_data();
            IMapUnit mb = a.get_pack_data();

            if (ma == null || mb == null)
                return 0;

            return (int)(Math.Pow(ma.x - mb.x, 2) + Math.Pow(ma.y - mb.y, 2));
        }
Exemple #9
0
    public static void update_pl_atk(IBaseUnit sprite, long cur_clock_tm)
    {
        var pl = sprite.get_pack_data();
        if (pl.atking == null)
            return;

        var cd_tm = sprite.get_atk_cd();

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

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

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

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

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

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

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

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

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

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

        // TO DO : update face

        var tm_interval = cur_clock_tm - pl.atking.start_tm;

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

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

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

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

            return;
        }

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

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

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

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

                ++val.atkedcnt;

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

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

                //sys.dumpobj(val);

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

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

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

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

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

        tar_sprite.atk_by(sprite);

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

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

            return;
        }

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

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

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

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

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

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

        // send attack msg
        sprite.broad_cast_zone_msg_and_self(18, ret);
        if (tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer)
        {
            //目标不在视野  需要补发消息
            //    if (!sprite.is_ply_inzone(tar_pl.sid))
            //    {
            //::send_rpc(tar_pl.sid, 18, ret);
            //    }
        }
    }
Exemple #10
0
    //当单位配置中 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");
            }
        }
    }
Exemple #11
0
    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;
        }
    }
Exemple #12
0
    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;
        }
    }
Exemple #13
0
    public static bool _update_pl_tracing(IBaseUnit sprite, Variant trace, int frang, int trang, long cur_clock_tm)
    {
        var can_reach = true;

        var pl = sprite.get_pack_data();

        // 1秒搜索2次目标
        if (trace["trace_tm_left"]._int32 > 0 || cur_clock_tm - sprite.last_trace_target_tm > 500)
        {
            var target = sprite.gmap.map_sprites[trace["tar_iid"]._int32];
            var tar_pl = target.get_pack_data();

            double dist_x = pl.x - tar_pl.x;
            double dist_y = pl.y - tar_pl.y;
            double dist2 = dist_x * dist_x + dist_y * dist_y;

            if (dist2 > frang)
            {
                // 不在攻击范围,追击
                if (pl.speed > 0)
                {
                    Point2D cur_grid_pos = new Point2D()
                    {
                        x = (pl.x / game_const.map_grid_pixel),
                        y = (pl.y / game_const.map_grid_pixel)
                    };
                    Point2D tar_grid_pos = new Point2D()
                    {
                        x = (tar_pl.x / game_const.map_grid_pixel),
                        y = (tar_pl.y / game_const.map_grid_pixel)
                    };

                    var path = sprite.gmap.find_path(cur_grid_pos.x, cur_grid_pos.y, tar_grid_pos.x, tar_grid_pos.y);

                    // 在路径中删除当前格子
                    if (path != null && path.Count > 0)
                        path.pop();

                    if (path != null && path.Count > 0)
                    {
                        var i = 0;
                        for (; i < path.Count; ++i)
                        {
                            var pt = path[i];
                            var to_x = pt.x * game_const.map_grid_pixel + 16;
                            var to_y = pt.y * game_const.map_grid_pixel + 16;

                            dist_x = to_x - tar_pl.x;
                            dist_y = to_y - tar_pl.y;
                            if (dist_x * dist_x + dist_y * dist_y > trang)
                            {
                                break;
                            }
                        }

                        //Utility.trace_err("monster["+this.mondata.iid+"] trace tar_iid[" + trace.tar_iid +"] break on i[" +i+"]\n");

                        if (i == path.Count)
                        {
                            // TO DO : in attack range?
                            // 转化之后的格子坐标在攻击范围内,当前像素位置不在攻击范围之内!
                            var pt = path.pop();
                            path.Clear();
                            path.push(pt);
                        }
                        else if (i > 0)
                        {
                            path = path.slice(i - 1);
                        }
                        else
                        {
                            // 移动到路劲终点亦无法攻击对象?!
                            can_reach = false;
                        }

                        if (path.Count > 0 && (path[0].x.CompareTo(cur_grid_pos.x) > 0 || path[0].y.CompareTo(cur_grid_pos.y) > 0))
                        {
                            // 移动
                            var start_tm = cur_clock_tm - trace["trace_tm_left"]._int32;
                            //Utility.trace_err("sprite ["+pl.iid+"] trace tar_iid[" + trace.tar_iid +"] cur tm["+ cur_clock_tm +"] start tm[" +start_tm+"]\n");

                            pl.moving = new moving() { start_tm = start_tm, pts = path, to_x = path[0].x, to_y = path[0].y, float_x = (pl.x), float_y = (pl.y) };

                            //var data = {start_tm=pl.moving.start_tm, iid=pl.iid, frm_x=pl.x, frm_y=pl.y, to_x=path[0].x, to_y=path[0].y};
                            //// send move msg to clients
                            ////gmap.broadcast_map_rpc(9, data);
                            //sprite.broad_cast_zone_msg_and_self(9, data);
                        }
                    }
                    else
                    {
                        // TO DO : path not found?
                        // delete this.mondata.atking;
                        can_reach = false;
                    }
                }
            }
            // 在攻击范围,
            else if (dist2 <= trang)
            {
                // 在攻击范围,
                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=cur_clock_tm- trace.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;
                }
            }

            sprite.last_trace_target_tm = cur_clock_tm;
        }

        return can_reach;
    }
Exemple #14
0
    public bool is_player_in_pc_zone(IBaseUnit ply)
    {
        if (this.map_conf.pk_zone.Count <= 0)
            return false;

        IMapUnit pl = ply.get_pack_data();
        foreach (var z in map_conf.pk_zone)
        {
            if (pl.x > z.x && pl.x < z.x + z.width &&
                pl.y > z.y && pl.y < z.y + z.height)
            {
                return true;
            }
        }

        return false;
    }
Exemple #15
0
 public void release_pet_mon(IBaseUnit mon)
 {
     // 回收战斗宠物实例
     IMapUnit mondata = mon.get_pack_data();
     List<IBaseUnit> list = null;
     if (this.petmon_cache.TryGetValue(mondata.mid, out list))
         list.Add(mon);
     else
     {
         list = new List<IBaseUnit>();
         list.Add(mon);
         this.petmon_cache.Add(mondata.mid, list);
     }
 }
Exemple #16
0
        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;
        }
Exemple #17
0
        public static void apply_rang_eff(long cur_clock_tm, IBaseUnit from, IPoint2D center, List<tres_conf> sk_res, rang_conf trang, int sid, int per)
        {
            var gmap = from.gmap;
            var maxi = trang.maxi;
            if (maxi == 0)
                maxi = 0x7fffffff;
            int aff_count = 0;
            Utility.debug(" ================= apply_rang_eff ================= ");
            //var test_cost_tm = sys.clock_time();
            int cirang = trang.cirang;
            if (cirang > 0)
            {
                // 以center中心、cirang为半径的圆形区域
                var pow_range = cirang * cirang;
                //var inzoneplys = from.get_inz_plys(); 
                foreach (var val in gmap.map_players.Values)
                {
                    if (val.isdie() || val.isghost())
                    {
                        continue;
                    }

                    var pl_data = val.get_pack_data();

                    var dist_x = Math.Abs(pl_data.x - center.x);
                    if (dist_x > cirang)
                    {
                        Utility.debug("pow_range[" + pow_range + "] <= dist_x[" + dist_x + "]     center.x[" + center.x + "] , center.y[" + center.y + "] pl_data.x[" + pl_data.x + "] , pl_data.y[" + pl_data.y + "]");
                        continue; // 不在范围内
                    }

                    var dist_y = Math.Abs(pl_data.y - center.y);
                    if (dist_y > cirang)
                    {
                        Utility.debug("pow_range[" + pow_range + "] <= dist_y[" + dist_y + "]     center.x[" + center.x + "] , center.y[" + center.y + "] pl_data.x[" + pl_data.x + "] , pl_data.y[" + pl_data.y + "]");
                        continue; // 不在范围内
                    }
                    var rang1 = dist_x * dist_x + dist_y * dist_y;
                    if (rang1 > pow_range)
                    {
                        Utility.debug("pow_range[" + pow_range + "] <= rang1[" + rang1 + "]     center.x[" + center.x + "] , center.y[" + center.y + "] pl_data.x[" + pl_data.x + "] , pl_data.y[" + pl_data.y + "]");
                        continue;
                    }

                    var affed = false;
                    foreach (var tres in sk_res)
                    {
                        var ret = apply_skill_eff_to(cur_clock_tm, from, val, tres, tres.aff, sid, per);
                        if (ret)
                        {
                            affed = true;
                        }
                    }

                    if (affed)
                    {
                        ++aff_count;
                        if (aff_count >= maxi)
                        {
                            break;
                        }
                    }
                }
                if (aff_count < maxi)
                {
                    //var inzonemons = from.get_inz_mons(); 
                    foreach (IBaseUnit val in gmap.map_mons.Values)
                    {
                        if (val.isdie() || val.isghost())
                        {
                            continue;
                        }

                        var pl_data = val.get_pack_data();

                        var dist_x = Math.Abs(pl_data.x - center.x);
                        if (dist_x - pl_data.size > cirang) continue; // 不在范围内

                        var dist_y = Math.Abs(pl_data.y - center.y);
                        if (dist_y - pl_data.size > cirang) continue; // 不在范围内

                        var rang1 = Math.Sqrt(dist_x * dist_x + dist_y * dist_y);
                        if (rang1 - pl_data.size > cirang)
                        {
                            continue; // 不在范围内
                        }

                        var affed = false;
                        foreach (var tres in sk_res)
                        {
                            var ret = apply_skill_eff_to(cur_clock_tm, from, val, tres, tres.aff, sid, per);
                            if (ret)
                            {
                                affed = true;
                            }
                        }

                        if (affed)
                        {
                            ++aff_count;
                            if (aff_count >= maxi)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            else if (trang.fan != null)
            {
                int fan_angle = trang.fan.angle;
                int fan_rang = trang.fan.rang;
                // 以from为中心,center为目标,fan.rang为半径,fan.angle为角度的扇形区域
                var frm_pl = from.get_pack_data();
                var x1 = center.x - frm_pl.x;
                var y1 = center.y - frm_pl.y;
                var rang1 = x1 * x1 + y1 * y1;
                if (rang1 != 0)
                {
                    rang1 = Math.Sqrt(rang1);
                    var h_angle = Math.Cos(fan_angle / 360.0 * Math.PI);
                    var maxrange = fan_rang;
                    var pow_maxrange = maxrange * maxrange;
                    //var inzoneplys = from.get_inz_plys();  
                    foreach (var val in gmap.map_players.Values)
                    {
                        if (val.isdie() || val.isghost())
                        {
                            continue;
                        }

                        var pl_data = val.get_pack_data();
                        var x2 = pl_data.x - frm_pl.x;
                        if (Math.Abs(x2) >= maxrange) continue; // 不在范围内

                        var y2 = pl_data.y - frm_pl.y;
                        if (Math.Abs(y2) >= maxrange) continue; // 不在范围内

                        double rang2 = x2 * x2 + y2 * y2;
                        //sys.trace( sys.SLT_DETAIL, "x2 = " + x2 + "   y2 = " + y2 + "\n"  );
                        if (rang2 >= pow_maxrange)
                        {
                            continue; // 不在范围内
                        }

                        rang2 = Math.Sqrt(rang2);
                        var angleVal = (rang2 != 0) ? (x1 * x2 + y1 * y2) / (rang2 * rang1) : 1;
                        //sys.trace( sys.SLT_DETAIL, "apply_rang_eff rang2 = " + rang2 + "rang1 = " + rang1 + "\n"  );
                        //sys.trace( sys.SLT_DETAIL, "apply_rang_eff angleVal = " + angleVal + "h_angle = " + h_angle + "\n"  );
                        if (angleVal < h_angle)
                        {
                            continue;// 不在范围内
                        }

                        var new_per = per;
                        if (trang.fan.decay != null && trang.fan.decay.Count > 0)
                        {//衰减
                            var dist = rang2;
                            foreach (var decay in trang.fan.decay)
                            {
                                if (decay.min <= dist && decay.max > dist)
                                {
                                    new_per *= (int)(decay.per / 100.0);
                                    break;
                                }
                            }
                        }

                        var affed = false;
                        foreach (var tres in sk_res)
                        {
                            var ret = apply_skill_eff_to(cur_clock_tm, from, val, tres, tres.aff, sid, new_per);
                            if (ret)
                            {
                                affed = true;
                            }
                        }

                        if (affed)
                        {
                            ++aff_count;
                            if (aff_count >= maxi) break;
                        }
                    }
                    if (aff_count < maxi)
                    {
                        //var inzonemons = from.get_inz_mons(); 
                        foreach (IBaseUnit val in gmap.map_mons.Values)
                        {
                            if (val.isdie() || val.isghost())
                            {
                                continue;
                            }

                            var pl_data = val.get_pack_data();
                            var x2 = pl_data.x - frm_pl.x;
                            if (Math.Abs(x2) - pl_data.size >= maxrange) continue; // 不在范围内

                            var y2 = pl_data.y - frm_pl.y;
                            if (Math.Abs(y2) - pl_data.size >= maxrange) continue; // 不在范围内

                            var rang2 = Math.Sqrt(x2 * x2 + y2 * y2);
                            //sys.trace( sys.SLT_DETAIL, "x2 = " + x2 + "   y2 = " + y2 + "\n"  );
                            if (rang2 - pl_data.size >= maxrange)
                            {
                                continue; // 不在范围内
                            }

                            var angleVal = (rang2 != 0) ? (x1 * x2 + y1 * y2) / (rang2 * rang1) : 1;
                            //sys.trace( sys.SLT_DETAIL, "apply_rang_eff rang2 = " + rang2 + "rang1 = " + rang1 + "\n"  );
                            //sys.trace( sys.SLT_DETAIL, "apply_rang_eff angleVal = " + angleVal + "h_angle = " + h_angle + "\n"  );
                            if (angleVal < h_angle)
                            {
                                continue;// 不在范围内
                            }

                            var new_per = per;
                            if (trang.fan.decay != null && trang.fan.decay.Count > 0)
                            {//衰减
                                var dist = rang2;
                                foreach (var decay in trang.fan.decay)
                                {
                                    if (decay.min <= dist && decay.max > dist)
                                    {
                                        new_per *= (int)(decay.per / 100.0);
                                        break;
                                    }
                                }
                            }

                            var affed = false;
                            foreach (var tres in sk_res)
                            {
                                var ret = apply_skill_eff_to(cur_clock_tm, from, val, tres, tres.aff, sid, new_per);
                                if (ret)
                                {
                                    affed = true;
                                }
                            }

                            if (affed)
                            {
                                ++aff_count;
                                if (aff_count >= maxi) break;
                            }
                        }
                    }
                }
            }
            else if (trang.ray != null)
            {
                // 以from为中心,center为目标,fan.dist为距离,fan.width为宽度的矩形区域
                var ray = trang.ray;
                var frm_pl = from.get_pack_data();
                var x1 = center.x - frm_pl.x;
                var y1 = center.y - frm_pl.y;
                var rang1 = x1 * x1 + y1 * y1;
                if (rang1 != 0)
                {
                    rang1 = Math.Sqrt(rang1);
                    var hwidth = ray.width / 2.0;
                    //var inzoneplys = from.get_inz_plys();       
                    foreach (var val in gmap.map_players.Values)
                    {
                        if (val.isdie() || val.isghost())
                        {
                            continue;
                        }

                        var pl_data = val.get_pack_data();

                        var x2 = pl_data.x - frm_pl.x;
                        var y2 = pl_data.y - frm_pl.y;

                        var dotVal = x1 * x2 + y1 * y2;
                        //sys.trace( sys.SLT_DETAIL, " iid = " + pl_data.iid + "      dotVal = " + dotVal + "\n"  );
                        if (dotVal < 0)
                        {
                            continue;// 不在范围内
                        }

                        var projVal = dotVal / rang1;
                        //sys.trace( sys.SLT_DETAIL, " dotVal = " + dotVal + "     projVal = " + projVal + "\n"  );
                        if (projVal - pl_data.size > ray.dist)
                        {
                            continue;// 不在范围内
                        }

                        var vertVal = x2 * x2 + y2 * y2 - projVal * projVal;//小数会产生误差  出现负数的情况
                                                                            //sys.trace( sys.SLT_DETAIL, "apply_rang_eff vertVal = " + vertVal + "  pl_data.size =" + pl_data.size + "\n"  );
                        if (vertVal > 0 && Math.Sqrt(vertVal) > hwidth)
                        {
                            continue;// 不在范围内
                        }

                        var affed = false;
                        foreach (var tres in sk_res)
                        {
                            var ret = apply_skill_eff_to(cur_clock_tm, from, val, tres, tres.aff, sid, per);
                            if (ret)
                            {
                                affed = true;
                            }
                        }

                        if (affed)
                        {
                            ++aff_count;
                            if (aff_count >= maxi) break;
                        }
                    }
                    if (aff_count < maxi)
                    {
                        //var inzonemons = from.get_inz_mons(); 
                        foreach (var val in gmap.map_mons.Values)
                        {
                            if (val.isdie() || val.isghost())
                            {
                                continue;
                            }

                            var pl_data = val.get_pack_data();

                            var x2 = pl_data.x - frm_pl.x;
                            var y2 = pl_data.y - frm_pl.y;

                            var dotVal = x1 * x2 + y1 * y2;
                            //sys.trace( sys.SLT_DETAIL, " iid = " + pl_data.iid + "      dotVal = " + dotVal + "\n"  );
                            if (dotVal < 0)
                            {
                                continue;// 不在范围内
                            }

                            var projVal = dotVal / rang1;
                            //sys.trace( sys.SLT_DETAIL, " dotVal = " + dotVal + "     projVal = " + projVal + "\n"  );
                            if (projVal - pl_data.size > ray.dist)
                            {
                                continue;// 不在范围内
                            }

                            var vertVal = x2 * x2 + y2 * y2 - projVal * projVal;//小数会产生误差  出现负数的情况
                                                                                //sys.trace( sys.SLT_DETAIL, "apply_rang_eff vertVal = " + vertVal + "  pl_data.size =" + pl_data.size + "\n"  );
                            if (vertVal > 0 && Math.Sqrt(vertVal) > hwidth)
                            {
                                continue;// 不在范围内
                            }

                            var affed = false;
                            foreach (var tres in sk_res)
                            {
                                var ret = apply_skill_eff_to(cur_clock_tm, from, val, tres, tres.aff, sid, per);
                                if (ret)
                                {
                                    affed = true;
                                }
                            }

                            if (affed)
                            {
                                ++aff_count;
                                if (aff_count >= maxi) break;
                            }
                        }
                    }
                }
            }

            //sys.trace( sys.SLT_DETAIL, " apply_rang_eff  tm= " + (sys.clock_time()-test_cost_tm) + " \n" );
        }
Exemple #18
0
    //    {
    //    level = 1,
    //    atktp = atk_type.ATKTP_ATK,

    //    atk_min = 100,
    //    atk_max = 100,
    //    matk_min = 100,
    //    matk_max = 100,
    //    atk_rate = 1000, // 命中率
    //    miss_rate = 0,  // 闪避
    //    pkatkrate = 100,
    //    pkmisrate = 100,

    //    criatk = 0,
    //    criatk_debuffs = 0, //暴击抵抗,相对 criatk 的抵抗 ,千分比, 算法:受到暴击击的概率降低xx 
    //    cridmg = 0,
    //    exatk = 0,
    //    exatk_debuffs = 0, // 卓越一击率抵抗, 相对 exatk 的抵抗 ,千分比, 算法:受到卓越一击的概率降低xx
    //    exdmg = 0,
    //    dobrate = 0,
    //    igdef_rate = 0,
    //    igdef_rate_debuffs = 0, // 抵抗无视防御几率
    //    def_red = 0,
    //    dmg_red = 0,
    //    atk_dmg_mul = 0,
    //    igdmg_red = 0,  // 无视伤害减免几率,千分比
    //    igatk_dmg_mul = 0,// 无视伤害增益几率,千分比
    //    hpsuck = 0,     // 每次攻击吸收生命值
    //    hpsuck_dmgmul = 0, // 每次攻击吸收生命值增加伤害比例
    //    addResist = [0,0,0,0,0,0,0], // 属性攻击
    //    clansred = 0,
    //    iid = 0,
    //};

    // damage { noratk: } ??
    public static Variant apply_dmg_on_pl_ex(IBaseUnit tar_sprite, IBaseUnit frm_sprite, damage damage, long cur_clock_tm, int per, bool wpnatk = false, bool direct_dmg = false)
    {
        // TO DO : 优化: per = 1000时不需要计算增益
        //direct_dmg 默认伤害....? 技能伤害, 追击伤害, 有miss几率
        //wpnatk 是否默认攻击

        //::g_dump( "apply_dmg [ damage ] ===>>>> ",  damage ) ;
        //::g_dump( "apply_dmg [ flags ] ===>>>> ",  { wpnatk = wpnatk, direct_dmg = direct_dmg } ) ;
        if (frm_sprite != null)
        {
            frm_sprite.on_hurt(tar_sprite);
        }

        tar_sprite.on_be_hurt(frm_sprite);

        var tar_pl = tar_sprite.get_pack_data();

        // 取不到状态添加对象情况下,本函数frm_sprite可能为空,则需要默认的计算参数
        var pl = default(IMapUnit);// g_dmg_calc_def_pl;

        if (frm_sprite != null)
        {
            pl = frm_sprite.get_pack_data();
            pl.last_atk_tm = cur_clock_tm; // 触发普通攻击cd
        }

        var ret = new Variant();
        ret["hited"] = 3;
        ret["criatk"] = 0;
        ret["dmg"] = 0;
        ret["dobdmg"] = false;
        ret["isdie"] = false;
        ret["frm_iid"] = pl.iid;
        ret["to_iid"] = tar_pl.iid;


        // 计算玩家 VS NPC 等级调整伤害
        //var dmg_per_add = 0;
        var is_pvp = true;
        if (frm_sprite != null)
        {
            if (frm_sprite.get_sprite_type() == map_sprite_type.MstMonster)
            {
                is_pvp = false;
            }
        }

        if (tar_sprite.get_sprite_type() == map_sprite_type.MstMonster)
        {
            is_pvp = false;
        }

        // miss check
        var bAllMiss = false;
        if (direct_dmg)
        {
            if (is_pvp)
            {
                // pvp
                var atk_rate = 100 * (pl.pkatkrate / (pl.pkatkrate + tar_pl.pkmisrate)/* * (pl.level/(pl.level + tar_pl.level))*/);
                var lvl_dist = tar_pl.level - pl.level;
                if (lvl_dist >= 300)
                {
                    atk_rate -= 15;
                }
                else if (lvl_dist >= 200)
                {
                    atk_rate -= 10;
                }
                else if (lvl_dist >= 100)
                {
                    atk_rate -= 5;
                }

                var judg = Utility.random(0, 100);
                if (judg > atk_rate)
                {
                    // miss
                    ret["hited"] = 1;
                    return ret;
                }
            }
            else
            {
                // pve
                var atk_rate = 100.0 * (pl.atk_rate - tar_pl.miss_rate) / pl.atk_rate;
                if (atk_rate < 5)
                {
                    if (atk_rate < 0)
                    {
                        bAllMiss = true;
                    }
                    atk_rate = 5;
                }

                var judg = Utility.random(0, 100);
                if (judg > atk_rate)
                {
                    // miss
                    ret["hited"] = 1;
                    return ret;
                }
            }
        }

        double targetDef = tar_pl.def;
        if (is_pvp) targetDef += tar_pl.pkdef;

        targetDef = (targetDef - targetDef * (pl.def_red / 1000.0));




        var igdef_rate = pl.igdef_rate - tar_pl.igdef_rate_debuffs;
        if (igdef_rate > 0)
        {
            var judg = Utility.random(0, 1000);
            if (judg < igdef_rate)
            {
                targetDef = 0;
                ret["criatk"] = 1; // 无视防御
            }
        }


        //Utility.trace_info("apply_dmg_on_pl frm_sprite:["+frm_sprite+"] per["+per+"]\n");
        //sys.dumpobj(pl);

        //var combat_conf = get_general_combat_conf();

        double total_dmg = 0;

        // TO DO : 计算伤害 damage 是否是物理伤害
        if (pl.atktp == atk_type.ATKTP_MATK && !wpnatk && (damage.plyatk != 1))
        {
            //pl.atktp == atk_type.ATKTP_MATK  是 魔攻攻击分类角色
            // !wpnatk  不是默认攻击
            //  (!("plyatk" in damage) || damage.plyatk!=1) 不是物理攻击

            // 根据魔法攻击计算伤害

            int dmg_min = damage.dmg_min + pl.matk_min * damage.noratk;
            int dmg_max = damage.dmg_max + pl.matk_max * damage.noratk;
            if (is_pvp && pl.pkmatk != 0)
            {//pvp魔法攻击增加
                dmg_min += pl.pkmatk;
                dmg_max += pl.pkmatk;
            }

            if (damage.attr >= 0)
            {// 属性攻击
                dmg_min += pl.addResist[damage.attr];
                dmg_max += pl.addResist[damage.attr];
            }

            // TO DO : 根据装备武器不同来计算伤害
            //if(direct_dmg && frm_sprite)
            //{
            //    //frm_sprite.get_equip_by_pos(6); // 获取装备的武器
            //}

            double dmg = 0;
            var dmg_calced = false;

            if (damage.noratk > 0 && (pl.criatk - pl.criatk_debuffs > 0 || pl.exatk - pl.exatk_debuffs > 0))
            {
                var judg = Utility.random(0, 1000);
                if (judg < pl.exatk - pl.exatk_debuffs)
                {//卓越一击几率
                    dmg = dmg_max - targetDef;
                    dmg += dmg_max * (0.2 + pl.exper_add / 1000.0);
                    dmg += pl.exdmg;

                    ret["criatk"] = 2; // 卓越一击

                    dmg_calced = true;
                }
                else
                {
                    judg = Utility.random(0, 1000);
                    if (judg < pl.criatk - pl.criatk_debuffs)
                    {// 会心一击几率
                        dmg = dmg_max - targetDef;
                        dmg += pl.cridmg;

                        ret["criatk"] = 3; // 会心一击

                        dmg_calced = true;
                    }
                }
            }

            if (!dmg_calced)
            {
                dmg = Utility.random(dmg_min, dmg_max + 1);

                //if(is_pvp)
                //{
                //    dmg = dmg - (targetDef*tar_sprite.game_conf.pvp_def_per/100.0);
                //}
                //else
                //{
                //    dmg = dmg - targetDef;
                //}      
            }

            if (frm_sprite != null && frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer)
            {
                //// 技能攻击,技能额外加成
                //int dmg_mul = damage["noratk"];
                //var baseatt_conf = frm_sprite.carr_gen_conf.baseatt[0];
                //if( ("inte2atk" in baseatt_conf) && baseatt_conf.inte2atk != 0 )
                //{
                //    dmg_mul += pl.inte/(pl.inte+baseatt_conf.inte2atk);
                //}
                ////sys.trace( sys.SLT_DETAIL, "atk_type.ATKTP_MATK  dmg_mul=" + dmg_mul + " baseatt_conf.inte2atk =" + baseatt_conf.inte2atk + "\n")
                //dmg = dmg * dmg_mul;
            }

            if (dmg <= 0)
            {
                dmg = 1;
            }

            total_dmg += dmg;
        }
        else
        {
            // 根据攻击力计算伤害

            var skil_dmg_min = damage.dmg_min + pl.atk_min;
            var skil_dmg_max = damage.dmg_max + pl.atk_max;
            if (is_pvp && pl.pkatk != 0)
            {
                skil_dmg_min += pl.pkatk;
                skil_dmg_max += pl.pkatk;
            }

            if (damage.attr >= 0)
            {
                skil_dmg_min += pl.addResist[damage.attr];
                skil_dmg_max += pl.addResist[damage.attr];
            }

            double dmg = 0;
            var dmg_calced = false;

            if (damage.noratk > 0 && (pl.criatk - pl.criatk_debuffs > 0 || pl.exatk - pl.exatk_debuffs > 0))
            {
                var judg = Utility.random(0, 1000);
                if (judg < pl.exatk - pl.exatk_debuffs)
                {
                    dmg = skil_dmg_max;
                    dmg += skil_dmg_max * (0.2 + pl.exper_add / 1000.0);
                    dmg += pl.cridmg;
                    dmg += pl.exdmg;

                    ret["criatk"] = 2; // 卓越一击

                    dmg_calced = true;
                }
                else
                {
                    judg = Utility.random(0, 1000);
                    if (judg < pl.criatk - pl.criatk_debuffs)
                    {
                        dmg = skil_dmg_max;
                        dmg += pl.cridmg;

                        ret["criatk"] = 3; // 会心一击

                        dmg_calced = true;
                    }
                }
            }

            if (!dmg_calced)
            {
                dmg = Utility.random(skil_dmg_min, skil_dmg_max + 1);
            }

            //if(is_pvp)
            //{
            //    dmg = dmg -  (targetDef*tar_sprite.game_conf.pvp_def_per/100.0);
            //}
            //else
            //{
            //    dmg = dmg - targetDef;
            //}      

            if (!wpnatk && frm_sprite != null && frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer)
            {
                // 物理技能攻击,技能额外加成
                var dmg_mul = damage.noratk;
                //var baseatt_conf = frm_sprite.carr_gen_conf.baseatt[0];
                //if( ("inte2atk" in baseatt_conf) && baseatt_conf.inte2atk != 0 )
                //{
                //    dmg_mul += pl.inte/(pl.inte+baseatt_conf.inte2atk);
                //}
                //sys.trace( sys.SLT_DETAIL, "atk_type.ATKTP_ATK  dmg_mul=" + dmg_mul + "\n")
                dmg = dmg * dmg_mul;
            }

            if (dmg <= 0)
            {
                dmg = 1;
            }

            total_dmg += dmg;
        }

        if (bAllMiss)
        {//pve中 攻击者攻击几率 小于 被攻击者 miss几率时,攻击减益到30%
            total_dmg = (total_dmg * 30) / 100;
        }

        if (tar_pl.dmg_red != 1)
        {//伤害减免
            if (pl.igdmg_red <= 0)
            {   //无视伤害减免几率
                total_dmg = (total_dmg * tar_pl.dmg_red);
            }
            else
            {
                var judg = Utility.random(0, 1000);
                if (judg >= pl.igdmg_red)
                {
                    total_dmg = (total_dmg * tar_pl.dmg_red);
                }
            }
        }
        if (is_pvp && tar_pl.pkdmg_red != 1)
        { //pvp 伤害减免
            total_dmg = (total_dmg * tar_pl.pkdmg_red);
        }

        var tlevel = pl.level / 10;
        if (total_dmg >= 0 && total_dmg < tlevel)
        {
            if (tlevel < 1)
            {
                tlevel = 1;
            }

            total_dmg = tlevel;
        }

        // TO DO : sprite damage, 小精灵伤害

        if (direct_dmg)
        {
            // 计算生命损耗伤害加成
            if (frm_sprite != null && pl.hpsuck > 0)
            {
                // 损耗自己生命
                if (pl.hp > pl.hpsuck)
                {
                    pl.hp -= pl.hpsuck;
                    if (pl.hp < 0) pl.hp = 0;

                    // broadcast hpchange msg
                    //frm_sprite.broad_cast_zone_msg_and_self(26, {iid=pl.iid, hpchange={hpadd=-pl.hpsuck, die=(pl.hp <= 0), frm_iid=pl.iid}});

                    //if(pl.cid >0)
                    //{
                    //    var tid = team.get_ply_teamid(pl.cid);
                    //    if(tid > 0)
                    //    {
                    //        // 在队伍中,发送队友属性变化消息
                    //        team_bcast_rpc_except(tid, 138, {cid=pl.cid, hp=pl.hp}, pl.sid);
                    //    }
                    //}

                    if (pl.hpsuck_dmgmul > 0)
                    {
                        // 增加攻击伤害
                        total_dmg = total_dmg * ((1000.0 + pl.hpsuck_dmgmul) / 1000.0);
                    }
                }
            }
            var atk_dmg_mul = pl.atk_dmg_mul;
            if (pl.igatk_dmg_mul > 0)
            {   //无视伤害增益几率
                var judg = Utility.random(0, 1000);
                if (judg < pl.igatk_dmg_mul)
                {
                    atk_dmg_mul = 0;
                }
            }
            if (is_pvp)
            {
                total_dmg += (total_dmg * ((atk_dmg_mul + pl.pkatk_dmg_mul) / 1000.0));
            }
            else
            {
                total_dmg += (total_dmg * (atk_dmg_mul / 1000.0));
            }

            //// 计算技能伤害的属性加成值
            //if(damage.ContainsKey("attdmg_mul"))
            //{
            //    foreach(var attdmg in damage["attdmg_mul"])
            //    {
            //        var val = 0;
            //        if(attdmg.name in pl)
            //        {
            //            val = pl[attdmg.name];
            //        }
            //        total_dmg *= ((attdmg.base + val * attdmg.val ) / attdmg.basediv);
            //    }
            //}
            //if("attdmg_add" in damage)
            //{
            //    foreach(attdmg in damage.attdmg_add)
            //    {
            //        var val = 0;
            //        if(attdmg.name in pl)
            //        {
            //            val = pl[attdmg.name];
            //        }
            //        total_dmg += ((attdmg.base + val * attdmg.val ) / attdmg.basediv);
            //    }
            //}


            //if((tar_sprite.get_sprite_type()==map_sprite_type.MstMonster) && tar_pl.clanatt_eff)
            //{
            //    // 需要计算副本中帮派科技伤害减免
            //    var clanper = 1000 - tar_pl.clanred + pl.clansred;

            //    //Utility.trace_info("calc clanatt total_dmg["+total_dmg+"] clanper["+clanper+"] pl.clansred["+pl.clansred+"] tar_pl.clanred["+tar_pl.clanred+"]\n");

            //    total_dmg = (total_dmg * ((clanper)/1000.0));

            //    //Utility.trace_info("calc clanatt total_dmg["+total_dmg+"]\n");
            //}

            // TO DO : 吸蓝 mpsteal
        }

        total_dmg += damage.hp_dmg;

        total_dmg = (total_dmg * (per / 1000.0));
        //sys.dumpobj(damage);
        //Utility.trace_info("total_dmg:["+total_dmg+"]\n");

        if (total_dmg.CompareTo(0) > 0)
        {
            var real_atk_dmg = total_dmg;

            if (total_dmg > 0)
            {
                if (frm_sprite != null)
                {
                    tar_sprite.onhate(frm_sprite, total_dmg);
                    tar_sprite.ondmg(frm_sprite, total_dmg);

                    if (frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer)
                    {
                        if (frm_sprite.gmap.blvlmap)
                        {
                            frm_sprite.gmap.worldsvr.on_dmg(frm_sprite, tar_sprite, total_dmg);
                        }
                    }

                    if (direct_dmg)
                    {
                        frm_sprite.calc_weapon_dura(total_dmg); // 计算装备耐久损耗
                        frm_sprite.on_make_direct_dmg();
                    }
                }

                if (direct_dmg)
                {
                    tar_sprite.calc_eqp_dura(total_dmg); // 计算装备耐久损耗

                    // 计算双倍伤害
                    if (pl.dobrate > 0)
                    {
                        var judg = Utility.random(0, 1000);
                        if (judg < pl.dobrate)
                        {
                            total_dmg += total_dmg;
                            ret["dobdmg"] = true;
                        }
                    }
                }

                // 吸收伤害
                total_dmg = pl_absorb_dmg(tar_sprite, tar_pl, total_dmg);
                // 魔法抵扣生命
                total_dmg = pl_hpdmg_2_mpdmg(tar_sprite, tar_pl, total_dmg);
                // 伤害链接
                pl_dmg_link(tar_sprite, tar_pl, total_dmg);

            }

            if (is_pvp && total_dmg > 0)
            {
                var pkignore_dp = false;//无视dp  
                var pkigdp_rate = pl.pkigdp_rate - tar_pl.pkigdp_rate_debuffs;
                if (pkigdp_rate > 0)
                {
                    var judg = Utility.random(0, 1000);
                    pkignore_dp = judg < pkigdp_rate;
                }
                if (!pkignore_dp)
                {
                    if (tar_pl.dp < total_dmg)
                    {
                        var dp_dmg = tar_pl.dp;
                        tar_pl.dp = 0;

                        //剩余值 10倍作用于hp
                        total_dmg = ((total_dmg - dp_dmg));//*tar_sprite.game_conf.ply_hp_dmg_factor);
                        tar_pl.hp -= (int)total_dmg;
                        if (tar_pl.hp < 0) tar_pl.hp = 0;

                        ret["dp_dmg"] = dp_dmg;
                    }
                    else
                    {
                        tar_pl.dp -= (int)total_dmg;
                        if (tar_pl.dp > tar_pl.max_dp) tar_pl.dp = tar_pl.max_dp;

                        ret["dp_dmg"] = total_dmg;
                        total_dmg = 0;
                    }
                }
                else
                {
                    //剩余值 10倍作用于hp
                    total_dmg = (total_dmg * 10);//tar_sprite.game_conf.ply_hp_dmg_factor);
                    tar_pl.hp -= (int)total_dmg;
                    if (tar_pl.hp < 0) tar_pl.hp = 0;
                }
                //sys.trace( sys.SLT_DETAIL, "tar_pl.cid =" + tar_pl.cid + "    tar_pl.dp = " +  tar_pl.dp + "    tar_pl.hp = " +  tar_pl.hp + "\n");      
            }
            else
            {
                tar_pl.hp -= (int)total_dmg;
                if (tar_pl.hp < 0) tar_pl.hp = 0;
                if (tar_pl.hp > tar_pl.max_hp) tar_pl.hp = tar_pl.max_hp;
            }

            // broadcast hpchange msg
            //tar_sprite.broad_cast_zone_msg_and_self(26, {iid=tar_pl.iid, hpchange={hpadd=-total_dmg, die=(tar_pl.hp <= 0), frm_iid=pl.iid}});
            ret["isdie"] = (tar_pl.hp <= 0);
            ret["dmg"] = total_dmg;

            //if(tar_pl.cid >0)
            //{
            //    var tid = team.get_ply_teamid(tar_pl.cid);
            //    if(tid > 0)
            //    {
            //        // 在队伍中,发送队友属性变化消息
            //        if( is_pvp )
            //        {
            //            team_bcast_rpc_except(tid, 138, {cid=tar_pl.cid, hp=tar_pl.hp, dp=tar_pl.dp}, tar_pl.sid);
            //        }
            //        else
            //        {
            //            team_bcast_rpc_except(tid, 138, {cid=tar_pl.cid, hp=tar_pl.hp}, tar_pl.sid);
            //        }         
            //    }
            //}

            if (tar_pl.hp <= 0)
            {
                // die!
                tar_sprite.die(frm_sprite);
            }
            //目标死亡,本次伤害不反弹
            if (frm_sprite != null && real_atk_dmg > 0 && tar_pl.iid != pl.iid && tar_pl.hp > 0)
            {
                // 反弹伤害
                double dmg = 0;
                if (tar_pl.rev_dmg_mul > 0)
                {
                    dmg = (real_atk_dmg * ((tar_pl.rev_dmg_mul) / 1000.0));
                    if (dmg <= 0) dmg = 1;
                }
                if (tar_pl.rev_atk > 0)
                {
                    var judg = Utility.random(0, 1000);
                    if (judg < tar_pl.rev_atk)
                    {
                        dmg += real_atk_dmg;
                    }
                }

                //if(is_pvp)
                //{
                //    dmg = (dmg * combat_conf.pk_dmg_per/100);
                //}

                if (dmg > 0)
                {
                    // 吸收伤害
                    dmg = pl_absorb_dmg(frm_sprite, pl, dmg);
                    // 魔法抵扣生命
                    dmg = pl_hpdmg_2_mpdmg(frm_sprite, pl, dmg);

                    frm_sprite.onhate(tar_sprite, dmg);
                    frm_sprite.ondmg(tar_sprite, dmg);

                    //var frm_hpchange = {frm_iid=tar_pl.iid}
                    if (is_pvp)
                    {
                        //sys.trace( sys.SLT_DETAIL, "pl.dp =" + pl.dp + "pl.hp = "+ pl.hp + "\n");
                        if (pl.dp < dmg)
                        {
                            var dp_dmg = pl.dp;
                            pl.dp = 0;
                            //剩余值 10倍作用于hp
                            dmg = ((dmg - dp_dmg));//*tar_sprite.game_conf.ply_hp_dmg_factor);
                            pl.hp -= (int)dmg;
                            if (pl.hp < 0) pl.hp = 0;

                            //frm_hpchange.dpadd <- -dp_dmg;
                            //frm_hpchange.hpadd <- -dmg;
                            //frm_hpchange.die <- pl.hp <= 0;
                        }
                        else
                        {
                            pl.dp -= (int)dmg;

                            //frm_hpchange.dpadd <- -dmg;
                        }
                        //sys.dumpobj( frm_hpchange ); 
                    }
                    else
                    {
                        pl.hp -= (int)dmg;
                        if (pl.hp < 0) pl.hp = 0;

                        //frm_hpchange.hpadd <- -dmg;
                        //frm_hpchange.die <- pl.hp <= 0;
                    }

                    // broadcast hpchange msg
                    //frm_sprite.broad_cast_zone_msg_and_self(26, {iid=pl.iid, hpchange=frm_hpchange});

                    //if(pl.cid > 0)
                    ////if("cid" in pl)
                    //{
                    //    var tid = team.get_ply_teamid(pl.cid);
                    //    if(tid > 0)
                    //    {
                    //        // 在队伍中,发送队友属性变化消息
                    //        if ( is_pvp )
                    //        {
                    //             team_bcast_rpc_except(tid, 138, {cid=pl.cid, hp=pl.hp, dp=pl.dp}, pl.sid);
                    //        }
                    //        else
                    //        {
                    //            team_bcast_rpc_except(tid, 138, {cid=pl.cid, hp=pl.hp}, pl.sid);
                    //        }                       
                    //    }
                    //}

                    if (pl.hp <= 0)
                    {
                        // 被弹死了
                        frm_sprite.die(tar_sprite);
                    }
                }
            }
        }

        // 魔法值、怒气值调整
        var mpchanged = false;
        //var mpchange_rpc = {};
        if (damage.mp_dmg != 0)
        {
            var mpdmg = (damage.mp_dmg * per / 1000);

            tar_pl.mp -= mpdmg;
            if (tar_pl.mp < 0) tar_pl.mp = 0;
            if (tar_pl.mp > tar_pl.max_mp) tar_pl.mp = tar_pl.max_mp;

            //mpchange_rpc.mpadd <- -mpdmg;
            mpchanged = true;

            if (frm_sprite != null)
            {
                tar_sprite.onhate(frm_sprite, mpdmg);
            }
        }

        if (mpchanged && tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer)
        {
            // send mpchange msg
            //::send_rpc(tar_pl.sid, 32, mpchange_rpc);
        }

        return ret;
    }
Exemple #19
0
        public static game_err_code check_target_type(IBaseUnit caster, IBaseUnit tar_sprite, int aff, map_pk_setting_type map_pk_seting)
        {
            IMapUnit pl = caster.get_pack_data();
            IMapUnit tar_pl = tar_sprite.get_pack_data();
            if (pl.iid != tar_pl.iid)
            {
                // 作用于其他角色          
                if ((aff & (int)skill_aff_type.SAT_ENERMY) != (int)skill_aff_type.SAT_ENERMY)
                {
                    if (caster.can_atk(tar_sprite))
                        return game_err_code.SKIL_INVALIDE_TAREGET;//敌人

                    // 根据aff判断盟友关系从而确定是否受此状态影响
                    var isaily = caster.isaily(tar_sprite);
                    if (isaily)
                    {
                        if ((aff & (int)skill_aff_type.SAT_ALLY) != (int)skill_aff_type.SAT_ALLY)
                            return game_err_code.SKIL_INVALIDE_TAREGET;
                        // 不对盟友产生影响                 
                    }
                    else
                    {//中立方
                        if ((aff & (int)skill_aff_type.SAT_MID) != (int)skill_aff_type.SAT_MID)
                            return game_err_code.SKIL_INVALIDE_TAREGET;
                    }
                }
                else if (caster.get_sprite_type() == map_sprite_type.MstPlayer)
                {// 根据地图、个人pk状态决定是否可以释放技能    
                    if (tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer)
                    {
                        if (map_pk_seting == map_pk_setting_type.MPST_PEACE)
                            return game_err_code.CANT_PK_IN_PEACE_MAP;

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

                        if (map_pk_seting == map_pk_setting_type.MPST_NORMAL)
                        {
                            if (!tar_sprite.can_atk_direct())
                            {
                                //不可攻击的玩家
                                if (!caster.can_atk(tar_sprite))
                                    return game_err_code.CANT_ATK;
                            }
                        }
                        else
                        {
                            //pk地图
                            if (!caster.can_atk(tar_sprite))
                                return game_err_code.CANT_ATK;
                        }
                    }
                    else if (tar_sprite.get_sprite_type() == map_sprite_type.MstMonster)
                    {
                        if (tar_sprite.owner_ply != null)
                        {
                            //战宠     
                            var owner_sprite = tar_sprite.owner_ply;
                            var ower_pl = owner_sprite.get_pack_data();
                            if (ower_pl.iid == pl.iid)
                                return game_err_code.CANT_ATTACK_SELF_PET;

                            if (map_pk_seting == map_pk_setting_type.MPST_PEACE)
                                return game_err_code.CANT_PK_IN_PEACE_MAP;

                            if (pl.in_pczone || ower_pl.in_pczone)
                                return game_err_code.CANT_PK_IN_PEACE_ZONE;

                            if (map_pk_seting == map_pk_setting_type.MPST_NORMAL)
                            {
                                if (!owner_sprite.can_atk_direct())
                                {
                                    //不可攻击的玩家
                                    if (!caster.can_atk(owner_sprite))
                                        return game_err_code.CANT_ATK;
                                }
                            }
                            else
                            {
                                //pk地图
                                if (!caster.can_atk(owner_sprite))
                                    return game_err_code.CANT_ATK;
                            }
                        }
                        else
                        {
                            if (!caster.can_atk(tar_sprite))
                                return game_err_code.CANT_ATK;
                        }
                    }
                }
                else
                {
                    if (!caster.can_atk(tar_sprite))
                        return game_err_code.CANT_ATK;
                }
            }
            else
            {
                // 作用于自己
                if ((aff & (int)skill_aff_type.SAT_SELF) != (int)skill_aff_type.SAT_SELF)
                    return game_err_code.SKIL_INVALIDE_TAREGET; // 不对自己产生影响
            }

            return game_err_code.RES_OK;
        }
Exemple #20
0
        public static void update_pl_state(long cur_clock_tm, IBaseUnit sprite)
        {
            var pl = sprite.get_pack_data();

            if (pl.states != null)
                return;

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

                                }

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

                                }

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

                    val.start_tm += tm_elapsed;
                }

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

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

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

            //if (rmv_state_rpc.ids.len() > 0)
            //{
            //    // broadcast rmv_state msg
            //    sprite.broad_cast_zone_msg_and_self(31, rmv_state_rpc);
            //}
        }
Exemple #21
0
        public bool onhate(IBaseUnit atker, int hate_value, bool callhatp = true)
        {
            if (this.collect_tar > 0)
                return false;

            if (this.mondata.revange == 0)
                return false;

            if (this.running_tm > 0)
                return false;

            if (atker.isdie())
                return false;

            if (atker.get_sprite_type() == map_sprite_type.MstMonster)
                if (atker.collect_tar > 0)
                    return false;

            if (!can_atk(atker))
                return false;

            int atker_iid = atker.get_pack_data().iid;
            if (this.iid == atker_iid)
                return false;


            if (this.monconf.ai.hate_add > 0)
            {
                hate_value = this.monconf.ai.hate_add;
            }

            if (this.hatelist.ContainsKey(atker_iid))
                this.hatelist[atker_iid] += hate_value;
            else
            {
                this.hatelist[atker_iid] = hate_value;

                if (this.monconf.ai.hatp > 0)
                {
                    long dist2 = this.mondata.defrang * this.mondata.defrang;
                    foreach (KeyValuePair<int, IBaseUnit> pair in this.gmap.map_mons)
                    {
                        var m = pair.Value as Monster;
                        if (m.iid == this.iid)
                            continue;

                        if (m.monconf.ai.hatp <= 0)
                            continue;

                        if (!same_hatp(m))
                            continue;

                        if (m.hatelist.ContainsKey(atker_iid))
                            continue;

                        if (Utility.distance2(this, m) < dist2)
                        {
                            m.onhate(atker, hate_value, false);
                        }
                    }
                }
            }

            if (this.mondata.atking == null)
            {
                if (this.mondata.patrol != null && this.mondata.patrol.tracing == null)
                {
                    this.mondata.patrol.movto.trinitx = (int)this.mondata.x;
                    this.mondata.patrol.movto.trinity = (int)this.mondata.y;
                    this.mondata.patrol.movto.tracing = true;
                }

                long now = DateTime.Now.ToBinary();
                //Dictionary<string,long>
                this.mondata.atking = new atking() { tar_iid = atker.iid, start_tm = now - this.mondata.atkcdtm, trace_tm_left = 0 };

                //TODO broadcast
                this.broad_cast_zone_msg(12, new NetMsgData());
            }

            return true;
        }
Exemple #22
0
        //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;
        }
Exemple #23
0
        public bool isaily(IBaseUnit spr)
        {
            if (null != this.owner_ply)
                return this.owner_ply.isaily(spr);

            if (spr.get_sprite_type() == map_sprite_type.MstMonster && null != spr.owner_ply)
            {
                spr = spr.owner_ply;
            }

            IMapUnit pl = spr.get_pack_data();
            if (pl.lvlsideid > 0)
            {
                return pl.lvlsideid == this.mondata.lvlsideid;
            }

            if (spr.get_sprite_type() == map_sprite_type.MstMonster)
                return true;

            return false;
        }
Exemple #24
0
        public static game_err_code _add_bstate_to_ply(int bstate_id, IBaseUnit ply)
        {
            long cur_tm_s = DateTime.Now.ToBinary();

            var bstate_conf = Utility.get_bstate_desc(bstate_id);

            if (bstate_conf == null)
            {
                return game_err_code.CONFIG_ERR;
            }

            BState cur_exist_bstate = null;
            //var ret_state = null;

            IMapUnit pl = ply.get_pack_data();

            if (pl.bstates != null)
            {
                foreach (var bstate in pl.bstates)
                {
                    if (bstate.conf.id == bstate_id)
                    {
                        // 已经有这个祝福状态了
                        cur_exist_bstate = bstate;
                        break;
                    }

                    if (bstate.conf.uni_tp == bstate_conf.uni_tp)
                    {
                        //// 有相同类型的祝福状态(但id不同),不能添加
                        //return game_err_code.BSTATE_SAME_TP_BSTATE_EXIST;

                        // 移除相同类型不同id的祝福状态
                        pl.bstates.Remove(bstate);

                        // send bstate_change msg
                        //::send_rpc(ply.pinfo.sid, 19, { rmvid = bstate.id});
                        break;
                    }
                }
            }
            else
            {
                pl.bstates = new List<BState>();
            }

            if (cur_exist_bstate != null)
            {
                // 已有同一祝福状态,增加持续时间,更改参数
                //ret_state = { id = bstate_conf.id};

                if (bstate_conf.eff.maxpar > 0)
                {
                    if (cur_exist_bstate.par + bstate_conf.eff.par > bstate_conf.eff.maxpar)
                    {
                        // 超出允许叠加参数上限
                        return game_err_code.MAX_BSTATE_PAR_REACHED;
                    }

                    cur_exist_bstate.par += bstate_conf.eff.par;
                    //ret_state.par < -cur_exist_bstate.par;
                }

                if (bstate_conf.merg_tm == 1)
                {
                    cur_exist_bstate.end_tm = cur_exist_bstate.end_tm + bstate_conf.tm; // 延迟持续时间
                }
                else
                {
                    cur_exist_bstate.end_tm = cur_tm_s + bstate_conf.tm; // 延迟持续时间
                }
                //ret_state.end_tm < -cur_exist_bstate.end_tm;
            }
            else
            {
                long ticktm = 0;
                if (bstate_conf.eff.ticktm > 0)
                {
                    ticktm = cur_tm_s + bstate_conf.eff.ticktm;
                }

                BState bstate = new BState()
                {
                    id = bstate_conf.id,
                    par = bstate_conf.eff.par,
                    end_tm = cur_tm_s + bstate_conf.tm,
                    ticktm = ticktm,
                    conf = bstate_conf
                };
                pl.bstates.push(bstate);

                //ret_state = bstate;
            }

            // send bstate_change msg
            //::send_rpc(ply.pinfo.sid, 19, { mod = ret_state});

            return game_err_code.RES_OK;
        }
Exemple #25
0
        public void call_petmon(int mid, long fintm)
        {
            // 创建出战战斗宠物

            if (this.gmap == null)
            {
                return;
            }

            //相同 战宠   已招则取消召唤
            if (petmon_inst != null && petmon_inst.get_pack_data().mid == mid)
            {
                release_petmon();
                return;
            }

            release_petmon(false, false);

            map_mon_conf monconf = new map_mon_conf() { mid = mid, x = 0, y = 0, r_x = 8, r_y = 8, spwan_time = 0 };
            petmon_inst = this.gmap.new_pet_mon(this, monconf);
            if (null == petmon_inst)
            {
                return;
            }

            this.pet_mon.mid = mid;
            this.pet_mon.fintm = fintm;

            IMapUnit mondata = petmon_inst.get_pack_data();

            mondata.follow = new follow()
            {
                start_tm = Utility.time(),
                tar_iid = pinfo.iid,
                trace_tm_left = 0,
                frang = 78400,
                trang = 8100,
                do_ai = true
            };//280*280
        }
Exemple #26
0
        // 移除指定祝福状态
        public static void rmv_bstate(int sid, Variant rpc, IBaseUnit ply)
        {
            IMapUnit pl = ply.get_pack_data();
            if (pl.bstates == null || pl.bstates.Count <= 0)
                return;

            int removed_id = rpc["id"]._int32;
            var to_rmv_idx = 0;
            BState to_rmv_bstate = null;
            for (int i = 0; i < pl.bstates.Count; i++)
            {
                if (pl.bstates[i].id == removed_id)
                {
                    to_rmv_bstate = pl.bstates[i];
                    to_rmv_idx = i;
                    pl.bstates.RemoveAt(i);
                    break;
                }
            }

            if (to_rmv_bstate == null)
                return;

            // send bstate_change msg
            //::send_rpc(ply.pinfo.sid, 19, { rmvid = to_rmv_bstate.id});
        }
Exemple #27
0
        public void ondmg(IBaseUnit atker, int dmg)
        {
            int atker_cid = atker.get_pack_data().cid;
            long now_s = DateTime.Now.ToBinary();
            // 被攻击
            if (this.kp_asist_rec)
            {
                // 需要记录助攻
                if (atker.get_sprite_type() == map_sprite_type.MstMonster)
                {
                    return;
                }

                this.beatk_ply_cids[atker_cid] = now_s;  // 记录攻击者cid

                this.lastdmgtm = now_s; // 记录最后一次受伤害时间
            }

            if (gmap.pk_seting == map_pk_setting_type.MPST_NORMAL)
            {
                if (atker.get_sprite_type() == map_sprite_type.MstPlayer)
                {
                    if (atker_cid != pinfo.cid && !this.can_atk_direct())
                    {
                        if (!atker.defend_tm_map.ContainsKey(pinfo.cid))
                        {
                            //是否被正当防御 
                            //是否第一次记录
                            defend_tm_map[atker_cid] = now_s + 10000;

                        }
                    }
                }
            }
        }
Exemple #28
0
        //获取祝福的掉落倍率
        public static int _get_bstate_rate_mul(IBaseUnit ply)
        {
            IMapUnit pl = ply.get_pack_data();
            if (pl.bstates == null || pl.bstates.Count <= 0)
                return 0;

            foreach (var bstate in pl.bstates)
            {
                if (bstate.conf.eff.tp == (int)bstate_eff_type.BET_RATE_MUL)
                {
                    return bstate.conf.eff.par;
                }
            }

            return 0;
        }
Exemple #29
0
        public bool can_atk(IBaseUnit spr)
        {
            if (spr.get_sprite_type() == map_sprite_type.MstMonster && spr.owner_ply != null)
                spr = spr.owner_ply; // 用主人代替宠物检查敌我关系

            IMapUnit pl = spr.get_pack_data();
            if (pl.iid == this.pinfo.iid)
                return false;

            //if (spr.get_sprite_type() == map_sprite_type.MstPlayer && pl.level < game_conf.pk_safe_lvl)
            //{
            //    return false;
            //}

            if (pl.lvlsideid != 0)
            {
                if (pinfo.lvlsideid != pl.lvlsideid)
                    return true;

                if ((gmap != null && !gmap.ignore_side) || spr.get_sprite_type() == map_sprite_type.MstMonster)
                    return false;
            }

            bool cannt_pk = false;
            switch (pinfo.pk_state)
            {
                case pk_state_type.PKST_PEACE:
                    cannt_pk = spr.get_sprite_type() == map_sprite_type.MstPlayer;
                    break;
                case pk_state_type.PKST_PK_ALL:
                    cannt_pk = false;
                    break;
                case pk_state_type.PKST_PK_TEAM:
                    if (pl.teamid == 0 || pinfo.teamid == 0)
                        cannt_pk = false;
                    else
                        cannt_pk = pl.teamid == pinfo.teamid;
                    break;
                case pk_state_type.PKST_PK_CLAN:

                    if (pl.clanid == 0 || pinfo.clanid == 0)
                        cannt_pk = false;
                    else
                        cannt_pk = pl.clanid == pinfo.clanid;
                    break;
            }

            return !cannt_pk;
        }
Exemple #30
0
        public static void _update_pl_bstate(long cur_tm_s, IBaseUnit ply)
        {
            IMapUnit pl = ply.get_pack_data();
            if (pl.bstates == null || pl.bstates.Count <= 0)
                return;

            var bstates = pl.bstates;
            for (var idx = 0; idx < bstates.Count; ++idx)
            {
                var bstate = bstates[idx];

                if (bstate.end_tm < cur_tm_s)
                {
                    // 到时间,结束状态
                    bstates.RemoveAt(idx);
                    --idx;

                    // send bstate_change msg
                    //::send_rpc(ply.pinfo.sid, 19, { rmvid = bstate.id});

                    continue;
                }

                if (bstate.ticktm > 0 && bstate.ticktm < cur_tm_s)
                {
                    // 达到定时触发时间

                    bstate.ticktm = cur_tm_s + bstate.conf.eff.ticktm; // 更新下次触发时间

                    var par_change = 0;

                    if (bstate.conf.eff.tp == (int)bstate_eff_type.BET_ADD_HP)
                    {
                        // 增加生命状态

                        var hp_add = pl.max_hp - pl.hp;
                        if (hp_add <= 0)
                        {
                            continue;
                        }

                        if (hp_add > bstate.conf.eff.add)
                        {
                            hp_add = bstate.conf.eff.add;
                        }

                        if (hp_add > bstate.par)
                        {
                            hp_add = bstate.par;
                        }

                        ply.modify_hp(hp_add);

                        bstate.par -= hp_add; // 扣除存储值
                    }
                    else if (bstate.conf.eff.tp == (int)bstate_eff_type.BET_ADD_MP)
                    {
                        // 增加法力状态

                        var mp_add = pl.max_mp - pl.mp;
                        if (mp_add <= 0)
                        {
                            continue;
                        }

                        if (mp_add > bstate.conf.eff.add)
                        {
                            mp_add = bstate.conf.eff.add;
                        }

                        if (mp_add > bstate.par)
                        {
                            mp_add = bstate.par;
                        }

                        ply.modify_mp(mp_add);

                        bstate.par -= mp_add; // 扣除存储值
                    }
                    else
                    {
                        // err,错误的状态,需要删除
                        bstate.par = 0;
                    }

                    //var ret_msg = null;
                    if (bstate.par > 0)
                    {
                        //ret_msg = { mod ={ id = bstate.id, par = bstate.par} };
                    }
                    else
                    {
                        // 消耗完了存储值,删除状态
                        //ret_msg = { rmvid = bstate.id};

                        bstates.RemoveAt(idx);
                        --idx;
                    }

                    // send bstate_change msg
                    //::send_rpc(ply.pinfo.sid, 19, ret_msg);
                }
            }

            //if (ply.pinfo.bstates.len() <= 0)
            //{
            //    delete ply.pinfo.bstates;
            //}
        }