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); // } // } //} }
var(gameWorld, timeEntity) = state;