Exemplo n.º 1
0
        public void update(gameWorld world, long now, long time_elapsed)
        {
            if (gmap.map_fined)
                return;

            if (first_respawn)
            {
                respawn(false);
                first_respawn = false;
                return;
            }

            if (respawn_tm > 0)
            {
                if (this.die_tm > 0 && respawn_tm - this.die_tm > 3000)
                {
                    this.set_die(true);
                    this.die_tm = 0;
                }

                if (this.mondata.respawn_tm > 0 && respawn_tm < now)
                {
                    respawn(true);

                    this._trig_respawn_act(now);
                }

                return;
            }

            if (this.collect_tar > 0)
                return;

            Skill.update_pl_state(now, this);

            long tm_left = grid_map.update_pl_move(this, now);

            if (this.mondata.moving == null)
            {
                if (this.mondata.atking != null)
                {
                    this.mondata.atking.trace_tm_left = tm_left;
                    grid_map.update_pl_atk_tracing(this, now);
                    grid_map.update_pl_move(this, now);
                }
            }

            if (this.running_tm <= 0 && this.monconf.ai.aggres > 0 && this.owner_ply == null)
            {
                List<IBaseUnit> inz_players = this.get_inz_plys();
                foreach (IBaseUnit sprite in inz_players)
                {
                    if (sprite.isdie() || sprite.isghost())
                        continue;

                    if (!this.can_atk(sprite))
                        continue;

                    IMapUnit pl = sprite.get_pack_data();

                    if (pl.invisible > this.mondata.observer)
                        continue;

                    long dist2 = Utility.distance2(this, sprite);
                    long atk_dist2 = (long)Math.Pow(this.mondata.defrang, 2);

                    if (dist2 < atk_dist2)
                    {
                        if (!this.hatelist.ContainsKey(sprite.iid))
                        {
                            this.onhate(sprite, 1);
                            break;
                        }
                    }
                    else
                    {
                        if (this.monconf.ai.clhor > 0)
                        {
                            if (this.hatelist.Count > 0)
                                this.hatelist.Clear();
                        }

                        if (this.mondata.atking != null && sprite.iid == this.mondata.atking.tar_iid)
                            this.cancel_atk();
                    }
                }

                if (this.mondata.atk_oth_mon)
                {
                    foreach (var sp_x in this.gmap.map_mons.Values)
                    {
                        if (sp_x.isdie() || sp_x.isghost())
                            continue;

                        if (!this.can_atk(sp_x))
                            continue;

                        if (sp_x.get_pack_data().invisible > this.mondata.observer)
                            continue;

                        if (sp_x.collect_tar > 0)
                            continue;

                        long dist2 = Utility.distance2(sp_x, this);
                        long atk_dist2 = (long)Math.Pow(this.mondata.defrang, 2);

                        if (dist2 < atk_dist2)
                        {
                            if (!this.hatelist.ContainsKey(sp_x.iid))
                                if (this.onhate(sp_x, 1))
                                    break;
                        }
                        else if (this.monconf.ai.clhor < 0)
                        {
                            if (this.hatelist.ContainsKey(sp_x.iid))
                                this.hatelist.Remove(sp_x.iid);

                            if (this.mondata.atking != null && this.mondata.atking.tar_iid == sp_x.iid)
                                this.cancel_atk();
                        }
                    }
                }
            }

            if (now > this.next_pick_atk_target_tm)
                this._pick_atk_target(now);

            if (this.mondata.followply && now > this.next_pick_follow_tm && this.mondata.follow == null)
            {
                foreach (IBaseUnit sp_x in this.gmap.map_players.Values)
                {
                    if (!this.isaily(sp_x))
                        continue;

                    if (sp_x.get_pack_data().invisible > this.mondata.observer)
                        continue;

                    var pl = sp_x.get_pack_data();
                    this.mondata.follow = new follow() { do_ai = false, start_tm = now, tar_iid = sp_x.iid, trace_tm_left = 0, frang = 40000, trang = 8100 };
                    break;
                }

                this.next_pick_follow_tm = now + 1000;
            }

            _do_next_castsk(now);
            grid_map.update_pl_atk(this, now);

            gmap.update_skill_casting(this, this.mondata, now);
            gmap.update_skill_holding(this, this.mondata, now);
            gmap.update_jumping(this, this.mondata, now);
            gmap.update_teleping(this, this.mondata, now);

            if (this.mondata.atking != null)
            {
                this.mondata.atking.trace_tm_left = 0;
                grid_map.update_pl_atk_tracing(this, now);

                if (now > this.next_mov_tm)
                {
                    if (this.mondata.keepdist)
                        grid_map.update_keep_atk_range(this, now);

                    if (this.monconf.ai.cond != null)
                    {
                        foreach (var cond in this.monconf.ai.cond)
                        {
                            _do_ai_act(cond.act, now);
                        }
                    }

                    double init_x = this.mondata.init_x * StaticStuff.GRID_WIDTH + 16;
                    double init_y = this.mondata.init_y * StaticStuff.GRID_WIDTH + 16;
                    bool need_fall_back = true;

                    if (this.mondata.patrol != null && this.mondata.patrol.movto != null)
                    {
                        init_x = this.mondata.patrol.movto.trinitx;
                        init_y = this.mondata.patrol.movto.trinity;
                        need_fall_back = false;
                    }

                    if (this.mondata.follow != null)
                    {
                        if (this.gmap.map_sprites.ContainsKey(this.mondata.follow.tar_iid))
                        {
                            IMapUnit follow_pl = this.gmap.map_sprites[this.mondata.follow.tar_iid].get_pack_data();

                            init_x = follow_pl.x;
                            init_y = follow_pl.y;
                        }
                    }

                    long dist2 = (long)(Math.Pow(this.mondata.x - init_x, 2) + Math.Pow(this.mondata.y - init_y, 2));

                    if (dist2 > this.mondata.tracerang2)
                    {
                        this.mondata.atking = null;
                        this.running_tm = this.mondata.running_tm;
                        this._clear_hate_list();

                        if (need_fall_back && this.mondata.speed > 0)
                        {
                            Point2D cur_g = new Point2D(this.mondata.x / StaticStuff.GRID_WIDTH,
                                this.mondata.y / StaticStuff.GRID_WIDTH);
                            List<Point2D> path =
                                Utility.findPath(this.gmap.mapid, (int)cur_g.x, (int)cur_g.y, this.mondata.init_x,
                                    this.mondata.init_y);

                            if (path != null && path.Count > 0)
                            {
                                this.mondata.moving = new moving()
                                {
                                    start_tm = now,
                                    pts = path,
                                    to_x = this.mondata.init_x,
                                    to_y = this.mondata.init_y,
                                    float_x = this.mondata.x,
                                    float_y = this.mondata.y
                                };

                                //TODO broad cast
                            }
                        }
                    }

                    this.next_mov_tm = now + this.monconf.ai.thinktm;
                }
            }
            else if (this.mondata.follow != null)
            {
                this.mondata.follow.trace_tm_left = 0;
                grid_map.update_pl_follow_tracing(this, now);

                if (this.mondata.moving == null && this.mondata.follow != null && this.mondata.follow.do_ai)
                {
                    IMapUnit f_pl = this.gmap.map_sprites[this.mondata.follow.tar_iid].get_pack_data();
                    this.mondata.init_x = (int)(f_pl.x / StaticStuff.GRID_WIDTH);
                    this.mondata.init_y = (int)(f_pl.y / StaticStuff.GRID_WIDTH);

                    this.update_ai_mover(now);
                }
            }
            else
            {
                this._try_patrol(now);
                this.update_ai_mover(now);
            }

            this.update_resume(now);

            if (this.shkilawd)
            {
                if (now - this.lastdmgtm > 10 * 1000)
                {
                    // 3秒内未被攻击,清理伤害列表
                    foreach (KeyValuePair<int, int> pair in this.dmglist)
                    {
                        IBaseUnit target = this.gmap.get_player_by_cid(pair.Key);
                        if (null == target)
                            continue;

                        if (!this.is_ply_inzone(target.get_pack_data().sid))
                            continue;

                        // send self_attchange msg
                        //::send_rpc(target.pinfo.sid, 32, { mondmg = 0, total_mondmg = 0, mid = this.mondata.mid});
                    }

                    this.dmglist.Clear();
                }

                // 共享击杀奖励类怪物,发送伤害值至附近玩家
                //if (this.notify_hate_tm < cur_tm_s)
                //{
                //    local total_dmg = 0;
                //    foreach (cid, dmg in this.dmglist)
                //{
                //        total_dmg += dmg;
                //    }

                //    foreach (cid, dmg in this.dmglist)
                //{
                //        if (!(cid in this.gmap.map_players_bycid))
                //    {
                //            continue;
                //        }

                //        local target = this.gmap.map_players_bycid[cid];

                //        if (!this.is_ply_inzone(target.pinfo.sid))
                //        {
                //            continue;
                //        }

                //    // send self_attchange msg
                //    ::send_rpc(target.pinfo.sid, 32, { mondmg = dmg, total_mondmg = total_dmg, mid = this.mondata.mid});
                //    }

                //    this.notify_hate_tm = cur_tm_s + 2; // 2秒同步一次
                //}
            }

            if (this.check_pos_tm < now)
            {
                // 检查位置合法性
                var grid_pos = this.gmap.get_grid_by_pt(this.mondata.x, this.mondata.y);
                if (grid_pos == null || (this.mondata.x < 0) || (this.mondata.y < 0))
                {
                    int to_x = this.mondata.init_x * game_const.map_grid_pixel + 16;
                    int to_y = this.mondata.init_y * game_const.map_grid_pixel + 16;

                    Utility.trace_err("monster mid[" + this.mondata.mid + "] pos x[" + this.mondata.x + "] y[" + this.mondata.y + "] illegal correct to x[" + to_x + "] y[" + to_y + "]\n");

                    this.mondata.x = to_x;
                    this.mondata.y = to_y;

                    //this.broad_cast_zone_msg_and_self(8, { iid = this.mondata.iid, x = this.mondata.x, y = this.mondata.y});
                }

                this.check_pos_tm = now + 15; // 15秒检查一次
            }

            if (this.running_tm > 0)
            {
                //sys.trace(sys.SLT_DETAIL, "this.running_tm ["+this.running_tm+"] \n");
                this.running_tm -= time_elapsed;
                if (this.running_tm < 0) this.running_tm = 0;
            }

            //if (this.mondata.arrive)
            //{
            //    // 判断是否触发到达地点动作

            //    foreach (cond in this.mondata.arrive)
            //    {
            //        local arrive = cond.arrive[0];

            //        // 检查目标点到达条件
            //        local pos = { x = (this.mondata.x / game_const.map_grid_pixel).tointeger(), y = (this.mondata.y / game_const.map_grid_pixel).tointeger() };
            //        local distx = pos.x - arrive.x;
            //        local disty = pos.y - arrive.y;

            //        local dist2 = distx * distx + disty * disty;
            //        local cond2 = arrive.rad * arrive.rad;
            //        if (dist2 > cond2)
            //        {
            //            // 未到达指定地点
            //            continue;
            //        }

            //        // 到达指定地点
            //        if (_check_act_cond(cond, false))
            //        {
            //            _do_ai_act(cond.act, cur_clock_tm);
            //        }
            //    }
            //}
        }
Exemplo n.º 2
0
 var(gameWorld, timeEntity) = state;