Beispiel #1
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;
        }
Beispiel #2
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;
        }