QuestDialogs.cs 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992
  1. using System.Diagnostics;
  2. using System.Text.RegularExpressions;
  3. using System.Threading.Tasks;
  4. using Client.MirControls;
  5. using Client.MirGraphics;
  6. using Client.MirNetwork;
  7. using Client.MirObjects;
  8. using Client.MirSounds;
  9. using SlimDX.Direct3D9;
  10. using C = ClientPackets;
  11. using Font = System.Drawing.Font;
  12. namespace Client.MirScenes.Dialogs
  13. {
  14. public sealed class QuestListDialog : MirImageControl
  15. {
  16. private readonly MirButton _acceptButton, _finishButton;
  17. private MirLabel _availableQuestLabel;
  18. public List<ClientQuestProgress> Quests = new List<ClientQuestProgress>();
  19. public int SelectedIndex = 0;
  20. public ClientQuestProgress SelectedQuest;
  21. public QuestMessage Message;
  22. public QuestRewards Reward;
  23. public QuestRow[] Rows = new QuestRow[5];
  24. public int StartIndex = 0;
  25. public uint CurrentNPCID = 0;
  26. public QuestListDialog()
  27. {
  28. Index = 950;
  29. Library = Libraries.Prguse;
  30. Movable = true;
  31. Sort = true;
  32. Location = new Point(GameScene.Scene.NPCDialog.Size.Width + 47, 0);
  33. MirImageControl TitleLabel = new MirImageControl
  34. {
  35. Index = 14,
  36. Library = Libraries.Title,
  37. Location = new Point(18, 9), //Y = 9
  38. Parent = this
  39. };
  40. #region QuestSelection
  41. MirButton upQuestButton = new MirButton
  42. {
  43. Index = 951,
  44. HoverIndex = 952,
  45. PressedIndex = 953,
  46. Library = Libraries.Prguse,
  47. Parent = this,
  48. Location = new Point(291, 35),
  49. Sound = SoundList.ButtonA,
  50. };
  51. upQuestButton.Click += (o, e) =>
  52. {
  53. if (SelectedQuest != null)
  54. {
  55. SelectedIndex = FindSelectedIndex();
  56. if (SelectedIndex > 0)
  57. SelectedIndex--;
  58. else
  59. StartIndex--;
  60. }
  61. RefreshInterface();
  62. };
  63. MirButton downQuestButton = new MirButton
  64. {
  65. Index = 957,
  66. HoverIndex = 958,
  67. PressedIndex = 959,
  68. Library = Libraries.Prguse,
  69. Parent = this,
  70. Location = new Point(291, 83),
  71. Sound = SoundList.ButtonA,
  72. };
  73. downQuestButton.Click += (o, e) =>
  74. {
  75. if (SelectedQuest != null)
  76. {
  77. SelectedIndex = FindSelectedIndex();
  78. if (SelectedIndex < Rows.Length - 1)
  79. SelectedIndex++;
  80. else
  81. StartIndex++;
  82. }
  83. RefreshInterface();
  84. };
  85. #endregion
  86. #region Buttons
  87. _acceptButton = new MirButton
  88. {
  89. Index = 270,
  90. HoverIndex = 271,
  91. PressedIndex = 272,
  92. Library = Libraries.Title,
  93. Parent = this,
  94. Location = new Point(40, 436),
  95. Sound = SoundList.ButtonA,
  96. };
  97. _acceptButton.Click += (o, e) =>
  98. {
  99. if (Reward == null || SelectedQuest.Taken) return;
  100. Network.Enqueue(new C.AcceptQuest { NPCIndex = SelectedQuest.QuestInfo.NPCIndex, QuestIndex = SelectedQuest.QuestInfo.Index });
  101. //Hide();
  102. };
  103. _finishButton = new MirButton
  104. {
  105. Index = 273,
  106. HoverIndex = 274,
  107. PressedIndex = 275,
  108. Library = Libraries.Title,
  109. Parent = this,
  110. Location = new Point(40, 436),
  111. Sound = SoundList.ButtonA,
  112. Visible = false
  113. };
  114. _finishButton.Click += (o, e) =>
  115. {
  116. if (Reward == null || !SelectedQuest.Completed) return;
  117. if (Reward.SelectedItemIndex < 0 && SelectedQuest.QuestInfo.RewardsSelectItem.Count > 0)
  118. {
  119. MirMessageBox messageBox = new MirMessageBox(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.YouMustSelectRewardItem));
  120. messageBox.Show();
  121. return;
  122. }
  123. Network.Enqueue(new C.FinishQuest { QuestIndex = SelectedQuest.QuestInfo.Index, SelectedItemIndex = Reward.SelectedItemIndex });
  124. //Hide();
  125. };
  126. MirButton leaveButton = new MirButton
  127. {
  128. Index = 276,
  129. HoverIndex = 277,
  130. PressedIndex = 278,
  131. Library = Libraries.Title,
  132. Parent = this,
  133. Location = new Point(205, 436),
  134. Sound = SoundList.ButtonA,
  135. };
  136. leaveButton.Click += (o, e) => Hide();
  137. #endregion
  138. #region Message Area
  139. MirButton upButton = new MirButton
  140. {
  141. Index = 197,
  142. HoverIndex = 198,
  143. PressedIndex = 199,
  144. Library = Libraries.Prguse2,
  145. Parent = this,
  146. Size = new Size(16, 14),
  147. Location = new Point(292, 136),
  148. Sound = SoundList.ButtonA,
  149. Visible = true
  150. };
  151. MirButton downButton = new MirButton
  152. {
  153. Index = 207,
  154. HoverIndex = 208,
  155. Library = Libraries.Prguse2,
  156. PressedIndex = 209,
  157. Parent = this,
  158. Size = new Size(16, 14),
  159. Location = new Point(292, 282),
  160. Sound = SoundList.ButtonA,
  161. Visible = true
  162. };
  163. MirButton positionBar = new MirButton
  164. {
  165. Index = 205,
  166. HoverIndex = 206,
  167. PressedIndex = 206,
  168. Library = Libraries.Prguse2,
  169. Location = new Point(292, 149),
  170. Parent = this,
  171. Movable = true,
  172. Sound = SoundList.None,
  173. Visible = false
  174. };
  175. Message = new QuestMessage(upButton, downButton, positionBar, 10)
  176. {
  177. Font = new Font(Settings.FontName, 9F),
  178. Parent = this,
  179. Size = new Size(280, 160),
  180. Location = new Point(10, 135),
  181. PosMinY = 149,
  182. PosMaxY = 263
  183. };
  184. #endregion
  185. #region Rewards
  186. Reward = new QuestRewards
  187. {
  188. Parent = this,
  189. Visible = false,
  190. Size = new Size(313, 130),
  191. Location = new Point(5, 307)
  192. };
  193. #endregion
  194. _availableQuestLabel = new MirLabel
  195. {
  196. Font = new Font(Settings.FontName, 8F),
  197. Parent = this,
  198. AutoSize = true,
  199. Location = new Point(210, 8)
  200. };
  201. MirButton closeButton = new MirButton
  202. {
  203. Index = 360,
  204. HoverIndex = 361,
  205. PressedIndex = 362,
  206. Library = Libraries.Prguse2,
  207. Parent = this,
  208. Location = new Point(289, 3),
  209. Sound = SoundList.ButtonA,
  210. };
  211. closeButton.Click += (o, e) => Hide();
  212. MirButton helpButton = new MirButton
  213. {
  214. Index = 257,
  215. HoverIndex = 258,
  216. PressedIndex = 259,
  217. Library = Libraries.Prguse2,
  218. Parent = this,
  219. Location = new Point(266, 3),
  220. Sound = SoundList.ButtonA,
  221. };
  222. helpButton.Click += (o, e) => GameScene.Scene.HelpDialog.DisplayPage(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.Quests));
  223. }
  224. public override void Show()
  225. {
  226. if (Visible) return;
  227. Visible = true;
  228. CurrentNPCID = GameScene.NPCID;
  229. Reset();
  230. DisplayInfo();
  231. }
  232. public override void Hide()
  233. {
  234. if (!Visible) return;
  235. Visible = false;
  236. GameScene.Scene.NPCDialog.Hide();
  237. }
  238. public void Toggle()
  239. {
  240. if (!Visible)
  241. Show();
  242. else
  243. Hide();
  244. }
  245. public void DisplayInfo()
  246. {
  247. if (!GetAvailableQuests())
  248. {
  249. Hide();
  250. return;
  251. }
  252. Reset();
  253. RefreshInterface();
  254. }
  255. public void Reset()
  256. {
  257. StartIndex = 0;
  258. SelectedIndex = 0;
  259. SelectedQuest = null;
  260. Message.Visible = false;
  261. Reward.Visible = false;
  262. for (int i = 0; i < Rows.Length; i++)
  263. {
  264. if(Rows[i] != null) Rows[i].Dispose();
  265. Rows[i] = null;
  266. }
  267. }
  268. public bool GetAvailableQuests()
  269. {
  270. NPCObject npc = (NPCObject)MapControl.GetObject(CurrentNPCID);
  271. if (npc != null)
  272. {
  273. Quests = npc.GetAvailableQuests();
  274. }
  275. return Quests.Count >= 1 && npc != null;
  276. }
  277. public void RefreshInterface()
  278. {
  279. _availableQuestLabel.Text = GameLanguage.ClientTextMap.GetLocalization((ClientTextKeys.AvailableQuestList), Quests.Count);
  280. int maxIndex = Quests.Count - Rows.Length;
  281. if (StartIndex > maxIndex) StartIndex = maxIndex;
  282. if (StartIndex < 0) StartIndex = 0;
  283. for (int i = 0; i < Rows.Length; i++)
  284. {
  285. if (i >= Quests.Count) break;
  286. if (Rows[i] != null)
  287. Rows[i].Dispose();
  288. Rows[i] = new QuestRow
  289. {
  290. Quest = Quests[i + StartIndex],
  291. Location = new Point(9, 36 + i * 19),
  292. Parent = this,
  293. };
  294. Rows[i].Click += (o, e) =>
  295. {
  296. QuestRow row = (QuestRow) o;
  297. if (row.Quest != SelectedQuest)
  298. {
  299. SelectedQuest = row.Quest;
  300. Reward.UpdateRewards(SelectedQuest);
  301. Message.UpdateQuest(SelectedQuest);
  302. SelectedIndex = FindSelectedIndex();
  303. UpdateRows();
  304. ReDisplayButtons();
  305. }
  306. };
  307. if (SelectedQuest != null)
  308. {
  309. if (SelectedIndex == i)
  310. {
  311. SelectedQuest = Rows[i].Quest;
  312. Reward.UpdateRewards(SelectedQuest);
  313. Message.UpdateQuest(SelectedQuest);
  314. }
  315. }
  316. }
  317. UpdateRows();
  318. ReDisplayButtons();
  319. }
  320. public void UpdateRows()
  321. {
  322. if (SelectedQuest == null)
  323. {
  324. if (Rows[0] == null) return;
  325. SelectedQuest = Rows[0].Quest;
  326. Reward.UpdateRewards(SelectedQuest);
  327. Message.UpdateQuest(SelectedQuest);
  328. }
  329. for (int i = 0; i < Rows.Length; i++)
  330. {
  331. if (Rows[i] == null) continue;
  332. Rows[i].Selected = false;
  333. if (Rows[i].Quest == SelectedQuest)
  334. {
  335. Rows[i].Selected = true;
  336. }
  337. Rows[i].UpdateInterface();
  338. }
  339. }
  340. public void ReDisplayButtons()
  341. {
  342. _acceptButton.Visible = false;
  343. _finishButton.Visible = false;
  344. if (Reward != null)
  345. {
  346. Reward.Visible = true;
  347. Message.Visible = true;
  348. }
  349. if (SelectedQuest != null)
  350. {
  351. if (!SelectedQuest.Taken && MapControl.User.CurrentQuests.Count < Globals.MaxConcurrentQuests)
  352. _acceptButton.Visible = true;
  353. if (SelectedQuest.Completed && Reward != null)
  354. _finishButton.Visible = true;
  355. }
  356. }
  357. public int FindSelectedIndex()
  358. {
  359. int selectedIndex = 0;
  360. if (SelectedQuest != null)
  361. {
  362. for (int i = 0; i < Rows.Length; i++)
  363. {
  364. if (Rows[i] == null || SelectedQuest != Rows[i].Quest) continue;
  365. selectedIndex = i;
  366. }
  367. }
  368. return selectedIndex;
  369. }
  370. protected override void Dispose(bool disposing)
  371. {
  372. base.Dispose(disposing);
  373. Quests.Clear();
  374. SelectedQuest = null;
  375. Message = null;
  376. Reward = null;
  377. foreach (QuestRow row in Rows.Where(row => row != null && !row.IsDisposed))
  378. {
  379. row.Dispose();
  380. }
  381. }
  382. }
  383. public sealed class QuestDetailDialog : MirImageControl
  384. {
  385. private readonly MirButton _shareButton, _pauseButton, _cancelButton;
  386. public ClientQuestProgress Quest;
  387. public QuestMessage Message;
  388. public QuestRewards Reward;
  389. public QuestDetailDialog()
  390. {
  391. Index = 960;
  392. Library = Libraries.Prguse;
  393. Movable = true;
  394. Sort = true;
  395. Location = new Point(Settings.ScreenWidth / 2 + 20, 60);
  396. MirImageControl TitleLabel = new MirImageControl
  397. {
  398. Index = 16,
  399. Library = Libraries.Title,
  400. Location = new Point(18, 9),
  401. Parent = this
  402. };
  403. #region Message Area
  404. MirButton upButton = new MirButton
  405. {
  406. Index = 197,
  407. HoverIndex = 198,
  408. PressedIndex = 199,
  409. Library = Libraries.Prguse2,
  410. Parent = this,
  411. Size = new Size(16, 14),
  412. Location = new Point(293, 33),
  413. Sound = SoundList.ButtonA,
  414. Visible = true
  415. };
  416. MirButton downButton = new MirButton
  417. {
  418. Index = 207,
  419. HoverIndex = 208,
  420. Library = Libraries.Prguse2,
  421. PressedIndex = 209,
  422. Parent = this,
  423. Size = new Size(16, 14),
  424. Location = new Point(293, 280),
  425. Sound = SoundList.ButtonA,
  426. Visible = true
  427. };
  428. MirButton positionBar = new MirButton
  429. {
  430. Index = 205,
  431. HoverIndex = 206,
  432. PressedIndex = 206,
  433. Library = Libraries.Prguse2,
  434. Location = new Point(293, 48),
  435. Parent = this,
  436. Movable = true,
  437. Sound = SoundList.None,
  438. Visible = false
  439. };
  440. Message = new QuestMessage(upButton, downButton, positionBar, 16, true)
  441. {
  442. Font = new Font(Settings.FontName, 9F),
  443. Parent = this,
  444. Size = new Size(280, 320),
  445. Location = new Point(10, 35),
  446. PosMinY = 46,
  447. PosMaxY = 261
  448. };
  449. #endregion
  450. #region Rewards
  451. Reward = new QuestRewards
  452. {
  453. Parent = this,
  454. Size = new Size(315, 130),
  455. Location = new Point(5, 307)
  456. };
  457. #endregion
  458. #region Buttons
  459. _shareButton = new MirButton
  460. {
  461. Index = 616,
  462. HoverIndex = 617,
  463. PressedIndex = 618,
  464. Library = Libraries.Title,
  465. Parent = this,
  466. Location = new Point(40, 436),
  467. Sound = SoundList.ButtonA
  468. };
  469. _shareButton.Click += (o, e) =>
  470. {
  471. Network.Enqueue(new C.ShareQuest { QuestIndex = Quest.Id });
  472. };
  473. _pauseButton = new MirButton
  474. {
  475. Index = 270,
  476. HoverIndex = 271,
  477. PressedIndex = 272,
  478. Library = Libraries.Title,
  479. Parent = this,
  480. Location = new Point(120, 436),
  481. Sound = SoundList.ButtonA,
  482. Visible = false
  483. };
  484. _cancelButton = new MirButton
  485. {
  486. Index = 203,
  487. HoverIndex = 204,
  488. PressedIndex = 205,
  489. Library = Libraries.Title,
  490. Parent = this,
  491. Location = new Point(200, 436),
  492. Sound = SoundList.ButtonA,
  493. };
  494. _cancelButton.Click += (o, e) =>
  495. {
  496. MirMessageBox messageBox = new MirMessageBox(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.AskCancelQuest), MirMessageBoxButtons.YesNo);
  497. messageBox.YesButton.Click += (o1, a) =>
  498. {
  499. Network.Enqueue(new C.AbandonQuest { QuestIndex = Quest.Id });
  500. Hide();
  501. };
  502. messageBox.Show();
  503. };
  504. #endregion
  505. MirButton closeButton = new MirButton
  506. {
  507. Index = 360,
  508. HoverIndex = 361,
  509. PressedIndex = 362,
  510. Library = Libraries.Prguse2,
  511. Parent = this,
  512. Location = new Point(289, 3),
  513. Sound = SoundList.ButtonA,
  514. };
  515. closeButton.Click += (o, e) => Hide();
  516. //MirButton helpButton = new MirButton
  517. //{
  518. // Index = 257,
  519. // HoverIndex = 258,
  520. // PressedIndex = 259,
  521. // Library = Libraries.Prguse2,
  522. // Parent = this,
  523. // Location = new Point(266, 3),
  524. // Sound = SoundList.ButtonA,
  525. //};
  526. //helpButton.Click += (o, e) => GameScene.Scene.HelpDialog.DisplayPage("Quests");
  527. }
  528. public void DisplayQuestDetails(ClientQuestProgress quest)
  529. {
  530. if (quest == null) return;
  531. Quest = quest;
  532. Reward.UpdateRewards(Quest);
  533. Message.UpdateQuest(Quest);
  534. Show();
  535. }
  536. }
  537. public sealed class QuestDiaryDialog : MirImageControl
  538. {
  539. public List<ClientQuestProgress> Quests = new List<ClientQuestProgress>();
  540. public List<QuestGroupQuestItem> TaskGroups = new List<QuestGroupQuestItem>();
  541. public List<string> ExpandedGroups = new List<string>();
  542. private MirButton _closeButton;
  543. private MirLabel _takenQuestsLabel;
  544. public QuestDiaryDialog()
  545. {
  546. Index = 961;
  547. Library = Libraries.Prguse;
  548. Movable = true;
  549. Sort = true;
  550. Location = new Point(Settings.ScreenWidth / 2 - 300 - 20, 60);
  551. MirImageControl TitleLabel = new MirImageControl
  552. {
  553. Index = 15,
  554. Library = Libraries.Title,
  555. Location = new Point(18, 9),
  556. Parent = this
  557. };
  558. _takenQuestsLabel = new MirLabel
  559. {
  560. Font = new Font(Settings.FontName, 8F),
  561. Parent = this,
  562. AutoSize = true,
  563. Location = new Point(210, 7)
  564. };
  565. _closeButton = new MirButton
  566. {
  567. Index = 193,
  568. HoverIndex = 194,
  569. PressedIndex = 195,
  570. Library = Libraries.Title,
  571. Parent = this,
  572. Location = new Point(200, 436),
  573. Sound = SoundList.ButtonA,
  574. };
  575. _closeButton.Click += (o, e) => Hide();
  576. MirButton closeButton = new MirButton
  577. {
  578. Index = 360,
  579. HoverIndex = 361,
  580. PressedIndex = 362,
  581. Library = Libraries.Prguse2,
  582. Parent = this,
  583. Location = new Point(289, 3),
  584. Sound = SoundList.ButtonA,
  585. };
  586. closeButton.Click += (o, e) => Hide();
  587. }
  588. public void DisplayQuests()
  589. {
  590. ClearLog();
  591. Quests = GameScene.User.CurrentQuests;
  592. _takenQuestsLabel.Text = GameLanguage.ClientTextMap.GetLocalization((ClientTextKeys.TakenQuestsList), Quests.Count, Globals.MaxConcurrentQuests);
  593. var groupedQuests = Quests.GroupBy(d => d.QuestInfo.Group).ToList();
  594. int nextY = 40;
  595. foreach (var group in groupedQuests)
  596. {
  597. List<ClientQuestProgress> singleGroup = @group.ToList();
  598. bool expanded = ExpandedGroups.Count <= 0 || ExpandedGroups.Contains(@group.Key);
  599. QuestGroupQuestItem groupQuest = new QuestGroupQuestItem(group.Key, singleGroup, expanded)
  600. {
  601. Parent = this,
  602. Visible = true,
  603. Location = new Point(15, nextY),
  604. };
  605. groupQuest.ExpandedChanged += (o, e) =>
  606. {
  607. nextY = 40;
  608. foreach (QuestGroupQuestItem task in TaskGroups)
  609. {
  610. task.Location = new Point(15, nextY);
  611. nextY += task.SizeY;
  612. if (task.Expanded)
  613. {
  614. if (!ExpandedGroups.Contains(task.Group))
  615. ExpandedGroups.Add(task.Group);
  616. }
  617. else
  618. ExpandedGroups.Remove(task.Group);
  619. }
  620. };
  621. groupQuest.SelectedQuestChanged += (o, e) =>
  622. {
  623. QuestSingleQuestItem singleQuestItem = (QuestSingleQuestItem)o;
  624. if (singleQuestItem == null) return;
  625. foreach (QuestGroupQuestItem item in TaskGroups)
  626. {
  627. item.DeselectQuests();
  628. }
  629. singleQuestItem.Selected = true;
  630. };
  631. nextY += groupQuest.SizeY;
  632. TaskGroups.Add(groupQuest);
  633. }
  634. }
  635. public void ClearLog()
  636. {
  637. foreach (QuestGroupQuestItem taskGroupItem in TaskGroups)
  638. {
  639. taskGroupItem.Dispose();
  640. }
  641. TaskGroups.Clear();
  642. }
  643. public override void Show()
  644. {
  645. if (Visible) return;
  646. Visible = true;
  647. DisplayQuests();
  648. }
  649. public void Toggle()
  650. {
  651. if (!Visible)
  652. Show();
  653. else
  654. Hide();
  655. }
  656. protected override void Dispose(bool disposing)
  657. {
  658. base.Dispose(disposing);
  659. Quests.Clear();
  660. ClearLog();
  661. }
  662. }
  663. public sealed class QuestTrackingDialog : MirImageControl
  664. {
  665. public List<int> TrackedQuestsIds = new List<int>();
  666. public List<MirLabel> TaskLines = new List<MirLabel>();
  667. public Font QuestFont = new Font(Settings.FontName, 8F);
  668. private MirLabel _questNameLabel, _questTaskLabel;
  669. public QuestTrackingDialog()
  670. {
  671. Movable = true;
  672. Location = new Point(0, 100);
  673. Sort = false;
  674. }
  675. public void DisplayQuests()
  676. {
  677. foreach (MirLabel label in TaskLines)
  678. label.Dispose();
  679. List<ClientQuestProgress> questsToTrack = new List<ClientQuestProgress>();
  680. questsToTrack.Clear();
  681. questsToTrack.AddRange(from quest in MapObject.User.CurrentQuests from id in TrackedQuestsIds.Where(id => quest.Id == id) select quest);
  682. if (questsToTrack.Count < 1)
  683. {
  684. Hide();
  685. return;
  686. }
  687. int y = 0;
  688. for (int i = 0; i < questsToTrack.Count; i++)
  689. {
  690. _questNameLabel = new MirLabel
  691. {
  692. Text = questsToTrack[i].QuestInfo.Name,
  693. AutoSize = true,
  694. BackColour = Color.Transparent,
  695. Font = QuestFont,
  696. ForeColour = Color.LimeGreen,
  697. Location = new Point(5, 20 + y),
  698. OutLine = true,
  699. Parent = this,
  700. Visible = true,
  701. };
  702. TaskLines.Add(_questNameLabel);
  703. foreach (string questToTrack in questsToTrack[i].TaskList)
  704. {
  705. y += 15;
  706. string trackedQuest = questToTrack;
  707. _questTaskLabel = new MirLabel
  708. {
  709. Text = trackedQuest,
  710. AutoSize = true,
  711. BackColour = Color.Transparent,
  712. Font = QuestFont,
  713. ForeColour = Color.White, //trackedQuest.Contains("(Completed)") ? Color.LimeGreen :
  714. Location = new Point(25, 20 + y),
  715. OutLine = true,
  716. Parent = this,
  717. Visible = true,
  718. };
  719. TaskLines.Add(_questTaskLabel);
  720. }
  721. if (i >= 5) break;
  722. y += 30;
  723. }
  724. //Size = new Size(150, 20 + y + 30);
  725. Show();
  726. }
  727. public void AddQuest(ClientQuestProgress quest, bool New = false)
  728. {
  729. if (TrackedQuestsIds.Any(d => d == quest.Id) || TrackedQuestsIds.Count >= 5) return;
  730. TrackedQuestsIds.Add(quest.Id);
  731. DisplayQuests();
  732. if (!New)
  733. UpdateTrackedQuests();
  734. }
  735. public void RemoveQuest(ClientQuestProgress quest)
  736. {
  737. TrackedQuestsIds.Remove(quest.Id);
  738. DisplayQuests();
  739. UpdateTrackedQuests();
  740. }
  741. public void UpdateTrackedQuests()
  742. {
  743. for (int j = 0; j < Settings.TrackedQuests.Length; j++)
  744. {
  745. if (TrackedQuestsIds.Count > 0 && j < TrackedQuestsIds.Count)
  746. {
  747. Settings.TrackedQuests[j] = TrackedQuestsIds[j];
  748. continue;
  749. }
  750. Settings.TrackedQuests[j] = -1;
  751. }
  752. Settings.SaveTrackedQuests(GameScene.User.Name);
  753. }
  754. }
  755. //Sub controls
  756. public sealed class QuestRow : MirControl
  757. {
  758. public ClientQuestProgress Quest;
  759. public MirLabel NameLabel, RequirementLabel;
  760. public MirImageControl SelectedImage, IconImage;
  761. public bool Selected = false;
  762. public QuestRow()
  763. {
  764. Sound = SoundList.ButtonA;
  765. Size = new Size(200, 17);
  766. BeforeDraw += QuestRow_BeforeDraw;
  767. SelectedImage = new MirImageControl
  768. {
  769. Index = 956,
  770. Library = Libraries.Prguse,
  771. Location = new Point(25, 0),
  772. Parent = this,
  773. Visible = false
  774. };
  775. IconImage = new MirImageControl
  776. {
  777. Index = 0,
  778. Library = Libraries.Prguse,
  779. Location = new Point(3, 0),
  780. Parent = this,
  781. Visible = false
  782. };
  783. RequirementLabel = new MirLabel
  784. {
  785. Location = new Point(20, 0),
  786. Size = new Size(178, 17),
  787. DrawFormat = TextFormatFlags.VerticalCenter,
  788. Parent = this,
  789. NotControl = true,
  790. };
  791. NameLabel = new MirLabel
  792. {
  793. Location = new Point(60, 0),
  794. Size = new Size(140, 17),
  795. DrawFormat = TextFormatFlags.VerticalCenter,
  796. Parent = this,
  797. NotControl = true,
  798. };
  799. UpdateInterface();
  800. }
  801. void QuestRow_BeforeDraw(object sender, EventArgs e)
  802. {
  803. UpdateInterface();
  804. }
  805. public void UpdateInterface()
  806. {
  807. if (Quest == null) return;
  808. int iconTypeOffset = (int)Quest.Icon > 3 ? 15 : 0;
  809. IconImage.Index = 961 + (int)Quest.Icon + iconTypeOffset;
  810. IconImage.Visible = true;
  811. NameLabel.Text = Quest.QuestInfo.Name;
  812. RequirementLabel.Text = Quest.QuestInfo.MinLevelNeeded > 0 ? "Lv " + Quest.QuestInfo.MinLevelNeeded : "";
  813. SelectedImage.Visible = Selected;
  814. }
  815. protected override void Dispose(bool disposing)
  816. {
  817. base.Dispose(disposing);
  818. Quest = null;
  819. NameLabel = null;
  820. RequirementLabel = null;
  821. SelectedImage = null;
  822. IconImage = null;
  823. Selected = false;
  824. }
  825. }
  826. public sealed class QuestMessage : MirControl
  827. {
  828. public ClientQuestProgress Quest;
  829. public MirButton ScrollUpButton, ScrollDownButton, PositionBar;
  830. private static readonly Regex C = new Regex(@"{(.*?/.*?)}");
  831. private readonly MirLabel[] _textLabel;
  832. private readonly List<MirLabel> _textButtons = new List<MirLabel>();
  833. public int TopLine;
  834. public int BottomLine;
  835. public int LineCount = 10;
  836. public bool DisplayProgress;
  837. public int PosX, PosMinY, PosMaxY;
  838. public Font Font = new Font(Settings.FontName, 8F);
  839. public List<string> CurrentLines = new List<string>();
  840. private readonly string TaskTitle = GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.Tasks), ProgressTitle = GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.Progress), ReturnTitle = GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.QuestReturn), TimeLimitTitle = GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.TimeLimit);
  841. public QuestMessage(MirButton scrollUpButton, MirButton scrollDownButton, MirButton positionBar, int lineCount, bool displayProgress = false)
  842. {
  843. ScrollUpButton = scrollUpButton;
  844. ScrollDownButton = scrollDownButton;
  845. PositionBar = positionBar;
  846. DisplayProgress = displayProgress;
  847. MouseWheel += QuestMessage_MouseWheel;
  848. PositionBar.OnMoving += PositionBar_OnMoving;
  849. LineCount = lineCount;
  850. _textLabel = new MirLabel[LineCount];
  851. PosX = PositionBar.Location.X;
  852. PosMinY = PositionBar.Location.Y;
  853. PosMaxY = PositionBar.Location.Y;
  854. ScrollUpButton.Click += (o, e) =>
  855. {
  856. if (TopLine <= 0) return;
  857. TopLine--;
  858. NewText(CurrentLines, false);
  859. UpdatePositionBar();
  860. };
  861. ScrollDownButton.Click += (o, e) =>
  862. {
  863. if (TopLine + LineCount >= CurrentLines.Count) return;
  864. TopLine++;
  865. NewText(CurrentLines, false);
  866. UpdatePositionBar();
  867. };
  868. AfterDraw += QuestMessage_AfterDraw;
  869. }
  870. private void QuestMessage_AfterDraw(object sender, EventArgs e)
  871. {
  872. if (Quest == null || CurrentLines.Count < 1) return;
  873. int adjust = 0;
  874. for (int i = TopLine; i < BottomLine; i++)
  875. {
  876. if (i != 0 && CurrentLines[i] != TaskTitle && CurrentLines[i] != ProgressTitle && CurrentLines[i] != ReturnTitle && CurrentLines[i] != TimeLimitTitle) continue;
  877. Libraries.Prguse.Draw(919, new Point(DisplayLocation.X + 5, DisplayLocation.Y + 5 + (i - TopLine) * 15 + adjust), Color.White);
  878. adjust += 5;
  879. }
  880. }
  881. private void QuestMessage_MouseWheel(object sender, MouseEventArgs e)
  882. {
  883. int count = e.Delta / SystemInformation.MouseWheelScrollDelta;
  884. if (TopLine == 0 && count >= 0) return;
  885. if (TopLine == CurrentLines.Count - 1 && count <= 0) return;
  886. if (CurrentLines.Count <= LineCount) return;
  887. TopLine -= count;
  888. if (TopLine < 0) TopLine = 0;
  889. if (TopLine + LineCount > CurrentLines.Count - 1) TopLine = CurrentLines.Count - LineCount;
  890. NewText(CurrentLines, false);
  891. UpdatePositionBar();
  892. }
  893. private void PositionBar_OnMoving(object sender, MouseEventArgs e)
  894. {
  895. int x = PosX;
  896. int y = PositionBar.Location.Y;
  897. if (y >= PosMaxY) y = PosMaxY;
  898. if (y <= PosMinY) y = PosMinY;
  899. int location = y - PosMinY;
  900. int interval = (PosMaxY - PosMinY) / (CurrentLines.Count - LineCount);
  901. double yPoint = (double)location / interval;
  902. TopLine = Convert.ToInt16(Math.Floor(yPoint));
  903. PositionBar.Location = new Point(x, y);
  904. NewText(CurrentLines, false);
  905. }
  906. private void UpdatePositionBar()
  907. {
  908. if (CurrentLines.Count <= LineCount)
  909. {
  910. PositionBar.Visible = false;
  911. return;
  912. }
  913. PositionBar.Visible = true;
  914. int interval = (PosMaxY - PosMinY) / (CurrentLines.Count - LineCount);
  915. int x = PosX;
  916. int y = PosMinY + (TopLine * interval);
  917. if (y >= PosMaxY) y = PosMaxY;
  918. if (y <= PosMinY) y = PosMinY;
  919. PositionBar.Location = new Point(x, y);
  920. }
  921. public void UpdateQuest(ClientQuestProgress quest)
  922. {
  923. Quest = quest;
  924. CurrentLines.Clear();
  925. //add quest title at the beginning
  926. CurrentLines.Insert(0, Quest.QuestInfo.Name);
  927. if (Quest.Taken && !Quest.QuestInfo.SameFinishNPC && Quest.QuestInfo.CompletionDescription.Count > 0 && GameScene.Scene.QuestListDialog.CurrentNPCID == Quest.QuestInfo.FinishNPCIndex)
  928. {
  929. foreach (var line in Quest.QuestInfo.CompletionDescription)
  930. {
  931. CurrentLines.Add(line);
  932. }
  933. }
  934. else
  935. {
  936. foreach (var line in Quest.QuestInfo.Description)
  937. {
  938. CurrentLines.Add(line);
  939. }
  940. AdjustDescription();
  941. }
  942. NewText(CurrentLines);
  943. }
  944. private void AdjustDescription()
  945. {
  946. if (Quest.QuestInfo.TaskDescription.Count > 0)
  947. {
  948. CurrentLines.Add(" ");
  949. CurrentLines.Add(TaskTitle);
  950. foreach (string task in Quest.QuestInfo.TaskDescription)
  951. {
  952. CurrentLines.Add(task);
  953. }
  954. }
  955. if (Quest.QuestInfo.ReturnDescription.Count > 0)
  956. {
  957. CurrentLines.Add(" ");
  958. CurrentLines.Add(ReturnTitle);
  959. foreach (string questgiver in Quest.QuestInfo.ReturnDescription)
  960. {
  961. CurrentLines.Add(questgiver);
  962. }
  963. }
  964. if (Quest.QuestInfo.TimeLimitInSeconds > 0)
  965. {
  966. CurrentLines.Add(" ");
  967. CurrentLines.Add(TimeLimitTitle);
  968. CurrentLines.Add(Functions.PrintTimeSpanFromSeconds(Quest.QuestInfo.TimeLimitInSeconds, true));
  969. }
  970. if (Quest.Taken && Quest.TaskList.Count > 0 && DisplayProgress)
  971. {
  972. CurrentLines.Add(" ");
  973. CurrentLines.Add(ProgressTitle);
  974. foreach (string task in Quest.TaskList)
  975. {
  976. CurrentLines.Add(task);
  977. }
  978. }
  979. }
  980. private void NewText(List<string> lines, bool resetIndex = true)
  981. {
  982. if (resetIndex)
  983. {
  984. TopLine = 0;
  985. CurrentLines = lines;
  986. UpdatePositionBar();
  987. }
  988. foreach (MirLabel t in _textButtons.Where(t => t != null))
  989. t.Dispose();
  990. foreach (MirLabel t in _textLabel.Where(t => t != null))
  991. t.Text = "";
  992. _textButtons.Clear();
  993. int adjust = 0;
  994. BottomLine = lines.Count > LineCount ? ((LineCount + TopLine) > lines.Count ? lines.Count : (LineCount + TopLine)) : lines.Count;
  995. for (int i = TopLine; i < BottomLine; i++)
  996. {
  997. Font font = Font;
  998. Color fontColor = Color.White;
  999. bool title = false;
  1000. if (i == 0 || lines[i] == TaskTitle || lines[i] == ProgressTitle || lines[i] == ReturnTitle || lines[i] == TimeLimitTitle)
  1001. {
  1002. font = new Font(Settings.FontName, 10F, FontStyle.Bold);
  1003. title = true;
  1004. if (i == 0)
  1005. {
  1006. fontColor = Color.Yellow;
  1007. }
  1008. }
  1009. _textLabel[i - TopLine] = new MirLabel
  1010. {
  1011. Font = font,
  1012. ForeColour = fontColor,
  1013. DrawFormat = TextFormatFlags.WordBreak,
  1014. Visible = true,
  1015. Parent = this,
  1016. Size = new Size(Size.Width, 20),
  1017. Location = new Point(title ? 15 : 0, 0 + (i - TopLine) * 15 + adjust),
  1018. NotControl = true
  1019. };
  1020. if (title)
  1021. {
  1022. adjust += 5;
  1023. }
  1024. if (i >= lines.Count)
  1025. {
  1026. _textLabel[i - TopLine].Text = string.Empty;
  1027. continue;
  1028. }
  1029. string currentLine = lines[i];
  1030. List<Match> matchList = C.Matches(currentLine).Cast<Match>().ToList();
  1031. // Add link patterns (using static patterns from NPCDialog)
  1032. matchList.AddRange(NPCDialog.MonsterLink.Matches(currentLine).Cast<Match>());
  1033. matchList.AddRange(NPCDialog.NPCLink.Matches(currentLine).Cast<Match>());
  1034. matchList.AddRange(NPCDialog.ItemLink.Matches(currentLine).Cast<Match>());
  1035. int oldLength = currentLine.Length;
  1036. foreach (Match match in matchList.OrderBy(o => o.Index).ToList())
  1037. {
  1038. int offSet = oldLength - currentLine.Length;
  1039. // Check if this is a link type
  1040. string linkType = null;
  1041. if (NPCDialog.MonsterLink.Match(match.Value).Success)
  1042. linkType = "MONSTER";
  1043. else if (NPCDialog.NPCLink.Match(match.Value).Success)
  1044. linkType = "NPC";
  1045. else if (NPCDialog.ItemLink.Match(match.Value).Success)
  1046. linkType = "ITEM";
  1047. if (linkType != null)
  1048. {
  1049. string linkIdx = match.Groups["idx"].Captures.Count > 0 ? match.Groups["idx"].Captures[0].Value : match.Groups["idx"].Value;
  1050. string providedName = match.Groups["name"].Success ? match.Groups["name"].Captures[0].Value : null;
  1051. string displayName = NPCDialog.GetDisplayNameForLink(linkType, linkIdx, providedName);
  1052. if (string.IsNullOrEmpty(displayName))
  1053. displayName = $"LINK_{linkIdx}";
  1054. int matchStart = match.Index - offSet;
  1055. int matchLength = match.Length;
  1056. currentLine = currentLine.Remove(matchStart, matchLength).Insert(matchStart, displayName);
  1057. string text2 = currentLine.Substring(0, matchStart);
  1058. Point offset = NPCDialog.CalculateLinkOffset(text2, _textLabel[i - TopLine]);
  1059. Point anchorPoint = _textLabel[i - TopLine].Location.Add(offset);
  1060. NewLink(displayName, linkType, linkIdx, anchorPoint);
  1061. continue;
  1062. }
  1063. Capture capture = match.Groups[1].Captures[0];
  1064. string[] values = capture.Value.Split('/');
  1065. currentLine = currentLine.Remove(capture.Index - 1 - offSet, capture.Length + 2).Insert(capture.Index - 1 - offSet, values[0]);
  1066. string text = currentLine.Substring(0, capture.Index - 1 - offSet) + " ";
  1067. Size size = TextRenderer.MeasureText(CMain.Graphics, text, _textLabel[i - TopLine].Font, _textLabel[i - TopLine].Size, TextFormatFlags.TextBoxControl);
  1068. if (C.Match(match.Value).Success)
  1069. NewColour(values[0], values[1], _textLabel[i - TopLine].Location.Add(new Point(size.Width - 10, 0)));
  1070. }
  1071. _textLabel[i - TopLine].Text = currentLine;
  1072. _textLabel[i - TopLine].MouseWheel += QuestMessage_MouseWheel;
  1073. }
  1074. }
  1075. private void NewColour(string text, string colour, Point p)
  1076. {
  1077. Color textColour = Color.FromName(colour);
  1078. MirLabel temp = new MirLabel
  1079. {
  1080. AutoSize = true,
  1081. Visible = true,
  1082. Parent = this,
  1083. Location = p,
  1084. Text = text,
  1085. ForeColour = textColour,
  1086. Font = Font
  1087. };
  1088. temp.MouseWheel += QuestMessage_MouseWheel;
  1089. _textButtons.Add(temp);
  1090. }
  1091. private void NewLink(string text, string linkType, string linkIdx, Point p)
  1092. {
  1093. MirLabel temp = new MirLabel
  1094. {
  1095. AutoSize = true,
  1096. Visible = true,
  1097. Parent = this,
  1098. Location = p,
  1099. Text = text,
  1100. ForeColour = Color.Cyan,
  1101. Font = Font
  1102. };
  1103. temp.MouseEnter += (o, e) =>
  1104. {
  1105. temp.ForeColour = Color.Orange;
  1106. NPCDialog.ShowTooltipForLink(linkType, linkIdx, temp.DisplayLocation);
  1107. };
  1108. temp.MouseLeave += (o, e) =>
  1109. {
  1110. temp.ForeColour = Color.Cyan;
  1111. NPCDialog.HideTooltipForLink();
  1112. };
  1113. temp.MouseWheel += QuestMessage_MouseWheel;
  1114. _textButtons.Add(temp);
  1115. }
  1116. protected override void Dispose(bool disposing)
  1117. {
  1118. base.Dispose(disposing);
  1119. Quest = null;
  1120. ScrollUpButton = null;
  1121. ScrollDownButton = null;
  1122. PositionBar = null;
  1123. CurrentLines.Clear();
  1124. }
  1125. }
  1126. public sealed class QuestRewards : MirControl
  1127. {
  1128. private readonly MirLabel _goldLabel, _expLabel, _creditLabel;
  1129. public ClientQuestProgress Quest;
  1130. public int SelectedItemIndex = -1;
  1131. public ItemInfo SelectedItem = null;
  1132. public static QuestCell[] FixedItems = new QuestCell[5];
  1133. public static QuestCell[] SelectItems = new QuestCell[5];
  1134. public QuestRewards()
  1135. {
  1136. _expLabel = new MirLabel
  1137. {
  1138. Size = new Size(75, 20),
  1139. Location = new Point(40, 0),
  1140. Parent = this
  1141. };
  1142. _goldLabel = new MirLabel
  1143. {
  1144. Size = new Size(75, 20),
  1145. Parent = this
  1146. };
  1147. _creditLabel = new MirLabel
  1148. {
  1149. Size = new Size(75, 20),
  1150. Location = new Point(60, 0),
  1151. Parent = this
  1152. };
  1153. BeforeDraw += QuestReward_BeforeDraw;
  1154. }
  1155. public void UpdateRewards(ClientQuestProgress quest)
  1156. {
  1157. Quest = quest;
  1158. CleanRewards();
  1159. UpdateInterface();
  1160. Redraw();
  1161. }
  1162. void QuestReward_BeforeDraw(object sender, EventArgs e)
  1163. {
  1164. if (Quest == null) return;
  1165. ClientQuestInfo quest = Quest.QuestInfo;
  1166. int goldXOffset = 0;
  1167. int creditXOffset = 0;
  1168. if (quest.RewardExp > 0)
  1169. Libraries.Prguse.Draw(966, DisplayLocation.X + 10, DisplayLocation.Y + 2);
  1170. else
  1171. {
  1172. goldXOffset = -90;
  1173. creditXOffset -= 90;
  1174. }
  1175. if (quest.RewardGold > 0)
  1176. Libraries.Prguse.Draw(965, DisplayLocation.X + 100 + goldXOffset, DisplayLocation.Y + 2);
  1177. else
  1178. {
  1179. creditXOffset -= 90;
  1180. }
  1181. if (quest.RewardCredit > 0)
  1182. Libraries.Prguse.Draw(2447, DisplayLocation.X + 190 + creditXOffset, DisplayLocation.Y + 2);
  1183. Libraries.Title.Draw(17, DisplayLocation.X + 20, DisplayLocation.Y + 66);
  1184. }
  1185. public void CleanRewards()
  1186. {
  1187. foreach (QuestCell item in SelectItems.Where(item => item != null))
  1188. {
  1189. item.Dispose();
  1190. }
  1191. foreach (QuestCell item in FixedItems.Where(item => item != null))
  1192. {
  1193. item.Dispose();
  1194. }
  1195. SelectedItemIndex = -1;
  1196. SelectedItem = null;
  1197. }
  1198. public void UpdateInterface()
  1199. {
  1200. ClientQuestInfo quest = Quest.QuestInfo;
  1201. _goldLabel.Visible = false;
  1202. _expLabel.Visible = false;
  1203. _creditLabel.Visible = false;
  1204. int goldXOffset = 0;
  1205. int creditXOffset = 0;
  1206. if (quest.RewardExp > 0)
  1207. {
  1208. _expLabel.Text = quest.RewardExp.ToString();
  1209. _expLabel.Visible = true;
  1210. }
  1211. else
  1212. {
  1213. goldXOffset = -90;
  1214. creditXOffset -= 90;
  1215. }
  1216. if (quest.RewardGold > 0)
  1217. {
  1218. _goldLabel.Text = quest.RewardGold.ToString();
  1219. _goldLabel.Location = new Point(120 + goldXOffset, 0);
  1220. _goldLabel.Visible = true;
  1221. }
  1222. else
  1223. {
  1224. creditXOffset -= 90;
  1225. }
  1226. if (quest.RewardCredit > 0)
  1227. {
  1228. _creditLabel.Text = quest.RewardCredit.ToString();
  1229. _creditLabel.Location = new Point(210 + creditXOffset, 0);
  1230. _creditLabel.Visible = true;
  1231. }
  1232. if (quest.RewardsFixedItem.Count > 0)
  1233. {
  1234. //var fixedRewards = FilterRewards(quest.RewardsFixedItem);
  1235. for (int i = 0; i < FixedItems.Length; i++)
  1236. {
  1237. if (i >= quest.RewardsFixedItem.Count) break;
  1238. FixedItems[i] = new QuestCell
  1239. {
  1240. Item = quest.RewardsFixedItem[i].Item,
  1241. Count = quest.RewardsFixedItem[i].Count,
  1242. Parent = this,
  1243. Location = new Point(i * 45 + 15, 24),
  1244. Fixed = true
  1245. };
  1246. }
  1247. }
  1248. if (quest.RewardsSelectItem.Count > 0)
  1249. {
  1250. var selRewards = FilterRewards(quest.RewardsSelectItem);
  1251. for (int i = 0; i < SelectItems.Length; i++)
  1252. {
  1253. if (i >= selRewards.Count) break;
  1254. SelectItems[i] = new QuestCell
  1255. {
  1256. Item = selRewards[i].Item,
  1257. Count = selRewards[i].Count,
  1258. Parent = this,
  1259. Location = new Point(i * 45 + 15, 89),
  1260. };
  1261. SelectItems[i].Click += (o, e) =>
  1262. {
  1263. foreach (var itm in SelectItems)
  1264. {
  1265. if (itm == null) continue;
  1266. if (itm == o)
  1267. {
  1268. itm.Selected = true;
  1269. SelectedItem = itm.Item;
  1270. SelectedItemIndex = FindSelectedItemIndex();
  1271. }
  1272. else
  1273. itm.Selected = false;
  1274. }
  1275. Redraw();
  1276. };
  1277. }
  1278. }
  1279. }
  1280. public List<QuestItemReward> FilterRewards(List<QuestItemReward> rewardItems)
  1281. {
  1282. List<QuestItemReward> filteredRewards = new List<QuestItemReward>();
  1283. //Only display same sex items
  1284. foreach (var reward in rewardItems)
  1285. {
  1286. ItemInfo item = reward.Item;
  1287. switch (MapObject.User.Gender)
  1288. {
  1289. case MirGender.Male:
  1290. if (!item.RequiredGender.HasFlag(RequiredGender.Male)) continue;
  1291. break;
  1292. case MirGender.Female:
  1293. if (!item.RequiredGender.HasFlag(RequiredGender.Female)) continue;
  1294. break;
  1295. }
  1296. filteredRewards.Add(reward);
  1297. }
  1298. return filteredRewards;
  1299. }
  1300. public int FindSelectedItemIndex()
  1301. {
  1302. int selectedItemIndex = 0;
  1303. if (SelectedItem == null) return selectedItemIndex;
  1304. for (int i = 0; i < Quest.QuestInfo.RewardsSelectItem.Count; i++)
  1305. {
  1306. ItemInfo item = Quest.QuestInfo.RewardsSelectItem[i].Item;
  1307. if (item == null || SelectedItem != item) continue;
  1308. selectedItemIndex = i;
  1309. }
  1310. return selectedItemIndex;
  1311. }
  1312. protected override void Dispose(bool disposing)
  1313. {
  1314. base.Dispose(disposing);
  1315. Quest = null;
  1316. foreach (QuestCell cell in FixedItems.Where(cell => cell != null && !cell.IsDisposed))
  1317. {
  1318. cell.Dispose();
  1319. }
  1320. foreach (QuestCell cell in SelectItems.Where(cell => cell != null && !cell.IsDisposed))
  1321. {
  1322. cell.Dispose();
  1323. }
  1324. }
  1325. }
  1326. public sealed class QuestCell : MirControl
  1327. {
  1328. public ItemInfo Item;
  1329. public UserItem ShowItem;
  1330. public ushort Count;
  1331. public bool Selected;
  1332. public bool Fixed;
  1333. private MirLabel CountLabel { get; set; }
  1334. public QuestCell()
  1335. {
  1336. Size = new Size(32, 32);
  1337. }
  1338. protected override void OnMouseEnter()
  1339. {
  1340. base.OnMouseEnter();
  1341. if (ShowItem == null) ShowItem = new UserItem(Item) { MaxDura = Item.Durability, CurrentDura = Item.Durability };
  1342. GameScene.Scene.CreateItemLabel(ShowItem);
  1343. }
  1344. protected override void OnMouseLeave()
  1345. {
  1346. base.OnMouseLeave();
  1347. GameScene.Scene.DisposeItemLabel();
  1348. GameScene.HoverItem = null;
  1349. ShowItem = null;
  1350. }
  1351. protected internal override void DrawControl()
  1352. {
  1353. if (Item == null) return;
  1354. Size size = Libraries.Items.GetTrueSize(Item.Image);
  1355. Point offSet = new Point((40 - size.Width) / 2, (32 - size.Height) / 2);
  1356. CreateDisposeLabel();
  1357. if (Fixed)
  1358. {
  1359. Libraries.Prguse.Draw(989, DisplayLocation.X, DisplayLocation.Y - 1);
  1360. }
  1361. else if (Selected)
  1362. {
  1363. Libraries.Prguse.Draw(979, DisplayLocation.X, DisplayLocation.Y - 5);
  1364. }
  1365. Libraries.Items.Draw(Item.Image, offSet.X + DisplayLocation.X, offSet.Y + DisplayLocation.Y);
  1366. }
  1367. protected override void Dispose(bool disposing)
  1368. {
  1369. base.Dispose(disposing);
  1370. Item = null;
  1371. ShowItem = null;
  1372. DisposeCountLabel();
  1373. }
  1374. private void CreateDisposeLabel()
  1375. {
  1376. if (Count <= 1)
  1377. {
  1378. DisposeCountLabel();
  1379. return;
  1380. }
  1381. if (CountLabel == null || CountLabel.IsDisposed)
  1382. {
  1383. CountLabel = new MirLabel
  1384. {
  1385. AutoSize = true,
  1386. ForeColour = Color.Yellow,
  1387. NotControl = true,
  1388. OutLine = false,
  1389. Parent = this,
  1390. };
  1391. }
  1392. CountLabel.Text = Count.ToString("###0");
  1393. CountLabel.Location = new Point(Size.Width - CountLabel.Size.Width + 8, Size.Height - CountLabel.Size.Height);
  1394. }
  1395. private void DisposeCountLabel()
  1396. {
  1397. if (CountLabel != null && !CountLabel.IsDisposed)
  1398. CountLabel.Dispose();
  1399. CountLabel = null;
  1400. }
  1401. }
  1402. public sealed class QuestGroupQuestItem : MirControl
  1403. {
  1404. public string Group = string.Empty;
  1405. public List<ClientQuestProgress> Quests = new List<ClientQuestProgress>();
  1406. public bool Expanded = true;
  1407. public int SizeY = 15;
  1408. private readonly MirButton _expandButton;
  1409. private readonly MirLabel _groupLabel;
  1410. private readonly List<QuestSingleQuestItem> _tasks = new List<QuestSingleQuestItem>();
  1411. public event EventHandler ExpandedChanged;
  1412. private void OnExpandedChanged()
  1413. {
  1414. if (ExpandedChanged != null)
  1415. ExpandedChanged.Invoke(this, EventArgs.Empty);
  1416. }
  1417. public event EventHandler SelectedQuestChanged;
  1418. private void OnSelectedQuestChanged(object ob)
  1419. {
  1420. if (SelectedQuestChanged != null)
  1421. SelectedQuestChanged.Invoke(ob, EventArgs.Empty);
  1422. }
  1423. public QuestGroupQuestItem(string group, List<ClientQuestProgress> quests, bool expanded)
  1424. {
  1425. Group = group;
  1426. Quests = quests;
  1427. Expanded = expanded;
  1428. _expandButton = new MirButton
  1429. {
  1430. Index = Expanded ? 917 : 918,
  1431. Library = Libraries.Prguse,
  1432. Parent = this,
  1433. Size = new Size(16, 14),
  1434. Location = new Point(0, 0),
  1435. Sound = SoundList.ButtonA
  1436. };
  1437. _expandButton.Click += (o, e) => ChangeExpand();
  1438. _groupLabel = new MirLabel
  1439. {
  1440. Text = Group,
  1441. AutoSize = true,
  1442. Parent = this,
  1443. Font = new Font(Settings.FontName, 8F),
  1444. ForeColour = Color.LimeGreen,
  1445. Location = new Point(18, 0),
  1446. Visible = true,
  1447. };
  1448. for (int i = 0; i < Quests.Count; i++)
  1449. {
  1450. bool Track = Settings.TrackedQuests.Contains(Quests[i].Id) ? true : false;
  1451. QuestSingleQuestItem singleQuest = new QuestSingleQuestItem(Quests[i])
  1452. {
  1453. Parent = this,
  1454. Location = new Point(18, (15 * (i + 1))),
  1455. Size = new Size(280, 15),
  1456. Visible = Expanded
  1457. };
  1458. singleQuest.SelectedQuestChanged += (o, e) => OnSelectedQuestChanged(o);
  1459. _tasks.Add(singleQuest);
  1460. if (Expanded)
  1461. SizeY += 15;
  1462. }
  1463. Size = new Size(280, SizeY);
  1464. }
  1465. public void UpdatePositions()
  1466. {
  1467. SizeY = 15;
  1468. foreach (var singleTask in _tasks)
  1469. {
  1470. singleTask.Visible = Expanded;
  1471. if (Expanded) SizeY += 15;
  1472. }
  1473. Size = new Size(280, SizeY);
  1474. }
  1475. public void ClearTasks()
  1476. {
  1477. foreach (QuestSingleQuestItem task in _tasks)
  1478. {
  1479. task.Dispose();
  1480. }
  1481. _tasks.Clear();
  1482. }
  1483. public void DeselectQuests()
  1484. {
  1485. foreach (QuestSingleQuestItem task in _tasks)
  1486. {
  1487. task.Selected = false;
  1488. }
  1489. }
  1490. private void ChangeExpand()
  1491. {
  1492. Expanded = !Expanded;
  1493. _expandButton.Index = Expanded ? 917 : 918;
  1494. UpdatePositions();
  1495. OnExpandedChanged();
  1496. }
  1497. protected override void Dispose(bool disposing)
  1498. {
  1499. base.Dispose(disposing);
  1500. Group = string.Empty;
  1501. Quests.Clear();
  1502. _expandButton.Dispose();
  1503. _groupLabel.Dispose();
  1504. ClearTasks();
  1505. }
  1506. }
  1507. public sealed class QuestSingleQuestItem : MirControl
  1508. {
  1509. private MirLabel _questLabel, _stateLabel;
  1510. private readonly MirImageControl _selectedImage;
  1511. public ClientQuestProgress Quest;
  1512. public bool Selected;
  1513. public bool TrackQuest;
  1514. public event EventHandler SelectedQuestChanged;
  1515. private void OnSelectedQuestChanged()
  1516. {
  1517. if (SelectedQuestChanged != null)
  1518. SelectedQuestChanged.Invoke(this, EventArgs.Empty);
  1519. }
  1520. public QuestSingleQuestItem(ClientQuestProgress quest)
  1521. {
  1522. Quest = quest;
  1523. Size = new Size(250, 15);
  1524. TrackQuest = GameScene.Scene.QuestTrackingDialog.TrackedQuestsIds.Contains(quest.Id);
  1525. string name = Quest.QuestInfo.Name;
  1526. string level = string.Format("Lv{0}", Quest.QuestInfo.MinLevelNeeded);
  1527. string state = quest.Completed ? GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.Complete) : GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.InProgress);
  1528. bool lowLevelQuest = (MapObject.User.Level - quest.QuestInfo.MinLevelNeeded) > 10;
  1529. BeforeDraw += QuestTaskSingleItem_BeforeDraw;
  1530. AfterDraw += QuestTaskSingleItem_AfterDraw;
  1531. _selectedImage = new MirImageControl
  1532. {
  1533. Index = 956,
  1534. Library = Libraries.Prguse,
  1535. Location = new Point(-10, 0),
  1536. Parent = this,
  1537. Visible = false
  1538. };
  1539. _questLabel = new MirLabel
  1540. {
  1541. Text = string.Format("{0,-4} {1}", level, name),
  1542. AutoSize = true,
  1543. Font = new Font(Settings.FontName, 8F),
  1544. ForeColour = lowLevelQuest ? Color.Gray : quest.New ? Color.Yellow : Color.White,
  1545. Parent = this,
  1546. Location = new Point(0, 0),
  1547. Sound = SoundList.ButtonA
  1548. };
  1549. _questLabel.Click += (o, e) =>
  1550. {
  1551. MouseEventArgs me = e as MouseEventArgs;
  1552. if (me == null) return;
  1553. switch (me.Button)
  1554. {
  1555. case MouseButtons.Left:
  1556. GameScene.Scene.QuestDetailDialog.DisplayQuestDetails(Quest);
  1557. break;
  1558. case MouseButtons.Right:
  1559. {
  1560. if (TrackQuest)
  1561. {
  1562. GameScene.Scene.QuestTrackingDialog.RemoveQuest(Quest);
  1563. }
  1564. else
  1565. {
  1566. if (GameScene.Scene.QuestTrackingDialog.TrackedQuestsIds.Count >= 5) return;
  1567. GameScene.Scene.QuestTrackingDialog.AddQuest(Quest);
  1568. }
  1569. TrackQuest = !TrackQuest;
  1570. }
  1571. break;
  1572. }
  1573. OnSelectedQuestChanged();
  1574. };
  1575. _stateLabel = new MirLabel
  1576. {
  1577. Text = string.Format("{0}", state),
  1578. AutoSize = true,
  1579. Font = new Font(Settings.FontName, 8F),
  1580. ForeColour = lowLevelQuest ? Color.Gray : quest.New ? Color.Yellow : Color.White,
  1581. Parent = this,
  1582. Location = new Point(185, 0),
  1583. Sound = SoundList.ButtonA
  1584. };
  1585. }
  1586. void QuestTaskSingleItem_BeforeDraw(object sender, EventArgs e)
  1587. {
  1588. _selectedImage.Visible = Selected;
  1589. }
  1590. void QuestTaskSingleItem_AfterDraw(object sender, EventArgs e)
  1591. {
  1592. if (TrackQuest)
  1593. {
  1594. Libraries.Prguse.Draw(997, new Point(DisplayLocation.X - 15, DisplayLocation.Y), Color.White);
  1595. }
  1596. }
  1597. protected override void Dispose(bool disposing)
  1598. {
  1599. base.Dispose(disposing);
  1600. Quest = null;
  1601. _questLabel.Dispose();
  1602. _questLabel = null;
  1603. }
  1604. }
  1605. }