DisplayLayerWorld.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using GameEditorPlugin.Win32.Runtime;
  5. using CommonAI.ZoneClient;
  6. using System.Drawing;
  7. using System.Windows.Forms;
  8. using CommonLang;
  9. using CommonAIClient.Client;
  10. using CommonAI.Zone.ZoneEditor;
  11. using CommonLang.Protocol;
  12. using System.Drawing.Drawing2D;
  13. using CommonAI.Zone;
  14. using CommonAI.RTS;
  15. using CommonLang.Vector;
  16. using CommonAI.Zone.Helper;
  17. using CommonAI.Zone.Instance;
  18. using CommonLang.Property;
  19. using CommonAI.RTS.Manhattan;
  20. using CommonAI.ZoneClient.Agent;
  21. using CommonFroms.Drawing;
  22. namespace GameEditorPlugin.Win32.BattleClient
  23. {
  24. public class DisplayLayerWorld : DisplayManhattanTerrain
  25. {
  26. //--------------------------------------------------------------------
  27. [Desc("显示警戒范围", "show")]
  28. public bool ShowGuardRange = false;
  29. [Desc("显示攻击范围", "show")]
  30. public bool ShowAttackRange = false;
  31. [Desc("显示受击范围", "show")]
  32. public bool ShowDamageRange = false;
  33. [Desc("显示名字", "show")]
  34. public bool ShowName = false;
  35. [Desc("显示Flag名字", "show")]
  36. public bool ShowFlagName = false;
  37. [Desc("显示HP", "show")]
  38. public bool ShowHP = false;
  39. [Desc("显示详细日志", "show")]
  40. public bool ShowAllLog = false;
  41. //--------------------------------------------------------------------
  42. public static SolidBrush name_brush = new SolidBrush(Color.White);
  43. public static Font name_font = new Font(@"微软雅黑", 9f, FontStyle.Regular);
  44. public static Pen pen_write = new Pen(Color.White);
  45. public static Brush brush_hp = new SolidBrush(Color.FromArgb(0xff, 0, 0xff, 0));
  46. public static Brush brush_mp = new SolidBrush(Color.FromArgb(0xff, 0x80, 0x80, 0xff));
  47. public static Brush brush_black = new SolidBrush(Color.FromArgb(0xff, 0, 0, 0));
  48. public static Brush brush_attack = new SolidBrush(Color.FromArgb(0x80, 0xff, 0x00, 0x00));
  49. public readonly Random random = new Random();
  50. public float UpdateTimeScale = 1f;
  51. public bool Pause = false;
  52. private ZoneLayer layer;
  53. private AbstractBattle client;
  54. private HashMap<uint, DisplayLayerObject> objectes = new HashMap<uint, DisplayLayerObject>();
  55. private HashMap<string, DisplayGameFlag> flags = new HashMap<string, DisplayGameFlag>();
  56. private DisplayLayerObject selected_unit = null;
  57. private LocalClientStatus LocalStatus;
  58. private int mFPS = 0;
  59. public int UpdateIntervalMS { get; private set; }
  60. public DisplayLayerObject SelectedObject { get { return selected_unit; } }
  61. public ZoneLayer Layer { get { return layer; } }
  62. public AbstractBattle Client { get { return client; } }
  63. public int ObjectsCount { get { return this.Layer.ObjectsCount; } }
  64. //public int ServerObjectsCount { get { if (client is BattleLocal) { return (client as BattleLocal).Zone.AllObjectsCount; } return 0; } }
  65. public int FPS { get { return mFPS; } }
  66. public DisplayGameUnit DisplayActor
  67. {
  68. get
  69. {
  70. if (client.Actor != null)
  71. {
  72. return GetObject(client.Actor.ObjectID) as DisplayGameUnit;
  73. }
  74. return null;
  75. }
  76. }
  77. public int SpaceDIV
  78. {
  79. get
  80. {
  81. if (layer != null) return layer.SpaceDivSize;
  82. return 0;
  83. }
  84. }
  85. public override AstarManhattan PathFinder
  86. {
  87. get
  88. {
  89. if (layer != null) return layer.PathFinder;
  90. return null;
  91. }
  92. }
  93. public override int SpaceDivSize
  94. {
  95. get
  96. {
  97. if (layer != null) return layer.SpaceDivSize;
  98. return 0;
  99. }
  100. }
  101. public virtual void InitClient(AbstractBattle client)
  102. {
  103. this.layer = client.Layer;
  104. this.client = client;
  105. this.layer.LayerInit += OnLayerInit;
  106. this.layer.ObjectEnter += OnObjectEnter;
  107. this.layer.ObjectLeave += OnObjectLeave;
  108. this.layer.MessageReceived += OnMessageReceived;
  109. this.layer.ObjectMessageReceived += OnObjectMessageReceived;
  110. this.LocalStatus = new LocalClientStatus(this);
  111. }
  112. public override void Dispose()
  113. {
  114. this.client.Dispose();
  115. }
  116. public void SkipClientEvent()
  117. {
  118. LocalStatus.Skip();
  119. }
  120. //---------------------------------------------------
  121. private void OnLayerInit(ZoneLayer layer)
  122. {
  123. base.InitTerrain(layer.Terrain);
  124. foreach (DecorationData dt in layer.Data.Decorations)
  125. {
  126. ZoneEditorDecoration zed = layer.GetFlag<ZoneEditorDecoration>(dt.Name);
  127. DisplayGameDecoration gf = new DisplayGameDecoration(this, zed);
  128. flags.Add(dt.Name, gf);
  129. }
  130. setCameraScale(1, 1);
  131. setCamera(base.Terrain.TotalWidth / 2, base.Terrain.TotalHeight / 2);
  132. // if (client.Actor != null)
  133. // {
  134. // client.Actor.SendUnitGuard(true);
  135. // }
  136. }
  137. private void OnObjectEnter(ZoneLayer layer, ZoneObject obj)
  138. {
  139. if (obj is ZoneUnit)
  140. {
  141. DisplayGameUnit u = new DisplayGameUnit(this, obj as ZoneUnit);
  142. objectes.Add(obj.ObjectID, u);
  143. if (client.Actor != null && obj.ObjectID == client.Actor.ObjectID)
  144. {
  145. client.Actor.OnMoneyChanged += (ZoneUnit unit, int oldM, int newM) =>
  146. {
  147. showLog((newM - oldM).ToString(), unit.X, unit.Y, Color.Yellow);
  148. };
  149. client.Actor.OnHPChanged += (ZoneUnit unit, int oldM, int newM) =>
  150. {
  151. };
  152. client.Actor.OnMPChanged += (ZoneUnit unit, int oldM, int newM) =>
  153. {
  154. };
  155. }
  156. }
  157. if (obj is ZoneSpell)
  158. {
  159. DisplayGameSpell u = new DisplayGameSpell(this, obj as ZoneSpell);
  160. objectes.Add(obj.ObjectID, u);
  161. }
  162. if (obj is ZoneItem)
  163. {
  164. DisplayGameItem u = new DisplayGameItem(this, obj as ZoneItem);
  165. objectes.Add(obj.ObjectID, u);
  166. }
  167. }
  168. private void OnObjectLeave(ZoneLayer layer, ZoneObject obj)
  169. {
  170. objectes.RemoveByKey(obj.ObjectID);
  171. showLog("ObjectLeave: " + obj.Name, obj.X, obj.Y);
  172. }
  173. private void OnMessageReceived(ZoneLayer layer, IMessage msg)
  174. {
  175. LocalStatus.onEvent(msg);
  176. }
  177. private void OnObjectMessageReceived(ZoneLayer layer, IMessage msg, ZoneObject obj)
  178. {
  179. if (msg is UnitDoActionEvent)
  180. {
  181. showLog("UnitDoAction: " + obj.Name + " - " + (msg as UnitDoActionEvent).ActionName, obj.X, obj.Y);
  182. }
  183. else if (ShowAllLog)
  184. {
  185. showLog(msg.ToString(),
  186. obj.X + (float)(random.NextDouble() * obj.RadiusSize * 2),
  187. obj.Y + (float)(random.NextDouble() * obj.RadiusSize * 2));
  188. }
  189. }
  190. //---------------------------------------------------
  191. virtual protected void clientUpdate(int intervalMS)
  192. {
  193. client.BeginUpdate(intervalMS);
  194. client.Update();
  195. }
  196. override public void update(int intervalMS)
  197. {
  198. this.UpdateIntervalMS = intervalMS;
  199. this.LocalStatus.update(intervalMS);
  200. this.clientUpdate((int)(intervalMS * UpdateTimeScale));
  201. base.update(intervalMS);
  202. if (intervalMS > 0)
  203. {
  204. this.mFPS = (int)(1000 / intervalMS);
  205. }
  206. }
  207. //---------------------------------------------------
  208. #region Render
  209. protected readonly Pen pen_icon_border = new Pen(Color.Gray);
  210. protected readonly Brush brush_icon_body = new SolidBrush(Color.FromArgb(0xFF, 0x40, 0x40, 0x40));
  211. protected readonly Brush brush_icon_cd = new SolidBrush(Color.FromArgb(0x80, 0xFF, 0xFF, 0xFF));
  212. protected readonly Brush brush_text = new SolidBrush(Color.White);
  213. protected readonly Brush brush_text_error = new SolidBrush(Color.Red);
  214. protected readonly Brush brush_gauge = new SolidBrush(Color.FromArgb(0xA0, 0x20, 0xFF, 0x20));
  215. protected readonly Pen pen_path = new Pen(Color.White);
  216. override public void render(Graphics g)
  217. {
  218. base.render(g);
  219. LocalStatus.render(g);
  220. }
  221. protected override void renderObjects(Graphics g, RectangleF worldBounds)
  222. {
  223. drawObjectes(g, worldBounds, flags.Values);
  224. drawObjectes(g, worldBounds, objectes.Values);
  225. renderActorInMap(g, worldBounds);
  226. if (OnRenderLayer != null)
  227. {
  228. OnRenderLayer.Invoke(g, this);
  229. }
  230. }
  231. protected virtual void renderActorInMap(Graphics g, RectangleF worldBounds)
  232. {
  233. if (DisplayActor != null)
  234. {
  235. var actor = DisplayActor.Data as ZoneActor;
  236. if (actor != null)
  237. {
  238. var agent = actor.GetAgentByType<ActorMoveAgent>();
  239. if (agent != null && !agent.IsEnd)
  240. {
  241. pen_path.Width = 1f / getCameraScale();
  242. drawPath(g, new Vector2(actor.X, actor.Y), agent.WayPoints, pen_path, pen_path);
  243. }
  244. }
  245. }
  246. }
  247. protected override void renderScreen(Graphics g, RectangleF worldBounds)
  248. {
  249. renderUnitsHUD(g, flags.Values, worldBounds);
  250. renderUnitsHUD(g, objectes.Values, worldBounds);
  251. if (layer.Actor != null)
  252. {
  253. renderObjectHUD(g, 0, WindowH, AnchorStyles.Bottom | AnchorStyles.Left, layer.Actor);
  254. }
  255. if (SelectedObject is DisplayGameUnit)
  256. {
  257. renderObjectHUD(g, WindowW / 2, 0, AnchorStyles.Top | AnchorStyles.Left, (SelectedObject as DisplayGameUnit).Data);
  258. }
  259. renderHUD(g);
  260. if (OnRenderHUD != null)
  261. {
  262. OnRenderHUD.Invoke(g, this);
  263. }
  264. }
  265. private void renderUnitsHUD<T>(Graphics g, ICollection<T> list, RectangleF rect) where T : DisplayObject
  266. {
  267. foreach (var u in list)
  268. {
  269. if (CMath.intersectRect2(
  270. rect.X,
  271. rect.Y,
  272. rect.Width,
  273. rect.Height,
  274. u.X + u.LocalBounds.X,
  275. u.Y + u.LocalBounds.Y,
  276. u.LocalBounds.Width,
  277. u.LocalBounds.Height))
  278. {
  279. System.Drawing.Drawing2D.GraphicsState state = g.Save();
  280. g.TranslateTransform(
  281. worldToScreenX(u.X),
  282. worldToScreenY(u.Y));
  283. if (ShowHP)
  284. {
  285. u.renderHP(g);
  286. }
  287. if (ShowName)
  288. {
  289. u.renderName(g, font, name_brush);
  290. }
  291. g.Restore(state);
  292. }
  293. }
  294. }
  295. protected virtual void renderHUD(Graphics g)
  296. {
  297. float sw = WindowW / 2;
  298. float sy = 1;
  299. var rect_text = new TextRect();
  300. GraphicsState gs = g.Save();
  301. {
  302. {
  303. TimeSpan time = new TimeSpan(0, 0, 0, 0, (int)layer.ServerTimeMS);
  304. StringBuilder sb = new StringBuilder();
  305. sb.Append(" Time=" + time);
  306. sb.Append(" TimeScale=" + (this.UpdateTimeScale * 100) + "%");
  307. sb.Append(" Paused=" + (this.Pause));
  308. sb.Append(" LayerObjects=" + this.ObjectsCount);
  309. if ((client is BattleLocal))
  310. {
  311. sb.Append(" ZoneObjects=" + (client as BattleLocal).Zone.AllObjectsCount);
  312. }
  313. sy += rect_text.SetText(sb.ToString()).Draw(g, 1, sy, sw, 0);
  314. }
  315. {
  316. string mem = string.Format("SZ={0}/{1} SO={2}/{3} CZ={4}/{5} CO={6}/{7}",
  317. InstanceZone.ActiveZoneCount, InstanceZone.AllocZoneCount,
  318. InstanceZoneObject.ActiveObjectCount, InstanceZoneObject.AllocObjectCount,
  319. ZoneLayer.ActiveZoneLayerCount, ZoneLayer.AllocZoneLayerCount,
  320. ZoneObject.ActiveObjectCount, ZoneObject.AllocObjectCount);
  321. sy += rect_text.SetText(mem).Draw(g, 1, sy, sw, 0);
  322. }
  323. {
  324. string head = string.Format(" FPS={0} Mouse=({1} , {2})",
  325. this.FPS,
  326. screenToWorldX(base.MouseX).ToString("#0.0"),
  327. screenToWorldY(base.MouseY).ToString("#0.0"));
  328. sy += rect_text.SetText(head).Draw(g, 1, sy, sw, 0);
  329. }
  330. }
  331. if (client.IsNet)
  332. {
  333. StringBuilder sb = new StringBuilder();
  334. sb.Append(" Send=" + client.SendPackages);
  335. sb.Append(" Recv=" + client.RecvPackages);
  336. sb.Append(" Ping=" + client.CurrentPing);
  337. if (client.KickMessage != null)
  338. {
  339. sb.Append(" Kicked=" + client.KickMessage.message);
  340. }
  341. sy += rect_text.SetText(sb.ToString()).Draw(g, 1, sy, sw, 0);
  342. }
  343. if (client.Layer.ServerStatus != null)
  344. {
  345. var state = client.Layer.ServerStatus;
  346. List<string> sb = new List<string>();
  347. sb.Add("ServerStatus:");
  348. sb.Add(" PID=" + state.PID);
  349. sb.Add(" ActiveGameObjectCount=" + state.ActiveGameObjectCount);
  350. sb.Add(" ActiveInstanceZoneCount=" + state.ActiveInstanceZoneCount);
  351. sb.Add(" PrivateMemorySize=" + CUtils.ToBytesSizeString(state.PrivateMemorySize64));
  352. foreach (var line in sb)
  353. {
  354. sy += rect_text.SetText(line).Draw(g, 1, sy, sw, 0);
  355. }
  356. }
  357. {
  358. sy += rect_text.SetText(" 环境变量:").Draw(g, 1, sy, sw, 0);
  359. foreach (string evk in Layer.ListEnvironmentVars())
  360. {
  361. sy += rect_text.SetText(string.Format(" {0} = {1}", evk, Layer.GetEnvironmentVar(evk))).Draw(g, 1, sy, sw, 0);
  362. }
  363. if (Layer.Actor != null)
  364. {
  365. sy += rect_text.SetText(" 单位环境变量:").Draw(g, 1, sy, sw, 0);
  366. foreach (string evk in Layer.Actor.ListEnvironmentVars())
  367. {
  368. sy += rect_text.SetText(string.Format(" {0} = {1}", evk, Layer.Actor.GetEnvironmentVar(evk))).Draw(g, 1, sy, sw, 0);
  369. }
  370. }
  371. }
  372. g.Restore(gs);
  373. }
  374. protected virtual void renderObjectHUD(Graphics g, float start_x, float start_y, AnchorStyles anc, ZoneUnit unit)
  375. {
  376. float sy = start_y;
  377. var text_line = new TextLine() { anchor = anc };
  378. var gauge_line = new GaugeStrip() { anchor = anc };
  379. #region status
  380. {
  381. StringBuilder tl = new StringBuilder();
  382. using (var timelines = ListObjectPool<bool>.AllocAutoRelease())
  383. {
  384. unit.GetMultiTimeLineStatus(timelines);
  385. foreach (var e in timelines) { tl.Append((e ? 1 : 0)); }
  386. }
  387. string text = string.Format("OID={6} UUID={0} Force={12} HP={1}/{2} MP={3}/{4} SP={5} State={7} Speed={8} FCR={9} Level={10} TL[{11}]",
  388. unit.PlayerUUID,
  389. unit.HP, unit.MaxHP,
  390. unit.MP, unit.MaxMP,
  391. unit.SP,
  392. unit.ObjectID,
  393. unit.CurrentState,
  394. unit.MoveSpeedSEC / unit.Info.MoveSpeedSEC,
  395. unit.FastCastRate,
  396. unit.Level,
  397. tl,
  398. unit.Force);
  399. sy += text_line.SetText(text.ToString()).Draw(g, start_x, sy, 0, 0);
  400. }
  401. #endregion
  402. #region skills
  403. using (var skills = ListObjectPool<ZoneActor.SkillState>.AllocAutoRelease())
  404. {
  405. unit.GetSkillStatus(skills);
  406. if (skills.Count > 0)
  407. {
  408. var gauge_fan = new GaugeRectFan() { anchor = anc };
  409. float sw = 50;
  410. float sh = 50;
  411. float sx = start_x;
  412. float dy = 0;
  413. int i = 0;
  414. foreach (ZoneActor.SkillState ss in skills)
  415. {
  416. gauge_fan.text_brush = ss.IsActive ? brush_text : this.brush_text_error;
  417. dy = gauge_fan
  418. .SetText(ss.Data.Name, (ss.IsActive ? ToSkillShortKey(i) : null))
  419. .SetPercent(ss.CDPercent)
  420. .Draw(g, sx, sy, sw, sh);
  421. sx += sw;
  422. i++;
  423. }
  424. sy += dy;
  425. }
  426. }
  427. #endregion
  428. #region items
  429. if (unit is ZoneActor)
  430. {
  431. var actor = unit as ZoneActor;
  432. using (var items = ListObjectPool<ZoneActor.ItemSlot>.AllocAutoRelease())
  433. {
  434. actor.GetItemSlots(items);
  435. if (items.Count > 0)
  436. {
  437. var gauge_fan = new GaugeRectFan() { anchor = anc };
  438. float sw = 40;
  439. float sh = 40;
  440. float sx = start_x;
  441. float dy = 0;
  442. int i = 0;
  443. foreach (ZoneActor.ItemSlot item in items)
  444. {
  445. if (!item.IsEmpty)
  446. {
  447. string text1 = null;
  448. string text2 = null;
  449. float pct = 0;
  450. text1 = item.Data.Name;
  451. text2 = "x" + item.Count;
  452. var cd = actor.GetCoolDownItem(item.Data.ID);
  453. if (cd != null) pct = cd.Percent;
  454. dy = gauge_fan
  455. .SetText(text1, text2)
  456. .SetPercent(pct)
  457. .Draw(g, sx, sy, sw, sh);
  458. sx += sw;
  459. }
  460. i++;
  461. }
  462. sy += dy;
  463. }
  464. }
  465. }
  466. #endregion
  467. #region buffs
  468. using (var buffs = ListObjectPool<ZoneUnit.BuffState>.AllocAutoRelease())
  469. {
  470. unit.GetBuffStatus(buffs);
  471. if (buffs.Count > 0)
  472. {
  473. var gauge_fan = new GaugeRectFan() { anchor = anc };
  474. float sw = 20;
  475. float sh = 20;
  476. float sx = start_x;
  477. float dy = 0;
  478. int i = 0;
  479. foreach (ZoneActor.BuffState bs in buffs)
  480. {
  481. dy = gauge_fan
  482. .SetText(bs.Data.Name, null)
  483. .SetPercent(bs.CDPercent)
  484. .Draw(g, sx, sy, sw, sh);
  485. sx += sw;
  486. i++;
  487. }
  488. sy += dy;
  489. }
  490. }
  491. #endregion
  492. if (unit.ChantingSkill != null)
  493. {
  494. var ss = unit.ChantingSkill;
  495. float pct = (unit.ChantingSkillPassMS / (float)unit.ChantingSkillTotalMS);
  496. sy += gauge_line
  497. .SetText("吟唱:" + ss.Data.Name)
  498. .SetPercent(pct)
  499. .Draw(g, start_x + 4, sy, 200, 0);
  500. }
  501. if (unit.CurrentSkillAction != null)
  502. {
  503. var skill = unit.CurrentSkillAction;
  504. sy += gauge_line
  505. .SetText("引导:" + skill.SkillData.Name + "(" + skill.CurrentActionIndex + ")")
  506. .SetPercent(1 - skill.ExpirePercent)
  507. .Draw(g, start_x + 4, sy, 200, 0);
  508. }
  509. if (unit.PickEvent != null)
  510. {
  511. var pick = unit.PickEvent;
  512. sy += gauge_line
  513. .SetText("检取:" + pick.Tag.object_id)
  514. .SetPercent(pick.Percent)
  515. .Draw(g, start_x + 4, sy, 200, 0);
  516. }
  517. #region name
  518. {
  519. sy += text_line.SetText(unit.DisplayName).Draw(g, start_x, sy, 0, 0);
  520. }
  521. #endregion
  522. }
  523. #endregion
  524. //---------------------------------------------------
  525. public DisplayLayerObject GetObject(uint id)
  526. {
  527. return objectes.Get(id);
  528. }
  529. public DisplayGameFlag GetFlag(string name)
  530. {
  531. return flags.Get(name);
  532. }
  533. public DisplayGameUnit GetUnitByName(string name)
  534. {
  535. foreach (DisplayLayerObject u in objectes.Values)
  536. {
  537. if (u is DisplayGameUnit)
  538. {
  539. if (name.Equals((u as DisplayGameUnit).Name))
  540. {
  541. return u as DisplayGameUnit;
  542. }
  543. }
  544. }
  545. return null;
  546. }
  547. public DisplayLayerObject PickObject(float x, float y)
  548. {
  549. foreach (DisplayLayerObject u in objectes.Values)
  550. {
  551. if (u is DisplayGameSpell) continue;
  552. if (CMath.includeRectPoint2(
  553. u.X + u.LocalBounds.X,
  554. u.Y + u.LocalBounds.Y,
  555. u.LocalBounds.Width,
  556. u.LocalBounds.Height,
  557. x, y))
  558. {
  559. selected_unit = u;
  560. return selected_unit;
  561. }
  562. }
  563. selected_unit = null;
  564. return null;
  565. }
  566. public virtual string ToSkillShortKey(int index)
  567. {
  568. index++;
  569. if (index >= 1 && index <= 9) { return (index).ToString(); }
  570. if (index == 10) { return "0"; }
  571. if (index >= 11 && index <= 19) { return "num" + (index - 10).ToString(); }
  572. if (index == 20) { return "num0"; }
  573. return "";
  574. }
  575. public virtual int ToSkillIndex(Keys key)
  576. {
  577. if (key >= Keys.D1 && key <= Keys.D9)
  578. {
  579. int i = (key - Keys.D1);
  580. return i;
  581. }
  582. if (key == Keys.D0) { return 9; }
  583. if (key >= Keys.NumPad1 && key <= Keys.NumPad9)
  584. {
  585. int i = (key - Keys.NumPad1);
  586. return 10 + i;
  587. }
  588. if (key == Keys.NumPad0) { return 19; }
  589. return int.MaxValue;
  590. }
  591. public void ActorLaunchSkill(KeyEventArgs e, float mouseX, float mouseY)
  592. {
  593. ZoneActor actor = layer.Actor;
  594. if (actor != null)
  595. {
  596. List<ZoneActor.SkillState> status = actor.GetSkillStatus();
  597. int i = ToSkillIndex(e.KeyCode);
  598. if (i < status.Count)
  599. {
  600. ZoneActor.SkillState ss = status[i];
  601. actor.SendUnitLaunchSkill(ss.Data.ID, mouseX, mouseY);
  602. }
  603. }
  604. }
  605. public void ActorLaunchSkill(KeyEventArgs e, ZoneObject target)
  606. {
  607. ZoneActor actor = layer.Actor;
  608. if (actor != null)
  609. {
  610. List<ZoneActor.SkillState> status = actor.GetSkillStatus();
  611. int i = ToSkillIndex(e.KeyCode);
  612. if (i < status.Count)
  613. {
  614. ZoneActor.SkillState ss = status[i];
  615. actor.SendUnitLaunchSkill(ss.Data.ID, target.ObjectID);
  616. }
  617. }
  618. }
  619. public void ActorUseItem(KeyEventArgs e)
  620. {
  621. ZoneActor actor = layer.Actor;
  622. if (actor != null)
  623. {
  624. List<ZoneActor.ItemSlot> items = actor.GetItemSlots();
  625. int i = ToSkillIndex(e.KeyCode);
  626. if (i < items.Count)
  627. {
  628. ZoneActor.ItemSlot slot = items[i];
  629. actor.SendUnitUseItem(i);
  630. }
  631. }
  632. }
  633. //---------------------------------------------------
  634. class LocalClientStatus
  635. {
  636. public readonly DisplayLayerWorld Layer;
  637. private Vector2 mCameraPos = new Vector2();
  638. private bool mPause = false;
  639. private long mTimer;
  640. public LookAtEvent LookAt;
  641. public CameraMoveToEvent CameraMoveTo;
  642. public CameraFocusUnitEvent CameraFocus;
  643. public CameraZoomToEvent CameraZoomTo;
  644. public CameraRotateToEvent CameraRotateTo;
  645. public LocalClientStatus(DisplayLayerWorld layer)
  646. {
  647. this.Layer = layer;
  648. }
  649. public void Skip()
  650. {
  651. mPause = false;
  652. CameraMoveTo = null;
  653. CameraFocus = null;
  654. CameraZoomTo = null;
  655. CameraRotateTo = null;
  656. }
  657. internal void onEvent(IMessage evt)
  658. {
  659. if (evt is LookAtEvent)
  660. {
  661. LookAt = evt as LookAtEvent;
  662. }
  663. else if (evt is ChangeTimeScaleEvent)
  664. {
  665. ChangeTimeScaleEvent ctse = evt as ChangeTimeScaleEvent;
  666. Layer.UpdateTimeScale = ctse.TimeScalePct / 100f;
  667. }
  668. else if (evt is GamePauseEvent)
  669. {
  670. mPause = true;
  671. }
  672. else if (evt is GameResumeEvent)
  673. {
  674. mPause = false;
  675. }
  676. else if (evt is CameraResetEvent)
  677. {
  678. CameraMoveTo = null;
  679. CameraFocus = null;
  680. CameraZoomTo = null;
  681. CameraRotateTo = null;
  682. }
  683. else
  684. {
  685. if (evt is CameraMoveToEvent)
  686. CameraMoveTo = evt as CameraMoveToEvent;
  687. if (evt is CameraFocusUnitEvent)
  688. CameraFocus = evt as CameraFocusUnitEvent;
  689. if (evt is CameraZoomToEvent)
  690. CameraZoomTo = evt as CameraZoomToEvent;
  691. if (evt is CameraRotateToEvent)
  692. CameraRotateTo = evt as CameraRotateToEvent;
  693. }
  694. }
  695. internal void update(int intervalMS)
  696. {
  697. if (CameraMoveTo != null)
  698. {
  699. MathVector.moveTo(mCameraPos, CameraMoveTo.x, CameraMoveTo.y, MoveHelper.GetDistance(intervalMS, CameraMoveTo.MoveSpeedSec));
  700. Layer.setCamera(mCameraPos.X, mCameraPos.Y);
  701. }
  702. if (CameraFocus != null)
  703. {
  704. DisplayLayerObject obj = Layer.GetObject(CameraFocus.ObjectID);
  705. if (obj != null)
  706. {
  707. mCameraPos.SetX(obj.X);
  708. mCameraPos.SetY(obj.Y);
  709. Layer.setCamera(mCameraPos.X, mCameraPos.Y);
  710. }
  711. }
  712. if (mPause)
  713. {
  714. Layer.Pause = true;
  715. }
  716. mCameraPos.SetX(Layer.CameraX);
  717. mCameraPos.SetY(Layer.CameraY);
  718. mTimer += intervalMS;
  719. }
  720. internal void render(Graphics g)
  721. {
  722. if (LookAt != null)
  723. {
  724. float s = ((float)(Math.Abs(Math.Sin(mTimer / 100f) * 10))) + 1;
  725. float x = Layer.worldToScreenX(LookAt.x);
  726. float y = Layer.worldToScreenY(LookAt.y);
  727. g.DrawArc(DisplayLayerWorld.pen_write, x - s, y - s, s * 2, s * 2, 0, 360);
  728. }
  729. }
  730. }
  731. //---------------------------------------------------
  732. [Desc("渲染完HUD时触发")]
  733. public event OnRenderHUDHandler OnRenderHUD;
  734. public delegate void OnRenderHUDHandler(Graphics g, DisplayLayerWorld world);
  735. [Desc("渲染完场景时触发")]
  736. public event OnRenderLayerHandler OnRenderLayer;
  737. public delegate void OnRenderLayerHandler(Graphics g, DisplayLayerWorld world);
  738. }
  739. }