UserObject.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. using Client.MirScenes;
  2. using Client.MirScenes.Dialogs;
  3. using S = ServerPackets;
  4. namespace Client.MirObjects
  5. {
  6. public class UserObject : PlayerObject
  7. {
  8. public uint Id;
  9. public int HP, MP;
  10. public int AttackSpeed;
  11. public Stats Stats;
  12. public int CurrentHandWeight,
  13. CurrentWearWeight,
  14. CurrentBagWeight;
  15. public long Experience, MaxExperience;
  16. public bool TradeLocked;
  17. public uint TradeGoldAmount;
  18. public bool AllowTrade;
  19. public bool RentalGoldLocked;
  20. public bool RentalItemLocked;
  21. public uint RentalGoldAmount;
  22. public SpecialItemMode ItemMode;
  23. public BaseStats CoreStats = new BaseStats(0);
  24. public virtual BuffDialog GetBuffDialog => GameScene.Scene.BuffsDialog;
  25. public UserItem[] Inventory = new UserItem[46], Equipment = new UserItem[14], Trade = new UserItem[10], QuestInventory = new UserItem[40];
  26. public int BeltIdx = 6, HeroBeltIdx = 2;
  27. public bool HasExpandedStorage = false;
  28. public bool HasStoragePassword = false;
  29. public bool RequireStoragePassword = true;
  30. public DateTime StoragePasswordLastSet;
  31. public DateTime ExpandedStorageExpiryTime;
  32. public List<ClientMagic> Magics = new List<ClientMagic>();
  33. public List<ItemSets> ItemSets = new List<ItemSets>();
  34. public List<EquipmentSlot> MirSet = new List<EquipmentSlot>();
  35. public List<ClientIntelligentCreature> IntelligentCreatures = new List<ClientIntelligentCreature>();
  36. public IntelligentCreatureType SummonedCreatureType = IntelligentCreatureType.None;
  37. public bool CreatureSummoned;
  38. public int PearlCount = 0;
  39. public List<ClientQuestProgress> CurrentQuests = new List<ClientQuestProgress>();
  40. public List<int> CompletedQuests = new List<int>();
  41. public List<ClientMail> Mail = new List<ClientMail>();
  42. public bool Slaying, Thrusting, HalfMoon, CrossHalfMoon, DoubleSlash, TwinDrakeBlade, FlamingSword;
  43. public ClientMagic NextMagic;
  44. public Point NextMagicLocation;
  45. public MapObject NextMagicObject;
  46. public MirDirection NextMagicDirection;
  47. public QueuedAction QueuedAction;
  48. public UserObject() { }
  49. public UserObject(uint objectID) : base(objectID)
  50. {
  51. Stats = new Stats();
  52. }
  53. public virtual void Load(S.UserInformation info)
  54. {
  55. Id = info.RealId;
  56. Name = info.Name;
  57. Settings.LoadTrackedQuests(info.Name);
  58. NameColour = info.NameColour;
  59. GuildName = info.GuildName;
  60. GuildRankName = info.GuildRank;
  61. Class = info.Class;
  62. Gender = info.Gender;
  63. Level = info.Level;
  64. CurrentLocation = info.Location;
  65. MapLocation = info.Location;
  66. GameScene.Scene.MapControl.AddObject(this);
  67. Direction = info.Direction;
  68. Hair = info.Hair;
  69. HP = info.HP;
  70. MP = info.MP;
  71. Experience = info.Experience;
  72. MaxExperience = info.MaxExperience;
  73. LevelEffects = info.LevelEffects;
  74. Inventory = info.Inventory;
  75. Equipment = info.Equipment;
  76. QuestInventory = info.QuestInventory;
  77. HasExpandedStorage = info.HasExpandedStorage;
  78. HasStoragePassword = info.HasStoragePassword;
  79. RequireStoragePassword = info.RequireStoragePassword;
  80. StoragePasswordLastSet = info.StoragePasswordLastSet;
  81. ExpandedStorageExpiryTime = info.ExpandedStorageExpiryTime;
  82. Magics = info.Magics;
  83. for (int i = 0; i < Magics.Count; i++ )
  84. {
  85. Magics[i].CastTime += CMain.Time;
  86. }
  87. IntelligentCreatures = info.IntelligentCreatures;
  88. SummonedCreatureType = info.SummonedCreatureType;
  89. CreatureSummoned = info.CreatureSummoned;
  90. BindAllItems();
  91. RefreshStats();
  92. SetAction();
  93. }
  94. public void SetSlots(S.UserSlotsRefresh p)
  95. {
  96. Inventory = p.Inventory;
  97. Equipment = p.Equipment;
  98. BindAllItems();
  99. RefreshStats();
  100. }
  101. public override void SetLibraries()
  102. {
  103. base.SetLibraries();
  104. }
  105. public override void SetEffects()
  106. {
  107. base.SetEffects();
  108. }
  109. public void RefreshStats()
  110. {
  111. Stats.Clear();
  112. RefreshLevelStats();
  113. RefreshBagWeight();
  114. RefreshEquipmentStats();
  115. RefreshItemSetStats();
  116. RefreshMirSetStats();
  117. RefreshSkills();
  118. RefreshBuffs();
  119. RefreshGuildBuffs();
  120. SetLibraries();
  121. SetEffects();
  122. Stats[Stat.HP] += (Stats[Stat.HP] * Stats[Stat.HPRatePercent]) / 100;
  123. Stats[Stat.MP] += (Stats[Stat.MP] * Stats[Stat.MPRatePercent]) / 100;
  124. Stats[Stat.MaxAC] += (Stats[Stat.MaxAC] * Stats[Stat.MaxACRatePercent]) / 100;
  125. Stats[Stat.MaxMAC] += (Stats[Stat.MaxMAC] * Stats[Stat.MaxMACRatePercent]) / 100;
  126. Stats[Stat.MaxDC] += (Stats[Stat.MaxDC] * Stats[Stat.MaxDCRatePercent]) / 100;
  127. Stats[Stat.MaxMC] += (Stats[Stat.MaxMC] * Stats[Stat.MaxMCRatePercent]) / 100;
  128. Stats[Stat.MaxSC] += (Stats[Stat.MaxSC] * Stats[Stat.MaxSCRatePercent]) / 100;
  129. Stats[Stat.AttackSpeed] += (Stats[Stat.AttackSpeed] * Stats[Stat.AttackSpeedRatePercent]) / 100;
  130. RefreshStatCaps();
  131. if (this == User && Light < 3) Light = 3;
  132. AttackSpeed = 1400 - ((Stats[Stat.AttackSpeed] * 60) + Math.Min(370, (Level * 14)));
  133. if (AttackSpeed < 550) AttackSpeed = 550;
  134. PercentHealth = (byte)(HP / (float)Stats[Stat.HP] * 100);
  135. GameScene.Scene.Redraw();
  136. }
  137. private void RefreshLevelStats()
  138. {
  139. Light = 0;
  140. foreach (var stat in CoreStats.Stats)
  141. {
  142. Stats[stat.Type] = stat.Calculate(Class, Level);
  143. }
  144. }
  145. private void RefreshBagWeight()
  146. {
  147. CurrentBagWeight = 0;
  148. for (int i = 0; i < Inventory.Length; i++)
  149. {
  150. UserItem item = Inventory[i];
  151. if (item != null)
  152. {
  153. CurrentBagWeight += item.Weight;
  154. }
  155. }
  156. }
  157. private void RefreshEquipmentStats()
  158. {
  159. Weapon = -1;
  160. WeaponEffect = 0;
  161. Armour = 0;
  162. WingEffect = 0;
  163. MountType = -1;
  164. CurrentWearWeight = 0;
  165. CurrentHandWeight = 0;
  166. ItemMode = SpecialItemMode.None;
  167. FastRun = false;
  168. ItemSets.Clear();
  169. MirSet.Clear();
  170. for (int i = 0; i < Equipment.Length; i++)
  171. {
  172. UserItem temp = Equipment[i];
  173. if (temp == null) continue;
  174. ItemInfo realItem = Functions.GetRealItem(temp.Info, Level, Class, GameScene.ItemInfoList);
  175. if (realItem.Type == ItemType.Weapon || realItem.Type == ItemType.Torch)
  176. CurrentHandWeight = (int)Math.Min(int.MaxValue, CurrentHandWeight + temp.Weight);
  177. else
  178. CurrentWearWeight = (int)Math.Min(int.MaxValue, CurrentWearWeight + temp.Weight);
  179. if (temp.CurrentDura == 0 && realItem.Durability > 0) continue;
  180. if (realItem.Type == ItemType.Armour)
  181. {
  182. Armour = realItem.Shape;
  183. WingEffect = realItem.Effect;
  184. }
  185. if (realItem.Type == ItemType.Weapon)
  186. {
  187. Weapon = realItem.Shape;
  188. WeaponEffect = realItem.Effect;
  189. }
  190. if (realItem.Type == ItemType.Mount)
  191. {
  192. MountType = realItem.Shape;
  193. }
  194. if (temp.Info.IsFishingRod) continue;
  195. Stats.Add(realItem.Stats);
  196. Stats.Add(temp.AddedStats);
  197. Stats[Stat.MinAC] += temp.Awake.GetAC();
  198. Stats[Stat.MaxAC] += temp.Awake.GetAC();
  199. Stats[Stat.MinMAC] += temp.Awake.GetMAC();
  200. Stats[Stat.MaxMAC] += temp.Awake.GetMAC();
  201. Stats[Stat.MinDC] += temp.Awake.GetDC();
  202. Stats[Stat.MaxDC] += temp.Awake.GetDC();
  203. Stats[Stat.MinMC] += temp.Awake.GetMC();
  204. Stats[Stat.MaxMC] += temp.Awake.GetMC();
  205. Stats[Stat.MinSC] += temp.Awake.GetSC();
  206. Stats[Stat.MaxSC] += temp.Awake.GetSC();
  207. Stats[Stat.HP] += temp.Awake.GetHPMP();
  208. Stats[Stat.MP] += temp.Awake.GetHPMP();
  209. if (realItem.Light > Light) Light = realItem.Light;
  210. if (realItem.Unique != SpecialItemMode.None)
  211. {
  212. ItemMode |= realItem.Unique;
  213. }
  214. if (realItem.CanFastRun)
  215. {
  216. FastRun = true;
  217. }
  218. RefreshSocketStats(temp);
  219. if (realItem.Set == ItemSet.None) continue;
  220. ItemSets itemSet = ItemSets.Where(set => set.Set == realItem.Set && !set.Type.Contains(realItem.Type) && !set.SetComplete).FirstOrDefault();
  221. if (itemSet != null)
  222. {
  223. itemSet.Type.Add(realItem.Type);
  224. itemSet.Count++;
  225. }
  226. else
  227. {
  228. ItemSets.Add(new ItemSets { Count = 1, Set = realItem.Set, Type = new List<ItemType> { realItem.Type } });
  229. }
  230. //Mir Set
  231. if (realItem.Set == ItemSet.Mir)
  232. {
  233. if (!MirSet.Contains((EquipmentSlot)i))
  234. MirSet.Add((EquipmentSlot)i);
  235. }
  236. }
  237. if (ItemMode.HasFlag(SpecialItemMode.Muscle))
  238. {
  239. Stats[Stat.BagWeight] = Stats[Stat.BagWeight] * 2;
  240. Stats[Stat.WearWeight] = Stats[Stat.WearWeight] * 2;
  241. Stats[Stat.HandWeight] = Stats[Stat.HandWeight] * 2;
  242. }
  243. }
  244. private void RefreshSocketStats(UserItem equipItem)
  245. {
  246. if (equipItem == null) return;
  247. if (equipItem.Info.Type == ItemType.Weapon && equipItem.Info.IsFishingRod)
  248. {
  249. return;
  250. }
  251. if (equipItem.Info.Type == ItemType.Mount && !RidingMount)
  252. {
  253. return;
  254. }
  255. for (int i = 0; i < equipItem.Slots.Length; i++)
  256. {
  257. UserItem temp = equipItem.Slots[i];
  258. if (temp == null) continue;
  259. ItemInfo realItem = Functions.GetRealItem(temp.Info, Level, Class, GameScene.ItemInfoList);
  260. if (realItem.Type == ItemType.Weapon || realItem.Type == ItemType.Torch)
  261. CurrentHandWeight = (int)Math.Min(int.MaxValue, CurrentHandWeight + temp.Weight);
  262. else
  263. CurrentWearWeight = (int)Math.Min(int.MaxValue, CurrentWearWeight + temp.Weight);
  264. if (temp.CurrentDura == 0 && realItem.Durability > 0) continue;
  265. Stats.Add(realItem.Stats);
  266. Stats.Add(temp.AddedStats);
  267. if (realItem.Light > Light) Light = realItem.Light;
  268. if (realItem.Unique != SpecialItemMode.None)
  269. {
  270. ItemMode |= realItem.Unique;
  271. }
  272. }
  273. }
  274. private void RefreshItemSetStats()
  275. {
  276. bool hasSmashSetBonus = false; // Flag for Smash set AttackSpeed bonus
  277. bool hasPuritySetBonus = false; // Flag for Purity set Holy bonus
  278. bool hasHwanDevilSetBonus = false; // Flag for HwanDevil set Weight bonuses
  279. foreach (var s in ItemSets)
  280. {
  281. if ((s.Set == ItemSet.Smash) && (s.Type.Contains(ItemType.Ring)) && (s.Type.Contains(ItemType.Bracelet)))
  282. {
  283. if (!hasSmashSetBonus)
  284. {
  285. Stats[Stat.AttackSpeed] += 2;
  286. hasSmashSetBonus = true;
  287. }
  288. }
  289. if ((s.Set == ItemSet.Purity) && (s.Type.Contains(ItemType.Ring)) && (s.Type.Contains(ItemType.Bracelet)))
  290. {
  291. if (!hasPuritySetBonus)
  292. {
  293. Stats[Stat.Holy] += 3;
  294. hasPuritySetBonus = true;
  295. }
  296. }
  297. if ((s.Set == ItemSet.HwanDevil) && (s.Type.Contains(ItemType.Ring)) && (s.Type.Contains(ItemType.Bracelet)))
  298. {
  299. if (!hasHwanDevilSetBonus)
  300. {
  301. Stats[Stat.WearWeight] += 5;
  302. Stats[Stat.BagWeight] += 20;
  303. hasHwanDevilSetBonus = true;
  304. }
  305. }
  306. if ((s.Set == ItemSet.DarkGhost) && (s.Type.Contains(ItemType.Necklace)) && (s.Type.Contains(ItemType.Bracelet)))
  307. {
  308. Stats[Stat.HP] += 25;
  309. }
  310. if (!s.SetComplete) continue;
  311. switch (s.Set)
  312. {
  313. case ItemSet.Mundane:
  314. Stats[Stat.HP] += 50;
  315. break;
  316. case ItemSet.NokChi:
  317. Stats[Stat.MP] += 50;
  318. break;
  319. case ItemSet.TaoProtect:
  320. Stats[Stat.HP] += 30;
  321. Stats[Stat.MP] += 30;
  322. break;
  323. case ItemSet.RedOrchid:
  324. Stats[Stat.Accuracy] += 2;
  325. break;
  326. case ItemSet.RedFlower:
  327. Stats[Stat.HP] += 50;
  328. Stats[Stat.MP] -= 50;
  329. break;
  330. case ItemSet.Smash:
  331. Stats[Stat.MinDC] += 1;
  332. Stats[Stat.MaxDC] += 3;
  333. break;
  334. case ItemSet.HwanDevil:
  335. Stats[Stat.MinMC] += 1;
  336. Stats[Stat.MaxMC] += 2;
  337. break;
  338. case ItemSet.Purity:
  339. Stats[Stat.MinSC] += 1;
  340. Stats[Stat.MaxSC] += 2;
  341. break;
  342. case ItemSet.FiveString:
  343. Stats[Stat.HP] += (int)(((double)Stats[Stat.HP] / 100) * 30);
  344. Stats[Stat.MinAC] += 2;
  345. Stats[Stat.MaxAC] += 2;
  346. break;
  347. case ItemSet.Spirit:
  348. Stats[Stat.MinDC] += 2;
  349. Stats[Stat.MaxDC] += 5;
  350. Stats[Stat.AttackSpeed] += 2;
  351. break;
  352. case ItemSet.Bone:
  353. Stats[Stat.MaxAC] += 2;
  354. Stats[Stat.MaxMC] += 1;
  355. Stats[Stat.MaxSC] += 1;
  356. break;
  357. case ItemSet.Bug:
  358. Stats[Stat.MaxDC] += 1;
  359. Stats[Stat.MaxMC] += 1;
  360. Stats[Stat.MaxSC] += 1;
  361. Stats[Stat.MaxMAC] += 1;
  362. Stats[Stat.PoisonResist] += 1;
  363. break;
  364. case ItemSet.WhiteGold:
  365. Stats[Stat.MaxDC] += 2;
  366. Stats[Stat.MaxAC] += 2;
  367. break;
  368. case ItemSet.WhiteGoldH:
  369. Stats[Stat.MaxDC] += 3;
  370. Stats[Stat.HP] += 30;
  371. Stats[Stat.AttackSpeed] += 2;
  372. break;
  373. case ItemSet.RedJade:
  374. Stats[Stat.MaxMC] += 2;
  375. Stats[Stat.MaxMAC] += 2;
  376. break;
  377. case ItemSet.RedJadeH:
  378. Stats[Stat.MaxMC] += 2;
  379. Stats[Stat.MP] += 40;
  380. Stats[Stat.Agility] += 2;
  381. break;
  382. case ItemSet.Nephrite:
  383. Stats[Stat.MaxSC] += 2;
  384. Stats[Stat.MaxAC] += 1;
  385. Stats[Stat.MaxMAC] += 1;
  386. break;
  387. case ItemSet.NephriteH:
  388. Stats[Stat.MaxSC] += 2;
  389. Stats[Stat.HP] += 15;
  390. Stats[Stat.MP] += 20;
  391. Stats[Stat.Holy] += 1;
  392. Stats[Stat.Accuracy] += 1;
  393. break;
  394. case ItemSet.Whisker1:
  395. Stats[Stat.MaxDC] += 1;
  396. Stats[Stat.BagWeight] += 25;
  397. break;
  398. case ItemSet.Whisker2:
  399. Stats[Stat.MaxMC] += 1;
  400. Stats[Stat.BagWeight] += 17;
  401. break;
  402. case ItemSet.Whisker3:
  403. Stats[Stat.MaxSC] += 1;
  404. Stats[Stat.BagWeight] += 17;
  405. break;
  406. case ItemSet.Whisker4:
  407. Stats[Stat.MaxDC] += 1;
  408. Stats[Stat.BagWeight] += 20;
  409. break;
  410. case ItemSet.Whisker5:
  411. Stats[Stat.MaxDC] += 1;
  412. Stats[Stat.BagWeight] += 17;
  413. break;
  414. case ItemSet.Hyeolryong:
  415. Stats[Stat.MaxSC] += 2;
  416. Stats[Stat.HP] += 15;
  417. Stats[Stat.MP] += 20;
  418. Stats[Stat.Holy] += 1;
  419. Stats[Stat.Accuracy] += 1;
  420. break;
  421. case ItemSet.Monitor:
  422. Stats[Stat.MagicResist] += 1;
  423. Stats[Stat.PoisonResist] += 1;
  424. break;
  425. case ItemSet.Oppressive:
  426. Stats[Stat.MaxAC] += 1;
  427. Stats[Stat.Agility] += 1;
  428. break;
  429. case ItemSet.BlueFrost:
  430. Stats[Stat.MinDC] += 1;
  431. Stats[Stat.MaxDC] += 1;
  432. Stats[Stat.MinMC] += 1;
  433. Stats[Stat.MaxMC] += 1;
  434. Stats[Stat.HandWeight] += 1;
  435. Stats[Stat.WearWeight] += 2;
  436. break;
  437. case ItemSet.BlueFrostH:
  438. Stats[Stat.MinDC] += 1;
  439. Stats[Stat.MaxDC] += 2;
  440. Stats[Stat.MaxMC] += 2;
  441. Stats[Stat.Accuracy] += 1;
  442. Stats[Stat.HP] += 50;
  443. break;
  444. case ItemSet.DarkGhost:
  445. Stats[Stat.MP] += 25;
  446. Stats[Stat.AttackSpeed] += 2;
  447. break;
  448. }
  449. }
  450. }
  451. private void RefreshMirSetStats()
  452. {
  453. if (MirSet.Count() == 10)
  454. {
  455. Stats[Stat.MaxAC] += 1;
  456. Stats[Stat.MaxMAC] += 1;
  457. Stats[Stat.BagWeight] += 70;
  458. Stats[Stat.Luck] += 2;
  459. Stats[Stat.AttackSpeed] += 2;
  460. Stats[Stat.HP] += 70;
  461. Stats[Stat.MP] += 80;
  462. Stats[Stat.MagicResist] += 6;
  463. Stats[Stat.PoisonResist] += 6;
  464. }
  465. if (MirSet.Contains(EquipmentSlot.RingL) && MirSet.Contains(EquipmentSlot.RingR))
  466. {
  467. Stats[Stat.MaxMAC] += 1;
  468. Stats[Stat.MaxAC] += 1;
  469. }
  470. if (MirSet.Contains(EquipmentSlot.BraceletL) && MirSet.Contains(EquipmentSlot.BraceletR))
  471. {
  472. Stats[Stat.MinAC] += 1;
  473. Stats[Stat.MinMAC] += 1;
  474. }
  475. if ((MirSet.Contains(EquipmentSlot.RingL) | MirSet.Contains(EquipmentSlot.RingR)) && (MirSet.Contains(EquipmentSlot.BraceletL) | MirSet.Contains(EquipmentSlot.BraceletR)) && MirSet.Contains(EquipmentSlot.Necklace))
  476. {
  477. Stats[Stat.MaxMAC] += 1;
  478. Stats[Stat.MaxAC] += 1;
  479. Stats[Stat.BagWeight] += 30;
  480. Stats[Stat.WearWeight] += 17;
  481. }
  482. if (MirSet.Contains(EquipmentSlot.RingL) && MirSet.Contains(EquipmentSlot.RingR) && MirSet.Contains(EquipmentSlot.BraceletL) && MirSet.Contains(EquipmentSlot.BraceletR) && MirSet.Contains(EquipmentSlot.Necklace))
  483. {
  484. Stats[Stat.MaxMAC] += 1;
  485. Stats[Stat.MaxAC] += 1;
  486. Stats[Stat.BagWeight] += 20;
  487. Stats[Stat.WearWeight] += 10;
  488. }
  489. if (MirSet.Contains(EquipmentSlot.Armour) && MirSet.Contains(EquipmentSlot.Helmet) && MirSet.Contains(EquipmentSlot.Weapon))
  490. {
  491. Stats[Stat.MaxDC] += 2;
  492. Stats[Stat.MaxMC] += 1;
  493. Stats[Stat.MaxSC] += 1;
  494. Stats[Stat.Agility] += 1;
  495. }
  496. if (MirSet.Contains(EquipmentSlot.Armour) && MirSet.Contains(EquipmentSlot.Boots) && MirSet.Contains(EquipmentSlot.Belt))
  497. {
  498. Stats[Stat.MaxDC] += 1;
  499. Stats[Stat.MaxMC] += 1;
  500. Stats[Stat.MaxSC] += 1;
  501. Stats[Stat.HandWeight] += 17;
  502. }
  503. if (MirSet.Contains(EquipmentSlot.Armour) && MirSet.Contains(EquipmentSlot.Boots) && MirSet.Contains(EquipmentSlot.Belt) && MirSet.Contains(EquipmentSlot.Helmet) && MirSet.Contains(EquipmentSlot.Weapon))
  504. {
  505. Stats[Stat.MinDC] += 1;
  506. Stats[Stat.MaxDC] += 1;
  507. Stats[Stat.MinMC] += 1;
  508. Stats[Stat.MaxMC] += 1;
  509. Stats[Stat.MinSC] += 1;
  510. Stats[Stat.MaxSC] += 1;
  511. Stats[Stat.HandWeight] += 17;
  512. }
  513. }
  514. private void RefreshSkills()
  515. {
  516. int[] spiritSwordLvPlus = { 0, 3, 5, 8 };
  517. int[] slayingLvPlus = {5, 6, 7, 8};
  518. for (int i = 0; i < Magics.Count; i++)
  519. {
  520. ClientMagic magic = Magics[i];
  521. switch (magic.Spell)
  522. {
  523. case Spell.Fencing:
  524. Stats[Stat.Accuracy] += magic.Level * 3;
  525. //Stats[Stat.MaxAC] += (magic.Level + 1) * 3;
  526. break;
  527. case Spell.Slaying:
  528. // case Spell.FatalSword:
  529. Stats[Stat.Accuracy] += magic.Level;
  530. Stats[Stat.MaxDC] += slayingLvPlus[magic.Level];
  531. break;
  532. case Spell.SpiritSword:
  533. Stats[Stat.Accuracy] += spiritSwordLvPlus[magic.Level];
  534. // Stats[Stat.Accuracy] += magic.Level;
  535. // Stats[Stat.MaxDC] += (int)(Stats[Stat.MaxSC] * (magic.Level + 1) * 0.1F);
  536. break;
  537. }
  538. }
  539. }
  540. private void RefreshBuffs()
  541. {
  542. TransformType = -1;
  543. BuffDialog dialog = GetBuffDialog;
  544. for (int i = 0; i < dialog.Buffs.Count; i++)
  545. {
  546. ClientBuff buff = dialog.Buffs[i];
  547. Stats.Add(buff.Stats);
  548. switch (buff.Type)
  549. {
  550. case BuffType.SwiftFeet:
  551. Sprint = true;
  552. break;
  553. case BuffType.Transform:
  554. if (buff.Paused) continue;
  555. TransformType = (short)buff.Values[0];
  556. FastRun = true;
  557. break;
  558. }
  559. }
  560. }
  561. public void RefreshGuildBuffs()
  562. {
  563. if (User != this) return;
  564. if (GameScene.Scene.GuildDialog == null) return;
  565. for (int i = 0; i < GameScene.Scene.GuildDialog.EnabledBuffs.Count; i++)
  566. {
  567. GuildBuff buff = GameScene.Scene.GuildDialog.EnabledBuffs[i];
  568. if (buff == null) continue;
  569. if (!buff.Active) continue;
  570. if (buff.Info == null)
  571. {
  572. buff.Info = GameScene.Scene.GuildDialog.FindGuildBuffInfo(buff.Id);
  573. }
  574. if (buff.Info == null) continue;
  575. Stats.Add(buff.Info.Stats);
  576. }
  577. }
  578. public void RefreshStatCaps()
  579. {
  580. foreach (var cap in CoreStats.Caps.Values)
  581. {
  582. Stats[cap.Key] = Math.Min(cap.Value, Stats[cap.Key]);
  583. }
  584. Stats[Stat.HP] = Math.Max(0, Stats[Stat.HP]);
  585. Stats[Stat.MP] = Math.Max(0, Stats[Stat.MP]);
  586. Stats[Stat.MinAC] = Math.Max(0, Stats[Stat.MinAC]);
  587. Stats[Stat.MaxAC] = Math.Max(0, Stats[Stat.MaxAC]);
  588. Stats[Stat.MinMAC] = Math.Max(0, Stats[Stat.MinMAC]);
  589. Stats[Stat.MaxMAC] = Math.Max(0, Stats[Stat.MaxMAC]);
  590. Stats[Stat.MinDC] = Math.Max(0, Stats[Stat.MinDC]);
  591. Stats[Stat.MaxDC] = Math.Max(0, Stats[Stat.MaxDC]);
  592. Stats[Stat.MinMC] = Math.Max(0, Stats[Stat.MinMC]);
  593. Stats[Stat.MaxMC] = Math.Max(0, Stats[Stat.MaxMC]);
  594. Stats[Stat.MinSC] = Math.Max(0, Stats[Stat.MinSC]);
  595. Stats[Stat.MaxSC] = Math.Max(0, Stats[Stat.MaxSC]);
  596. Stats[Stat.MinDC] = Math.Min(Stats[Stat.MinDC], Stats[Stat.MaxDC]);
  597. Stats[Stat.MinMC] = Math.Min(Stats[Stat.MinMC], Stats[Stat.MaxMC]);
  598. Stats[Stat.MinSC] = Math.Min(Stats[Stat.MinSC], Stats[Stat.MaxSC]);
  599. }
  600. public void BindAllItems()
  601. {
  602. for (int i = 0; i < Inventory.Length; i++)
  603. {
  604. if (Inventory[i] == null) continue;
  605. GameScene.Bind(Inventory[i]);
  606. }
  607. for (int i = 0; i < Equipment.Length; i++)
  608. {
  609. if (Equipment[i] == null) continue;
  610. GameScene.Bind(Equipment[i]);
  611. }
  612. for (int i = 0; i < QuestInventory.Length; i++)
  613. {
  614. if (QuestInventory[i] == null) continue;
  615. GameScene.Bind(QuestInventory[i]);
  616. }
  617. }
  618. public ClientMagic GetMagic(Spell spell)
  619. {
  620. for (int i = 0; i < Magics.Count; i++)
  621. {
  622. ClientMagic magic = Magics[i];
  623. if (magic.Spell != spell) continue;
  624. return magic;
  625. }
  626. return null;
  627. }
  628. public void GetMaxGain(UserItem item)
  629. {
  630. int freeSpace = FreeSpace(Inventory);
  631. if (freeSpace > 0)
  632. {
  633. return;
  634. }
  635. ushort canGain = 0;
  636. foreach (UserItem inventoryItem in Inventory)
  637. {
  638. if (inventoryItem.Info != item.Info)
  639. {
  640. continue;
  641. }
  642. int availableStack = inventoryItem.Info.StackSize - inventoryItem.Count;
  643. if (availableStack == 0)
  644. {
  645. continue;
  646. }
  647. canGain += (ushort)availableStack;
  648. if (canGain >= item.Count)
  649. {
  650. return;
  651. }
  652. }
  653. if (canGain == 0)
  654. {
  655. item.Count = 0;
  656. return;
  657. }
  658. item.Count = canGain;
  659. }
  660. private int FreeSpace(UserItem[] array)
  661. {
  662. int freeSlots = 0;
  663. foreach (UserItem slot in array)
  664. {
  665. if (slot == null)
  666. {
  667. freeSlots++;
  668. }
  669. }
  670. return freeSlots;
  671. }
  672. public override void SetAction()
  673. {
  674. if (QueuedAction != null && !GameScene.Observing)
  675. {
  676. if ((ActionFeed.Count == 0) || (ActionFeed.Count == 1 && NextAction.Action == MirAction.Stance))
  677. {
  678. ActionFeed.Clear();
  679. ActionFeed.Add(QueuedAction);
  680. QueuedAction = null;
  681. }
  682. }
  683. base.SetAction();
  684. }
  685. public override void ProcessFrames()
  686. {
  687. bool clear = CMain.Time >= NextMotion;
  688. base.ProcessFrames();
  689. if (clear) QueuedAction = null;
  690. if ((CurrentAction == MirAction.Standing || CurrentAction == MirAction.MountStanding || CurrentAction == MirAction.Stance || CurrentAction == MirAction.Stance2 || CurrentAction == MirAction.DashFail) && (QueuedAction != null || NextAction != null))
  691. SetAction();
  692. }
  693. public void ClearMagic()
  694. {
  695. NextMagic = null;
  696. NextMagicDirection = 0;
  697. NextMagicLocation = Point.Empty;
  698. NextMagicObject = null;
  699. }
  700. }
  701. }