BotClient.Scene.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. using CommonAI.Zone;
  2. using CommonAI.Zone.ZoneEditor;
  3. using CommonAI.ZoneClient;
  4. using CommonLang;
  5. using CommonLang.Vector;
  6. using pomelo.area;
  7. using pomelo.connector;
  8. using Pomelo.DotNetClient;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Text;
  13. using XmdsCommon.Message;
  14. using XmdsCommon.ZoneClient;
  15. using XmdsCommon.EditorData;
  16. namespace XmdsBattleClientBot.Bot
  17. {
  18. // 游戏服相关 //
  19. partial class BotClient
  20. {
  21. public EnterSceneResponse LastEnterSceneResponse { get; private set; }
  22. public ChangeAreaResponse LastChangeAreaResponse { get; private set; }
  23. public RegionManager CurrentRegionManager { get; private set; }
  24. public NpcManager CurrentNpcManager { get; private set; }
  25. public HZZoneLayer CurrentZoneLayer { get; private set; }
  26. public ZoneActor CurrentZoneActor { get; private set; }
  27. public CommonAI.Data.SceneType CurrentSceneType { get; private set; }
  28. public void SendUnitGuard(bool guard)
  29. {
  30. if(CurrentZoneActor != null)
  31. {
  32. CurrentZoneActor.SendUnitGuard(guard);
  33. }
  34. }
  35. private void callback_gs_ChangeAreaPush(ChangeAreaPush push)
  36. {
  37. CurrentSceneType = (CommonAI.Data.SceneType)push.s2c_sceneType;
  38. this.IsFree = (CurrentSceneType == CommonAI.Data.SceneType.Normal || CurrentSceneType == CommonAI.Data.SceneType.HUANJING);
  39. }
  40. public void gs_EnterScene(Action<EnterSceneResponse> action, Action<Exception> error = null)
  41. {
  42. lock (this)
  43. {
  44. //TODO
  45. this.Client.LoginHandler.Request_EnterScene("" ,(r) =>
  46. {
  47. this.LastEnterSceneResponse = r; action(r);
  48. }, (err) => { if (error != null) error(err); });
  49. }
  50. }
  51. /// <summary>
  52. /// </summary>
  53. /// <param name="name"></param>
  54. /// <param name="type">0:普通进入,1:收到弹框点确认进副本</param>
  55. /// <param name="action"></param>
  56. /// <param name="error"></param>
  57. public void gs_ChangeSceneByTransport(string name, int type, Action<ChangeAreaResponse> action, Action<Exception> error = null)
  58. {
  59. client.GameSocket.playerHandler.changeAreaRequest(name, type, (err, msg) =>
  60. {
  61. if (type == 0)
  62. {
  63. client.GameSocket.playerHandler.changeAreaRequest(name, 1, (ex1, msg1) =>
  64. {
  65. this.LastChangeAreaResponse = msg1;
  66. if (msg1 != null && action != null) { action(msg1); }
  67. if (ex1 != null && error != null) { error(ex1); }
  68. });
  69. }
  70. else
  71. {
  72. this.LastChangeAreaResponse = msg;
  73. if (msg != null && action != null) { action(msg); }
  74. if (err != null)
  75. {
  76. if (error != null)
  77. {
  78. error(err);
  79. } else
  80. {
  81. log.Log(err.Message);
  82. }
  83. }
  84. }
  85. });
  86. }
  87. //监听战斗层已创建
  88. private void callback_client_OnCreateBattleClient(XmdsBattleClient.Battle.XmdsBattleClient obj)
  89. {
  90. if (CurrentNpcManager != null)
  91. {
  92. CurrentNpcManager.Dispose();
  93. }
  94. CurrentNpcManager = new NpcManager(this);
  95. obj.Layer.LayerInit += callback_layer_OnInit;
  96. obj.Layer.ActorAdded += callback_layer_OnActorAdded;
  97. obj.Layer.DecorationChanged += callback_layer_OnDecorationChanged;
  98. obj.Layer.MessageReceived += callback_layer_MessageReceived;
  99. obj.Layer.OnScriptCommand += callback_layer_OnScriptCommand; ;
  100. }
  101. private void callback_layer_OnInit(CommonAI.ZoneClient.ZoneLayer layer)
  102. {
  103. CurrentZoneLayer = layer as HZZoneLayer;
  104. CurrentZoneActor = null;
  105. if (CurrentRegionManager != null)
  106. CurrentRegionManager.Dispose();
  107. CurrentRegionManager = new RegionManager(this);
  108. Client.GameSocket.resourceHandler.queryAreaDataRequest((ex, msg) =>
  109. {
  110. if (ex == null)
  111. {
  112. CurrentNpcManager.AddAreaNpcList(msg);
  113. }
  114. });
  115. }
  116. private void callback_layer_OnActorAdded(CommonAI.ZoneClient.ZoneLayer layer, CommonAI.ZoneClient.ZoneActor actor)
  117. {
  118. CurrentZoneActor = layer.Actor;
  119. if (CurrentRegionManager != null)
  120. {
  121. CurrentRegionManager.callback_layer_OnActorAdded(actor);
  122. }
  123. }
  124. private void callback_layer_OnDecorationChanged(CommonAI.ZoneClient.ZoneLayer layer, CommonAI.ZoneClient.ZoneEditorDecoration ed)
  125. {
  126. }
  127. private void callback_layer_MessageReceived(ZoneLayer layer, CommonLang.Protocol.IMessage e)
  128. {
  129. if (e is ScriptCommandEvent)
  130. {
  131. // ScriptCommandEvent evt = e as ScriptCommandEvent;
  132. // string[] evt_param = evt.message.Split('|');
  133. // if (evt_param.Length == 2)
  134. // {
  135. // object[] param = evt_param[1].Split(',');
  136. // string funcName = "GlobalHooks." + evt_param[0];
  137. // if (LuaScriptMgr.Instance.IsFuncExists(funcName))
  138. // {
  139. // LuaScriptMgr.Instance.CallLuaFunction(funcName, param);
  140. // }
  141. // }
  142. }
  143. else if (e is ScriptAddUnitEventsB2C)
  144. {
  145. CurrentNpcManager.AddNpc(e as ScriptAddUnitEventsB2C);
  146. }
  147. else if (e is ScriptRemoveUnitEventsB2C)
  148. {
  149. CurrentNpcManager.RemoveNpc(e as ScriptRemoveUnitEventsB2C);
  150. }
  151. }
  152. private void callback_layer_OnScriptCommand(ZoneLayer layer, string msg)
  153. {
  154. string[] cmds = msg.Split(new char[] { '|' });
  155. if (cmds[0] == "ScriptAddUnitEvent")
  156. {
  157. CurrentNpcManager.AddNPC(cmds);
  158. }
  159. else if (cmds[0] == "ScriptRemoveUnitEvent")
  160. {
  161. }
  162. }
  163. public class NpcManager : IDisposable
  164. {
  165. private readonly BotClient bot;
  166. private HashMap<uint, Npc> AreaNpcList = new HashMap<uint, Npc>();
  167. private HashMap<uint, ScriptAddUnitEventsB2C> ZoneNpcList = new HashMap<uint, ScriptAddUnitEventsB2C>();
  168. internal NpcManager(BotClient bot)
  169. {
  170. this.bot = bot;
  171. }
  172. public void Dispose()
  173. {
  174. AreaNpcList.Clear();
  175. ZoneNpcList.Clear();
  176. }
  177. internal void AddAreaNpcList(pomelo.area.QueryAreaDataResponse msg)
  178. {
  179. AreaNpcList.Clear();
  180. if (msg.s2c_npcs != null)
  181. {
  182. foreach (var npc in msg.s2c_npcs)
  183. {
  184. AreaNpcList.Add(npc.id, npc);
  185. }
  186. }
  187. }
  188. internal void AddNPC(string[] param)
  189. {
  190. int templateId = 0;
  191. int.TryParse(param[1], out templateId);
  192. //int x = 0;
  193. //int.TryParse(param[2], out x);
  194. //int y = 0;
  195. //int.TryParse(param[3], out y);
  196. // npcs[fake_id_count] = templateId;
  197. // --fake_id_count;
  198. }
  199. internal void AddNpc(ScriptAddUnitEventsB2C e)
  200. {
  201. ZoneNpcList.Put(e.ObjectID, e);
  202. }
  203. internal void RemoveNpc(ScriptRemoveUnitEventsB2C e)
  204. {
  205. ZoneNpcList.RemoveByKey(e.ObjectID);
  206. }
  207. /// <summary>
  208. /// 根据模板找单位
  209. /// </summary>
  210. /// <param name="templateID"></param>
  211. /// <returns></returns>
  212. public Vector2 GetNpcByTemplateID(int templateID)
  213. {
  214. foreach (var u in ZoneNpcList.Values)
  215. {
  216. if (u.TemplateID == templateID)
  217. {
  218. return new Vector2(u.X, u.Y);
  219. }
  220. }
  221. if (bot.CurrentZoneLayer != null)
  222. {
  223. foreach (var u in AreaNpcList.Values)
  224. {
  225. if (u.templateId == templateID)
  226. {
  227. var vu = bot.CurrentZoneLayer.GetUnit(u.id);
  228. if (vu != null)
  229. {
  230. return new Vector2(vu.X, vu.Y);
  231. }
  232. }
  233. }
  234. var tu = bot.CurrentZoneLayer.GetUnitByTemplateID(templateID);
  235. if (tu != null)
  236. {
  237. return new Vector2(tu.X, tu.Y);
  238. }
  239. var fu = bot.CurrentZoneLayer.GetUnitFlagByTemplateID(templateID);
  240. if (fu != null)
  241. {
  242. return new Vector2(fu.X, fu.Y);
  243. }
  244. }
  245. return null;
  246. }
  247. }
  248. public class RegionManager : IDisposable
  249. {
  250. private readonly BotClient bot;
  251. /// <summary>
  252. /// 客户端本地维护的Region集合
  253. /// </summary>
  254. private List<RegionData> mRegions = null;
  255. private List<SceneTransRegion> mSceneTransRegionList = null;
  256. internal RegionManager(BotClient bot)
  257. {
  258. this.bot = bot;
  259. this.mRegions = new List<RegionData>(bot.Client.BattleClient.Layer.Data.Regions);
  260. this.mSceneTransRegionList = new List<SceneTransRegion>();
  261. foreach (var flag in bot.Client.BattleClient.Layer.Flags)
  262. {
  263. var ab = flag.EditorData.GetAbilityOf<XmdsCommon.EditorData.XmdsSceneTransportAbilityData>();
  264. if (ab != null)
  265. {
  266. mSceneTransRegionList.Add(new SceneTransRegion(bot, flag, ab));
  267. }
  268. }
  269. }
  270. public void Dispose()
  271. {
  272. mRegions.Clear();
  273. mSceneTransRegionList.Clear();
  274. }
  275. public List<RegionData> AllRegions()
  276. {
  277. return new List<RegionData>(mRegions);
  278. }
  279. public List<SceneObjectData> AllTransports()
  280. {
  281. List<SceneObjectData> ret = new List<SceneObjectData>();
  282. for (int i = 0; i < mSceneTransRegionList.Count; i++)
  283. {
  284. ret.Add(mSceneTransRegionList[i].Data.EditorData);
  285. }
  286. return ret;
  287. }
  288. public bool CheckTrans(int type, bool force_trans, Action<Exception> error = null)
  289. {
  290. for (int i = 0; i < mSceneTransRegionList.Count; i++)
  291. {
  292. if (mSceneTransRegionList[i].CheckTrans(type, force_trans, error))
  293. {
  294. return true;
  295. }
  296. }
  297. return false;
  298. }
  299. internal void Update()
  300. {
  301. for (int i = 0; i < mSceneTransRegionList.Count; i++)
  302. {
  303. mSceneTransRegionList[i].Update();
  304. }
  305. }
  306. /// <summary>
  307. /// 监听主角进入
  308. /// </summary>
  309. /// <param name="actor"></param>
  310. internal void callback_layer_OnActorAdded(CommonAI.ZoneClient.ZoneActor actor)
  311. {
  312. for (int i = 0; i < mSceneTransRegionList.Count; i++)
  313. {
  314. mSceneTransRegionList[i].BindActor(actor);
  315. }
  316. }
  317. private class SceneTransRegion
  318. {
  319. private readonly BotClient bot;
  320. private AbilityData m_Ability = null;
  321. private ZoneFlag m_Data = null;
  322. private CommonAI.ZoneClient.ZoneActor mActor = null;
  323. private float mRadius = 0;
  324. private bool mSendMsg = true;
  325. public AbilityData Ability { get { return m_Ability; } }
  326. public ZoneFlag Data { get { return m_Data; } }
  327. internal SceneTransRegion(BotClient bot, ZoneFlag rd, AbilityData data)
  328. {
  329. this.bot = bot;
  330. this.m_Ability = data;
  331. this.m_Data = rd;
  332. this.mRadius = m_Data.EditorData.Radius;
  333. }
  334. internal void BindActor(CommonAI.ZoneClient.ZoneActor actor)
  335. {
  336. this.mActor = actor;
  337. }
  338. internal void Update()
  339. {
  340. if (mActor != null)
  341. {
  342. if (CMath.intersectRound(m_Data.X, m_Data.Y, mRadius, mActor.X, mActor.Y, mActor.BodySize))
  343. {
  344. if (mSendMsg == false)
  345. {
  346. mSendMsg = true;
  347. SendTransRequest(1, false);
  348. }
  349. }
  350. else
  351. {
  352. mSendMsg = false;
  353. }
  354. }
  355. }
  356. internal bool CheckTrans(int type, bool force_trans, Action<Exception> error = null)
  357. {
  358. if (mActor != null)
  359. {
  360. if (CMath.intersectRound(m_Data.X, m_Data.Y, mRadius, mActor.X, mActor.Y, mActor.BodySize))
  361. {
  362. return SendTransRequest(type, force_trans, error);
  363. }
  364. }
  365. return false;
  366. }
  367. //发送协议.
  368. private bool SendTransRequest(int type, bool force_trans, Action<Exception> error = null)
  369. {
  370. if (m_Data.Enable || force_trans)
  371. {
  372. bot.gs_ChangeSceneByTransport(m_Data.Name, type, (msg) => { }, error);
  373. return true;
  374. }
  375. return false;
  376. }
  377. }
  378. }
  379. public enum DungeonType
  380. {
  381. 单人副本 = 1,
  382. 组队副本 = 2,
  383. 秘境副本 = 3,
  384. 超级副本 = 4,
  385. }
  386. public enum DungeonLevel
  387. {
  388. 普通 = 1,
  389. 精英 = 2,
  390. 英雄 = 3,
  391. }
  392. }
  393. }