NPCInfoForm.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. using Server.MirDatabase;
  2. using Server.MirEnvir;
  3. using System.Diagnostics;
  4. using System.Runtime.CompilerServices;
  5. namespace Server
  6. {
  7. public partial class NPCInfoForm : Form
  8. {
  9. public string NPCListPath = Path.Combine(Settings.ExportPath, "NPCList.csv");
  10. public Envir Envir => SMain.EditEnvir;
  11. private List<NPCInfo> _selectedNPCInfos;
  12. public NPCInfoForm()
  13. {
  14. InitializeComponent();
  15. for (int i = 0; i < Envir.MapInfoList.Count; i++) MapComboBox.Items.Add(Envir.MapInfoList[i]);
  16. if (ConquestHidden_combo.Items.Count != Envir.ConquestInfoList.Count)
  17. {
  18. ConquestHidden_combo.Items.Clear();
  19. ConquestHidden_combo.Items.Add("");
  20. for (int i = 0; i < Envir.ConquestInfoList.Count; i++)
  21. {
  22. ConquestHidden_combo.Items.Add(Envir.ConquestInfoList[i]);
  23. }
  24. }
  25. NPCSearchBox_TextChanged(this, EventArgs.Empty);
  26. UpdateInterface();
  27. }
  28. private void AddButton_Click(object sender, EventArgs e)
  29. {
  30. Envir.CreateNPCInfo();
  31. UpdateInterface();
  32. RefreshNPCList(); // Without this, the newly created NPC wont show on the NPCInfoListBox, not sure why?
  33. }
  34. private void RemoveButton_Click(object sender, EventArgs e)
  35. {
  36. if (_selectedNPCInfos.Count == 0) return;
  37. if (MessageBox.Show("Are you sure you want to remove the selected NPCs?", "Remove NPCs?", MessageBoxButtons.YesNo) != DialogResult.Yes) return;
  38. for (int i = 0; i < _selectedNPCInfos.Count; i++) Envir.Remove(_selectedNPCInfos[i]);
  39. if (Envir.NPCInfoList.Count == 0) Envir.NPCIndex = 0;
  40. UpdateInterface();
  41. }
  42. private void UpdateInterface()
  43. {
  44. _selectedNPCInfos = NPCInfoListBox.SelectedItems.Cast<NPCInfo>().ToList();
  45. if (_selectedNPCInfos.Count == 0)
  46. {
  47. ClearInterface();
  48. return;
  49. }
  50. NPCInfo info = _selectedNPCInfos[0];
  51. tabPage1.Enabled = true;
  52. tabPage2.Enabled = true;
  53. NPCIndexTextBox.Text = info.Index.ToString();
  54. NFileNameTextBox.Text = info.FileName;
  55. NNameTextBox.Text = info.Name;
  56. NXTextBox.Text = info.Location.X.ToString();
  57. NYTextBox.Text = info.Location.Y.ToString();
  58. NImageTextBox.Text = info.Image.ToString();
  59. NRateTextBox.Text = info.Rate.ToString();
  60. MapComboBox.SelectedItem = Envir.MapInfoList.FirstOrDefault(x => x.Index == info.MapIndex);
  61. MinLev_textbox.Text = info.MinLev.ToString();
  62. MaxLev_textbox.Text = info.MaxLev.ToString();
  63. Class_combo.Text = info.ClassRequired;
  64. ConquestHidden_combo.SelectedItem = Envir.ConquestInfoList.FirstOrDefault(x => x.Index == info.Conquest);
  65. Day_combo.Text = info.DayofWeek;
  66. TimeVisible_checkbox.Checked = info.TimeVisible;
  67. StartHour_combo.Text = info.HourStart.ToString();
  68. EndHour_combo.Text = info.HourEnd.ToString();
  69. StartMin_num.Value = info.MinuteStart;
  70. EndMin_num.Value = info.MinuteEnd;
  71. Flag_textbox.Text = info.FlagNeeded.ToString();
  72. ShowBigMapCheckBox.Checked = info.ShowOnBigMap;
  73. BigMapIconTextBox.Text = info.BigMapIcon.ToString();
  74. TeleportToCheckBox.Checked = info.CanTeleportTo;
  75. ConquestVisible_checkbox.Checked = info.ConquestVisible;
  76. LoadImage(info.Image);
  77. }
  78. // Clear the interface when no NPCs are selected
  79. private void ClearInterface()
  80. {
  81. tabPage1.Enabled = false;
  82. tabPage2.Enabled = false;
  83. NPCIndexTextBox.Text = string.Empty;
  84. NFileNameTextBox.Text = string.Empty;
  85. NNameTextBox.Text = string.Empty;
  86. NXTextBox.Text = string.Empty;
  87. NYTextBox.Text = string.Empty;
  88. NImageTextBox.Text = string.Empty;
  89. NRateTextBox.Text = string.Empty;
  90. MapComboBox.SelectedItem = null;
  91. MinLev_textbox.Text = string.Empty;
  92. MaxLev_textbox.Text = string.Empty;
  93. Class_combo.Text = string.Empty;
  94. ConquestHidden_combo.SelectedIndex = -1;
  95. Day_combo.Text = string.Empty;
  96. TimeVisible_checkbox.Checked = false;
  97. StartHour_combo.Text = string.Empty;
  98. EndHour_combo.Text = string.Empty;
  99. StartMin_num.Value = 0;
  100. EndMin_num.Value = 1;
  101. Flag_textbox.Text = string.Empty;
  102. ShowBigMapCheckBox.Checked = false;
  103. BigMapIconTextBox.Text = string.Empty;
  104. ConquestVisible_checkbox.Checked = true;
  105. }
  106. private void RefreshNPCList()
  107. {
  108. NPCInfoListBox.SelectedIndexChanged -= NPCInfoListBox_SelectedIndexChanged;
  109. List<bool> selected = new List<bool>();
  110. for (int i = 0; i < NPCInfoListBox.Items.Count; i++) selected.Add(NPCInfoListBox.GetSelected(i));
  111. NPCInfoListBox.Items.Clear();
  112. for (int i = 0; i < Envir.NPCInfoList.Count; i++) NPCInfoListBox.Items.Add(Envir.NPCInfoList[i]);
  113. for (int i = 0; i < selected.Count; i++) NPCInfoListBox.SetSelected(i, selected[i]);
  114. NPCInfoListBox.SelectedIndexChanged += NPCInfoListBox_SelectedIndexChanged;
  115. }
  116. private void NPCInfoListBox_SelectedIndexChanged(object sender, EventArgs e)
  117. {
  118. if (_selectedNPCInfos.Count > 0)
  119. {
  120. NPCInfo info = _selectedNPCInfos[0];
  121. LoadImage(info.Image);
  122. }
  123. else
  124. {
  125. LoadImage(0);
  126. }
  127. UpdateInterface();
  128. }
  129. private void LoadImage(ushort imageValue)
  130. {
  131. string filename = $"{imageValue}.bmp";
  132. string imagePath = Path.Combine(Environment.CurrentDirectory, "Envir", "Previews", "NPC", filename);
  133. if (File.Exists(imagePath))
  134. {
  135. using (FileStream fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
  136. {
  137. NPCPreview.Image = Image.FromStream(fs);
  138. }
  139. }
  140. else
  141. {
  142. NPCPreview.Image = null;
  143. }
  144. }
  145. private void NFileNameTextBox_TextChanged(object sender, EventArgs e)
  146. {
  147. if (ActiveControl != sender) return;
  148. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  149. _selectedNPCInfos[i].FileName = ActiveControl.Text;
  150. RefreshNPCList();
  151. }
  152. private void NNameTextBox_TextChanged(object sender, EventArgs e)
  153. {
  154. if (ActiveControl != sender) return;
  155. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  156. _selectedNPCInfos[i].Name = ActiveControl.Text;
  157. }
  158. private void NXTextBox_TextChanged(object sender, EventArgs e)
  159. {
  160. if (ActiveControl != sender) return;
  161. int temp;
  162. if (!int.TryParse(ActiveControl.Text, out temp))
  163. {
  164. ActiveControl.BackColor = Color.Red;
  165. return;
  166. }
  167. ActiveControl.BackColor = SystemColors.Window;
  168. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  169. _selectedNPCInfos[i].Location.X = temp;
  170. RefreshNPCList();
  171. }
  172. private void NYTextBox_TextChanged(object sender, EventArgs e)
  173. {
  174. if (ActiveControl != sender) return;
  175. int temp;
  176. if (!int.TryParse(ActiveControl.Text, out temp))
  177. {
  178. ActiveControl.BackColor = Color.Red;
  179. return;
  180. }
  181. ActiveControl.BackColor = SystemColors.Window;
  182. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  183. _selectedNPCInfos[i].Location.Y = temp;
  184. RefreshNPCList();
  185. }
  186. private void NImageTextBox_TextChanged(object sender, EventArgs e)
  187. {
  188. if (ActiveControl != sender) return;
  189. ushort temp;
  190. if (!ushort.TryParse(ActiveControl.Text, out temp))
  191. {
  192. ActiveControl.BackColor = Color.Red;
  193. return;
  194. }
  195. ActiveControl.BackColor = SystemColors.Window;
  196. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  197. _selectedNPCInfos[i].Image = temp;
  198. LoadImage(temp);
  199. }
  200. private void NRateTextBox_TextChanged(object sender, EventArgs e)
  201. {
  202. if (ActiveControl != sender) return;
  203. ushort temp;
  204. if (!ushort.TryParse(ActiveControl.Text, out temp))
  205. {
  206. ActiveControl.BackColor = Color.Red;
  207. return;
  208. }
  209. ActiveControl.BackColor = SystemColors.Window;
  210. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  211. _selectedNPCInfos[i].Rate = temp;
  212. }
  213. private void MapComboBox_SelectedIndexChanged(object sender, EventArgs e)
  214. {
  215. if (ActiveControl != sender) return;
  216. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  217. {
  218. MapInfo temp = (MapInfo)MapComboBox.SelectedItem;
  219. _selectedNPCInfos[i].MapIndex = temp.Index;
  220. }
  221. }
  222. private void NPCInfoForm_FormClosed(object sender, FormClosedEventArgs e)
  223. {
  224. Envir.SaveDB();
  225. }
  226. private void PasteMButton_Click(object sender, EventArgs e)
  227. {
  228. string data = Clipboard.GetText();
  229. if (!data.StartsWith("NPC", StringComparison.OrdinalIgnoreCase))
  230. {
  231. MessageBox.Show("Cannot Paste, Copied data is not NPC Information.");
  232. return;
  233. }
  234. string[] npcs = data.Split(new[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
  235. //for (int i = 1; i < npcs.Length; i++)
  236. // NPCInfo.FromText(npcs[i]);
  237. UpdateInterface();
  238. }
  239. private void ExportAllButton_Click(object sender, EventArgs e)
  240. {
  241. ExportNPCs(Envir.NPCInfoList);
  242. }
  243. private void ExportSelected_Click(object sender, EventArgs e)
  244. {
  245. var list = NPCInfoListBox.SelectedItems.Cast<NPCInfo>().ToList();
  246. ExportNPCs(list);
  247. }
  248. public void ExportNPCs(List<NPCInfo> NPCs)
  249. {
  250. if (NPCs.Count == 0) return;
  251. SaveFileDialog sfd = new SaveFileDialog();
  252. sfd.InitialDirectory = Path.Combine(Application.StartupPath, "Exports");
  253. sfd.FileName = "NpcInfoExport.csv";
  254. sfd.Filter = "CSV File|*.csv";
  255. sfd.ShowDialog();
  256. if (sfd.FileName == string.Empty) return;
  257. using (StreamWriter sw = File.CreateText(sfd.FileName))
  258. {
  259. string colume = "Index,FileName,MapFileName,LocationX,LocationY,Name,Image,Rate,ShowOnBigMap,BigMapIcon,CanTeleportTo,ConquestVisible,MinLev,MaxLev,TimeVisible,HourStart,MinuteStart,HourEnd,MinuteEnd";
  260. sw.WriteLine(colume);
  261. for (int j = 0; j < NPCs.Count; j++)
  262. {
  263. sw.WriteLine(NPCs[j].ToText());
  264. }
  265. }
  266. MessageBox.Show("NPC Export complete");
  267. }
  268. private void ImportButton_Click(object sender, EventArgs e)
  269. {
  270. string Path = string.Empty;
  271. OpenFileDialog ofd = new OpenFileDialog();
  272. ofd.Filter = "CSV File|*.csv";
  273. ofd.ShowDialog();
  274. if (ofd.FileName == string.Empty) return;
  275. Path = ofd.FileName;
  276. foreach (var m in File.ReadAllLines(Path).Skip(1))
  277. {
  278. try
  279. {
  280. NPCInfo.FromText(m);
  281. }
  282. catch { }
  283. }
  284. UpdateInterface();
  285. MessageBox.Show("NPC Import complete");
  286. }
  287. private void OpenNButton_Click(object sender, EventArgs e)
  288. {
  289. if (NFileNameTextBox.Text == string.Empty) return;
  290. var scriptPath = Path.Combine(Settings.NPCPath, NFileNameTextBox.Text + ".txt");
  291. if (File.Exists(scriptPath))
  292. {
  293. Shared.Helpers.FileIO.OpenScript(scriptPath, true);
  294. }
  295. else
  296. {
  297. Directory.CreateDirectory(Path.GetDirectoryName(scriptPath));
  298. File.Create(scriptPath).Close();
  299. Shared.Helpers.FileIO.OpenScript(scriptPath, true);
  300. }
  301. }
  302. private void MinLev_textbox_TextChanged(object sender, EventArgs e)
  303. {
  304. if (ActiveControl != sender) return;
  305. short temp;
  306. if (!short.TryParse(ActiveControl.Text, out temp))
  307. {
  308. ActiveControl.BackColor = Color.Red;
  309. return;
  310. }
  311. ActiveControl.BackColor = SystemColors.Window;
  312. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  313. _selectedNPCInfos[i].MinLev = temp;
  314. }
  315. private void HourShow_textbox_TextChanged(object sender, EventArgs e)
  316. {
  317. if (ActiveControl != sender) return;
  318. byte temp;
  319. if (!byte.TryParse(ActiveControl.Text, out temp))
  320. {
  321. ActiveControl.BackColor = Color.Red;
  322. return;
  323. }
  324. ActiveControl.BackColor = SystemColors.Window;
  325. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  326. _selectedNPCInfos[i].HourStart = temp;
  327. }
  328. private void MinutesShow_textbox_TextChanged(object sender, EventArgs e)
  329. {
  330. if (ActiveControl != sender) return;
  331. byte temp;
  332. if (!byte.TryParse(ActiveControl.Text, out temp))
  333. {
  334. ActiveControl.BackColor = Color.Red;
  335. return;
  336. }
  337. ActiveControl.BackColor = SystemColors.Window;
  338. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  339. _selectedNPCInfos[i].MinuteStart = temp;
  340. }
  341. private void Class_textbox_TextChanged(object sender, EventArgs e)
  342. {
  343. if (ActiveControl != sender) return;
  344. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  345. _selectedNPCInfos[i].ClassRequired = ActiveControl.Text;
  346. }
  347. private void CopyMButton_Click(object sender, EventArgs e)
  348. {
  349. MessageBox.Show(Envir.Now.DayOfWeek.ToString());
  350. }
  351. private void MaxLev_textbox_TextChanged(object sender, EventArgs e)
  352. {
  353. if (ActiveControl != sender) return;
  354. short temp;
  355. if (!short.TryParse(ActiveControl.Text, out temp))
  356. {
  357. ActiveControl.BackColor = Color.Red;
  358. return;
  359. }
  360. ActiveControl.BackColor = SystemColors.Window;
  361. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  362. _selectedNPCInfos[i].MaxLev = temp;
  363. }
  364. private void Class_combo_SelectedIndexChanged(object sender, EventArgs e)
  365. {
  366. if (ActiveControl != sender) return;
  367. string temp = ActiveControl.Text;
  368. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  369. _selectedNPCInfos[i].ClassRequired = temp;
  370. }
  371. private void Day_combo_SelectedIndexChanged(object sender, EventArgs e)
  372. {
  373. if (ActiveControl != sender) return;
  374. string temp = ActiveControl.Text;
  375. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  376. _selectedNPCInfos[i].DayofWeek = temp;
  377. }
  378. private void TimeVisible_checkbox_CheckedChanged(object sender, EventArgs e)
  379. {
  380. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  381. _selectedNPCInfos[i].TimeVisible = TimeVisible_checkbox.Checked;
  382. }
  383. private void StartHour_combo_SelectedIndexChanged(object sender, EventArgs e)
  384. {
  385. if (ActiveControl != sender) return;
  386. byte temp;
  387. if (!byte.TryParse(ActiveControl.Text, out temp))
  388. {
  389. ActiveControl.BackColor = Color.Red;
  390. return;
  391. }
  392. ActiveControl.BackColor = SystemColors.Window;
  393. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  394. _selectedNPCInfos[i].HourStart = temp;
  395. }
  396. private void EndHour_combo_SelectedIndexChanged(object sender, EventArgs e)
  397. {
  398. if (ActiveControl != sender) return;
  399. byte temp;
  400. if (!byte.TryParse(ActiveControl.Text, out temp))
  401. {
  402. ActiveControl.BackColor = Color.Red;
  403. return;
  404. }
  405. ActiveControl.BackColor = SystemColors.Window;
  406. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  407. _selectedNPCInfos[i].HourEnd = temp;
  408. }
  409. private void StartMin_num_ValueChanged(object sender, EventArgs e)
  410. {
  411. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  412. _selectedNPCInfos[i].MinuteStart = (byte)StartMin_num.Value;
  413. }
  414. private void EndMin_num_ValueChanged(object sender, EventArgs e)
  415. {
  416. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  417. _selectedNPCInfos[i].MinuteEnd = (byte)EndMin_num.Value;
  418. }
  419. private void Flag_textbox_TextChanged(object sender, EventArgs e)
  420. {
  421. if (ActiveControl != sender) return;
  422. int temp;
  423. if (!int.TryParse(ActiveControl.Text, out temp))
  424. {
  425. ActiveControl.BackColor = Color.Red;
  426. return;
  427. }
  428. ActiveControl.BackColor = SystemColors.Window;
  429. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  430. _selectedNPCInfos[i].FlagNeeded = temp;
  431. }
  432. private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
  433. {
  434. MessageBox.Show(Envir.Now.TimeOfDay.ToString());
  435. }
  436. private void NPCInfoForm_Load(object sender, EventArgs e)
  437. {
  438. }
  439. private void ConquestHidden_combo_SelectedIndexChanged(object sender, EventArgs e)
  440. {
  441. if (ActiveControl != sender) return;
  442. int conquestIndex = 0;
  443. if (ConquestHidden_combo.SelectedItem is ConquestInfo conquestInfo)
  444. {
  445. conquestIndex = conquestInfo.Index;
  446. }
  447. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  448. _selectedNPCInfos[i].Conquest = conquestIndex;
  449. }
  450. private void ShowBigMapCheckBox_CheckedChanged(object sender, EventArgs e)
  451. {
  452. if (ActiveControl != sender) return;
  453. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  454. _selectedNPCInfos[i].ShowOnBigMap = ShowBigMapCheckBox.Checked;
  455. }
  456. private void BigMapIconTextBox_TextChanged(object sender, EventArgs e)
  457. {
  458. if (ActiveControl != sender) return;
  459. int temp;
  460. if (!int.TryParse(ActiveControl.Text, out temp))
  461. {
  462. ActiveControl.BackColor = Color.Red;
  463. return;
  464. }
  465. ActiveControl.BackColor = SystemColors.Window;
  466. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  467. _selectedNPCInfos[i].BigMapIcon = temp;
  468. }
  469. private void TeleportToCheckBox_CheckedChanged(object sender, EventArgs e)
  470. {
  471. if (ActiveControl != sender) return;
  472. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  473. _selectedNPCInfos[i].CanTeleportTo = TeleportToCheckBox.Checked;
  474. }
  475. private void ConquestVisible_checkbox_CheckedChanged(object sender, EventArgs e)
  476. {
  477. if (ActiveControl != sender) return;
  478. for (int i = 0; i < _selectedNPCInfos.Count; i++)
  479. _selectedNPCInfos[i].ConquestVisible = ConquestVisible_checkbox.Checked;
  480. }
  481. #region NPC Search
  482. private void NPCSearchBox_TextChanged(object sender, EventArgs e)
  483. {
  484. string searchText = NPCSearchBox.Text.Trim().ToLower();
  485. // Show all items if the search box is empty or contains only whitespace
  486. if (string.IsNullOrWhiteSpace(searchText))
  487. {
  488. RefreshNPCList();
  489. return;
  490. }
  491. NPCInfoListBox.Items.Clear();
  492. // Filter NPCs based on search text
  493. foreach (var npc in Envir.NPCInfoList)
  494. {
  495. if (!string.IsNullOrEmpty(npc.Name) && npc.Name.ToLower().Contains(searchText) ||
  496. !string.IsNullOrEmpty(npc.FileName) && npc.FileName.ToLower().Contains(searchText))
  497. {
  498. NPCInfoListBox.Items.Add(npc);
  499. }
  500. }
  501. }
  502. #endregion
  503. }
  504. }