ItemData.cs 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459
  1. using System.Text.RegularExpressions;
  2. public class ItemInfo
  3. {
  4. public int Index;
  5. public string Name = string.Empty;
  6. public ItemType Type;
  7. public ItemGrade Grade;
  8. public RequiredType RequiredType = RequiredType.Level;
  9. public RequiredClass RequiredClass = RequiredClass.None;
  10. public RequiredGender RequiredGender = RequiredGender.None;
  11. public ItemSet Set;
  12. public short Shape;
  13. public byte Weight, Light, RequiredAmount;
  14. public ushort Image, Durability;
  15. public uint Price;
  16. public ushort StackSize = 1;
  17. public bool StartItem;
  18. public byte Effect;
  19. public bool NeedIdentify, ShowGroupPickup, GlobalDropNotify;
  20. public bool ClassBased;
  21. public bool LevelBased;
  22. public bool CanMine;
  23. public bool CanFastRun;
  24. public bool CanAwakening;
  25. public BindMode Bind = BindMode.None;
  26. public SpecialItemMode Unique = SpecialItemMode.None;
  27. public byte RandomStatsId;
  28. public RandomItemStat RandomStats;
  29. public string ToolTip = string.Empty;
  30. public byte Slots;
  31. public Stats Stats;
  32. public bool IsConsumable
  33. {
  34. get { return Type == ItemType.Potion || Type == ItemType.Scroll || Type == ItemType.Food || Type == ItemType.Transform || Type == ItemType.Script || Type == ItemType.SealedHero; }
  35. }
  36. public bool IsFishingRod
  37. {
  38. get { return Globals.FishingRodShapes.Contains(Shape); }
  39. }
  40. public string FriendlyName
  41. {
  42. get
  43. {
  44. string temp = Name;
  45. temp = Regex.Replace(temp, @"\d+$", string.Empty); //hides end numbers
  46. temp = Regex.Replace(temp, @"\[[^\]]*\]", string.Empty); //hides square brackets
  47. return temp;
  48. }
  49. }
  50. public ItemInfo()
  51. {
  52. Stats = new Stats();
  53. }
  54. public ItemInfo(BinaryReader reader, int version = int.MaxValue, int customVersion = int.MaxValue)
  55. {
  56. Index = reader.ReadInt32();
  57. Name = reader.ReadString();
  58. Type = (ItemType)reader.ReadByte();
  59. Grade = (ItemGrade)reader.ReadByte();
  60. RequiredType = (RequiredType)reader.ReadByte();
  61. RequiredClass = (RequiredClass)reader.ReadByte();
  62. RequiredGender = (RequiredGender)reader.ReadByte();
  63. Set = (ItemSet)reader.ReadByte();
  64. Shape = reader.ReadInt16();
  65. Weight = reader.ReadByte();
  66. Light = reader.ReadByte();
  67. RequiredAmount = reader.ReadByte();
  68. Image = reader.ReadUInt16();
  69. Durability = reader.ReadUInt16();
  70. if (version <= 84)
  71. {
  72. StackSize = (ushort)reader.ReadUInt32();
  73. }
  74. else
  75. {
  76. StackSize = reader.ReadUInt16();
  77. }
  78. Price = reader.ReadUInt32();
  79. if (version <= 84)
  80. {
  81. Stats = new Stats();
  82. Stats[Stat.MinAC] = reader.ReadByte();
  83. Stats[Stat.MaxAC] = reader.ReadByte();
  84. Stats[Stat.MinMAC] = reader.ReadByte();
  85. Stats[Stat.MaxMAC] = reader.ReadByte();
  86. Stats[Stat.MinDC] = reader.ReadByte();
  87. Stats[Stat.MaxDC] = reader.ReadByte();
  88. Stats[Stat.MinMC] = reader.ReadByte();
  89. Stats[Stat.MaxMC] = reader.ReadByte();
  90. Stats[Stat.MinSC] = reader.ReadByte();
  91. Stats[Stat.MaxSC] = reader.ReadByte();
  92. Stats[Stat.HP] = reader.ReadUInt16();
  93. Stats[Stat.MP] = reader.ReadUInt16();
  94. Stats[Stat.Accuracy] = reader.ReadByte();
  95. Stats[Stat.Agility] = reader.ReadByte();
  96. Stats[Stat.Luck] = reader.ReadSByte();
  97. Stats[Stat.AttackSpeed] = reader.ReadSByte();
  98. }
  99. StartItem = reader.ReadBoolean();
  100. if (version <= 84)
  101. {
  102. Stats[Stat.BagWeight] = reader.ReadByte();
  103. Stats[Stat.HandWeight] = reader.ReadByte();
  104. Stats[Stat.WearWeight] = reader.ReadByte();
  105. }
  106. Effect = reader.ReadByte();
  107. if (version <= 84)
  108. {
  109. Stats[Stat.Strong] = reader.ReadByte();
  110. Stats[Stat.MagicResist] = reader.ReadByte();
  111. Stats[Stat.PoisonResist] = reader.ReadByte();
  112. Stats[Stat.HealthRecovery] = reader.ReadByte();
  113. Stats[Stat.SpellRecovery] = reader.ReadByte();
  114. Stats[Stat.PoisonRecovery] = reader.ReadByte();
  115. Stats[Stat.HPRatePercent] = reader.ReadByte();
  116. Stats[Stat.MPRatePercent] = reader.ReadByte();
  117. Stats[Stat.CriticalRate] = reader.ReadByte();
  118. Stats[Stat.CriticalDamage] = reader.ReadByte();
  119. }
  120. byte bools = reader.ReadByte();
  121. NeedIdentify = (bools & 0x01) == 0x01;
  122. ShowGroupPickup = (bools & 0x02) == 0x02;
  123. ClassBased = (bools & 0x04) == 0x04;
  124. LevelBased = (bools & 0x08) == 0x08;
  125. CanMine = (bools & 0x10) == 0x10;
  126. if (version >= 77)
  127. {
  128. GlobalDropNotify = (bools & 0x20) == 0x20;
  129. }
  130. if (version <= 84)
  131. {
  132. Stats[Stat.MaxACRatePercent] = reader.ReadByte();
  133. Stats[Stat.MaxMACRatePercent] = reader.ReadByte();
  134. Stats[Stat.Holy] = reader.ReadByte();
  135. Stats[Stat.Freezing] = reader.ReadByte();
  136. Stats[Stat.PoisonAttack] = reader.ReadByte();
  137. }
  138. Bind = (BindMode)reader.ReadInt16();
  139. if (version <= 84)
  140. {
  141. Stats[Stat.Reflect] = reader.ReadByte();
  142. Stats[Stat.HPDrainRatePercent] = reader.ReadByte();
  143. }
  144. Unique = (SpecialItemMode)reader.ReadInt16();
  145. RandomStatsId = reader.ReadByte();
  146. CanFastRun = reader.ReadBoolean();
  147. CanAwakening = reader.ReadBoolean();
  148. if (version > 83)
  149. {
  150. Slots = reader.ReadByte();
  151. }
  152. if (version > 84)
  153. {
  154. Stats = new Stats(reader, version, customVersion);
  155. }
  156. bool isTooltip = reader.ReadBoolean();
  157. if (isTooltip)
  158. {
  159. ToolTip = reader.ReadString();
  160. }
  161. if (version < 70) //before db version 70 all specialitems had wedding rings disabled, after that it became a server option
  162. {
  163. if ((Type == ItemType.Ring) && (Unique != SpecialItemMode.None))
  164. Bind |= BindMode.NoWeddingRing;
  165. }
  166. }
  167. public void Save(BinaryWriter writer)
  168. {
  169. writer.Write(Index);
  170. writer.Write(Name);
  171. writer.Write((byte)Type);
  172. writer.Write((byte)Grade);
  173. writer.Write((byte)RequiredType);
  174. writer.Write((byte)RequiredClass);
  175. writer.Write((byte)RequiredGender);
  176. writer.Write((byte)Set);
  177. writer.Write(Shape);
  178. writer.Write(Weight);
  179. writer.Write(Light);
  180. writer.Write(RequiredAmount);
  181. writer.Write(Image);
  182. writer.Write(Durability);
  183. writer.Write(StackSize);
  184. writer.Write(Price);
  185. writer.Write(StartItem);
  186. writer.Write(Effect);
  187. byte bools = 0;
  188. if (NeedIdentify) bools |= 0x01;
  189. if (ShowGroupPickup) bools |= 0x02;
  190. if (ClassBased) bools |= 0x04;
  191. if (LevelBased) bools |= 0x08;
  192. if (CanMine) bools |= 0x10;
  193. if (GlobalDropNotify) bools |= 0x20;
  194. writer.Write(bools);
  195. writer.Write((short)Bind);
  196. writer.Write((short)Unique);
  197. writer.Write(RandomStatsId);
  198. writer.Write(CanFastRun);
  199. writer.Write(CanAwakening);
  200. writer.Write(Slots);
  201. Stats.Save(writer);
  202. writer.Write(ToolTip != null);
  203. if (ToolTip != null)
  204. writer.Write(ToolTip);
  205. }
  206. public static ItemInfo FromText(string text)
  207. {
  208. return null;
  209. }
  210. public string ToText()
  211. {
  212. return null;
  213. }
  214. public override string ToString()
  215. {
  216. return string.Format("{0}: {1}", Index, Name);
  217. }
  218. }
  219. public class UserItem
  220. {
  221. public ulong UniqueID;
  222. public int ItemIndex;
  223. public ItemInfo Info;
  224. public ushort CurrentDura, MaxDura;
  225. public ushort Count = 1,
  226. GemCount = 0;
  227. public RefinedValue RefinedValue = RefinedValue.None;
  228. public byte RefineAdded = 0;
  229. public int RefineSuccessChance = 0;
  230. public bool DuraChanged;
  231. public int SoulBoundId = -1;
  232. public bool Identified = false;
  233. public bool Cursed = false;
  234. public int WeddingRing = -1;
  235. public UserItem[] Slots = new UserItem[0];
  236. public DateTime BuybackExpiryDate;
  237. public ExpireInfo ExpireInfo;
  238. public RentalInformation RentalInformation;
  239. public SealedInfo SealedInfo;
  240. public bool IsShopItem;
  241. public Awake Awake = new Awake();
  242. public Stats AddedStats;
  243. public bool IsAdded
  244. {
  245. get { return AddedStats.Count > 0 || Slots.Length > Info.Slots; }
  246. }
  247. public int Weight
  248. {
  249. get { return (Info.Type == ItemType.Amulet || Info.Type == ItemType.Bait) ? Info.Weight : Info.Weight * Count; }
  250. }
  251. public string FriendlyName
  252. {
  253. get { return Count > 1 ? string.Format("{0} ({1})", Info.FriendlyName, Count) : Info.FriendlyName; }
  254. }
  255. public bool GMMade { get; set; }
  256. public UserItem(ItemInfo info)
  257. {
  258. SoulBoundId = -1;
  259. ItemIndex = info.Index;
  260. Info = info;
  261. AddedStats = new Stats();
  262. SetSlotSize();
  263. }
  264. public UserItem(BinaryReader reader, int version = int.MaxValue, int customVersion = int.MaxValue)
  265. {
  266. UniqueID = reader.ReadUInt64();
  267. ItemIndex = reader.ReadInt32();
  268. CurrentDura = reader.ReadUInt16();
  269. MaxDura = reader.ReadUInt16();
  270. if (version <= 84)
  271. {
  272. Count = (ushort)reader.ReadUInt32();
  273. }
  274. else
  275. {
  276. Count = reader.ReadUInt16();
  277. }
  278. if (version <= 84)
  279. {
  280. AddedStats = new Stats();
  281. AddedStats[Stat.MaxAC] = reader.ReadByte();
  282. AddedStats[Stat.MaxMAC] = reader.ReadByte();
  283. AddedStats[Stat.MaxDC] = reader.ReadByte();
  284. AddedStats[Stat.MaxMC] = reader.ReadByte();
  285. AddedStats[Stat.MaxSC] = reader.ReadByte();
  286. AddedStats[Stat.Accuracy] = reader.ReadByte();
  287. AddedStats[Stat.Agility] = reader.ReadByte();
  288. AddedStats[Stat.HP] = reader.ReadByte();
  289. AddedStats[Stat.MP] = reader.ReadByte();
  290. AddedStats[Stat.AttackSpeed] = reader.ReadSByte();
  291. AddedStats[Stat.Luck] = reader.ReadSByte();
  292. }
  293. SoulBoundId = reader.ReadInt32();
  294. byte Bools = reader.ReadByte();
  295. Identified = (Bools & 0x01) == 0x01;
  296. Cursed = (Bools & 0x02) == 0x02;
  297. if (version <= 84)
  298. {
  299. AddedStats[Stat.Strong] = reader.ReadByte();
  300. AddedStats[Stat.MagicResist] = reader.ReadByte();
  301. AddedStats[Stat.PoisonResist] = reader.ReadByte();
  302. AddedStats[Stat.HealthRecovery] = reader.ReadByte();
  303. AddedStats[Stat.SpellRecovery] = reader.ReadByte();
  304. AddedStats[Stat.PoisonRecovery] = reader.ReadByte();
  305. AddedStats[Stat.CriticalRate] = reader.ReadByte();
  306. AddedStats[Stat.CriticalDamage] = reader.ReadByte();
  307. AddedStats[Stat.Freezing] = reader.ReadByte();
  308. AddedStats[Stat.PoisonAttack] = reader.ReadByte();
  309. }
  310. int count = reader.ReadInt32();
  311. SetSlotSize(count);
  312. for (int i = 0; i < count; i++)
  313. {
  314. if (reader.ReadBoolean()) continue;
  315. UserItem item = new UserItem(reader, version, customVersion);
  316. Slots[i] = item;
  317. }
  318. if (version <= 84)
  319. {
  320. GemCount = (ushort)reader.ReadUInt32();
  321. }
  322. else
  323. {
  324. GemCount = reader.ReadUInt16();
  325. }
  326. if (version > 84)
  327. {
  328. AddedStats = new Stats(reader, version, customVersion);
  329. }
  330. Awake = new Awake(reader);
  331. RefinedValue = (RefinedValue)reader.ReadByte();
  332. RefineAdded = reader.ReadByte();
  333. if (version > 85)
  334. {
  335. RefineSuccessChance = reader.ReadInt32();
  336. }
  337. WeddingRing = reader.ReadInt32();
  338. if (version < 65) return;
  339. if (reader.ReadBoolean())
  340. {
  341. ExpireInfo = new ExpireInfo(reader, version, customVersion);
  342. }
  343. if (version < 76)
  344. return;
  345. if (reader.ReadBoolean())
  346. RentalInformation = new RentalInformation(reader, version, customVersion);
  347. if (version < 83) return;
  348. IsShopItem = reader.ReadBoolean();
  349. if (version < 92) return;
  350. if (reader.ReadBoolean())
  351. {
  352. SealedInfo = new SealedInfo(reader, version, customVersion);
  353. }
  354. if (version > 107)
  355. {
  356. GMMade = reader.ReadBoolean();
  357. }
  358. }
  359. public void Save(BinaryWriter writer)
  360. {
  361. writer.Write(UniqueID);
  362. writer.Write(ItemIndex);
  363. writer.Write(CurrentDura);
  364. writer.Write(MaxDura);
  365. writer.Write(Count);
  366. writer.Write(SoulBoundId);
  367. byte Bools = 0;
  368. if (Identified) Bools |= 0x01;
  369. if (Cursed) Bools |= 0x02;
  370. writer.Write(Bools);
  371. writer.Write(Slots.Length);
  372. for (int i = 0; i < Slots.Length; i++)
  373. {
  374. writer.Write(Slots[i] == null);
  375. if (Slots[i] == null) continue;
  376. Slots[i].Save(writer);
  377. }
  378. writer.Write(GemCount);
  379. AddedStats.Save(writer);
  380. Awake.Save(writer);
  381. writer.Write((byte)RefinedValue);
  382. writer.Write(RefineAdded);
  383. writer.Write(RefineSuccessChance);
  384. writer.Write(WeddingRing);
  385. writer.Write(ExpireInfo != null);
  386. ExpireInfo?.Save(writer);
  387. writer.Write(RentalInformation != null);
  388. RentalInformation?.Save(writer);
  389. writer.Write(IsShopItem);
  390. writer.Write(SealedInfo != null);
  391. SealedInfo?.Save(writer);
  392. writer.Write(GMMade);
  393. }
  394. public int GetTotal(Stat type)
  395. {
  396. return AddedStats[type] + Info.Stats[type];
  397. }
  398. public uint Price()
  399. {
  400. if (Info == null) return 0;
  401. uint p = Info.Price;
  402. if (Info.Durability > 0)
  403. {
  404. float r = ((Info.Price / 2F) / Info.Durability);
  405. p = (uint)(MaxDura * r);
  406. if (MaxDura > 0)
  407. r = CurrentDura / (float)MaxDura;
  408. else
  409. r = 0;
  410. p = (uint)Math.Floor(p / 2F + ((p / 2F) * r) + Info.Price / 2F);
  411. }
  412. p = (uint)(p * (AddedStats.Count * 0.1F + 1F));
  413. return p * Count;
  414. }
  415. public uint RepairPrice()
  416. {
  417. if (Info == null || Info.Durability == 0)
  418. return 0;
  419. var p = Info.Price;
  420. if (Info.Durability > 0)
  421. {
  422. p = (uint)Math.Floor(MaxDura * ((Info.Price / 2F) / Info.Durability) + Info.Price / 2F);
  423. p = (uint)(p * (AddedStats.Count * 0.1F + 1F));
  424. }
  425. var cost = p * Count - Price();
  426. if (RentalInformation == null)
  427. return cost;
  428. return cost * 2;
  429. }
  430. public uint Quality()
  431. {
  432. uint q = (uint)(AddedStats.Count + Awake.GetAwakeLevel() + 1);
  433. return q;
  434. }
  435. public uint AwakeningPrice()
  436. {
  437. if (Info == null) return 0;
  438. uint p = 1500;
  439. p = (uint)((p * (1 + Awake.GetAwakeLevel() * 2)) * (uint)Info.Grade);
  440. return p;
  441. }
  442. public uint DisassemblePrice()
  443. {
  444. if (Info == null) return 0;
  445. uint p = 1500 * (uint)Info.Grade;
  446. p = (uint)(p * ((AddedStats.Count + Awake.GetAwakeLevel()) * 0.1F + 1F));
  447. return p;
  448. }
  449. public uint DowngradePrice()
  450. {
  451. if (Info == null) return 0;
  452. uint p = 3000;
  453. p = (uint)((p * (1 + (Awake.GetAwakeLevel() + 1) * 2)) * (uint)Info.Grade);
  454. return p;
  455. }
  456. public uint ResetPrice()
  457. {
  458. if (Info == null) return 0;
  459. uint p = 3000 * (uint)Info.Grade;
  460. p = (uint)(p * (AddedStats.Count * 0.2F + 1F));
  461. return p;
  462. }
  463. public void SetSlotSize(int? size = null)
  464. {
  465. if (size == null)
  466. {
  467. switch (Info.Type)
  468. {
  469. case ItemType.Mount:
  470. if (Info.Shape < 7)
  471. size = 4;
  472. else if (Info.Shape < 12)
  473. size = 5;
  474. break;
  475. case ItemType.Weapon:
  476. if (Info.Shape == 49 || Info.Shape == 50)
  477. size = 5;
  478. break;
  479. }
  480. }
  481. if (size == null && Info == null) return;
  482. if (size != null && size == Slots.Length) return;
  483. if (size == null && Info != null && Info.Slots == Slots.Length) return;
  484. Array.Resize(ref Slots, size ?? Info.Slots);
  485. }
  486. public ushort Image
  487. {
  488. get
  489. {
  490. switch (Info.Type)
  491. {
  492. #region Amulet and Poison Stack Image changes
  493. case ItemType.Amulet:
  494. if (Info.StackSize > 0)
  495. {
  496. switch (Info.Shape)
  497. {
  498. case 0: //Amulet
  499. if (Count >= 300) return 3662;
  500. if (Count >= 200) return 3661;
  501. if (Count >= 100) return 3660;
  502. return 3660;
  503. case 1: //Grey Poison
  504. if (Count >= 150) return 3675;
  505. if (Count >= 100) return 2960;
  506. if (Count >= 50) return 3674;
  507. return 3673;
  508. case 2: //Yellow Poison
  509. if (Count >= 150) return 3672;
  510. if (Count >= 100) return 2961;
  511. if (Count >= 50) return 3671;
  512. return 3670;
  513. }
  514. }
  515. break;
  516. }
  517. #endregion
  518. return Info.Image;
  519. }
  520. }
  521. public UserItem Clone()
  522. {
  523. UserItem item = new UserItem(Info)
  524. {
  525. UniqueID = UniqueID,
  526. CurrentDura = CurrentDura,
  527. MaxDura = MaxDura,
  528. Count = Count,
  529. GemCount = GemCount,
  530. DuraChanged = DuraChanged,
  531. SoulBoundId = SoulBoundId,
  532. Identified = Identified,
  533. Cursed = Cursed,
  534. Slots = Slots,
  535. AddedStats = new Stats(AddedStats),
  536. Awake = Awake,
  537. RefineAdded = RefineAdded,
  538. ExpireInfo = ExpireInfo,
  539. RentalInformation = RentalInformation,
  540. SealedInfo = SealedInfo,
  541. IsShopItem = IsShopItem,
  542. GMMade = GMMade
  543. };
  544. return item;
  545. }
  546. }
  547. public class ExpireInfo
  548. {
  549. public DateTime ExpiryDate;
  550. public ExpireInfo() { }
  551. public ExpireInfo(BinaryReader reader, int version = int.MaxValue, int Customversion = int.MaxValue)
  552. {
  553. ExpiryDate = DateTime.FromBinary(reader.ReadInt64());
  554. }
  555. public void Save(BinaryWriter writer)
  556. {
  557. writer.Write(ExpiryDate.ToBinary());
  558. }
  559. }
  560. public class SealedInfo
  561. {
  562. public DateTime ExpiryDate;
  563. public DateTime NextSealDate;
  564. public SealedInfo() { }
  565. public SealedInfo(BinaryReader reader, int version = int.MaxValue, int Customversion = int.MaxValue)
  566. {
  567. ExpiryDate = DateTime.FromBinary(reader.ReadInt64());
  568. if (version > 92)
  569. {
  570. NextSealDate = DateTime.FromBinary(reader.ReadInt64());
  571. }
  572. }
  573. public void Save(BinaryWriter writer)
  574. {
  575. writer.Write(ExpiryDate.ToBinary());
  576. writer.Write(NextSealDate.ToBinary());
  577. }
  578. }
  579. public class RentalInformation
  580. {
  581. public string OwnerName;
  582. public BindMode BindingFlags = BindMode.None;
  583. public DateTime ExpiryDate;
  584. public bool RentalLocked;
  585. public RentalInformation() { }
  586. public RentalInformation(BinaryReader reader, int version = int.MaxValue, int CustomVersion = int.MaxValue)
  587. {
  588. OwnerName = reader.ReadString();
  589. BindingFlags = (BindMode)reader.ReadInt16();
  590. ExpiryDate = DateTime.FromBinary(reader.ReadInt64());
  591. RentalLocked = reader.ReadBoolean();
  592. }
  593. public void Save(BinaryWriter writer)
  594. {
  595. writer.Write(OwnerName);
  596. writer.Write((short)BindingFlags);
  597. writer.Write(ExpiryDate.ToBinary());
  598. writer.Write(RentalLocked);
  599. }
  600. }
  601. public class GameShopItem
  602. {
  603. public int ItemIndex;
  604. public int GIndex;
  605. public ItemInfo Info;
  606. public uint GoldPrice = 0;
  607. public uint CreditPrice = 0;
  608. public ushort Count = 1;
  609. public string Class = "";
  610. public string Category = "";
  611. public int Stock = 0;
  612. public bool iStock = false;
  613. public bool Deal = false;
  614. public bool TopItem = false;
  615. public DateTime Date;
  616. public bool CanBuyGold = false;
  617. public bool CanBuyCredit = false;
  618. public GameShopItem()
  619. {
  620. }
  621. public GameShopItem(BinaryReader reader, int version = int.MaxValue, int Customversion = int.MaxValue)
  622. {
  623. ItemIndex = reader.ReadInt32();
  624. GIndex = reader.ReadInt32();
  625. GoldPrice = reader.ReadUInt32();
  626. CreditPrice = reader.ReadUInt32();
  627. if (version <= 84)
  628. {
  629. Count = (ushort)reader.ReadUInt32();
  630. }
  631. else
  632. {
  633. Count = reader.ReadUInt16();
  634. }
  635. Class = reader.ReadString();
  636. Category = reader.ReadString();
  637. Stock = reader.ReadInt32();
  638. iStock = reader.ReadBoolean();
  639. Deal = reader.ReadBoolean();
  640. TopItem = reader.ReadBoolean();
  641. Date = DateTime.FromBinary(reader.ReadInt64());
  642. if (version > 105)
  643. {
  644. CanBuyCredit = reader.ReadBoolean();
  645. CanBuyGold = reader.ReadBoolean();
  646. }
  647. }
  648. public GameShopItem(BinaryReader reader, bool packet = false)
  649. {
  650. ItemIndex = reader.ReadInt32();
  651. GIndex = reader.ReadInt32();
  652. Info = new ItemInfo(reader);
  653. GoldPrice = reader.ReadUInt32();
  654. CreditPrice = reader.ReadUInt32();
  655. Count = reader.ReadUInt16();
  656. Class = reader.ReadString();
  657. Category = reader.ReadString();
  658. Stock = reader.ReadInt32();
  659. iStock = reader.ReadBoolean();
  660. Deal = reader.ReadBoolean();
  661. TopItem = reader.ReadBoolean();
  662. Date = DateTime.FromBinary(reader.ReadInt64());
  663. CanBuyCredit = reader.ReadBoolean();
  664. CanBuyGold = reader.ReadBoolean();
  665. }
  666. public void Save(BinaryWriter writer, bool packet = false)
  667. {
  668. writer.Write(ItemIndex);
  669. writer.Write(GIndex);
  670. if (packet) Info.Save(writer);
  671. writer.Write(GoldPrice);
  672. writer.Write(CreditPrice);
  673. writer.Write(Count);
  674. writer.Write(Class);
  675. writer.Write(Category);
  676. writer.Write(Stock);
  677. writer.Write(iStock);
  678. writer.Write(Deal);
  679. writer.Write(TopItem);
  680. writer.Write(Date.ToBinary());
  681. writer.Write(CanBuyCredit);
  682. writer.Write(CanBuyGold);
  683. }
  684. public override string ToString()
  685. {
  686. return string.Format("{0}: {1}", GIndex, Info.Name);
  687. }
  688. }
  689. public class Awake
  690. {
  691. //Awake Option
  692. public static byte AwakeSuccessRate = 70;
  693. public static byte AwakeHitRate = 70;
  694. public static int MaxAwakeLevel = 5;
  695. public static byte Awake_WeaponRate = 1;
  696. public static byte Awake_HelmetRate = 1;
  697. public static byte Awake_ArmorRate = 5;
  698. public static byte AwakeChanceMin = 1;
  699. public static float[] AwakeMaterialRate = new float[5] { 1.0F, 1.0F, 1.0F, 1.0F, 1.0F };
  700. public static byte[] AwakeChanceMax = new byte[5] { 1, 2, 3, 4, 5 };
  701. public static List<List<byte>[]> AwakeMaterials = new List<List<byte>[]>();
  702. public AwakeType Type = AwakeType.None;
  703. readonly List<byte> listAwake = new List<byte>();
  704. public Awake() { }
  705. public Awake(BinaryReader reader)
  706. {
  707. Type = (AwakeType)reader.ReadByte();
  708. int count = reader.ReadInt32();
  709. for (int i = 0; i < count; i++)
  710. {
  711. listAwake.Add(reader.ReadByte());
  712. }
  713. }
  714. public void Save(BinaryWriter writer)
  715. {
  716. writer.Write((byte)Type);
  717. writer.Write(listAwake.Count);
  718. foreach (byte value in listAwake)
  719. {
  720. writer.Write(value);
  721. }
  722. }
  723. public bool IsMaxLevel() { return listAwake.Count == Awake.MaxAwakeLevel; }
  724. public int GetAwakeLevel() { return listAwake.Count; }
  725. public byte GetAwakeValue()
  726. {
  727. byte total = 0;
  728. foreach (byte value in listAwake)
  729. {
  730. total += value;
  731. }
  732. return total;
  733. }
  734. public bool CheckAwakening(UserItem item, AwakeType type)
  735. {
  736. if (item.Info.Bind.HasFlag(BindMode.DontUpgrade))
  737. return false;
  738. if (item.Info.CanAwakening != true)
  739. return false;
  740. if (item.Info.Grade == ItemGrade.None)
  741. return false;
  742. if (IsMaxLevel()) return false;
  743. if (this.Type == AwakeType.None)
  744. {
  745. if (item.Info.Type == ItemType.Weapon)
  746. {
  747. if (type == AwakeType.DC ||
  748. type == AwakeType.MC ||
  749. type == AwakeType.SC)
  750. {
  751. this.Type = type;
  752. return true;
  753. }
  754. else
  755. return false;
  756. }
  757. else if (item.Info.Type == ItemType.Helmet)
  758. {
  759. if (type == AwakeType.AC ||
  760. type == AwakeType.MAC)
  761. {
  762. this.Type = type;
  763. return true;
  764. }
  765. else
  766. return false;
  767. }
  768. else if (item.Info.Type == ItemType.Armour)
  769. {
  770. if (type == AwakeType.HPMP)
  771. {
  772. this.Type = type;
  773. return true;
  774. }
  775. else
  776. return false;
  777. }
  778. else
  779. return false;
  780. }
  781. else
  782. {
  783. if (this.Type == type)
  784. return true;
  785. else
  786. return false;
  787. }
  788. }
  789. public int UpgradeAwake(UserItem item, AwakeType type, out bool[] isHit)
  790. {
  791. //return -1 condition error, -1 = dont upgrade, 0 = failed, 1 = Succeed,
  792. isHit = null;
  793. if (CheckAwakening(item, type) != true)
  794. return -1;
  795. Random rand = new Random(DateTime.Now.Millisecond);
  796. if (rand.Next(0, 100) <= AwakeSuccessRate)
  797. {
  798. isHit = Awakening(item);
  799. return 1;
  800. }
  801. else
  802. {
  803. isHit = MakeHit(1, out _);
  804. return 0;
  805. }
  806. }
  807. public int RemoveAwake()
  808. {
  809. if (listAwake.Count > 0)
  810. {
  811. listAwake.Remove(listAwake[listAwake.Count - 1]);
  812. if (listAwake.Count == 0)
  813. Type = AwakeType.None;
  814. return 1;
  815. }
  816. else
  817. {
  818. Type = AwakeType.None;
  819. return 0;
  820. }
  821. }
  822. public int GetAwakeLevelValue(int i) { return listAwake[i]; }
  823. public byte GetDC() { return (Type == AwakeType.DC ? GetAwakeValue() : (byte)0); }
  824. public byte GetMC() { return (Type == AwakeType.MC ? GetAwakeValue() : (byte)0); }
  825. public byte GetSC() { return (Type == AwakeType.SC ? GetAwakeValue() : (byte)0); }
  826. public byte GetAC() { return (Type == AwakeType.AC ? GetAwakeValue() : (byte)0); }
  827. public byte GetMAC() { return (Type == AwakeType.MAC ? GetAwakeValue() : (byte)0); }
  828. public byte GetHPMP() { return (Type == AwakeType.HPMP ? GetAwakeValue() : (byte)0); }
  829. private bool[] MakeHit(int maxValue, out int makeValue)
  830. {
  831. float stepValue = (float)maxValue / 5.0f;
  832. float totalValue = 0.0f;
  833. bool[] isHit = new bool[5];
  834. Random rand = new Random(DateTime.Now.Millisecond);
  835. for (int i = 0; i < 5; i++)
  836. {
  837. if (rand.Next(0, 100) < AwakeHitRate)
  838. {
  839. totalValue += stepValue;
  840. isHit[i] = true;
  841. }
  842. else
  843. {
  844. isHit[i] = false;
  845. }
  846. }
  847. makeValue = totalValue <= 1.0f ? 1 : (int)totalValue;
  848. return isHit;
  849. }
  850. private bool[] Awakening(UserItem item)
  851. {
  852. int minValue = AwakeChanceMin;
  853. int maxValue = (AwakeChanceMax[(int)item.Info.Grade - 1] < minValue) ? minValue : AwakeChanceMax[(int)item.Info.Grade - 1];
  854. bool[] returnValue = MakeHit(maxValue, out int result);
  855. switch (item.Info.Type)
  856. {
  857. case ItemType.Weapon:
  858. result *= (int)Awake_WeaponRate;
  859. break;
  860. case ItemType.Armour:
  861. result *= (int)Awake_ArmorRate;
  862. break;
  863. case ItemType.Helmet:
  864. result *= (int)Awake_HelmetRate;
  865. break;
  866. default:
  867. result = 0;
  868. break;
  869. }
  870. listAwake.Add((byte)result);
  871. return returnValue;
  872. }
  873. }
  874. public class ItemRentalInformation
  875. {
  876. public ulong ItemId;
  877. public string ItemName;
  878. public string RentingPlayerName;
  879. public DateTime ItemReturnDate;
  880. public ItemRentalInformation() { }
  881. public ItemRentalInformation(BinaryReader reader, int version = int.MaxValue, int customVersion = int.MaxValue)
  882. {
  883. ItemId = reader.ReadUInt64();
  884. ItemName = reader.ReadString();
  885. RentingPlayerName = reader.ReadString();
  886. ItemReturnDate = DateTime.FromBinary(reader.ReadInt64());
  887. }
  888. public void Save(BinaryWriter writer)
  889. {
  890. writer.Write(ItemId);
  891. writer.Write(ItemName);
  892. writer.Write(RentingPlayerName);
  893. writer.Write(ItemReturnDate.ToBinary());
  894. }
  895. }
  896. public class ItemSets
  897. {
  898. public ItemSet Set;
  899. public List<ItemType> Type;
  900. private byte Amount
  901. {
  902. get
  903. {
  904. switch (Set)
  905. {
  906. case ItemSet.Mundane:
  907. case ItemSet.NokChi:
  908. case ItemSet.TaoProtect:
  909. case ItemSet.Whisker1:
  910. case ItemSet.Whisker2:
  911. case ItemSet.Whisker3:
  912. case ItemSet.Whisker4:
  913. case ItemSet.Whisker5:
  914. return 2;
  915. case ItemSet.RedOrchid:
  916. case ItemSet.RedFlower:
  917. case ItemSet.Smash:
  918. case ItemSet.HwanDevil:
  919. case ItemSet.Purity:
  920. case ItemSet.FiveString:
  921. case ItemSet.Bone:
  922. case ItemSet.Bug:
  923. case ItemSet.DarkGhost:
  924. return 3;
  925. case ItemSet.Recall:
  926. return 4;
  927. case ItemSet.Spirit:
  928. case ItemSet.WhiteGold:
  929. case ItemSet.WhiteGoldH:
  930. case ItemSet.RedJade:
  931. case ItemSet.RedJadeH:
  932. case ItemSet.Nephrite:
  933. case ItemSet.NephriteH:
  934. case ItemSet.Hyeolryong:
  935. case ItemSet.Monitor:
  936. case ItemSet.Oppressive:
  937. case ItemSet.Paeok:
  938. case ItemSet.Sulgwan:
  939. case ItemSet.BlueFrostH:
  940. case ItemSet.BlueFrost:
  941. return 5;
  942. default:
  943. return 0;
  944. }
  945. }
  946. }
  947. public byte Count;
  948. public bool SetComplete
  949. {
  950. get
  951. {
  952. return Count >= Amount;
  953. }
  954. }
  955. }
  956. public class RandomItemStat
  957. {
  958. public byte MaxDuraChance, MaxDuraStatChance, MaxDuraMaxStat;
  959. public byte MaxAcChance, MaxAcStatChance, MaxAcMaxStat, MaxMacChance, MaxMacStatChance, MaxMacMaxStat, MaxDcChance, MaxDcStatChance, MaxDcMaxStat, MaxMcChance, MaxMcStatChance, MaxMcMaxStat, MaxScChance, MaxScStatChance, MaxScMaxStat;
  960. public byte AccuracyChance, AccuracyStatChance, AccuracyMaxStat, AgilityChance, AgilityStatChance, AgilityMaxStat, HpChance, HpStatChance, HpMaxStat, MpChance, MpStatChance, MpMaxStat, StrongChance, StrongStatChance, StrongMaxStat;
  961. public byte MagicResistChance, MagicResistStatChance, MagicResistMaxStat, PoisonResistChance, PoisonResistStatChance, PoisonResistMaxStat;
  962. public byte HpRecovChance, HpRecovStatChance, HpRecovMaxStat, MpRecovChance, MpRecovStatChance, MpRecovMaxStat, PoisonRecovChance, PoisonRecovStatChance, PoisonRecovMaxStat;
  963. public byte CriticalRateChance, CriticalRateStatChance, CriticalRateMaxStat, CriticalDamageChance, CriticalDamageStatChance, CriticalDamageMaxStat;
  964. public byte FreezeChance, FreezeStatChance, FreezeMaxStat, PoisonAttackChance, PoisonAttackStatChance, PoisonAttackMaxStat;
  965. public byte AttackSpeedChance, AttackSpeedStatChance, AttackSpeedMaxStat, LuckChance, LuckStatChance, LuckMaxStat;
  966. public byte CurseChance;
  967. public byte SlotChance, SlotStatChance, SlotMaxStat;
  968. public RandomItemStat(ItemType Type = ItemType.Book)
  969. {
  970. switch (Type)
  971. {
  972. case ItemType.Weapon:
  973. SetWeapon();
  974. break;
  975. case ItemType.Armour:
  976. SetArmour();
  977. break;
  978. case ItemType.Helmet:
  979. SetHelmet();
  980. break;
  981. case ItemType.Belt:
  982. case ItemType.Boots:
  983. SetBeltBoots();
  984. break;
  985. case ItemType.Necklace:
  986. SetNecklace();
  987. break;
  988. case ItemType.Bracelet:
  989. SetBracelet();
  990. break;
  991. case ItemType.Ring:
  992. SetRing();
  993. break;
  994. case ItemType.Mount:
  995. SetMount();
  996. break;
  997. }
  998. }
  999. public void SetWeapon()
  1000. {
  1001. MaxDuraChance = 2;
  1002. MaxDuraStatChance = 13;
  1003. MaxDuraMaxStat = 13;
  1004. MaxDcChance = 15;
  1005. MaxDcStatChance = 15;
  1006. MaxDcMaxStat = 13;
  1007. MaxMcChance = 20;
  1008. MaxMcStatChance = 15;
  1009. MaxMcMaxStat = 13;
  1010. MaxScChance = 20;
  1011. MaxScStatChance = 15;
  1012. MaxScMaxStat = 13;
  1013. AttackSpeedChance = 60;
  1014. AttackSpeedStatChance = 30;
  1015. AttackSpeedMaxStat = 3;
  1016. StrongChance = 24;
  1017. StrongStatChance = 20;
  1018. StrongMaxStat = 2;
  1019. AccuracyChance = 30;
  1020. AccuracyStatChance = 20;
  1021. AccuracyMaxStat = 2;
  1022. }
  1023. public void SetArmour()
  1024. {
  1025. MaxDuraChance = 2;
  1026. MaxDuraStatChance = 10;
  1027. MaxDuraMaxStat = 3;
  1028. MaxAcChance = 30;
  1029. MaxAcStatChance = 15;
  1030. MaxAcMaxStat = 7;
  1031. MaxMacChance = 30;
  1032. MaxMacStatChance = 15;
  1033. MaxMacMaxStat = 7;
  1034. MaxDcChance = 40;
  1035. MaxDcStatChance = 20;
  1036. MaxDcMaxStat = 7;
  1037. MaxMcChance = 40;
  1038. MaxMcStatChance = 20;
  1039. MaxMcMaxStat = 7;
  1040. MaxScChance = 40;
  1041. MaxScStatChance = 20;
  1042. MaxScMaxStat = 7;
  1043. }
  1044. public void SetHelmet()
  1045. {
  1046. MaxDuraChance = 2;
  1047. MaxDuraStatChance = 10;
  1048. MaxDuraMaxStat = 3;
  1049. MaxAcChance = 30;
  1050. MaxAcStatChance = 15;
  1051. MaxAcMaxStat = 7;
  1052. MaxMacChance = 30;
  1053. MaxMacStatChance = 15;
  1054. MaxMacMaxStat = 7;
  1055. MaxDcChance = 40;
  1056. MaxDcStatChance = 20;
  1057. MaxDcMaxStat = 7;
  1058. MaxMcChance = 40;
  1059. MaxMcStatChance = 20;
  1060. MaxMcMaxStat = 7;
  1061. MaxScChance = 40;
  1062. MaxScStatChance = 20;
  1063. MaxScMaxStat = 7;
  1064. }
  1065. public void SetBeltBoots()
  1066. {
  1067. MaxDuraChance = 2;
  1068. MaxDuraStatChance = 10;
  1069. MaxDuraMaxStat = 3;
  1070. MaxAcChance = 30;
  1071. MaxAcStatChance = 30;
  1072. MaxAcMaxStat = 3;
  1073. MaxMacChance = 30;
  1074. MaxMacStatChance = 30;
  1075. MaxMacMaxStat = 3;
  1076. MaxDcChance = 30;
  1077. MaxDcStatChance = 30;
  1078. MaxDcMaxStat = 3;
  1079. MaxMcChance = 30;
  1080. MaxMcStatChance = 30;
  1081. MaxMcMaxStat = 3;
  1082. MaxScChance = 30;
  1083. MaxScStatChance = 30;
  1084. MaxScMaxStat = 3;
  1085. AgilityChance = 60;
  1086. AgilityStatChance = 30;
  1087. AgilityMaxStat = 3;
  1088. }
  1089. public void SetNecklace()
  1090. {
  1091. MaxDuraChance = 2;
  1092. MaxDuraStatChance = 10;
  1093. MaxDuraMaxStat = 3;
  1094. MaxDcChance = 15;
  1095. MaxDcStatChance = 30;
  1096. MaxDcMaxStat = 7;
  1097. MaxMcChance = 15;
  1098. MaxMcStatChance = 30;
  1099. MaxMcMaxStat = 7;
  1100. MaxScChance = 15;
  1101. MaxScStatChance = 30;
  1102. MaxScMaxStat = 7;
  1103. AccuracyChance = 60;
  1104. AccuracyStatChance = 30;
  1105. AccuracyMaxStat = 7;
  1106. AgilityChance = 60;
  1107. AgilityStatChance = 30;
  1108. AgilityMaxStat = 7;
  1109. }
  1110. public void SetBracelet()
  1111. {
  1112. MaxDuraChance = 2;
  1113. MaxDuraStatChance = 10;
  1114. MaxDuraMaxStat = 3;
  1115. MaxAcChance = 20;
  1116. MaxAcStatChance = 30;
  1117. MaxAcMaxStat = 6;
  1118. MaxMacChance = 20;
  1119. MaxMacStatChance = 30;
  1120. MaxMacMaxStat = 6;
  1121. MaxDcChance = 30;
  1122. MaxDcStatChance = 30;
  1123. MaxDcMaxStat = 6;
  1124. MaxMcChance = 30;
  1125. MaxMcStatChance = 30;
  1126. MaxMcMaxStat = 6;
  1127. MaxScChance = 30;
  1128. MaxScStatChance = 30;
  1129. MaxScMaxStat = 6;
  1130. }
  1131. public void SetRing()
  1132. {
  1133. MaxDuraChance = 2;
  1134. MaxDuraStatChance = 10;
  1135. MaxDuraMaxStat = 3;
  1136. MaxAcChance = 25;
  1137. MaxAcStatChance = 20;
  1138. MaxAcMaxStat = 6;
  1139. MaxMacChance = 25;
  1140. MaxMacStatChance = 20;
  1141. MaxMacMaxStat = 6;
  1142. MaxDcChance = 15;
  1143. MaxDcStatChance = 30;
  1144. MaxDcMaxStat = 6;
  1145. MaxMcChance = 15;
  1146. MaxMcStatChance = 30;
  1147. MaxMcMaxStat = 6;
  1148. MaxScChance = 15;
  1149. MaxScStatChance = 30;
  1150. MaxScMaxStat = 6;
  1151. }
  1152. public void SetMount()
  1153. {
  1154. SetRing();
  1155. }
  1156. }
  1157. public class ChatItem
  1158. {
  1159. public ulong UniqueID;
  1160. public string Title;
  1161. public MirGridType Grid;
  1162. public string RegexInternalName
  1163. {
  1164. get { return $"<{Title.Replace("(", "\\(").Replace(")", "\\)")}>"; }
  1165. }
  1166. public string InternalName
  1167. {
  1168. get { return $"<{Title}/{UniqueID}>"; }
  1169. }
  1170. public ChatItem() { }
  1171. public ChatItem(BinaryReader reader)
  1172. {
  1173. UniqueID = reader.ReadUInt64();
  1174. Title = reader.ReadString();
  1175. Grid = (MirGridType)reader.ReadByte();
  1176. }
  1177. public void Save(BinaryWriter writer)
  1178. {
  1179. writer.Write(UniqueID);
  1180. writer.Write(Title);
  1181. writer.Write((byte)Grid);
  1182. }
  1183. }