InventoryDialog.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. using Client.MirControls;
  2. using Client.MirGraphics;
  3. using Client.MirNetwork;
  4. using Client.MirObjects;
  5. using Client.MirSounds;
  6. using C = ClientPackets;
  7. namespace Client.MirScenes.Dialogs
  8. {
  9. public sealed class InventoryDialog : MirImageControl
  10. {
  11. public MirImageControl WeightBar;
  12. public MirImageControl[] LockBar = new MirImageControl[10];
  13. public MirItemCell[] Grid;
  14. public MirItemCell[] QuestGrid;
  15. public MirButton CloseButton, ItemButton, ItemButton2, QuestButton, AddButton, DelItemButton;
  16. public MirLabel GoldLabel, WeightLabel;
  17. private bool _deleteMode;
  18. private Size _binSize;
  19. private MirImageControl _deleteCursorIcon;
  20. public bool DeleteMode => _deleteMode;
  21. public InventoryDialog()
  22. {
  23. Index = 196;
  24. Library = Libraries.Title;
  25. Movable = true;
  26. Sort = true;
  27. Visible = false;
  28. WeightBar = new MirImageControl
  29. {
  30. Index = 24,
  31. Library = Libraries.Prguse,
  32. Location = new Point(182, 217),
  33. Parent = this,
  34. DrawImage = false,
  35. NotControl = true,
  36. };
  37. ItemButton = new MirButton
  38. {
  39. Index = 197,
  40. Library = Libraries.Title,
  41. Location = new Point(6, 7),
  42. Parent = this,
  43. Size = new Size(72, 23),
  44. Sound = SoundList.ButtonA,
  45. };
  46. ItemButton.Click += Button_Click;
  47. ItemButton2 = new MirButton
  48. {
  49. Index = 738,
  50. Library = Libraries.Title,
  51. Location = new Point(76, 7),
  52. Parent = this,
  53. Size = new Size(72, 23),
  54. Sound = SoundList.ButtonA,
  55. };
  56. ItemButton2.Click += Button_Click;
  57. QuestButton = new MirButton
  58. {
  59. Index = 739,
  60. Library = Libraries.Title,
  61. Location = new Point(146, 7),
  62. Parent = this,
  63. Size = new Size(72, 23),
  64. Sound = SoundList.ButtonA,
  65. };
  66. QuestButton.Click += Button_Click;
  67. AddButton = new MirButton
  68. {
  69. Index = 483,
  70. HoverIndex = 484,
  71. PressedIndex = 485,
  72. Library = Libraries.Title,
  73. Location = new Point(235, 5),
  74. Parent = this,
  75. Size = new Size(72, 23),
  76. Sound = SoundList.ButtonA,
  77. Visible = false,
  78. };
  79. AddButton.Click += (o1, e) =>
  80. {
  81. int openLevel = (GameScene.User.Inventory.Length - 46) / 4;
  82. int openGold = (1000000 + openLevel * 1000000);
  83. MirMessageBox messageBox = new MirMessageBox(GameLanguage.ClientTextMap.GetLocalization((ClientTextKeys.ExtraSlots4), openGold), MirMessageBoxButtons.OKCancel);
  84. messageBox.OKButton.Click += (o, a) =>
  85. {
  86. Network.Enqueue(new C.Chat { Message = "@ADDINVENTORY" });
  87. };
  88. messageBox.Show();
  89. };
  90. CloseButton = new MirButton
  91. {
  92. HoverIndex = 361,
  93. Index = 360,
  94. Location = new Point(289, 3),
  95. Library = Libraries.Prguse2,
  96. Parent = this,
  97. PressedIndex = 362,
  98. Sound = SoundList.ButtonA,
  99. };
  100. CloseButton.Click += (o, e) => Hide();
  101. DelItemButton = new MirButton
  102. {
  103. Index = 366,
  104. HoverIndex = 367,
  105. PressedIndex = 368,
  106. Location = new Point(291, 212),
  107. Library = Libraries.Prguse2,
  108. Parent = this,
  109. Sound = SoundList.ButtonA,
  110. };
  111. DelItemButton.Click += DelItemButton_Click;
  112. _deleteCursorIcon = new MirImageControl
  113. {
  114. Parent = GameScene.Scene,
  115. Library = Libraries.Prguse2,
  116. Index = 366,
  117. NotControl = true,
  118. Visible = false
  119. };
  120. GoldLabel = new MirLabel
  121. {
  122. Parent = this,
  123. Location = new Point(40, 212),
  124. Size = new Size(111, 14),
  125. Sound = SoundList.Gold,
  126. };
  127. GoldLabel.Click += (o, e) =>
  128. {
  129. if (GameScene.SelectedCell == null)
  130. GameScene.PickedUpGold = !GameScene.PickedUpGold && GameScene.Gold > 0;
  131. };
  132. Grid = new MirItemCell[8 * 10];
  133. for (int x = 0; x < 8; x++)
  134. {
  135. for (int y = 0; y < 10; y++)
  136. {
  137. int idx = 8 * y + x;
  138. Grid[idx] = new MirItemCell
  139. {
  140. ItemSlot = 6 + idx,
  141. GridType = MirGridType.Inventory,
  142. Library = Libraries.Items,
  143. Parent = this,
  144. Location = new Point(x * 36 + 9 + x, y % 5 * 32 + 37 + y % 5),
  145. };
  146. if (idx >= 40)
  147. Grid[idx].Visible = false;
  148. }
  149. }
  150. QuestGrid = new MirItemCell[8 * 5];
  151. for (int x = 0; x < 8; x++)
  152. {
  153. for (int y = 0; y < 5; y++)
  154. {
  155. QuestGrid[8 * y + x] = new MirItemCell
  156. {
  157. ItemSlot = 8 * y + x,
  158. GridType = MirGridType.QuestInventory,
  159. Library = Libraries.Items,
  160. Parent = this,
  161. Location = new Point(x * 36 + 9 + x, y * 32 + 37 + y),
  162. Visible = false
  163. };
  164. }
  165. }
  166. WeightLabel = new MirLabel
  167. {
  168. Parent = this,
  169. Location = new Point(268, 212),
  170. Size = new Size(26, 14)
  171. };
  172. WeightBar.BeforeDraw += WeightBar_BeforeDraw;
  173. for (int i = 0; i < LockBar.Length; i++)
  174. {
  175. LockBar[i] = new MirImageControl
  176. {
  177. Index = 307,
  178. Library = Libraries.Prguse2,
  179. Location = new Point(9 + i % 2 * 148, 37 + i / 2 * 33),
  180. Parent = this,
  181. DrawImage = true,
  182. NotControl = true,
  183. Visible = false,
  184. };
  185. }
  186. }
  187. void Button_Click(object sender, EventArgs e)
  188. {
  189. // Ctrl + Left-click: move selected item to the tab's bag without switching tabs.
  190. if (GameScene.SelectedCell != null &&
  191. e is MouseEventArgs me &&
  192. me.Button == MouseButtons.Left &&
  193. (Control.ModifierKeys & Keys.Control) == Keys.Control)
  194. {
  195. if (sender == ItemButton)
  196. {
  197. TryMoveSelectedInventoryItem(false);
  198. }
  199. else if (sender == ItemButton2)
  200. {
  201. TryMoveSelectedInventoryItem(true);
  202. }
  203. return;
  204. }
  205. if (GameScene.User.Inventory.Length == 46 && sender == ItemButton2)
  206. {
  207. MirMessageBox messageBox = new MirMessageBox(GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.ExtraSlots8), MirMessageBoxButtons.OKCancel);
  208. messageBox.OKButton.Click += (o, a) =>
  209. {
  210. Network.Enqueue(new C.Chat { Message = "@ADDINVENTORY" });
  211. };
  212. messageBox.Show();
  213. }
  214. else
  215. {
  216. if (sender == ItemButton)
  217. {
  218. RefreshInventory();
  219. }
  220. else if (sender == ItemButton2)
  221. {
  222. RefreshInventory2();
  223. }
  224. else if (sender == QuestButton)
  225. {
  226. Reset();
  227. ItemButton.Index = 737;
  228. ItemButton2.Index = 738;
  229. QuestButton.Index = 198;
  230. if (GameScene.User.Inventory.Length == 46)
  231. {
  232. ItemButton2.Index = 169;
  233. }
  234. foreach (var grid in QuestGrid)
  235. {
  236. grid.Visible = true;
  237. }
  238. }
  239. }
  240. }
  241. private bool TryMoveSelectedInventoryItem(bool toSecondBag)
  242. {
  243. // Allow dragging an item (inventory or belt) onto a bag tab to move it to that bag page.
  244. var selected = GameScene.SelectedCell;
  245. if (selected == null || selected.Item == null || selected.Locked || selected.GridType != MirGridType.Inventory)
  246. return false;
  247. const int firstBagVisibleSlots = 40; // 40 slots per bag page, belt is handled separately.
  248. int firstBagStart = GameScene.User.BeltIdx;
  249. int secondBagStart = firstBagStart + firstBagVisibleSlots;
  250. int inventoryLength = GameScene.User.Inventory.Length;
  251. bool targetIsSecond = toSecondBag;
  252. if (targetIsSecond && inventoryLength <= secondBagStart) return false; // no expanded bag
  253. if (targetIsSecond && selected.ItemSlot >= secondBagStart) return false; // already there
  254. if (!targetIsSecond && selected.ItemSlot >= firstBagStart && selected.ItemSlot < secondBagStart) return false; // already in first bag
  255. int start = targetIsSecond ? secondBagStart : firstBagStart;
  256. int end = targetIsSecond ? inventoryLength : secondBagStart;
  257. int? targetSlot = FindFirstEmptySlot(start, end, GameScene.User.Inventory);
  258. if (targetSlot == null) return false; // no space
  259. Network.Enqueue(new C.MoveItem { Grid = MirGridType.Inventory, From = selected.ItemSlot, To = targetSlot.Value });
  260. selected.Locked = true;
  261. MirItemCell targetCell = Grid.FirstOrDefault(c => c.ItemSlot == targetSlot.Value);
  262. if (targetCell != null)
  263. targetCell.Locked = true;
  264. GameScene.SelectedCell = null;
  265. return true;
  266. }
  267. private static int? FindFirstEmptySlot(int start, int end, UserItem[] items)
  268. {
  269. for (int i = start; i < end; i++)
  270. {
  271. if (items[i] == null)
  272. return i;
  273. }
  274. return null;
  275. }
  276. void Reset()
  277. {
  278. foreach (MirItemCell grid in QuestGrid)
  279. {
  280. grid.Visible = false;
  281. }
  282. foreach (MirItemCell grid in Grid)
  283. {
  284. grid.Visible = false;
  285. }
  286. for (int i = 0; i < LockBar.Length; i++)
  287. {
  288. LockBar[i].Visible = false;
  289. }
  290. AddButton.Visible = false;
  291. }
  292. public void RefreshInventory()
  293. {
  294. Reset();
  295. ItemButton.Index = 197;
  296. ItemButton2.Index = 738;
  297. QuestButton.Index = 739;
  298. if (GameScene.User.Inventory.Length == 46)
  299. {
  300. ItemButton2.Index = 169;
  301. }
  302. foreach (var grid in Grid)
  303. {
  304. if (grid.ItemSlot < 46)
  305. grid.Visible = true;
  306. else
  307. grid.Visible = false;
  308. }
  309. }
  310. public void RefreshInventory2()
  311. {
  312. Reset();
  313. ItemButton.Index = 737;
  314. ItemButton2.Index = 168;
  315. QuestButton.Index = 739;
  316. foreach (var grid in Grid)
  317. {
  318. if (grid.ItemSlot < 46 || grid.ItemSlot >= GameScene.User.Inventory.Length)
  319. grid.Visible = false;
  320. else
  321. grid.Visible = true;
  322. }
  323. int openLevel = (GameScene.User.Inventory.Length - 46) / 4;
  324. for (int i = 0; i < LockBar.Length; i++)
  325. {
  326. LockBar[i].Visible = (i < openLevel) ? false : true;
  327. }
  328. AddButton.Visible = openLevel >= 10 ? false : true;
  329. }
  330. public void Process()
  331. {
  332. WeightLabel.Text = GameScene.User.Inventory.Count(t => t == null).ToString();
  333. //WeightLabel.Text = (MapObject.User.MaxBagWeight - MapObject.User.CurrentBagWeight).ToString();
  334. GoldLabel.Text = GameScene.Gold.ToString("###,###,##0");
  335. // Delete-mode cursor icon follows the mouse
  336. if (_deleteMode && _deleteCursorIcon != null && _deleteCursorIcon.Visible)
  337. UpdateDeleteCursorPos();
  338. }
  339. private void WeightBar_BeforeDraw(object sender, EventArgs e)
  340. {
  341. if (WeightBar.Library == null) return;
  342. double percent = MapObject.User.CurrentBagWeight / (double)MapObject.User.Stats[Stat.BagWeight];
  343. if (percent > 1) percent = 1;
  344. if (percent <= 0) return;
  345. // Weight bar art based on fill
  346. if (percent <= 0.50)
  347. {
  348. WeightBar.Library = Libraries.Prguse;
  349. WeightBar.Index = 24;
  350. }
  351. else if (percent <= 0.75)
  352. {
  353. WeightBar.Library = Libraries.UI_32bit;
  354. WeightBar.Index = 471;
  355. }
  356. else
  357. {
  358. WeightBar.Library = Libraries.UI_32bit;
  359. WeightBar.Index = 470;
  360. }
  361. Rectangle section = new Rectangle
  362. {
  363. Size = new Size((int)((WeightBar.Size.Width - 3) * percent), WeightBar.Size.Height)
  364. };
  365. WeightBar.Library.Draw(WeightBar.Index, section, WeightBar.DisplayLocation, Color.White, false);
  366. }
  367. public MirItemCell GetCell(ulong id)
  368. {
  369. for (int i = 0; i < Grid.Length; i++)
  370. {
  371. if (Grid[i].Item == null || Grid[i].Item.UniqueID != id) continue;
  372. return Grid[i];
  373. }
  374. return null;
  375. }
  376. public MirItemCell GetQuestCell(ulong id)
  377. {
  378. return QuestGrid.FirstOrDefault(t => t.Item != null && t.Item.UniqueID == id);
  379. }
  380. public void DisplayItemGridEffect(ulong id, int type = 0)
  381. {
  382. MirItemCell cell = GetCell(id);
  383. if (cell.Item == null) return;
  384. MirAnimatedControl animEffect = null;
  385. switch (type)
  386. {
  387. case 0:
  388. animEffect = new MirAnimatedControl
  389. {
  390. Animated = true,
  391. AnimationCount = 9,
  392. AnimationDelay = 150,
  393. Index = 410,
  394. Library = Libraries.Prguse,
  395. Location = cell.Location,
  396. Parent = this,
  397. Loop = false,
  398. NotControl = true,
  399. UseOffSet = true,
  400. Blending = true,
  401. BlendingRate = 1F
  402. };
  403. animEffect.AfterAnimation += (o, e) => animEffect.Dispose();
  404. SoundManager.PlaySound(20000 + (ushort)Spell.MagicShield * 10);
  405. break;
  406. }
  407. }
  408. public override void OnMouseMove(MouseEventArgs e)
  409. {
  410. if (_deleteMode) UpdateDeleteCursorPos();
  411. base.OnMouseMove(e);
  412. }
  413. private void DelItemButton_Click(object sender, EventArgs e)
  414. {
  415. if (GameScene.SelectedCell != null &&
  416. GameScene.SelectedCell.GridType == MirGridType.Inventory &&
  417. GameScene.SelectedCell.Item != null)
  418. {
  419. PromptDelete(GameScene.SelectedCell);
  420. return;
  421. }
  422. ToggleDeleteMode(!_deleteMode);
  423. }
  424. public override void OnMouseClick(MouseEventArgs e)
  425. {
  426. // Right-click anywhere on the inventory cancels the bin toggle
  427. if (_deleteMode && e.Button == MouseButtons.Right)
  428. {
  429. ToggleDeleteMode(false);
  430. return;
  431. }
  432. base.OnMouseClick(e);
  433. }
  434. public void ToggleDeleteMode(bool on)
  435. {
  436. _deleteMode = on;
  437. DelItemButton.Index = on ? 368 : 366;
  438. if (_deleteCursorIcon != null)
  439. {
  440. _deleteCursorIcon.Visible = on;
  441. if (on)
  442. {
  443. // Use the same library as you created the icon with (Prguse2)
  444. _deleteCursorIcon.Index = 366;
  445. _binSize = _deleteCursorIcon.Library != null
  446. ? _deleteCursorIcon.Library.GetSize(366)
  447. : Size.Empty;
  448. UpdateDeleteCursorPos();
  449. }
  450. }
  451. SoundManager.PlaySound(on ? SoundList.ButtonA : SoundList.ButtonB);
  452. }
  453. private void UpdateDeleteCursorPos()
  454. {
  455. if (!_deleteMode || _deleteCursorIcon == null || !_deleteCursorIcon.Visible) return;
  456. // Top-center above the pointer: bottom edge of the icon touches the cursor
  457. int x = CMain.MPoint.X - (_binSize.Width / 2);
  458. int y = CMain.MPoint.Y - _binSize.Height;
  459. _deleteCursorIcon.Location = new Point(x, y);
  460. _deleteCursorIcon.BringToFront();
  461. }
  462. public void PromptDelete(MirItemCell cell)
  463. {
  464. if (cell == null || cell.Item == null) return;
  465. var item = cell.Item;
  466. var name = item.FriendlyName;
  467. void CancelDelete()
  468. {
  469. GameScene.SelectedCell = null;
  470. cell.Locked = false;
  471. cell.Opacity = 1F;
  472. cell.Redraw();
  473. ToggleDeleteMode(false);
  474. }
  475. void DoDelete(ushort amt)
  476. {
  477. SendDeleteItem(item.UniqueID, amt, false);
  478. CancelDelete();
  479. }
  480. if (item.Count > 1)
  481. {
  482. var amountPrompt = GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.DeleteItemAmountPrompt, name);
  483. var amountBox = new MirAmountBox(amountPrompt, item.Image, item.Count);
  484. amountBox.OKButton.Click += (o, a) =>
  485. {
  486. var amt = (ushort)Math.Max(1, Math.Min(amountBox.Amount, item.Count));
  487. DoDelete(amt);
  488. };
  489. // Cancel closes the amount box AND exits delete mode
  490. if (amountBox.CancelButton != null)
  491. amountBox.CancelButton.Click += (o, a) => CancelDelete();
  492. amountBox.Show();
  493. }
  494. else
  495. {
  496. var confirmPrompt = GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.DeleteItemConfirmPrompt, name);
  497. var mb = new MirMessageBox(confirmPrompt, MirMessageBoxButtons.YesNo);
  498. mb.YesButton.Click += (o, a) => { DoDelete(1); };
  499. mb.NoButton.Click += (o, a) => { CancelDelete(); };
  500. mb.Show();
  501. }
  502. }
  503. private void SendDeleteItem(ulong uniqueId, ushort count, bool heroInventory)
  504. {
  505. Network.Enqueue(new C.DeleteItem { UniqueID = uniqueId, Count = count, HeroInventory = heroInventory });
  506. }
  507. }
  508. public sealed class BeltDialog : MirImageControl
  509. {
  510. public MirLabel[] Key = new MirLabel[6];
  511. public MirButton CloseButton, RotateButton;
  512. public MirItemCell[] Grid;
  513. public BeltDialog()
  514. {
  515. Index = 1932;
  516. Library = Libraries.Prguse;
  517. Movable = true;
  518. Sort = true;
  519. Visible = true;
  520. Location = new Point(GameScene.Scene.MainDialog.Location.X + 230, Settings.ScreenHeight - 150);
  521. BeforeDraw += BeltPanel_BeforeDraw;
  522. for (int i = 0; i < Key.Length; i++)
  523. {
  524. Key[i] = new MirLabel
  525. {
  526. Parent = this,
  527. Size = new Size(26, 14),
  528. Location = new Point(8 + i * 35, 2),
  529. Text = (i + 1).ToString()
  530. };
  531. }
  532. RotateButton = new MirButton
  533. {
  534. HoverIndex = 1927,
  535. Index = 1926,
  536. Location = new Point(222, 3),
  537. Library = Libraries.Prguse,
  538. Parent = this,
  539. PressedIndex = 1928,
  540. Sound = SoundList.ButtonA,
  541. Hint = GameLanguage.ClientTextMap.GetLocalization(ClientTextKeys.Rotate)
  542. };
  543. RotateButton.Click += (o, e) => Flip();
  544. CloseButton = new MirButton
  545. {
  546. HoverIndex = 1924,
  547. Index = 1923,
  548. Location = new Point(222, 19),
  549. Library = Libraries.Prguse,
  550. Parent = this,
  551. PressedIndex = 1925,
  552. Sound = SoundList.ButtonA,
  553. Hint = GameLanguage.ClientTextMap.GetLocalization((ClientTextKeys.CloseKey), CMain.InputKeys.GetKey(KeybindOptions.Belt))
  554. };
  555. CloseButton.Click += (o, e) => Hide();
  556. Grid = new MirItemCell[6];
  557. for (int x = 0; x < 6; x++)
  558. {
  559. Grid[x] = new MirItemCell
  560. {
  561. ItemSlot = x,
  562. Size = new Size(32, 32),
  563. GridType = MirGridType.Inventory,
  564. Library = Libraries.Items,
  565. Parent = this,
  566. Location = new Point(x * 35 + 12, 3),
  567. };
  568. }
  569. }
  570. private void BeltPanel_BeforeDraw(object sender, EventArgs e)
  571. {
  572. //if Transparent return
  573. if (Libraries.Prguse != null)
  574. Libraries.Prguse.Draw(Index + 1, DisplayLocation, Color.White, false, 0.5F);
  575. }
  576. public void Flip()
  577. {
  578. //0,70 LOCATION
  579. if (Index == 1932)
  580. {
  581. Index = 1944;
  582. Location = new Point(0, 200);
  583. for (int x = 0; x < 6; x++)
  584. Grid[x].Location = new Point(3, x * 35 + 12);
  585. CloseButton.Index = 1935;
  586. CloseButton.HoverIndex = 1936;
  587. CloseButton.Location = new Point(3, 222);
  588. CloseButton.PressedIndex = 1937;
  589. RotateButton.Index = 1938;
  590. RotateButton.HoverIndex = 1939;
  591. RotateButton.Location = new Point(19, 222);
  592. RotateButton.PressedIndex = 1940;
  593. }
  594. else
  595. {
  596. Index = 1932;
  597. Location = new Point(GameScene.Scene.MainDialog.Location.X + 230, Settings.ScreenHeight - 150);
  598. for (int x = 0; x < 6; x++)
  599. Grid[x].Location = new Point(x * 35 + 12, 3);
  600. CloseButton.Index = 1923;
  601. CloseButton.HoverIndex = 1924;
  602. CloseButton.Location = new Point(222, 19);
  603. CloseButton.PressedIndex = 1925;
  604. RotateButton.Index = 1926;
  605. RotateButton.HoverIndex = 1927;
  606. RotateButton.Location = new Point(222, 3);
  607. RotateButton.PressedIndex = 1928;
  608. }
  609. for (int i = 0; i < Key.Length; i++)
  610. {
  611. Key[i].Location = (Index != 1932) ? new Point(-1, 11 + i * 35) : new Point(8 + i * 35, 2);
  612. }
  613. }
  614. public MirItemCell GetCell(ulong id)
  615. {
  616. for (int i = 0; i < Grid.Length; i++)
  617. {
  618. if (Grid[i].Item == null || Grid[i].Item.UniqueID != id) continue;
  619. return Grid[i];
  620. }
  621. return null;
  622. }
  623. }
  624. }