ItemInfoFormNew.cs 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407
  1. using System.Data;
  2. using System.Text;
  3. using System.Text.RegularExpressions;
  4. using System.Threading.Tasks;
  5. using Microsoft.VisualBasic;
  6. using Server.MirEnvir;
  7. namespace Server.Database
  8. {
  9. public partial class ItemInfoFormNew : Form
  10. {
  11. public Envir Envir => SMain.EditEnvir;
  12. private readonly Array StatEnums = Enum.GetValues(typeof(Stat));
  13. private readonly Array BindEnums = Enum.GetValues(typeof(BindMode));
  14. private readonly Array SpecialEnums = Enum.GetValues(typeof(SpecialItemMode));
  15. private bool _isInGemContext = false;
  16. private Dictionary<int, string> _defaultItemHeaderMappings = new();
  17. private Dictionary<int, string> _gemItemHeaderMappings = new();
  18. private DataTable Table;
  19. public ItemInfoFormNew()
  20. {
  21. InitializeComponent();
  22. SetDoubleBuffered(itemInfoGridView);
  23. InitializeItemInfoFilters();
  24. InitializeItemInfoGridView();
  25. CreateDynamicColumns();
  26. PopulateTable();
  27. MapHeaderText();
  28. LoadDropRecipeQuestFiles();
  29. // register after initializing data to prevent erroneous throws
  30. itemInfoGridView.CellValueChanged += CellValueChanged;
  31. itemInfoGridView.CellValidating += itemInfoGridView_CellValidating;
  32. itemInfoGridView.MouseClick += ItemInfoGridView_MouseClick;
  33. itemInfoGridView.SelectionChanged += ItemInfoGridView_SelectionChanged;
  34. itemInfoGridView.CellBeginEdit += ItemInfoGridView_CellBeginEdit;
  35. itemInfoGridView.CellEndEdit += ItemInfoGridView_CellEndEdit;
  36. }
  37. public static void SetDoubleBuffered(Control c)
  38. {
  39. System.Reflection.PropertyInfo aProp =
  40. typeof(Control).GetProperty(
  41. "DoubleBuffered",
  42. System.Reflection.BindingFlags.NonPublic |
  43. System.Reflection.BindingFlags.Instance);
  44. aProp.SetValue(c, true, null);
  45. }
  46. private void InitializeItemInfoFilters()
  47. {
  48. Dictionary<String, String> filterItems = new()
  49. {
  50. { "-1", "" }
  51. };
  52. var types = Enum.GetValues(typeof(ItemType));
  53. foreach (ItemType type in types)
  54. {
  55. filterItems.Add(((byte)type).ToString(), type.ToString());
  56. }
  57. drpFilterType.DataSource = new BindingSource(filterItems, null);
  58. drpFilterType.DisplayMember = "Value";
  59. drpFilterType.ValueMember = "Key";
  60. }
  61. private void InitializeItemInfoGridView()
  62. {
  63. Modified.ValueType = typeof(bool);
  64. ItemIndex.ValueType = typeof(int);
  65. ItemName.ValueType = typeof(string);
  66. ItemRandomStatsId.ValueType = typeof(byte);
  67. ItemRequiredAmount.ValueType = typeof(byte);
  68. ItemImage.ValueType = typeof(ushort);
  69. ItemShape.ValueType = typeof(short);
  70. ItemEffect.ValueType = typeof(byte);
  71. ItemStackSize.ValueType = typeof(ushort);
  72. ItemSlots.ValueType = typeof(byte);
  73. ItemWeight.ValueType = typeof(byte);
  74. ItemLightIntensity.ValueType = typeof(byte);
  75. ItemLightRange.ValueType = typeof(byte);
  76. ItemDurability.ValueType = typeof(ushort);
  77. ItemPrice.ValueType = typeof(uint);
  78. ItemToolTip.ValueType = typeof(string);
  79. StartItem.ValueType = typeof(bool);
  80. NeedIdentify.ValueType = typeof(bool);
  81. ShowGroupPickup.ValueType = typeof(bool);
  82. GlobalDropNotify.ValueType = typeof(bool);
  83. ClassBased.ValueType = typeof(bool);
  84. LevelBased.ValueType = typeof(bool);
  85. CanMine.ValueType = typeof(bool);
  86. CanFastRun.ValueType = typeof(bool);
  87. CanAwakening.ValueType = typeof(bool);
  88. //Basic
  89. ItemType.ValueType = typeof(ItemType);
  90. ItemType.DataSource = Enum2DataTable<ItemType>();
  91. ItemType.ValueMember = "Value";
  92. ItemType.DisplayMember = "Display";
  93. ItemGrade.ValueType = typeof(ItemGrade);
  94. ItemGrade.DataSource = Enum2DataTable<ItemGrade>();
  95. ItemGrade.ValueMember = "Value";
  96. ItemGrade.DisplayMember = "Display";
  97. ItemRequiredType.ValueType = typeof(RequiredType);
  98. ItemRequiredType.DataSource = Enum2DataTable<RequiredType>();
  99. ItemRequiredType.ValueMember = "Value";
  100. ItemRequiredType.DisplayMember = "Display";
  101. ItemRequiredGender.ValueType = typeof(RequiredGender);
  102. ItemRequiredGender.DataSource = Enum2DataTable<RequiredGender>();
  103. ItemRequiredGender.ValueMember = "Value";
  104. ItemRequiredGender.DisplayMember = "Display";
  105. ItemRequiredClass.ValueType = typeof(RequiredClass);
  106. ItemRequiredClass.DataSource = Enum2DataTable<RequiredClass>();
  107. ItemRequiredClass.ValueMember = "Value";
  108. ItemRequiredClass.DisplayMember = "Display";
  109. ItemSet.ValueType = typeof(ItemSet);
  110. ItemSet.DataSource = Enum2DataTable<ItemSet>();
  111. ItemSet.ValueMember = "Value";
  112. ItemSet.DisplayMember = "Display";
  113. }
  114. public static DataTable Enum2DataTable<T>()
  115. {
  116. DataTable enumTable = new DataTable();
  117. enumTable.Columns.Add(new DataColumn("Value", Enum.GetUnderlyingType(typeof(T))));
  118. enumTable.Columns.Add(new DataColumn("Display", typeof(string)));
  119. DataRow EnumRow;
  120. foreach (T E in Enum.GetValues(typeof(T)))
  121. {
  122. EnumRow = enumTable.NewRow();
  123. EnumRow["Value"] = E;
  124. EnumRow["Display"] = E.ToString();
  125. enumTable.Rows.Add(EnumRow);
  126. }
  127. return enumTable;
  128. }
  129. private void CreateDynamicColumns()
  130. {
  131. foreach (Stat stat in StatEnums)
  132. {
  133. if (stat == Stat.Unknown) continue;
  134. var key = stat.ToString();
  135. var strKey = RegexFunctions.SeperateCamelCase(key.Replace("Rate", "").Replace("Multiplier", "").Replace("Percent", ""));
  136. var sign = "";
  137. if (key.Contains("Percent"))
  138. sign = "%";
  139. else if (key.Contains("Multiplier"))
  140. sign = "x";
  141. var col = new DataGridViewTextBoxColumn
  142. {
  143. HeaderText = $"{strKey} {sign}",
  144. Name = "Stat" + stat.ToString(),
  145. ValueType = typeof(int),
  146. DataPropertyName = "Stat" + stat.ToString()
  147. };
  148. itemInfoGridView.Columns.Add(col);
  149. }
  150. foreach (BindMode bind in BindEnums)
  151. {
  152. if (bind == BindMode.None) continue;
  153. var col = new DataGridViewCheckBoxColumn
  154. {
  155. HeaderText = bind.ToString(),
  156. Name = "Bind" + bind.ToString(),
  157. ValueType = typeof(bool),
  158. DataPropertyName = "Bind" + bind.ToString()
  159. };
  160. itemInfoGridView.Columns.Add(col);
  161. }
  162. foreach (SpecialItemMode special in SpecialEnums)
  163. {
  164. if (special == SpecialItemMode.None) continue;
  165. var col = new DataGridViewCheckBoxColumn
  166. {
  167. HeaderText = special.ToString(),
  168. Name = "Special" + special.ToString(),
  169. ValueType = typeof(bool),
  170. DataPropertyName = "Special" + special.ToString()
  171. };
  172. itemInfoGridView.Columns.Add(col);
  173. }
  174. }
  175. private void PopulateTable()
  176. {
  177. Table = new DataTable("itemInfo");
  178. foreach (DataGridViewColumn col in itemInfoGridView.Columns)
  179. {
  180. Table.Columns.Add(col.DataPropertyName, col.ValueType);
  181. }
  182. foreach (ItemInfo item in Envir.ItemInfoList)
  183. {
  184. DataRow row = Table.NewRow();
  185. row["Modified"] = false;
  186. row["ItemIndex"] = item.Index;
  187. row["ItemName"] = item.Name;
  188. row["ItemType"] = item.Type;
  189. row["ItemGrade"] = item.Grade;
  190. row["ItemRequiredType"] = item.RequiredType;
  191. row["ItemRequiredGender"] = item.RequiredGender;
  192. row["ItemRequiredClass"] = item.RequiredClass;
  193. row["ItemSet"] = item.Set;
  194. row["ItemRandomStatsId"] = item.RandomStatsId;
  195. row["ItemRequiredAmount"] = item.RequiredAmount;
  196. row["ItemImage"] = item.Image;
  197. row["ItemShape"] = item.Shape;
  198. row["ItemEffect"] = item.Effect;
  199. row["ItemStackSize"] = item.StackSize;
  200. row["ItemSlots"] = item.Slots;
  201. row["ItemWeight"] = item.Weight;
  202. row["ItemLightRange"] = (byte)(item.Light % 15);
  203. row["ItemLightIntensity"] = (byte)(item.Light / 15);
  204. row["ItemDurability"] = item.Durability;
  205. row["ItemPrice"] = item.Price;
  206. row["ItemToolTip"] = item.ToolTip;
  207. row["StartItem"] = item.StartItem;
  208. row["NeedIdentify"] = item.NeedIdentify;
  209. row["ShowGroupPickup"] = item.ShowGroupPickup;
  210. row["GlobalDropNotify"] = item.GlobalDropNotify;
  211. row["ClassBased"] = item.ClassBased;
  212. row["LevelBased"] = item.LevelBased;
  213. row["CanMine"] = item.CanMine;
  214. row["CanFastRun"] = item.CanFastRun;
  215. row["CanAwakening"] = item.CanAwakening;
  216. foreach (Stat stat in StatEnums)
  217. {
  218. if (stat == Stat.Unknown) continue;
  219. row["Stat" + stat.ToString()] = item.Stats[stat];
  220. }
  221. foreach (BindMode bind in BindEnums)
  222. {
  223. if (bind == BindMode.None) continue;
  224. row["Bind" + bind.ToString()] = item.Bind.HasFlag(bind);
  225. }
  226. foreach (SpecialItemMode special in SpecialEnums)
  227. {
  228. if (special == SpecialItemMode.None) continue;
  229. row["Special" + special.ToString()] = item.Unique.HasFlag(special);
  230. }
  231. Table.Rows.Add(row);
  232. }
  233. itemInfoGridView.DataSource = Table;
  234. itemInfoGridView.Columns["Modified"].ReadOnly = true;
  235. }
  236. private void UpdateFilter()
  237. {
  238. if (itemInfoGridView.DataSource == null)
  239. {
  240. return;
  241. }
  242. var filterText = txtSearch.Text;
  243. var filterType = ((KeyValuePair<string, string>)drpFilterType.SelectedItem).Key;
  244. if (string.IsNullOrEmpty(filterText) &&
  245. filterType == "-1")
  246. {
  247. (itemInfoGridView.DataSource as DataTable).DefaultView.RowFilter = string.Empty;
  248. return;
  249. }
  250. string rowFilter = string.Format("([ItemType] = '{0}' OR '{0}' = -1) AND [ItemName] LIKE '%{1}%'", filterType, filterText);
  251. (itemInfoGridView.DataSource as DataTable).DefaultView.RowFilter = rowFilter;
  252. }
  253. private void SaveForm()
  254. {
  255. int lastIndex = 0;
  256. if (Envir.ItemInfoList.Count > 0)
  257. {
  258. lastIndex = Envir.ItemInfoList.Max(x => x.Index);
  259. }
  260. foreach (DataGridViewRow row in itemInfoGridView.Rows)
  261. {
  262. var name = row.Cells["ItemName"].Value;
  263. if (name == null || name.GetType() == typeof(System.DBNull) || string.IsNullOrWhiteSpace((string)name))
  264. {
  265. continue;
  266. }
  267. ItemInfo item;
  268. if (string.IsNullOrEmpty((string)row.Cells["ItemIndex"].FormattedValue))
  269. {
  270. Envir.ItemInfoList.Add(item = new ItemInfo());
  271. item.Index = ++lastIndex;
  272. }
  273. else
  274. {
  275. int index = (int)row.Cells["ItemIndex"].Value;
  276. item = Envir.ItemInfoList.FirstOrDefault(x => x.Index == index);
  277. if (row.Cells["Modified"].Value != null && (bool)row.Cells["Modified"].Value == false) continue;
  278. }
  279. item.Name = (string)row.Cells["ItemName"].Value;
  280. item.Type = (ItemType)row.Cells["ItemType"].Value;
  281. item.Grade = (ItemGrade)row.Cells["ItemGrade"].Value;
  282. item.RequiredType = (RequiredType)row.Cells["ItemRequiredType"].Value;
  283. item.RequiredGender = (RequiredGender)row.Cells["ItemRequiredGender"].Value;
  284. item.RequiredClass = (RequiredClass)row.Cells["ItemRequiredClass"].Value;
  285. item.Set = (ItemSet)row.Cells["ItemSet"].Value;
  286. item.RandomStatsId = (byte)row.Cells["ItemRandomStatsId"].Value;
  287. item.RequiredAmount = (byte)row.Cells["ItemRequiredAmount"].Value;
  288. item.Image = (ushort)row.Cells["ItemImage"].Value;
  289. item.Shape = (short)row.Cells["ItemShape"].Value;
  290. item.Effect = (byte)row.Cells["ItemEffect"].Value;
  291. item.StackSize = (ushort)row.Cells["ItemStackSize"].Value;
  292. item.Slots = (byte)row.Cells["ItemSlots"].Value;
  293. item.Weight = (byte)row.Cells["ItemWeight"].Value;
  294. item.StartItem = (bool)row.Cells["StartItem"].Value;
  295. item.NeedIdentify = (bool)row.Cells["NeedIdentify"].Value;
  296. item.ShowGroupPickup = (bool)row.Cells["ShowGroupPickup"].Value;
  297. item.GlobalDropNotify = (bool)row.Cells["GlobalDropNotify"].Value;
  298. item.ClassBased = (bool)row.Cells["ClassBased"].Value;
  299. item.LevelBased = (bool)row.Cells["LevelBased"].Value;
  300. item.CanMine = (bool)row.Cells["CanMine"].Value;
  301. item.CanFastRun = (bool)row.Cells["CanFastRun"].Value;
  302. item.CanAwakening = (bool)row.Cells["CanAwakening"].Value;
  303. var light = ((byte)row.Cells["ItemLightRange"].Value % 15) + ((byte)row.Cells["ItemLightIntensity"].Value * 15);
  304. item.Light = (byte)Math.Min(byte.MaxValue, light);
  305. item.Durability = (ushort)row.Cells["ItemDurability"].Value;
  306. item.Price = (uint)row.Cells["ItemPrice"].Value;
  307. item.ToolTip = row.Cells["ItemToolTip"].Value.ToString();
  308. item.Stats.Clear();
  309. item.Bind = BindMode.None;
  310. item.Unique = SpecialItemMode.None;
  311. foreach (DataGridViewColumn col in itemInfoGridView.Columns)
  312. {
  313. if (col.Name.StartsWith("Stat"))
  314. {
  315. var stat = col.Name.Substring(4);
  316. Stat enumStat = (Stat)Enum.Parse(typeof(Stat), stat);
  317. item.Stats[enumStat] = (int)row.Cells[col.Name].Value;
  318. }
  319. else if (col.Name.StartsWith("Bind"))
  320. {
  321. var bind = col.Name.Substring(4);
  322. BindMode enumBind = (BindMode)Enum.Parse(typeof(BindMode), bind);
  323. if ((bool)row.Cells[col.Name].Value)
  324. {
  325. item.Bind |= enumBind;
  326. }
  327. }
  328. else if (col.Name.StartsWith("Special"))
  329. {
  330. var special = col.Name.Substring(7);
  331. SpecialItemMode enumSpecial = (SpecialItemMode)Enum.Parse(typeof(SpecialItemMode), special);
  332. if ((bool)row.Cells[col.Name].Value)
  333. {
  334. item.Unique |= enumSpecial;
  335. }
  336. }
  337. }
  338. }
  339. SaveDropRecipeQuestFiles();
  340. }
  341. private DataRow FindRowByItemName(string value)
  342. {
  343. foreach (DataRow row in Table.Rows)
  344. {
  345. var val = row["ItemName"];
  346. if (val?.ToString().Equals(value) ?? false)
  347. {
  348. return row;
  349. }
  350. }
  351. return null;
  352. }
  353. private DataRow FindRowByItemIndex(string value)
  354. {
  355. foreach (DataRow row in Table.Rows)
  356. {
  357. var val = row["ItemIndex"];
  358. if (val?.ToString().Equals(value) ?? false)
  359. {
  360. return row;
  361. }
  362. }
  363. return null;
  364. }
  365. private void itemInfoGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
  366. {
  367. var col = itemInfoGridView.Columns[e.ColumnIndex];
  368. if (col.Name.Equals("Modified", comparisonType: StringComparison.CurrentCultureIgnoreCase) ||
  369. col.Name.Equals("ItemIndex", comparisonType: StringComparison.CurrentCultureIgnoreCase))
  370. {
  371. return;
  372. }
  373. var cell = itemInfoGridView.Rows[e.RowIndex].Cells[col.Name];
  374. var val = e.FormattedValue.ToString();
  375. itemInfoGridView.Rows[e.RowIndex].ErrorText = "";
  376. if (cell.OwningColumn.Name == "ItemName")
  377. {
  378. var existingRow = FindRowByItemName(val);
  379. if (existingRow != null)
  380. {
  381. var existingIndex = existingRow["ItemIndex"].ToString();
  382. var currentIndex = itemInfoGridView.Rows[e.RowIndex].Cells["ItemIndex"].Value?.ToString() ?? "";
  383. if (existingIndex != currentIndex)
  384. {
  385. e.Cancel = true;
  386. itemInfoGridView.Rows[e.RowIndex].ErrorText = "An item with this name already exists.";
  387. }
  388. }
  389. }
  390. //Only AttackSpeed stat can be negative
  391. else if (col.ValueType == typeof(int) && col.Name != "StatAttackSpeed" && int.TryParse(val, out int val1) && val1 < 0)
  392. {
  393. e.Cancel = true;
  394. itemInfoGridView.Rows[e.RowIndex].ErrorText = "the value must be a positive integer";
  395. }
  396. else if (col.ValueType == typeof(int) && !int.TryParse(val, out _))
  397. {
  398. e.Cancel = true;
  399. itemInfoGridView.Rows[e.RowIndex].ErrorText = "the value must be an integer";
  400. }
  401. else if (col.ValueType == typeof(byte) && !byte.TryParse(val, out _))
  402. {
  403. e.Cancel = true;
  404. itemInfoGridView.Rows[e.RowIndex].ErrorText = "the value must be a byte";
  405. }
  406. else if (col.ValueType == typeof(short) && !short.TryParse(val, out _))
  407. {
  408. e.Cancel = true;
  409. itemInfoGridView.Rows[e.RowIndex].ErrorText = "the value must be a short";
  410. }
  411. else if (col.ValueType == typeof(ushort) && !ushort.TryParse(val, out _))
  412. {
  413. e.Cancel = true;
  414. itemInfoGridView.Rows[e.RowIndex].ErrorText = "the value must be a ushort";
  415. }
  416. else if (col.ValueType == typeof(long) && !long.TryParse(val, out _))
  417. {
  418. e.Cancel = true;
  419. itemInfoGridView.Rows[e.RowIndex].ErrorText = "the value must be a long";
  420. }
  421. if (!e.Cancel)
  422. {
  423. itemInfoGridView.Rows[e.RowIndex].Cells["Modified"].Value = true;
  424. }
  425. }
  426. private void rbtnViewAll_CheckedChanged(object sender, EventArgs e)
  427. {
  428. if (rbtnViewAll.Checked)
  429. {
  430. foreach (DataGridViewColumn col in itemInfoGridView.Columns)
  431. {
  432. if (col.Name == "Modified") continue;
  433. col.Visible = true;
  434. continue;
  435. }
  436. }
  437. }
  438. private void rbtnViewBasic_CheckedChanged(object sender, EventArgs e)
  439. {
  440. if (rbtnViewBasic.Checked)
  441. {
  442. foreach (DataGridViewColumn col in itemInfoGridView.Columns)
  443. {
  444. if (col.Name == "ItemIndex" || col.Name == "ItemName" || col.Name == "Modified")
  445. {
  446. continue;
  447. }
  448. if (col.Name.StartsWith("Item"))
  449. {
  450. col.Visible = true;
  451. continue;
  452. }
  453. col.Visible = false;
  454. }
  455. }
  456. }
  457. private void rbtnViewStats_CheckedChanged(object sender, EventArgs e)
  458. {
  459. if (rbtnViewStats.Checked)
  460. {
  461. foreach (DataGridViewColumn col in itemInfoGridView.Columns)
  462. {
  463. if (col.Name == "ItemIndex" || col.Name == "ItemName" || col.Name == "Modified")
  464. {
  465. continue;
  466. }
  467. if (col.Name.StartsWith("Stat"))
  468. {
  469. col.Visible = true;
  470. continue;
  471. }
  472. col.Visible = false;
  473. }
  474. }
  475. }
  476. private void rbtnViewBinding_CheckedChanged(object sender, EventArgs e)
  477. {
  478. if (rbtnViewBinding.Checked)
  479. {
  480. foreach (DataGridViewColumn col in itemInfoGridView.Columns)
  481. {
  482. if (col.Name == "ItemIndex" || col.Name == "ItemName" || col.Name == "Modified")
  483. {
  484. continue;
  485. }
  486. if (col.Name.StartsWith("Bind"))
  487. {
  488. col.Visible = true;
  489. continue;
  490. }
  491. col.Visible = false;
  492. }
  493. }
  494. }
  495. private void rBtnViewSpecial_CheckedChanged(object sender, EventArgs e)
  496. {
  497. var specialCols = new string[]
  498. {
  499. "StartItem", "NeedIdentify", "ShowGroupPickup", "GlobalDropNotify", "ClassBased", "LevelBased", "CanMine", "CanFastRun", "CanAwakening"
  500. };
  501. if (rBtnViewSpecial.Checked)
  502. {
  503. foreach (DataGridViewColumn col in itemInfoGridView.Columns)
  504. {
  505. if (col.Name == "ItemIndex" || col.Name == "ItemName" || col.Name == "Modified")
  506. {
  507. continue;
  508. }
  509. if (col.Name.StartsWith("Special"))
  510. {
  511. col.Visible = true;
  512. continue;
  513. }
  514. if (specialCols.Contains(col.Name))
  515. {
  516. col.Visible = true;
  517. continue;
  518. }
  519. col.Visible = false;
  520. }
  521. }
  522. }
  523. private void drpFilterType_SelectedIndexChanged(object sender, EventArgs e)
  524. {
  525. if (itemInfoGridView.DataSource == null)
  526. {
  527. return;
  528. }
  529. UpdateFilter();
  530. var filterType = ((KeyValuePair<string, string>)drpFilterType.SelectedItem).Value;
  531. if (filterType == global::ItemType.Gem.ToString())
  532. {
  533. SwapGemContext(true);
  534. }
  535. else
  536. {
  537. SwapGemContext(false);
  538. }
  539. }
  540. private void txtSearch_KeyDown(object sender, KeyEventArgs e)
  541. {
  542. if (e.KeyCode == Keys.Enter)
  543. {
  544. UpdateFilter();
  545. e.Handled = true;
  546. e.SuppressKeyPress = true;
  547. }
  548. }
  549. private async void btnImport_Click(object sender, EventArgs e)
  550. {
  551. OpenFileDialog ofd = new OpenFileDialog();
  552. ofd.Filter = "CSV (*.csv)|*.csv";
  553. if (ofd.ShowDialog() == DialogResult.OK)
  554. {
  555. var fileName = ofd.FileName;
  556. bool fileError = false;
  557. var rows = File.ReadAllLines(fileName);
  558. if (rows.Length > 1)
  559. {
  560. var columns = rows[0].Split(',');
  561. if (columns.Length < 2)
  562. {
  563. fileError = true;
  564. MessageBox.Show("No columns to import.");
  565. }
  566. if (!fileError)
  567. {
  568. itemInfoGridView.EditMode = DataGridViewEditMode.EditProgrammatically;
  569. int rowsEdited = 0;
  570. this.itemInfoGridView.CurrentCell = this.itemInfoGridView[1, 0];
  571. var formTitle = this.Text;
  572. await Task.Run(() =>
  573. {
  574. for (int i = 1; i < rows.Length; i++)
  575. {
  576. var row = rows[i];
  577. var cells = row.Split(',');
  578. if (string.IsNullOrWhiteSpace(cells[0]))
  579. {
  580. continue;
  581. }
  582. if (cells.Length != columns.Length)
  583. {
  584. fileError = true;
  585. MessageBox.Show($"Row {i} column count does not match the headers column count.");
  586. break;
  587. }
  588. var dataRow = FindRowByItemIndex(cells[0]);
  589. try
  590. {
  591. var progress = ((rowsEdited + 1) / (double)(rows.Length - 1)) * 100;
  592. Invoke(() => this.Text = $"{formTitle} - Importing Progress: {(int)progress}% ({rowsEdited + 1}/{rows.Length - 1})");
  593. Invoke(() => itemInfoGridView.BeginEdit(true));
  594. bool isNew = false;
  595. if (dataRow == null)
  596. {
  597. dataRow = Table.NewRow();
  598. isNew = true;
  599. }
  600. for (int j = 1; j < columns.Length; j++)
  601. {
  602. var column = columns[j];
  603. if (string.IsNullOrWhiteSpace(column))
  604. {
  605. continue;
  606. }
  607. var dataColumn = itemInfoGridView.Columns[column];
  608. if (dataColumn == null)
  609. {
  610. throw new Exception($"Column {column} was not found.");
  611. }
  612. if (dataColumn.Name == "ItemName")
  613. {
  614. var existingRow = FindRowByItemName(cells[j]);
  615. if (existingRow != null)
  616. {
  617. var existingIndex = existingRow["ItemIndex"].ToString();
  618. var currentIndex = dataRow["ItemIndex"].ToString() ?? "";
  619. if (existingIndex != currentIndex)
  620. {
  621. throw new Exception($"An item named {cells[j]} already exists.");
  622. }
  623. }
  624. if (!isNew) ItemNameChange(dataRow[column].ToString(), cells[j]);
  625. }
  626. if (dataColumn.ValueType.IsEnum)
  627. {
  628. dataRow[column] = Enum.Parse(dataColumn.ValueType, cells[j]);
  629. }
  630. else
  631. {
  632. if (dataColumn.Name == "ItemToolTip")
  633. {
  634. dataRow[column] = cells[j].Trim('"').Replace("\\r\\n", "\r\n");
  635. }
  636. else
  637. {
  638. dataRow[column] = cells[j];
  639. }
  640. }
  641. }
  642. dataRow["Modified"] = true;
  643. if (isNew)
  644. {
  645. Table.Rows.Add(dataRow);
  646. }
  647. rowsEdited++;
  648. }
  649. catch (Exception ex)
  650. {
  651. fileError = true;
  652. MessageBox.Show($"Error when importing item {cells[0]}. {ex.Message}");
  653. break;
  654. }
  655. finally
  656. {
  657. Invoke(() => itemInfoGridView.EndEdit());
  658. }
  659. }
  660. });
  661. itemInfoGridView.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
  662. if (!fileError)
  663. {
  664. MessageBox.Show($"{rowsEdited} items have been imported.");
  665. }
  666. else
  667. {
  668. itemInfoGridView.ClearSelection();
  669. itemInfoGridView.Rows[rowsEdited].Selected = true;
  670. itemInfoGridView.CurrentCell = itemInfoGridView.Rows[rowsEdited].Cells[0];
  671. }
  672. this.Text = formTitle;
  673. }
  674. }
  675. else
  676. {
  677. MessageBox.Show("No rows to import.");
  678. }
  679. }
  680. }
  681. private void btnExport_Click(object sender, EventArgs e)
  682. {
  683. if (itemInfoGridView.Rows.Count > 0)
  684. {
  685. SaveFileDialog sfd = new SaveFileDialog();
  686. sfd.Filter = "CSV (*.csv)|*.csv";
  687. sfd.FileName = "ItemInfo Output.csv";
  688. bool fileError = false;
  689. if (sfd.ShowDialog() == DialogResult.OK)
  690. {
  691. if (File.Exists(sfd.FileName))
  692. {
  693. try
  694. {
  695. File.Delete(sfd.FileName);
  696. }
  697. catch (IOException ex)
  698. {
  699. fileError = true;
  700. MessageBox.Show("It wasn't possible to write the data to the disk." + ex.Message);
  701. }
  702. }
  703. if (!fileError)
  704. {
  705. try
  706. {
  707. int columnCount = itemInfoGridView.Columns.Count;
  708. string columnNames = "";
  709. var outputCsv = new List<string>(itemInfoGridView.Rows.Count + 1);
  710. for (int i = 1; i < columnCount; i++)
  711. {
  712. columnNames += itemInfoGridView.Columns[i].Name.ToString() + ",";
  713. }
  714. outputCsv.Add(columnNames);
  715. var line = new StringBuilder();
  716. for (int i = 1; (i - 1) < itemInfoGridView.Rows.Count; i++)
  717. {
  718. line.Clear();
  719. var row = itemInfoGridView.Rows[i - 1];
  720. var name = row.Cells["ItemName"].Value;
  721. if (name == null || name.GetType() == typeof(System.DBNull) || string.IsNullOrWhiteSpace((string)name))
  722. {
  723. continue;
  724. }
  725. for (int j = 1; j < columnCount; j++)
  726. {
  727. var cell = row.Cells[j];
  728. var col = itemInfoGridView.Columns[j];
  729. var valueType = col.ValueType;
  730. if (valueType.IsEnum)
  731. {
  732. line.Append(((Enum.ToObject(valueType, cell.Value ?? 0))?.ToString() ?? "") + ",");
  733. }
  734. else
  735. {
  736. var val = cell.Value?.ToString() ?? "";
  737. if (col.Name == "ItemToolTip")
  738. {
  739. line.Append($"\"{val.Replace("\r\n", "\\r\\n")}\",");
  740. }
  741. else
  742. {
  743. line.Append($"{val},");
  744. }
  745. }
  746. }
  747. if (line.Length > 0)
  748. outputCsv.Add(line.ToString());
  749. }
  750. File.WriteAllLines(sfd.FileName, outputCsv, Encoding.UTF8);
  751. MessageBox.Show("Data Exported Successfully.", "Info");
  752. }
  753. catch (Exception ex)
  754. {
  755. MessageBox.Show("Error :" + ex.Message);
  756. }
  757. }
  758. }
  759. }
  760. else
  761. {
  762. MessageBox.Show("No Items To Export.", "Info");
  763. }
  764. }
  765. private void itemInfoGridView_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
  766. {
  767. var row = e.Row;
  768. row.Cells["Modified"].Value = (bool)true;
  769. row.Cells["ItemName"].Value = "";
  770. row.Cells["ItemType"].Value = (ItemType)0;
  771. row.Cells["ItemGrade"].Value = (ItemGrade)0;
  772. row.Cells["ItemRequiredType"].Value = (RequiredType)0;
  773. row.Cells["ItemRequiredGender"].Value = RequiredGender.None;
  774. row.Cells["ItemRequiredClass"].Value = RequiredClass.None;
  775. row.Cells["ItemSet"].Value = (ItemSet)0;
  776. row.Cells["ItemRandomStatsId"].Value = (byte)0;
  777. row.Cells["ItemRequiredAmount"].Value = (byte)0;
  778. row.Cells["ItemImage"].Value = (ushort)0;
  779. row.Cells["ItemShape"].Value = (short)0;
  780. row.Cells["ItemEffect"].Value = (byte)0;
  781. row.Cells["ItemStackSize"].Value = (ushort)1;
  782. row.Cells["ItemSlots"].Value = (byte)0;
  783. row.Cells["ItemWeight"].Value = (byte)0;
  784. row.Cells["ItemLightRange"].Value = (byte)0;
  785. row.Cells["ItemLightIntensity"].Value = (byte)0;
  786. row.Cells["ItemDurability"].Value = (ushort)0;
  787. row.Cells["ItemPrice"].Value = (uint)0;
  788. row.Cells["ItemToolTip"].Value = (string)"";
  789. row.Cells["StartItem"].Value = false;
  790. row.Cells["NeedIdentify"].Value = false;
  791. row.Cells["ShowGroupPickup"].Value = false;
  792. row.Cells["GlobalDropNotify"].Value = false;
  793. row.Cells["ClassBased"].Value = false;
  794. row.Cells["LevelBased"].Value = false;
  795. row.Cells["CanMine"].Value = false;
  796. row.Cells["CanFastRun"].Value = false;
  797. row.Cells["CanAwakening"].Value = false;
  798. foreach (Stat stat in StatEnums)
  799. {
  800. if (stat == Stat.Unknown) continue;
  801. row.Cells["Stat" + stat.ToString()].Value = 0;
  802. }
  803. foreach (BindMode bind in BindEnums)
  804. {
  805. if (bind == BindMode.None) continue;
  806. row.Cells["Bind" + bind.ToString()].Value = false;
  807. }
  808. foreach (SpecialItemMode special in SpecialEnums)
  809. {
  810. if (special == SpecialItemMode.None) continue;
  811. row.Cells["Special" + special.ToString()].Value = false;
  812. }
  813. }
  814. private void ItemInfoGridView_MouseClick(object sender, MouseEventArgs e)
  815. {
  816. if (e.Button == MouseButtons.Right &&
  817. itemInfoGridView.SelectedRows.Count > 1)
  818. {
  819. var mouseOverRow = itemInfoGridView.HitTest(e.X, e.Y).RowIndex;
  820. var mouseOverCol = itemInfoGridView.HitTest(e.X, e.Y).ColumnIndex;
  821. if (mouseOverRow >= 0 &&
  822. mouseOverCol >= 0)
  823. {
  824. var colName = itemInfoGridView.Rows[mouseOverRow].Cells[mouseOverCol].OwningColumn.HeaderText;
  825. if (colName == "Modified" ||
  826. colName == "Index" ||
  827. colName == "Name" ||
  828. itemInfoGridView.Rows[mouseOverRow].Cells[mouseOverCol] is DataGridViewComboBoxCell
  829. )
  830. {
  831. return;
  832. }
  833. String promptText = $"Enter new value for column [{colName}]:";
  834. if (itemInfoGridView.Rows[mouseOverRow].Cells[mouseOverCol] is DataGridViewCheckBoxCell)
  835. {
  836. promptText += $"{Environment.NewLine}[[Enter 1 for tick or 0 for untick]]";
  837. }
  838. var updateValue = Interaction.InputBox(promptText,
  839. "Bulk Update",
  840. String.Empty);
  841. if (!String.IsNullOrEmpty(updateValue))
  842. {
  843. foreach (DataGridViewRow selectedRow in itemInfoGridView.SelectedRows)
  844. {
  845. selectedRow.Cells[mouseOverCol].Value = updateValue;
  846. }
  847. // for some reason datagridview doesn't reflect selected cell value updating like this
  848. // so re-assigning value fixes it.
  849. if (itemInfoGridView.Rows[mouseOverRow].Cells[mouseOverCol] is DataGridViewCheckBoxCell)
  850. {
  851. itemInfoGridView.Rows[mouseOverRow].Cells[mouseOverCol].Value = updateValue;
  852. }
  853. }
  854. }
  855. }
  856. }
  857. private void itemInfoGridView_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
  858. {
  859. var row = e.Row;
  860. if (row.Cells["ItemIndex"].Value != null)
  861. {
  862. int index = (int)row.Cells["ItemIndex"].Value;
  863. var item = Envir.ItemInfoList.FirstOrDefault(x => x.Index == index);
  864. Envir.ItemInfoList.Remove(item);
  865. }
  866. }
  867. private void itemInfoGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
  868. {
  869. }
  870. private void Gameshop_button_Click(object sender, EventArgs e)
  871. {
  872. foreach (DataGridViewRow row in itemInfoGridView.Rows)
  873. {
  874. if (row.Selected && row.Cells["ItemIndex"].Value != null)
  875. {
  876. int index = (int)row.Cells["ItemIndex"].Value;
  877. var item = Envir.ItemInfoList.FirstOrDefault(x => x.Index == index);
  878. Envir.AddToGameShop(item);
  879. }
  880. }
  881. Envir.SaveDB();
  882. }
  883. private void CellValueChanged(object sender, DataGridViewCellEventArgs e)
  884. {
  885. if (itemInfoGridView.CurrentCell is DataGridViewComboBoxCell ||
  886. itemInfoGridView.CurrentCell is DataGridViewCheckBoxCell &&
  887. e.RowIndex != -1)
  888. {
  889. if (itemInfoGridView.Rows[e.RowIndex].DataBoundItem != null)
  890. {
  891. itemInfoGridView.Rows[e.RowIndex].Cells["Modified"].Value = true;
  892. }
  893. }
  894. }
  895. private void ItemInfoGridView_SelectionChanged(object sender, EventArgs e)
  896. {
  897. if (itemInfoGridView.CurrentRow != null &&
  898. itemInfoGridView.CurrentRow.Index != -1)
  899. {
  900. var itemType = itemInfoGridView.CurrentRow.Cells["ItemType"];
  901. bool isGemSelected = (global::ItemType)itemType.Value == global::ItemType.Gem;
  902. SwapGemContext(isGemSelected);
  903. }
  904. }
  905. private void CurrentCellDirtyStateChanged(object sender, EventArgs e)
  906. {
  907. if (itemInfoGridView.IsCurrentCellDirty)
  908. {
  909. itemInfoGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
  910. }
  911. }
  912. private void ItemInfoFormNew_FormClosing(object sender, FormClosingEventArgs e)
  913. {
  914. List<String> inError = new();
  915. int indexColumn = itemInfoGridView.Columns["ItemIndex"].Index;
  916. int nameColumn = itemInfoGridView.Columns["ItemName"].Index;
  917. for (int i = 0; i < itemInfoGridView.RowCount; i++)
  918. {
  919. if (!String.IsNullOrEmpty(itemInfoGridView.Rows[i].ErrorText))
  920. {
  921. inError.Add($"Index: [{itemInfoGridView.Rows[i].Cells[indexColumn].Value}] Item: [{itemInfoGridView.Rows[i].Cells[nameColumn].Value}]");
  922. }
  923. }
  924. if (inError.Count > 0)
  925. {
  926. String msg = string.Join(Environment.NewLine, inError);
  927. if (MessageBox.Show($"The following items are invalid: {msg}", "Discard Invalid Items?", MessageBoxButtons.OKCancel) != DialogResult.OK)
  928. {
  929. e.Cancel = true;
  930. return;
  931. }
  932. }
  933. SaveForm();
  934. Envir.SaveDB();
  935. }
  936. private void MapHeaderText()
  937. {
  938. for (int i = 0; i < itemInfoGridView.ColumnCount; i++)
  939. {
  940. var col = itemInfoGridView.Columns[i];
  941. _defaultItemHeaderMappings.Add(i, col.HeaderText);
  942. }
  943. foreach (var entry in _defaultItemHeaderMappings)
  944. {
  945. switch (entry.Value.Trim())
  946. {
  947. case nameof(SpecialItemMode.Paralize):
  948. _gemItemHeaderMappings.Add(entry.Key, "Weapon");
  949. break;
  950. case nameof(SpecialItemMode.Teleport):
  951. _gemItemHeaderMappings.Add(entry.Key, "Armour");
  952. break;
  953. case nameof(SpecialItemMode.ClearRing):
  954. _gemItemHeaderMappings.Add(entry.Key, "Helmet");
  955. break;
  956. case nameof(SpecialItemMode.Protection):
  957. _gemItemHeaderMappings.Add(entry.Key, "Necklace");
  958. break;
  959. case nameof(SpecialItemMode.Revival):
  960. _gemItemHeaderMappings.Add(entry.Key, "Bracelet");
  961. break;
  962. case nameof(SpecialItemMode.Muscle):
  963. _gemItemHeaderMappings.Add(entry.Key, "Ring");
  964. break;
  965. case nameof(SpecialItemMode.Flame):
  966. _gemItemHeaderMappings.Add(entry.Key, "Amulet");
  967. break;
  968. case nameof(SpecialItemMode.Healing):
  969. _gemItemHeaderMappings.Add(entry.Key, "Belt");
  970. break;
  971. case nameof(SpecialItemMode.Probe):
  972. _gemItemHeaderMappings.Add(entry.Key, "Boots");
  973. break;
  974. case nameof(SpecialItemMode.Skill):
  975. _gemItemHeaderMappings.Add(entry.Key, "Stone");
  976. break;
  977. case nameof(SpecialItemMode.NoDuraLoss):
  978. _gemItemHeaderMappings.Add(entry.Key, "Torch");
  979. break;
  980. case "Critical Damage":
  981. _gemItemHeaderMappings.Add(entry.Key, "Max Stats (All)");
  982. break;
  983. case "Critical":
  984. _gemItemHeaderMappings.Add(entry.Key, "Base Rate %");
  985. break;
  986. case "Reflect":
  987. _gemItemHeaderMappings.Add(entry.Key, "Success Drop");
  988. break;
  989. case "HP Drain %":
  990. _gemItemHeaderMappings.Add(entry.Key, "Max Gem Stat");
  991. break;
  992. }
  993. }
  994. }
  995. private void SwapGemContext(bool showGemInfo)
  996. {
  997. // are we already showing correct field names?
  998. if ((showGemInfo && _isInGemContext) ||
  999. (!showGemInfo && !_isInGemContext))
  1000. {
  1001. return;
  1002. }
  1003. foreach (var entry in _gemItemHeaderMappings)
  1004. {
  1005. var col = itemInfoGridView.Columns[entry.Key];
  1006. col.HeaderText = showGemInfo ?
  1007. _gemItemHeaderMappings[entry.Key] :
  1008. _defaultItemHeaderMappings[entry.Key];
  1009. col.DefaultCellStyle.BackColor = showGemInfo ?
  1010. Color.Yellow :
  1011. Color.Empty;
  1012. }
  1013. _isInGemContext = showGemInfo;
  1014. }
  1015. private Dictionary<string, string[]> dropFilesContent;
  1016. private Dictionary<string, string[]> recipeFilesContent;
  1017. private Dictionary<string, string[]> questScriptFilesContent;
  1018. private Dictionary<string, string[]> npcScriptFilesContent;
  1019. private bool dropFileChange, recipeFileChange, questFileChange, npcFileChange;
  1020. private string ItemNameCellOldValue;
  1021. private void ItemInfoGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
  1022. {
  1023. if (itemInfoGridView.Columns[e.ColumnIndex].Name == "ItemName")
  1024. {
  1025. ItemNameCellOldValue = itemInfoGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value?.ToString();
  1026. }
  1027. else
  1028. {
  1029. ItemNameCellOldValue = string.Empty;
  1030. }
  1031. }
  1032. private void ItemInfoGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
  1033. {
  1034. if (itemInfoGridView.Columns[e.ColumnIndex].Name == "ItemName" &&
  1035. e.RowIndex != -1)
  1036. {
  1037. var newName = itemInfoGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value?.ToString() ?? string.Empty;
  1038. ItemNameChange(ItemNameCellOldValue, newName);
  1039. ItemNameCellOldValue = string.Empty;
  1040. }
  1041. }
  1042. private Dictionary<string, string[]> LoadScriptFiles(string path, string searchPattern)
  1043. {
  1044. var filesContent = new Dictionary<string, string[]>();
  1045. foreach (var file in Directory.GetFiles(path, searchPattern, SearchOption.AllDirectories))
  1046. {
  1047. filesContent.Add(file, File.ReadAllLines(file));
  1048. }
  1049. return filesContent;
  1050. }
  1051. private void SaveScriptFile(Dictionary<string, string[]> files)
  1052. {
  1053. foreach (var file in files)
  1054. {
  1055. File.WriteAllLines(file.Key, file.Value);
  1056. }
  1057. }
  1058. private void LoadDropRecipeQuestFiles()
  1059. {
  1060. dropFilesContent = LoadScriptFiles(@"Envir\Drops", "*.txt");
  1061. recipeFilesContent = LoadScriptFiles(@"Envir\Recipe", "*.txt");
  1062. questScriptFilesContent = LoadScriptFiles(@"Envir\Quests", "*.txt");
  1063. npcScriptFilesContent = LoadScriptFiles(@"Envir\NPCs", "*.txt");
  1064. }
  1065. private void SaveDropRecipeQuestFiles()
  1066. {
  1067. if (dropFileChange) SaveScriptFile(dropFilesContent);
  1068. if (recipeFileChange) SaveScriptFile(recipeFilesContent);
  1069. if (questFileChange) SaveScriptFile(questScriptFilesContent);
  1070. if (npcFileChange) SaveScriptFile(npcScriptFilesContent);
  1071. }
  1072. private void RenameRecipeFile(string oldName, string newName)
  1073. {
  1074. var oldFilePath = recipeFilesContent.Keys.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x).Equals(oldName, StringComparison.OrdinalIgnoreCase));
  1075. if (oldFilePath != null)
  1076. {
  1077. var newFilePath = Path.Combine(Path.GetDirectoryName(oldFilePath), newName + Path.GetExtension(oldFilePath));
  1078. File.Move(oldFilePath, newFilePath);
  1079. recipeFilesContent[newFilePath] = recipeFilesContent[oldFilePath];
  1080. recipeFilesContent.Remove(oldFilePath);
  1081. }
  1082. }
  1083. private void ItemNameChange(string oldName, string newName)
  1084. {
  1085. if (!string.IsNullOrWhiteSpace(oldName) && !string.IsNullOrWhiteSpace(newName) && !oldName.Equals(newName, StringComparison.OrdinalIgnoreCase))
  1086. {
  1087. foreach (var file in dropFilesContent)
  1088. {
  1089. var lines = file.Value;
  1090. for (int i = 0; i < lines.Length; i++)
  1091. {
  1092. var line = lines[i];
  1093. var match = Regex.Match(line, @"^\d+/\d+\s+(\S+)");
  1094. if (match.Success && match.Groups[1].Value.Equals(oldName, StringComparison.OrdinalIgnoreCase))
  1095. {
  1096. var itemName = match.Groups[1].Value;
  1097. if (itemName.Equals(oldName, StringComparison.OrdinalIgnoreCase))
  1098. {
  1099. lines[i] = line.Replace(itemName, newName);
  1100. dropFileChange = true;
  1101. }
  1102. }
  1103. }
  1104. }
  1105. foreach (var file in recipeFilesContent.Keys.ToList())
  1106. {
  1107. if (!recipeFilesContent.ContainsKey(file)) continue;
  1108. var lines = recipeFilesContent[file];
  1109. for (int i = 0; i < lines.Length; i++)
  1110. {
  1111. var line = lines[i];
  1112. if (!string.IsNullOrWhiteSpace(line) && !line.StartsWith("["))
  1113. {
  1114. var match = Regex.Match(line, @"^([^\s|[]+)(?=\s?)");
  1115. if (match.Success)
  1116. {
  1117. string itemName = match.Groups[1].Value;
  1118. if (itemName.Equals(oldName, StringComparison.OrdinalIgnoreCase))
  1119. {
  1120. lines[i] = line.Replace(itemName, newName);
  1121. recipeFileChange = true;
  1122. }
  1123. }
  1124. }
  1125. }
  1126. if (Path.GetFileNameWithoutExtension(file).Equals(oldName, StringComparison.OrdinalIgnoreCase))
  1127. {
  1128. RenameRecipeFile(oldName, newName);
  1129. recipeFileChange = true;
  1130. }
  1131. }
  1132. foreach (var file in questScriptFilesContent)
  1133. {
  1134. var lines = file.Value;
  1135. bool isItem = false;
  1136. for (int i = 0; i < lines.Length; i++)
  1137. {
  1138. var line = lines[i];
  1139. if (line.StartsWith("[@ItemTasks]") || line.StartsWith("[@CarryItems]") || line.StartsWith("[@FixedRewards]") || line.StartsWith("[@SelectRewards]"))
  1140. {
  1141. isItem = true;
  1142. }
  1143. else if (string.IsNullOrWhiteSpace(line) || line.StartsWith("["))
  1144. {
  1145. isItem = false;
  1146. }
  1147. else if (isItem)
  1148. {
  1149. var match = Regex.Match(line, @"^([^\s|[]+)(?=\s?)");
  1150. if (match.Success)
  1151. {
  1152. string itemName = match.Groups[1].Value;
  1153. if (itemName.Equals(oldName, StringComparison.OrdinalIgnoreCase))
  1154. {
  1155. lines[i] = line.Replace(itemName, newName);
  1156. questFileChange = true;
  1157. }
  1158. }
  1159. }
  1160. }
  1161. }
  1162. foreach (var file in npcScriptFilesContent)
  1163. {
  1164. var lines = file.Value;
  1165. bool isConversion = false;
  1166. for (int i = 0; i < lines.Length; i++)
  1167. {
  1168. var line = lines[i];
  1169. if (string.IsNullOrWhiteSpace(line))
  1170. {
  1171. continue;
  1172. }
  1173. else if (line.StartsWith("[RECIPE]") || line.StartsWith("[Trade]"))
  1174. {
  1175. isConversion = true;
  1176. }
  1177. else if (isConversion && line.StartsWith("["))
  1178. {
  1179. isConversion = false;
  1180. }
  1181. else if (isConversion)
  1182. {
  1183. var match = Regex.Match(line, @"^(\S+)(?=\s?)");
  1184. if (match.Success)
  1185. {
  1186. string itemName = match.Groups[1].Value;
  1187. if (itemName.Equals(oldName, StringComparison.OrdinalIgnoreCase))
  1188. {
  1189. lines[i] = line.Replace(itemName, newName);
  1190. npcFileChange = true;
  1191. }
  1192. }
  1193. }
  1194. }
  1195. }
  1196. }
  1197. }
  1198. }
  1199. }