public const string file_folder = "";// @"D:\PrimaryServer\whserver\\"; public Grd(map_conf map) { this.width = map.width; this.height = map.height; FileStream fs = new FileStream(file_folder + map.map_grd.file, FileMode.Open); StreamReader sr = new StreamReader(fs); var ba = sr.ReadToEnd().ToCharArray(); length = ba.Length / 2; grd_ary = new Point2D[length]; List<Point2D> walkables = new List<Point2D>(); for (int i = 0; i < length; i++) { short ba1 = (short)(((short)ba[i * 2]) << 8); short ba2 = (short)ba[i * 2 + 1]; //short g_walkable = (short)(((short)ba[i * 2]) << 8 + ba[i * 2 + 1]); int g_walkable = ba1 + ba2; Point2D grid = new Point2D(i / this.width, i % this.width); grid.walkable = g_walkable; grid.distance = int.MaxValue; grid.index = i; grd_ary[i] = grid; if (g_walkable == 0) walkables.Add(grid); } walkable_grd = walkables.ToArray(); sr.Close(); fs.Close(); }
public void _move_to_patrol_node() { var patrol = this.mondata.patrol; // 寻路 Point2D cur_grid = new Point2D((this.mondata.x / game_const.map_grid_pixel), (this.mondata.y / game_const.map_grid_pixel)); var path = gmap.find_path(cur_grid.x, cur_grid.y, patrol.movto.x, patrol.movto.y); //sys.trace(sys.SLT_DETAIL, "find path["+path+"]\n"); if (path != null && path.Count > 0) { // 移动 this.mondata.moving = new moving() { start_tm = Utility.time(), pts = path, to_x = patrol.movto.x, to_y = patrol.movto.y, float_x = (this.mondata.x), float_y = (this.mondata.y) }; //local data = { start_tm = this.mondata.moving.start_tm, iid = this.mondata.iid, frm_x = this.mondata.x, frm_y = this.mondata.y, to_x = patrol.movto.x, to_y = patrol.movto.y }; // send move msg to clients //gmap.broadcast_map_rpc(9, data); //sys.trace(sys.SLT_DETAIL, "patrol move: ply_cnt["+this.get_inz_ply_cnt()+"]\n"); //sys.dumpobj(data); //this.broad_cast_zone_msg(9, data); } else { // 寻路失败,跳过这个节点 //sys.trace(sys.SLT_ERR, "map["+gmap.mapid+"] monster mid["+this.mondata.mid+"] patrol node idx["+patrol.idx+"] find path err, path:\n"); //sys.dumpobj(path); patrol.movto = null; ++patrol.idx; if (patrol.idx >= patrol.path.Count) { patrol.idx = 0; --this.mondata.patrol.cnt; } } }
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); // } // } //} }
public void update_ai_mover(long c_tm) { if (c_tm <= next_mov_tm) return; long now = DateTime.Now.ToBinary(); if (this.mondata.patrol == null && this.mondata.moving == null && this.mondata.speed > 0) { bool ifmove = false; Point2D grid = new Point2D(this.mondata.init_x, this.mondata.init_y); int start_x = (int)grid.x - this.mondata.r_x; int start_y = (int)grid.y - this.mondata.r_y; if (start_x < 0) start_x = 0; if (start_y < 0) start_y = 0; int end_x = start_x + 2 * this.mondata.r_x; int end_y = start_y + 2 * this.mondata.r_y; Point2D cur_grid = new Point2D(this.mondata.x / StaticStuff.GRID_WIDTH, this.mondata.y / StaticStuff.GRID_WIDTH); if (start_x > cur_grid.x || start_y > cur_grid.y || end_x < cur_grid.x || end_y < cur_grid.y) ifmove = true; else { if (this.monconf.ai.mover > 0 && new Random().Next(0, 100) < monconf.ai.mover) { ifmove = true; } } if (ifmove && this.mondata.speed > 0) { int to_x = Utility.random(start_x, end_x + 1); int to_y = Utility.random(start_y, end_y + 1); List<Point2D> path = Utility.findPath(this.gmap.mapid, cur_grid, new Point2D(to_x, to_y)); if (null != path && path.Count > 0) { moving move = new moving(); this.mondata.moving = move; move.start_tm = now; move.pts = path; move.to_x = to_x; move.to_y = to_y; move.float_x = this.mondata.x; move.float_y = this.mondata.y; //TODO broadcast } } } this.next_mov_tm = now + this.monconf.ai.thinktm; }
public bool _move_to(int x, int y) { if (this.mondata.speed <= 0) return true; Point2D cur_grid = new Point2D() { x = this.mondata.x / StaticStuff.GRID_WIDTH, y = this.mondata.y / StaticStuff.GRID_WIDTH }; List<Point2D> path = new List<Point2D>();//TODO 产生路径 if (null == path) return false; if (path.Count <= 0) return false; this.mondata.moving = new moving() { start_tm = Utility.time(), pts = path, to_x = x, to_y = y, float_x = (this.mondata.x), float_y = (this.mondata.y) }; return true; }
public static Point2D valpoint_on_line(IMapUnit frm_mapUnit, IPoint2D to_pos, int max_rang, int sublen = 0) { Point2D frm_pos = new Point2D(frm_mapUnit.x, frm_mapUnit.y); return valpoint_on_line(frm_pos, to_pos, max_rang, sublen); }
public static List<Point2D> findPath(int mapid, Point2D start_grid, Point2D end_grid) { return findPath(mapid, (int)start_grid.x, (int)start_grid.y, (int)end_grid.x, (int)end_grid.y); }
public static Point2D normalize_vec2(Point2D point) { return normalize_vec2(point.x, point.y); }