PageRenderTime 42ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/Scripts/Mobiles/PlayerMobile.cs

https://bitbucket.org/servuo/servuo
C# | 6246 lines | 5156 code | 1060 blank | 30 comment | 1277 complexity | 9dac92646eb6963edc8dc6bb52ee9bbb MD5 | raw file
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using Server.Accounting;
  5. using Server.ContextMenus;
  6. using Server.Engines.CannedEvil;
  7. using Server.Engines.Craft;
  8. using Server.Engines.Help;
  9. using Server.Engines.PartySystem;
  10. using Server.Engines.Quests;
  11. using Server.Engines.XmlSpawner2;
  12. using Server.Factions;
  13. using Server.Gumps;
  14. using Server.Items;
  15. using Server.Misc;
  16. using Server.Multis;
  17. using Server.Network;
  18. using Server.Regions;
  19. using Server.Spells;
  20. using Server.Spells.Bushido;
  21. using Server.Spells.Fifth;
  22. using Server.Spells.Necromancy;
  23. using Server.Spells.Ninjitsu;
  24. using Server.Spells.Seventh;
  25. using Server.Spells.Spellweaving;
  26. using Server.Targeting;
  27. namespace Server.Mobiles
  28. {
  29. #region Enums
  30. [Flags]
  31. public enum PlayerFlag // First 16 bits are reserved for default-distro use, start custom flags at 0x00010000
  32. {
  33. None = 0x00000000,
  34. Glassblowing = 0x00000001,
  35. Masonry = 0x00000002,
  36. SandMining = 0x00000004,
  37. StoneMining = 0x00000008,
  38. ToggleMiningStone = 0x00000010,
  39. KarmaLocked = 0x00000020,
  40. AutoRenewInsurance = 0x00000040,
  41. UseOwnFilter = 0x00000080,
  42. PublicMyRunUO = 0x00000100,
  43. PagingSquelched = 0x00000200,
  44. Young = 0x00000400,
  45. AcceptGuildInvites = 0x00000800,
  46. DisplayChampionTitle = 0x00001000,
  47. HasStatReward = 0x00002000,
  48. Bedlam = 0x00010000,
  49. LibraryFriend = 0x00020000,
  50. Spellweaving = 0x00040000,
  51. GemMining = 0x00080000,
  52. ToggleMiningGem = 0x00100000,
  53. BasketWeaving = 0x00200000,
  54. AbyssEntry = 0x00400000,
  55. ToggleClippings = 0x00800000,
  56. ToggleCutClippings = 0x01000000,
  57. ToggleCutReeds = 0x02000000,
  58. MechanicalLife = 0x04000000
  59. }
  60. public enum NpcGuild
  61. {
  62. None,
  63. MagesGuild,
  64. WarriorsGuild,
  65. ThievesGuild,
  66. RangersGuild,
  67. HealersGuild,
  68. MinersGuild,
  69. MerchantsGuild,
  70. TinkersGuild,
  71. TailorsGuild,
  72. FishermensGuild,
  73. BardsGuild,
  74. BlacksmithsGuild
  75. }
  76. public enum SolenFriendship
  77. {
  78. None,
  79. Red,
  80. Black
  81. }
  82. #endregion
  83. public partial class PlayerMobile : Mobile, IHonorTarget
  84. {
  85. #region Mount Blocking
  86. public void SetMountBlock(BlockMountType type, TimeSpan duration, bool dismount)
  87. {
  88. if (dismount)
  89. {
  90. BaseMount.Dismount(this, this, type, duration, false);
  91. }
  92. else
  93. {
  94. BaseMount.SetMountPrevention(this, type, duration);
  95. }
  96. }
  97. #endregion
  98. #region Stygian Abyss
  99. public override void ToggleFlying()
  100. {
  101. if (this.Race != Race.Gargoyle)
  102. return;
  103. else if (this.Flying)
  104. {
  105. this.Freeze(TimeSpan.FromSeconds(1));
  106. this.Animate(61, 10, 1, true, false, 0);
  107. this.Flying = false;
  108. BuffInfo.RemoveBuff(this, BuffIcon.Fly);
  109. this.SendMessage("You have landed.");
  110. BaseMount.Dismount(this);
  111. return;
  112. }
  113. BlockMountType type = BaseMount.GetMountPrevention(this);
  114. if (!this.Alive)
  115. this.SendLocalizedMessage(1113082); // You may not fly while dead.
  116. else if (this.IsBodyMod && !(this.BodyMod == 666 || this.BodyMod == 667))
  117. this.SendLocalizedMessage(1112453); // You can't fly in your current form!
  118. else if (type != BlockMountType.None)
  119. {
  120. switch (type)
  121. {
  122. case BlockMountType.Dazed:
  123. this.SendLocalizedMessage(1112457);
  124. break; // You are still too dazed to fly.
  125. case BlockMountType.BolaRecovery:
  126. this.SendLocalizedMessage(1112455);
  127. break; // You cannot fly while recovering from a bola throw.
  128. case BlockMountType.DismountRecovery:
  129. this.SendLocalizedMessage(1112456);
  130. break; // You cannot fly while recovering from a dismount maneuver.
  131. }
  132. return;
  133. }
  134. else if (this.Hits < 25) // TODO confirm
  135. this.SendLocalizedMessage(1112454); // You must heal before flying.
  136. else
  137. {
  138. if (!this.Flying)
  139. {
  140. // No message?
  141. if (this.Spell is FlySpell)
  142. {
  143. FlySpell spell = (FlySpell)this.Spell;
  144. spell.Stop();
  145. }
  146. new FlySpell(this).Cast();
  147. }
  148. else
  149. {
  150. this.Flying = false;
  151. BuffInfo.RemoveBuff(this, BuffIcon.Fly);
  152. }
  153. }
  154. }
  155. #endregion
  156. private class CountAndTimeStamp
  157. {
  158. private int m_Count;
  159. private DateTime m_Stamp;
  160. public CountAndTimeStamp()
  161. {
  162. }
  163. public DateTime TimeStamp
  164. {
  165. get
  166. {
  167. return this.m_Stamp;
  168. }
  169. }
  170. public int Count
  171. {
  172. get
  173. {
  174. return this.m_Count;
  175. }
  176. set
  177. {
  178. this.m_Count = value;
  179. this.m_Stamp = DateTime.Now;
  180. }
  181. }
  182. }
  183. private DesignContext m_DesignContext;
  184. private NpcGuild m_NpcGuild;
  185. private DateTime m_NpcGuildJoinTime;
  186. private DateTime m_NextBODTurnInTime;
  187. private TimeSpan m_NpcGuildGameTime;
  188. private PlayerFlag m_Flags;
  189. private int m_StepsTaken;
  190. private int m_Profession;
  191. private bool m_IsStealthing; // IsStealthing should be moved to Server.Mobiles
  192. private bool m_IgnoreMobiles; // IgnoreMobiles should be moved to Server.Mobiles
  193. private int m_NonAutoreinsuredItems; // number of items that could not be automaitically reinsured because gold in bank was not enough
  194. private bool m_NinjaWepCooldown;
  195. /*
  196. * a value of zero means, that the mobile is not executing the spell. Otherwise,
  197. * the value should match the BaseMana required
  198. */
  199. private int m_ExecutesLightningStrike; // move to Server.Mobiles??
  200. private DateTime m_LastOnline;
  201. private Server.Guilds.RankDefinition m_GuildRank;
  202. private int m_GuildMessageHue, m_AllianceMessageHue;
  203. private List<Mobile> m_AutoStabled;
  204. private List<Mobile> m_AllFollowers;
  205. private List<Mobile> m_RecentlyReported;
  206. #region Guantlet Points
  207. private double m_GauntletPoints;
  208. [CommandProperty(AccessLevel.Administrator)]
  209. public double GauntletPoints
  210. {
  211. get
  212. {
  213. return this.m_GauntletPoints;
  214. }
  215. set
  216. {
  217. this.m_GauntletPoints = value;
  218. }
  219. }
  220. #endregion
  221. #region Getters & Setters
  222. public List<Mobile> RecentlyReported
  223. {
  224. get
  225. {
  226. return this.m_RecentlyReported;
  227. }
  228. set
  229. {
  230. this.m_RecentlyReported = value;
  231. }
  232. }
  233. public List<Mobile> AutoStabled
  234. {
  235. get
  236. {
  237. return this.m_AutoStabled;
  238. }
  239. }
  240. public bool NinjaWepCooldown
  241. {
  242. get
  243. {
  244. return this.m_NinjaWepCooldown;
  245. }
  246. set
  247. {
  248. this.m_NinjaWepCooldown = value;
  249. }
  250. }
  251. public List<Mobile> AllFollowers
  252. {
  253. get
  254. {
  255. if (this.m_AllFollowers == null)
  256. this.m_AllFollowers = new List<Mobile>();
  257. return this.m_AllFollowers;
  258. }
  259. }
  260. public Server.Guilds.RankDefinition GuildRank
  261. {
  262. get
  263. {
  264. if (this.AccessLevel >= AccessLevel.GameMaster)
  265. return Server.Guilds.RankDefinition.Leader;
  266. else
  267. return this.m_GuildRank;
  268. }
  269. set
  270. {
  271. this.m_GuildRank = value;
  272. }
  273. }
  274. [CommandProperty(AccessLevel.GameMaster)]
  275. public int GuildMessageHue
  276. {
  277. get
  278. {
  279. return this.m_GuildMessageHue;
  280. }
  281. set
  282. {
  283. this.m_GuildMessageHue = value;
  284. }
  285. }
  286. [CommandProperty(AccessLevel.GameMaster)]
  287. public int AllianceMessageHue
  288. {
  289. get
  290. {
  291. return this.m_AllianceMessageHue;
  292. }
  293. set
  294. {
  295. this.m_AllianceMessageHue = value;
  296. }
  297. }
  298. [CommandProperty(AccessLevel.GameMaster)]
  299. public int Profession
  300. {
  301. get
  302. {
  303. return this.m_Profession;
  304. }
  305. set
  306. {
  307. this.m_Profession = value;
  308. }
  309. }
  310. public int StepsTaken
  311. {
  312. get
  313. {
  314. return this.m_StepsTaken;
  315. }
  316. set
  317. {
  318. this.m_StepsTaken = value;
  319. }
  320. }
  321. [CommandProperty(AccessLevel.GameMaster)]
  322. public bool IsStealthing // IsStealthing should be moved to Server.Mobiles
  323. {
  324. get
  325. {
  326. return this.m_IsStealthing;
  327. }
  328. set
  329. {
  330. this.m_IsStealthing = value;
  331. }
  332. }
  333. [CommandProperty(AccessLevel.GameMaster)]
  334. public bool IgnoreMobiles // IgnoreMobiles should be moved to Server.Mobiles
  335. {
  336. get
  337. {
  338. return this.m_IgnoreMobiles;
  339. }
  340. set
  341. {
  342. if (this.m_IgnoreMobiles != value)
  343. {
  344. this.m_IgnoreMobiles = value;
  345. this.Delta(MobileDelta.Flags);
  346. }
  347. }
  348. }
  349. [CommandProperty(AccessLevel.GameMaster)]
  350. public NpcGuild NpcGuild
  351. {
  352. get
  353. {
  354. return this.m_NpcGuild;
  355. }
  356. set
  357. {
  358. this.m_NpcGuild = value;
  359. }
  360. }
  361. [CommandProperty(AccessLevel.GameMaster)]
  362. public DateTime NpcGuildJoinTime
  363. {
  364. get
  365. {
  366. return this.m_NpcGuildJoinTime;
  367. }
  368. set
  369. {
  370. this.m_NpcGuildJoinTime = value;
  371. }
  372. }
  373. [CommandProperty(AccessLevel.GameMaster)]
  374. public DateTime NextBODTurnInTime
  375. {
  376. get
  377. {
  378. return this.m_NextBODTurnInTime;
  379. }
  380. set
  381. {
  382. this.m_NextBODTurnInTime = value;
  383. }
  384. }
  385. [CommandProperty(AccessLevel.GameMaster)]
  386. public DateTime LastOnline
  387. {
  388. get
  389. {
  390. return this.m_LastOnline;
  391. }
  392. set
  393. {
  394. this.m_LastOnline = value;
  395. }
  396. }
  397. [CommandProperty(AccessLevel.GameMaster)]
  398. public DateTime LastMoved
  399. {
  400. get
  401. {
  402. return this.LastMoveTime;
  403. }
  404. }
  405. [CommandProperty(AccessLevel.GameMaster)]
  406. public TimeSpan NpcGuildGameTime
  407. {
  408. get
  409. {
  410. return this.m_NpcGuildGameTime;
  411. }
  412. set
  413. {
  414. this.m_NpcGuildGameTime = value;
  415. }
  416. }
  417. private int m_ToTItemsTurnedIn;
  418. [CommandProperty(AccessLevel.GameMaster)]
  419. public int ToTItemsTurnedIn
  420. {
  421. get
  422. {
  423. return this.m_ToTItemsTurnedIn;
  424. }
  425. set
  426. {
  427. this.m_ToTItemsTurnedIn = value;
  428. }
  429. }
  430. private int m_ToTTotalMonsterFame;
  431. [CommandProperty(AccessLevel.GameMaster)]
  432. public int ToTTotalMonsterFame
  433. {
  434. get
  435. {
  436. return this.m_ToTTotalMonsterFame;
  437. }
  438. set
  439. {
  440. this.m_ToTTotalMonsterFame = value;
  441. }
  442. }
  443. public int ExecutesLightningStrike
  444. {
  445. get
  446. {
  447. return this.m_ExecutesLightningStrike;
  448. }
  449. set
  450. {
  451. this.m_ExecutesLightningStrike = value;
  452. }
  453. }
  454. private int m_VASTotalMonsterFame;
  455. [CommandProperty(AccessLevel.GameMaster)]
  456. public int VASTotalMonsterFame
  457. {
  458. get
  459. {
  460. return this.m_VASTotalMonsterFame;
  461. }
  462. set
  463. {
  464. this.m_VASTotalMonsterFame = value;
  465. }
  466. }
  467. [CommandProperty(AccessLevel.GameMaster)]
  468. public int ToothAche
  469. {
  470. get
  471. {
  472. return CandyCane.GetToothAche(this);
  473. }
  474. set
  475. {
  476. CandyCane.SetToothAche(this, value);
  477. }
  478. }
  479. [CommandProperty(AccessLevel.GameMaster)]
  480. public bool MechanicalLife
  481. {
  482. get
  483. {
  484. return this.GetFlag(PlayerFlag.MechanicalLife);
  485. }
  486. set
  487. {
  488. this.SetFlag(PlayerFlag.MechanicalLife, value);
  489. }
  490. }
  491. #endregion
  492. #region PlayerFlags
  493. public PlayerFlag Flags
  494. {
  495. get
  496. {
  497. return this.m_Flags;
  498. }
  499. set
  500. {
  501. this.m_Flags = value;
  502. }
  503. }
  504. [CommandProperty(AccessLevel.GameMaster)]
  505. public bool PagingSquelched
  506. {
  507. get
  508. {
  509. return this.GetFlag(PlayerFlag.PagingSquelched);
  510. }
  511. set
  512. {
  513. this.SetFlag(PlayerFlag.PagingSquelched, value);
  514. }
  515. }
  516. [CommandProperty(AccessLevel.GameMaster)]
  517. public bool Glassblowing
  518. {
  519. get
  520. {
  521. return this.GetFlag(PlayerFlag.Glassblowing);
  522. }
  523. set
  524. {
  525. this.SetFlag(PlayerFlag.Glassblowing, value);
  526. }
  527. }
  528. [CommandProperty(AccessLevel.GameMaster)]
  529. public bool Masonry
  530. {
  531. get
  532. {
  533. return this.GetFlag(PlayerFlag.Masonry);
  534. }
  535. set
  536. {
  537. this.SetFlag(PlayerFlag.Masonry, value);
  538. }
  539. }
  540. [CommandProperty(AccessLevel.GameMaster)]
  541. public bool SandMining
  542. {
  543. get
  544. {
  545. return this.GetFlag(PlayerFlag.SandMining);
  546. }
  547. set
  548. {
  549. this.SetFlag(PlayerFlag.SandMining, value);
  550. }
  551. }
  552. [CommandProperty(AccessLevel.GameMaster)]
  553. public bool StoneMining
  554. {
  555. get
  556. {
  557. return this.GetFlag(PlayerFlag.StoneMining);
  558. }
  559. set
  560. {
  561. this.SetFlag(PlayerFlag.StoneMining, value);
  562. }
  563. }
  564. [CommandProperty(AccessLevel.GameMaster)]
  565. public bool GemMining
  566. {
  567. get
  568. {
  569. return this.GetFlag(PlayerFlag.GemMining);
  570. }
  571. set
  572. {
  573. this.SetFlag(PlayerFlag.GemMining, value);
  574. }
  575. }
  576. [CommandProperty(AccessLevel.GameMaster)]
  577. public bool BasketWeaving
  578. {
  579. get
  580. {
  581. return this.GetFlag(PlayerFlag.BasketWeaving);
  582. }
  583. set
  584. {
  585. this.SetFlag(PlayerFlag.BasketWeaving, value);
  586. }
  587. }
  588. [CommandProperty(AccessLevel.GameMaster)]
  589. public bool ToggleMiningStone
  590. {
  591. get
  592. {
  593. return this.GetFlag(PlayerFlag.ToggleMiningStone);
  594. }
  595. set
  596. {
  597. this.SetFlag(PlayerFlag.ToggleMiningStone, value);
  598. }
  599. }
  600. [CommandProperty(AccessLevel.GameMaster)]
  601. public bool AbyssEntry
  602. {
  603. get
  604. {
  605. return this.GetFlag(PlayerFlag.AbyssEntry);
  606. }
  607. set
  608. {
  609. this.SetFlag(PlayerFlag.AbyssEntry, value);
  610. }
  611. }
  612. [CommandProperty(AccessLevel.GameMaster)]
  613. public bool ToggleMiningGem
  614. {
  615. get
  616. {
  617. return this.GetFlag(PlayerFlag.ToggleMiningGem);
  618. }
  619. set
  620. {
  621. this.SetFlag(PlayerFlag.ToggleMiningGem, value);
  622. }
  623. }
  624. [CommandProperty(AccessLevel.GameMaster)]
  625. public bool KarmaLocked
  626. {
  627. get
  628. {
  629. return this.GetFlag(PlayerFlag.KarmaLocked);
  630. }
  631. set
  632. {
  633. this.SetFlag(PlayerFlag.KarmaLocked, value);
  634. }
  635. }
  636. [CommandProperty(AccessLevel.GameMaster)]
  637. public bool AutoRenewInsurance
  638. {
  639. get
  640. {
  641. return this.GetFlag(PlayerFlag.AutoRenewInsurance);
  642. }
  643. set
  644. {
  645. this.SetFlag(PlayerFlag.AutoRenewInsurance, value);
  646. }
  647. }
  648. [CommandProperty(AccessLevel.GameMaster)]
  649. public bool UseOwnFilter
  650. {
  651. get
  652. {
  653. return this.GetFlag(PlayerFlag.UseOwnFilter);
  654. }
  655. set
  656. {
  657. this.SetFlag(PlayerFlag.UseOwnFilter, value);
  658. }
  659. }
  660. [CommandProperty(AccessLevel.GameMaster)]
  661. public bool PublicMyRunUO
  662. {
  663. get
  664. {
  665. return this.GetFlag(PlayerFlag.PublicMyRunUO);
  666. }
  667. set
  668. {
  669. this.SetFlag(PlayerFlag.PublicMyRunUO, value);
  670. this.InvalidateMyRunUO();
  671. }
  672. }
  673. [CommandProperty(AccessLevel.GameMaster)]
  674. public bool AcceptGuildInvites
  675. {
  676. get
  677. {
  678. return this.GetFlag(PlayerFlag.AcceptGuildInvites);
  679. }
  680. set
  681. {
  682. this.SetFlag(PlayerFlag.AcceptGuildInvites, value);
  683. }
  684. }
  685. [CommandProperty(AccessLevel.GameMaster)]
  686. public bool HasStatReward
  687. {
  688. get
  689. {
  690. return this.GetFlag(PlayerFlag.HasStatReward);
  691. }
  692. set
  693. {
  694. this.SetFlag(PlayerFlag.HasStatReward, value);
  695. }
  696. }
  697. #region QueensLoyaltySystem
  698. private long m_LevelExp; // Experience Needed for next Experience Level
  699. [CommandProperty(AccessLevel.Owner)]
  700. public long LevelExp
  701. {
  702. get
  703. {
  704. return this.m_LevelExp;
  705. }
  706. set
  707. {
  708. this.m_LevelExp = value;
  709. this.InvalidateProperties();
  710. }
  711. }
  712. private long m_Exp; // Experience at the current Experience Level
  713. [CommandProperty(AccessLevel.GameMaster)]
  714. public long Exp
  715. {
  716. get
  717. {
  718. return this.m_Exp;
  719. }
  720. set
  721. {
  722. this.m_Exp = value;
  723. this.InvalidateProperties();
  724. }
  725. }
  726. private int m_Level; // Experience Level
  727. [CommandProperty(AccessLevel.GameMaster)]
  728. public int Level
  729. {
  730. get
  731. {
  732. return this.m_Level;
  733. }
  734. set
  735. {
  736. this.m_Level = value;
  737. this.InvalidateProperties();
  738. }
  739. }
  740. public string m_ExpTitle; // Title based on both levels
  741. [CommandProperty(AccessLevel.Owner)]
  742. public string ExpTitle
  743. {
  744. get
  745. {
  746. return this.m_ExpTitle;
  747. }
  748. set
  749. {
  750. this.m_ExpTitle = value;
  751. this.InvalidateProperties();
  752. }
  753. }
  754. #endregion
  755. #region Plant system
  756. [CommandProperty(AccessLevel.GameMaster)]
  757. public bool ToggleClippings
  758. {
  759. get
  760. {
  761. return this.GetFlag(PlayerFlag.ToggleClippings);
  762. }
  763. set
  764. {
  765. this.SetFlag(PlayerFlag.ToggleClippings, value);
  766. }
  767. }
  768. [CommandProperty(AccessLevel.GameMaster)]
  769. public bool ToggleCutReeds
  770. {
  771. get
  772. {
  773. return this.GetFlag(PlayerFlag.ToggleCutReeds);
  774. }
  775. set
  776. {
  777. this.SetFlag(PlayerFlag.ToggleCutReeds, value);
  778. }
  779. }
  780. [CommandProperty(AccessLevel.GameMaster)]
  781. public bool ToggleCutClippings
  782. {
  783. get
  784. {
  785. return this.GetFlag(PlayerFlag.ToggleCutClippings);
  786. }
  787. set
  788. {
  789. this.SetFlag(PlayerFlag.ToggleCutClippings, value);
  790. }
  791. }
  792. private DateTime m_SSNextSeed;
  793. [CommandProperty(AccessLevel.GameMaster)]
  794. public DateTime SSNextSeed
  795. {
  796. get
  797. {
  798. return this.m_SSNextSeed;
  799. }
  800. set
  801. {
  802. this.m_SSNextSeed = value;
  803. }
  804. }
  805. private DateTime m_SSSeedExpire;
  806. [CommandProperty(AccessLevel.GameMaster)]
  807. public DateTime SSSeedExpire
  808. {
  809. get
  810. {
  811. return this.m_SSSeedExpire;
  812. }
  813. set
  814. {
  815. this.m_SSSeedExpire = value;
  816. }
  817. }
  818. private Point3D m_SSSeedLocation;
  819. public Point3D SSSeedLocation
  820. {
  821. get
  822. {
  823. return this.m_SSSeedLocation;
  824. }
  825. set
  826. {
  827. this.m_SSSeedLocation = value;
  828. }
  829. }
  830. private Map m_SSSeedMap;
  831. public Map SSSeedMap
  832. {
  833. get
  834. {
  835. return this.m_SSSeedMap;
  836. }
  837. set
  838. {
  839. this.m_SSSeedMap = value;
  840. }
  841. }
  842. #endregion
  843. #endregion
  844. #region Auto Arrow Recovery
  845. private Dictionary<Type, int> m_RecoverableAmmo = new Dictionary<Type, int>();
  846. public Dictionary<Type, int> RecoverableAmmo
  847. {
  848. get
  849. {
  850. return this.m_RecoverableAmmo;
  851. }
  852. }
  853. public void RecoverAmmo()
  854. {
  855. if (Core.SE && this.Alive)
  856. {
  857. foreach (KeyValuePair<Type, int> kvp in this.m_RecoverableAmmo)
  858. {
  859. if (kvp.Value > 0)
  860. {
  861. Item ammo = null;
  862. try
  863. {
  864. ammo = Activator.CreateInstance(kvp.Key) as Item;
  865. }
  866. catch
  867. {
  868. }
  869. if (ammo != null)
  870. {
  871. string name = ammo.Name;
  872. ammo.Amount = kvp.Value;
  873. if (name == null)
  874. {
  875. if (ammo is Arrow)
  876. name = "arrow";
  877. else if (ammo is Bolt)
  878. name = "bolt";
  879. }
  880. if (name != null && ammo.Amount > 1)
  881. name = String.Format("{0}s", name);
  882. if (name == null)
  883. name = String.Format("#{0}", ammo.LabelNumber);
  884. this.PlaceInBackpack(ammo);
  885. this.SendLocalizedMessage(1073504, String.Format("{0}\t{1}", ammo.Amount, name)); // You recover ~1_NUM~ ~2_AMMO~.
  886. }
  887. }
  888. }
  889. this.m_RecoverableAmmo.Clear();
  890. }
  891. }
  892. #endregion
  893. private DateTime m_AnkhNextUse;
  894. [CommandProperty(AccessLevel.GameMaster)]
  895. public DateTime AnkhNextUse
  896. {
  897. get
  898. {
  899. return this.m_AnkhNextUse;
  900. }
  901. set
  902. {
  903. this.m_AnkhNextUse = value;
  904. }
  905. }
  906. #region Mondain's Legacy
  907. [CommandProperty(AccessLevel.GameMaster)]
  908. public bool Bedlam
  909. {
  910. get
  911. {
  912. return this.GetFlag(PlayerFlag.Bedlam);
  913. }
  914. set
  915. {
  916. this.SetFlag(PlayerFlag.Bedlam, value);
  917. }
  918. }
  919. [CommandProperty(AccessLevel.GameMaster)]
  920. public bool LibraryFriend
  921. {
  922. get
  923. {
  924. return this.GetFlag(PlayerFlag.LibraryFriend);
  925. }
  926. set
  927. {
  928. this.SetFlag(PlayerFlag.LibraryFriend, value);
  929. }
  930. }
  931. [CommandProperty(AccessLevel.GameMaster)]
  932. public bool Spellweaving
  933. {
  934. get
  935. {
  936. return this.GetFlag(PlayerFlag.Spellweaving);
  937. }
  938. set
  939. {
  940. this.SetFlag(PlayerFlag.Spellweaving, value);
  941. }
  942. }
  943. #endregion
  944. [CommandProperty(AccessLevel.GameMaster)]
  945. public TimeSpan DisguiseTimeLeft
  946. {
  947. get
  948. {
  949. return DisguiseTimers.TimeRemaining(this);
  950. }
  951. }
  952. private DateTime m_PeacedUntil;
  953. [CommandProperty(AccessLevel.GameMaster)]
  954. public DateTime PeacedUntil
  955. {
  956. get
  957. {
  958. return this.m_PeacedUntil;
  959. }
  960. set
  961. {
  962. this.m_PeacedUntil = value;
  963. }
  964. }
  965. #region Scroll of Alacrity
  966. private DateTime m_AcceleratedStart;
  967. [CommandProperty(AccessLevel.GameMaster)]
  968. public DateTime AcceleratedStart
  969. {
  970. get
  971. {
  972. return this.m_AcceleratedStart;
  973. }
  974. set
  975. {
  976. this.m_AcceleratedStart = value;
  977. }
  978. }
  979. private SkillName m_AcceleratedSkill;
  980. [CommandProperty(AccessLevel.GameMaster)]
  981. public SkillName AcceleratedSkill
  982. {
  983. get
  984. {
  985. return this.m_AcceleratedSkill;
  986. }
  987. set
  988. {
  989. this.m_AcceleratedSkill = value;
  990. }
  991. }
  992. #endregion
  993. public static Direction GetDirection4(Point3D from, Point3D to)
  994. {
  995. int dx = from.X - to.X;
  996. int dy = from.Y - to.Y;
  997. int rx = dx - dy;
  998. int ry = dx + dy;
  999. Direction ret;
  1000. if (rx >= 0 && ry >= 0)
  1001. ret = Direction.West;
  1002. else if (rx >= 0 && ry < 0)
  1003. ret = Direction.South;
  1004. else if (rx < 0 && ry < 0)
  1005. ret = Direction.East;
  1006. else
  1007. ret = Direction.North;
  1008. return ret;
  1009. }
  1010. public override bool OnDroppedItemToWorld(Item item, Point3D location)
  1011. {
  1012. if (!base.OnDroppedItemToWorld(item, location))
  1013. return false;
  1014. if (Core.AOS)
  1015. {
  1016. IPooledEnumerable mobiles = this.Map.GetMobilesInRange(location, 0);
  1017. foreach (Mobile m in mobiles)
  1018. {
  1019. if (m.Z >= location.Z && m.Z < location.Z + 16)
  1020. {
  1021. mobiles.Free();
  1022. return false;
  1023. }
  1024. }
  1025. mobiles.Free();
  1026. }
  1027. BounceInfo bi = item.GetBounce();
  1028. if (bi != null)
  1029. {
  1030. Type type = item.GetType();
  1031. if (type.IsDefined(typeof(FurnitureAttribute), true) || type.IsDefined(typeof(DynamicFlipingAttribute), true))
  1032. {
  1033. object[] objs = type.GetCustomAttributes(typeof(FlipableAttribute), true);
  1034. if (objs != null && objs.Length > 0)
  1035. {
  1036. FlipableAttribute fp = objs[0] as FlipableAttribute;
  1037. if (fp != null)
  1038. {
  1039. int[] itemIDs = fp.ItemIDs;
  1040. Point3D oldWorldLoc = bi.m_WorldLoc;
  1041. Point3D newWorldLoc = location;
  1042. if (oldWorldLoc.X != newWorldLoc.X || oldWorldLoc.Y != newWorldLoc.Y)
  1043. {
  1044. Direction dir = GetDirection4(oldWorldLoc, newWorldLoc);
  1045. if (itemIDs.Length == 2)
  1046. {
  1047. switch ( dir )
  1048. {
  1049. case Direction.North:
  1050. case Direction.South:
  1051. item.ItemID = itemIDs[0];
  1052. break;
  1053. case Direction.East:
  1054. case Direction.West:
  1055. item.ItemID = itemIDs[1];
  1056. break;
  1057. }
  1058. }
  1059. else if (itemIDs.Length == 4)
  1060. {
  1061. switch ( dir )
  1062. {
  1063. case Direction.South:
  1064. item.ItemID = itemIDs[0];
  1065. break;
  1066. case Direction.East:
  1067. item.ItemID = itemIDs[1];
  1068. break;
  1069. case Direction.North:
  1070. item.ItemID = itemIDs[2];
  1071. break;
  1072. case Direction.West:
  1073. item.ItemID = itemIDs[3];
  1074. break;
  1075. }
  1076. }
  1077. }
  1078. }
  1079. }
  1080. }
  1081. }
  1082. return true;
  1083. }
  1084. public override int GetPacketFlags()
  1085. {
  1086. int flags = base.GetPacketFlags();
  1087. if (this.m_IgnoreMobiles)
  1088. flags |= 0x10;
  1089. return flags;
  1090. }
  1091. public override int GetOldPacketFlags()
  1092. {
  1093. int flags = base.GetOldPacketFlags();
  1094. if (this.m_IgnoreMobiles)
  1095. flags |= 0x10;
  1096. return flags;
  1097. }
  1098. public bool GetFlag(PlayerFlag flag)
  1099. {
  1100. return ((this.m_Flags & flag) != 0);
  1101. }
  1102. public void SetFlag(PlayerFlag flag, bool value)
  1103. {
  1104. if (value)
  1105. this.m_Flags |= flag;
  1106. else
  1107. this.m_Flags &= ~flag;
  1108. }
  1109. public DesignContext DesignContext
  1110. {
  1111. get
  1112. {
  1113. return this.m_DesignContext;
  1114. }
  1115. set
  1116. {
  1117. this.m_DesignContext = value;
  1118. }
  1119. }
  1120. public static void Initialize()
  1121. {
  1122. if (FastwalkPrevention)
  1123. PacketHandlers.RegisterThrottler(0x02, new ThrottlePacketCallback(MovementThrottle_Callback));
  1124. EventSink.Login += new LoginEventHandler(OnLogin);
  1125. EventSink.Logout += new LogoutEventHandler(OnLogout);
  1126. EventSink.Connected += new ConnectedEventHandler(EventSink_Connected);
  1127. EventSink.Disconnected += new DisconnectedEventHandler(EventSink_Disconnected);
  1128. if (Core.SE)
  1129. {
  1130. Timer.DelayCall(TimeSpan.Zero, new TimerCallback(CheckPets));
  1131. }
  1132. }
  1133. private static void CheckPets()
  1134. {
  1135. foreach (Mobile m in World.Mobiles.Values)
  1136. {
  1137. if (m is PlayerMobile)
  1138. {
  1139. PlayerMobile pm = (PlayerMobile)m;
  1140. if (((!pm.Mounted || (pm.Mount != null && pm.Mount is EtherealMount)) && (pm.AllFollowers.Count > pm.AutoStabled.Count)) ||
  1141. (pm.Mounted && (pm.AllFollowers.Count > (pm.AutoStabled.Count + 1))))
  1142. {
  1143. pm.AutoStablePets(); /* autostable checks summons, et al: no need here */
  1144. }
  1145. }
  1146. }
  1147. }
  1148. public override void OnSkillInvalidated(Skill skill)
  1149. {
  1150. if (Core.AOS && skill.SkillName == SkillName.MagicResist)
  1151. this.UpdateResistances();
  1152. }
  1153. public override int GetMaxResistance(ResistanceType type)
  1154. {
  1155. if (this.IsStaff())
  1156. return int.MaxValue;
  1157. int max = base.GetMaxResistance(type);
  1158. if (type != ResistanceType.Physical && 60 < max && Spells.Fourth.CurseSpell.UnderEffect(this))
  1159. max = 60;
  1160. if (Core.ML && this.Race == Race.Elf && type == ResistanceType.Energy)
  1161. max += 5; //Intended to go after the 60 max from curse
  1162. return max;
  1163. }
  1164. protected override void OnRaceChange(Race oldRace)
  1165. {
  1166. this.ValidateEquipment();
  1167. this.UpdateResistances();
  1168. }
  1169. public override int MaxWeight
  1170. {
  1171. get
  1172. {
  1173. return (((Core.ML && this.Race == Race.Human) ? 100 : 40) + (int)(3.5 * this.Str));
  1174. }
  1175. }
  1176. private int m_LastGlobalLight = -1, m_LastPersonalLight = -1;
  1177. public override void OnNetStateChanged()
  1178. {
  1179. this.m_LastGlobalLight = -1;
  1180. this.m_LastPersonalLight = -1;
  1181. }
  1182. public override void ComputeBaseLightLevels(out int global, out int personal)
  1183. {
  1184. global = LightCycle.ComputeLevelFor(this);
  1185. bool racialNightSight = (Core.ML && this.Race == Race.Elf);
  1186. if (this.LightLevel < 21 && (AosAttributes.GetValue(this, AosAttribute.NightSight) > 0 || racialNightSight))
  1187. personal = 21;
  1188. else
  1189. personal = this.LightLevel;
  1190. }
  1191. public override void CheckLightLevels(bool forceResend)
  1192. {
  1193. NetState ns = this.NetState;
  1194. if (ns == null)
  1195. return;
  1196. int global, personal;
  1197. this.ComputeLightLevels(out global, out personal);
  1198. if (!forceResend)
  1199. forceResend = (global != this.m_LastGlobalLight || personal != this.m_LastPersonalLight);
  1200. if (!forceResend)
  1201. return;
  1202. this.m_LastGlobalLight = global;
  1203. this.m_LastPersonalLight = personal;
  1204. ns.Send(GlobalLightLevel.Instantiate(global));
  1205. ns.Send(new PersonalLightLevel(this, personal));
  1206. }
  1207. public override int GetMinResistance(ResistanceType type)
  1208. {
  1209. int magicResist = (int)(this.Skills[SkillName.MagicResist].Value * 10);
  1210. int min = int.MinValue;
  1211. if (magicResist >= 1000)
  1212. min = 40 + ((magicResist - 1000) / 50);
  1213. else if (magicResist >= 400)
  1214. min = (magicResist - 400) / 15;
  1215. if (min > MaxPlayerResistance)
  1216. min = MaxPlayerResistance;
  1217. int baseMin = base.GetMinResistance(type);
  1218. if (min < baseMin)
  1219. min = baseMin;
  1220. return min;
  1221. }
  1222. public override void OnManaChange(int oldValue)
  1223. {
  1224. base.OnManaChange(oldValue);
  1225. if (this.m_ExecutesLightningStrike > 0)
  1226. {
  1227. if (this.Mana < this.m_ExecutesLightningStrike)
  1228. {
  1229. LightningStrike.ClearCurrentMove(this);
  1230. }
  1231. }
  1232. }
  1233. private static void OnLogin(LoginEventArgs e)
  1234. {
  1235. Mobile from = e.Mobile;
  1236. CheckAtrophies(from);
  1237. if (AccountHandler.LockdownLevel > AccessLevel.VIP)
  1238. {
  1239. string notice;
  1240. Accounting.Account acct = from.Account as Accounting.Account;
  1241. if (acct == null || !acct.HasAccess(from.NetState))
  1242. {
  1243. if (from.IsPlayer())
  1244. notice = "The server is currently under lockdown. No players are allowed to log in at this time.";
  1245. else
  1246. notice = "The server is currently under lockdown. You do not have sufficient access level to connect.";
  1247. Timer.DelayCall(TimeSpan.FromSeconds(1.0), new TimerStateCallback(Disconnect), from);
  1248. }
  1249. else if (from.AccessLevel >= AccessLevel.Administrator)
  1250. {
  1251. notice = "The server is currently under lockdown. As you are an administrator, you may change this from the [Admin gump.";
  1252. }
  1253. else
  1254. {
  1255. notice = "The server is currently under lockdown. You have sufficient access level to connect.";
  1256. }
  1257. from.SendGump(new NoticeGump(1060637, 30720, notice, 0xFFC000, 300, 140, null, null));
  1258. return;
  1259. }
  1260. if (from is PlayerMobile)
  1261. ((PlayerMobile)from).ClaimAutoStabledPets();
  1262. }
  1263. private bool m_NoDeltaRecursion;
  1264. public void ValidateEquipment()
  1265. {
  1266. if (this.m_NoDeltaRecursion || this.Map == null || this.Map == Map.Internal)
  1267. return;
  1268. if (this.Items == null)
  1269. return;
  1270. this.m_NoDeltaRecursion = true;
  1271. Timer.DelayCall(TimeSpan.Zero, new TimerCallback(ValidateEquipment_Sandbox));
  1272. }
  1273. private void ValidateEquipment_Sandbox()
  1274. {
  1275. try
  1276. {
  1277. if (this.Map == null || this.Map == Map.Internal)
  1278. return;
  1279. List<Item> items = this.Items;
  1280. if (items == null)
  1281. return;
  1282. bool moved = false;
  1283. int str = this.Str;
  1284. int dex = this.Dex;
  1285. int intel = this.Int;
  1286. #region Factions
  1287. int factionItemCount = 0;
  1288. #endregion
  1289. Mobile from = this;
  1290. #region Ethics
  1291. Ethics.Ethic ethic = Ethics.Ethic.Find(from);
  1292. #endregion
  1293. for (int i = items.Count - 1; i >= 0; --i)
  1294. {
  1295. if (i >= items.Count)
  1296. continue;
  1297. Item item = items[i];
  1298. #region Ethics
  1299. if ((item.SavedFlags & 0x100) != 0)
  1300. {
  1301. if (item.Hue != Ethics.Ethic.Hero.Definition.PrimaryHue)
  1302. {
  1303. item.SavedFlags &= ~0x100;
  1304. }
  1305. else if (ethic != Ethics.Ethic.Hero)
  1306. {
  1307. from.AddToBackpack(item);
  1308. moved = true;
  1309. continue;
  1310. }
  1311. }
  1312. else if ((item.SavedFlags & 0x200) != 0)
  1313. {
  1314. if (item.Hue != Ethics.Ethic.Evil.Definition.PrimaryHue)
  1315. {
  1316. item.SavedFlags &= ~0x200;
  1317. }
  1318. else if (ethic != Ethics.Ethic.Evil)
  1319. {
  1320. from.AddToBackpack(item);
  1321. moved = true;
  1322. continue;
  1323. }
  1324. }
  1325. #endregion
  1326. if (item is BaseWeapon)
  1327. {
  1328. BaseWeapon weapon = (BaseWeapon)item;
  1329. bool drop = false;
  1330. if (dex < weapon.DexRequirement)
  1331. drop = true;
  1332. else if (str < AOS.Scale(weapon.StrRequirement, 100 - weapon.GetLowerStatReq()))
  1333. drop = true;
  1334. else if (intel < weapon.IntRequirement)
  1335. drop = true;
  1336. else if (weapon.RequiredRace != null && weapon.RequiredRace != this.Race)
  1337. drop = true;
  1338. if (drop)
  1339. {
  1340. string name = weapon.Name;
  1341. if (name == null)
  1342. name = String.Format("#{0}", weapon.LabelNumber);
  1343. from.SendLocalizedMessage(1062001, name); // You can no longer wield your ~1_WEAPON~
  1344. from.AddToBackpack(weapon);
  1345. moved = true;
  1346. }
  1347. }
  1348. else if (item is BaseArmor)
  1349. {
  1350. BaseArmor armor = (BaseArmor)item;
  1351. bool drop = false;
  1352. if (!armor.AllowMaleWearer && !from.Female && from.AccessLevel < AccessLevel.GameMaster)
  1353. {
  1354. drop = true;
  1355. }
  1356. else if (!armor.AllowFemaleWearer && from.Female && from.AccessLevel < AccessLevel.GameMaster)
  1357. {
  1358. drop = true;
  1359. }
  1360. else if (armor.RequiredRace != null && armor.RequiredRace != this.Race)
  1361. {
  1362. drop = true;
  1363. }
  1364. else
  1365. {
  1366. int strBonus = armor.ComputeStatBonus(StatType.Str), strReq = armor.ComputeStatReq(StatType.Str);
  1367. int dexBonus = armor.ComputeStatBonus(StatType.Dex), dexReq = armor.ComputeStatReq(StatType.Dex);
  1368. int intBonus = armor.ComputeStatBonus(StatType.Int), intReq = armor.ComputeStatReq(StatType.Int);
  1369. if (dex < dexReq || (dex + dexBonus) < 1)
  1370. drop = true;
  1371. else if (str < strReq || (str + strBonus) < 1)
  1372. drop = true;
  1373. else if (intel < intReq || (intel + intBonus) < 1)
  1374. drop = true;
  1375. }
  1376. if (drop)
  1377. {
  1378. string name = armor.Name;
  1379. if (name == null)
  1380. name = String.Format("#{0}", armor.LabelNumber);
  1381. if (armor is BaseShield)
  1382. from.SendLocalizedMessage(1062003, name); // You can no longer equip your ~1_SHIELD~
  1383. else
  1384. from.SendLocalizedMessage(1062002, name); // You can no longer wear your ~1_ARMOR~
  1385. from.AddToBackpack(armor);
  1386. moved = true;
  1387. }
  1388. }
  1389. else if (item is BaseClothing)
  1390. {
  1391. BaseClothing clothing = (BaseClothing)item;
  1392. bool drop = false;
  1393. if (!clothing.AllowMaleWearer && !from.Female && from.AccessLevel < AccessLevel.GameMaster)
  1394. {
  1395. drop = true;
  1396. }
  1397. else if (!clothing.AllowFemaleWearer && from.Female && from.AccessLevel < AccessLevel.GameMaster)
  1398. {
  1399. drop = true;
  1400. }
  1401. else if (clothing.RequiredRace != null && clothing.RequiredRace != this.Race)
  1402. {
  1403. drop = true;
  1404. }
  1405. else
  1406. {
  1407. int strBonus = clothing.ComputeStatBonus(StatType.Str);
  1408. int strReq = clothing.ComputeStatReq(StatType.Str);
  1409. if (str < strReq || (str + strBonus) < 1)
  1410. drop = true;
  1411. }
  1412. if (drop)
  1413. {
  1414. string name = clothing.Name;
  1415. if (name == null)
  1416. name = String.Format("#{0}", clothing.LabelNumber);
  1417. from.SendLocalizedMessage(1062002, name); // You can no longer wear your ~1_ARMOR~
  1418. from.AddToBackpack(clothing);
  1419. moved = true;
  1420. }
  1421. }
  1422. FactionItem factionItem = FactionItem.Find(item);
  1423. if (factionItem != null)
  1424. {
  1425. bool drop = false;
  1426. Faction ourFaction = Faction.Find(this);
  1427. if (ourFaction == null || ourFaction != factionItem.Faction)
  1428. drop = true;
  1429. else if (++factionItemCount > FactionItem.GetMaxWearables(this))
  1430. drop = true;
  1431. if (drop)
  1432. {
  1433. from.AddToBackpack(item);
  1434. moved = true;
  1435. }
  1436. }
  1437. }
  1438. if (moved)
  1439. from.SendLocalizedMessage(500647); // Some equipment has been moved to your backpack.
  1440. }
  1441. catch (Exception e)
  1442. {
  1443. Console.WriteLine(e);
  1444. }
  1445. finally
  1446. {
  1447. this.m_NoDeltaRecursion = false;
  1448. }
  1449. }
  1450. public override void Delta(MobileDelta flag)
  1451. {
  1452. base.Delta(flag);
  1453. if ((flag & MobileDelta.Stat) != 0)
  1454. this.ValidateEquipment();
  1455. if ((flag & (MobileDelta.Name | MobileDelta.Hue)) != 0)
  1456. this.InvalidateMyRunUO();
  1457. }
  1458. private static void Disconnect(object state)
  1459. {
  1460. NetState ns = ((Mobile)state).NetState;
  1461. if (ns != null)
  1462. ns.Dispose();
  1463. }
  1464. private static void OnLogout(LogoutEventArgs e)
  1465. {
  1466. if (e.Mobile is PlayerMobile)
  1467. ((PlayerMobile)e.Mobile).AutoStablePets();
  1468. #region Scroll of Alacrity
  1469. if (((PlayerMobile)e.Mobile).AcceleratedStart > DateTime.Now)
  1470. {
  1471. ((PlayerMobile)e.Mobile).AcceleratedStart = DateTime.Now;
  1472. Server.Items.ScrollofAlacrity.AlacrityEnd((PlayerMobile)e.Mobile);
  1473. }
  1474. #endregion
  1475. }
  1476. private static void EventSink_Connected(ConnectedEventArgs e)
  1477. {
  1478. PlayerMobile pm = e.Mobile as PlayerMobile;
  1479. if (pm != null)
  1480. {
  1481. pm.m_SessionStart = DateTime.Now;
  1482. if (pm.m_Quest != null)
  1483. pm.m_Quest.StartTimer();
  1484. #region Mondain's Legacy
  1485. QuestHelper.StartTimer(pm);
  1486. #endregion
  1487. pm.BedrollLogout = false;
  1488. pm.LastOnline = DateTime.Now;
  1489. }
  1490. DisguiseTimers.StartTimer(e.Mobile);
  1491. Timer.DelayCall(TimeSpan.Zero, new TimerStateCallback(ClearSpecialMovesCallback), e.Mobile);
  1492. }
  1493. private static void ClearSpecialMovesCallback(object state)
  1494. {
  1495. Mobile from = (Mobile)state;
  1496. SpecialMove.ClearAllMoves(from);
  1497. }
  1498. private static void EventSink_Disconnected(DisconnectedEventArgs e)
  1499. {
  1500. Mobile from = e.Mobile;
  1501. DesignContext context = DesignContext.Find(from);
  1502. if (context != null)
  1503. {
  1504. /* Client disconnected
  1505. * - Remove design context
  1506. * - Eject all from house
  1507. * - Restore relocated entities
  1508. */
  1509. // Remove design context
  1510. DesignContext.Remove(from);
  1511. // Eject all from house
  1512. from.RevealingAction();
  1513. foreach (Item item in context.Foundation.GetItems())
  1514. item.Location = context.Foundation.BanLocation;
  1515. foreach (Mobile mobile in context.Foundation.GetMobiles())
  1516. mobile.Location = context.Foundation.BanLocation;
  1517. // Restore relocated entities
  1518. context.Foundation.RestoreRelocatedEntities();
  1519. }
  1520. PlayerMobile pm = e.Mobile as PlayerMobile;
  1521. if (pm != null)
  1522. {
  1523. pm.m_GameTime += (DateTime.Now - pm.m_SessionStart);
  1524. if (pm.m_Quest != null)
  1525. pm.m_Quest.StopTimer();
  1526. #region Mondain's Legacy
  1527. QuestHelper.StopTimer(pm);
  1528. #endregion
  1529. pm.m_SpeechLog = null;
  1530. pm.LastOnline = DateTime.Now;
  1531. }
  1532. DisguiseTimers.StopTimer(from);
  1533. }
  1534. public override void RevealingAction()
  1535. {
  1536. if (this.m_DesignContext != null)
  1537. return;
  1538. Spells.Sixth.InvisibilitySpell.RemoveTimer(this);
  1539. base.RevealingAction();
  1540. this.m_IsStealthing = false; // IsStealthing should be moved to Server.Mobiles
  1541. }
  1542. [CommandProperty(AccessLevel.GameMaster)]
  1543. public override bool Hidden
  1544. {
  1545. get
  1546. {
  1547. return base.Hidden;
  1548. }
  1549. set
  1550. {
  1551. base.Hidden = value;
  1552. this.RemoveBuff(BuffIcon.Invisibility); //Always remove, default to the hiding icon EXCEPT in the invis spell where it's explicitly set
  1553. if (!this.Hidden)
  1554. {
  1555. this.RemoveBuff(BuffIcon.HidingAndOrStealth);
  1556. }
  1557. else // if( !InvisibilitySpell.HasTimer( this ) )
  1558. {
  1559. BuffInfo.AddBuff(this, new BuffInfo(BuffIcon.HidingAndOrStealth, 1075655)); //Hidden/Stealthing & You Are Hidden
  1560. }
  1561. }
  1562. }
  1563. public override void OnSubItemAdded(Item item)
  1564. {
  1565. if (this.AccessLevel < AccessLevel.GameMaster && item.IsChildOf(this.Backpack))
  1566. {
  1567. int maxWeight = WeightOverloading.GetMaxWeight(this);
  1568. int curWeight = Mobile.BodyWeight + this.TotalWeight;
  1569. if (curWeight > maxWeight)
  1570. this.SendLocalizedMessage(1019035, true, String.Format(" : {0} / {1}", curWeight, maxWeight));
  1571. }
  1572. }
  1573. public override bool CanBeHarmful(Mobile target, bool message, bool ignoreOurBlessedness)
  1574. {
  1575. if (this.m_DesignContext != null || (target is PlayerMobile && ((PlayerMobile)target).m_DesignContext != null))
  1576. return false;
  1577. #region Mondain's Legacy
  1578. if (this.Peaced)
  1579. {
  1580. //!+ TODO: message
  1581. return false;
  1582. }
  1583. #endregion
  1584. if ((target is BaseVendor && ((BaseVendor)target).IsInvulnerable) || target is PlayerVendor || target is TownCrier)
  1585. {
  1586. if (message)
  1587. {
  1588. if (target.Title == null)
  1589. this.SendMessage("{0} the vendor cannot be harmed.", target.Name);
  1590. else
  1591. this.SendMessage("{0} {1} cannot be harmed.", target.Name, target.Title);
  1592. }
  1593. return false;
  1594. }
  1595. return base.CanBeHarmful(target, message, ignoreOurBlessedness);
  1596. }
  1597. public override bool CanBeBeneficial(Mobile target, bool message, bool allowDead)
  1598. {
  1599. if (this.m_DesignContext != null || (target is PlayerMobile && ((PlayerMobile)target).m_DesignContext != null))
  1600. return false;
  1601. return base.CanBeBeneficial(target, message, allowDead);
  1602. }
  1603. public override bool CheckContextMenuDisplay(IEntity target)
  1604. {
  1605. return (this.m_DesignContext == null);
  1606. }
  1607. public override void OnItemAdded(Item item)
  1608. {
  1609. base.OnItemAdded(item);
  1610. if (item is BaseArmor || item is BaseWeapon)
  1611. {
  1612. this.Hits = this.Hits;
  1613. this.Stam = this.Stam;
  1614. this.Mana = this.Mana;
  1615. }
  1616. if (this.NetState != null)
  1617. this.CheckLightLevels(false);
  1618. this.InvalidateMyRunUO();
  1619. }
  1620. public override void OnItemRemoved(Item item)
  1621. {
  1622. base.OnItemRemoved(item);
  1623. if (item is BaseArmor || item is BaseWeapon)
  1624. {
  1625. this.Hits = this.Hits;
  1626. this.Stam = this.Stam;
  1627. this.Mana = this.Mana;
  1628. }
  1629. if (this.NetState != null)
  1630. this.CheckLightLevels(false);
  1631. this.InvalidateMyRunUO();
  1632. }
  1633. public override double ArmorRating
  1634. {
  1635. get
  1636. {
  1637. //BaseArmor ar;
  1638. double rating = 0.0;
  1639. this.AddArmorRating(ref rating, this.NeckArmor);
  1640. this.AddArmorRating(ref rating, this.HandArmor);
  1641. this.AddArmorRating(ref rating, this.HeadArmor);
  1642. this.AddArmorRating(ref rating, this.ArmsArmor);
  1643. this.AddArmorRating(ref rating, this.LegsArmor);
  1644. this.AddArmorRating(ref rating, this.ChestArmor);
  1645. this.AddArmorRating(ref rating, this.ShieldArmor);
  1646. return this.VirtualArmor + this.VirtualArmorMod + rating;
  1647. }
  1648. }
  1649. private void AddArmorRating(ref double rating, Item armor)
  1650. {
  1651. BaseArmor ar = armor as BaseArmor;
  1652. if (ar != null && (!Core.AOS || ar.ArmorAttributes.MageArmor == 0))
  1653. rating += ar.ArmorRatingScaled;
  1654. }
  1655. #region [Stats]Max
  1656. [CommandProperty(AccessLevel.GameMaster)]
  1657. public override int HitsMax
  1658. {
  1659. get
  1660. {
  1661. int strBase;
  1662. int strOffs = this.GetStatOffset(StatType.Str);
  1663. if (Core.AOS)
  1664. {
  1665. strBase = this.Str; //this.Str already includes GetStatOffset/str
  1666. strOffs = AosAttributes.GetValue(this, AosAttribute.BonusHits);
  1667. if (Core.ML && strOffs > 25 && this.IsPlayer())
  1668. strOffs = 25;
  1669. if (AnimalForm.UnderTransformation(this, typeof(BakeKitsune)) || AnimalForm.UnderTransformation(this, typeof(GreyWolf)))
  1670. strOffs += 20;
  1671. }
  1672. else
  1673. {
  1674. strBase = this.RawStr;
  1675. }
  1676. return (strBase / 2) + 50 + strOffs;
  1677. }
  1678. }
  1679. [CommandProperty(AccessLevel.GameMaster)]
  1680. public override int StamMax
  1681. {
  1682. get
  1683. {
  1684. return base.StamMax + AosAttributes.GetValue(this, AosAttribute.BonusStam);
  1685. }
  1686. }
  1687. [CommandProperty(AccessLevel.GameMaster)]
  1688. public override int ManaMax
  1689. {
  1690. get
  1691. {
  1692. return base.ManaMax + AosAttributes.GetValue(this, AosAttribute.BonusMana) + ((Core.ML && this.Race == Race.Elf) ? 20 : 0);
  1693. }
  1694. }
  1695. #endregion
  1696. #region Stat Getters/Setters
  1697. [CommandProperty(AccessLevel.GameMaster)]
  1698. public override int Str
  1699. {
  1700. get
  1701. {
  1702. if (Core.ML && this.IsPlayer())
  1703. return Math.Min(base.Str, 150);
  1704. return base.Str;
  1705. }
  1706. set
  1707. {
  1708. base.Str = value;
  1709. }
  1710. }
  1711. [CommandProperty(AccessLevel.GameMaster)]
  1712. public override int Int
  1713. {
  1714. get
  1715. {
  1716. if (Core.ML && this.IsPlayer())
  1717. return Math.Min(base.Int, 150);
  1718. return base.Int;
  1719. }
  1720. set
  1721. {
  1722. base.Int = value;
  1723. }
  1724. }
  1725. [CommandProperty(AccessLevel.GameMaster)]
  1726. public override int Dex
  1727. {
  1728. get
  1729. {
  1730. if (Core.ML && this.IsPlayer())
  1731. return Math.Min(base.Dex, 150);
  1732. return base.Dex;
  1733. }
  1734. set
  1735. {
  1736. base.Dex = value;
  1737. }
  1738. }
  1739. #endregion
  1740. public override bool Move(Direction d)
  1741. {
  1742. NetState ns = this.NetState;
  1743. if (ns != null)
  1744. {
  1745. if (this.HasGump(typeof(ResurrectGump)))
  1746. {
  1747. if (this.Alive)
  1748. {
  1749. this.CloseGump(typeof(ResurrectGump));
  1750. }
  1751. else
  1752. {
  1753. this.SendLocalizedMessage(500111); // You are frozen and cannot move.
  1754. return false;
  1755. }
  1756. }
  1757. }
  1758. TimeSpan speed = this.ComputeMovementSpeed(d);
  1759. bool res;
  1760. if (!this.Alive)
  1761. Server.Movement.MovementImpl.IgnoreMovableImpassables = true;
  1762. res = base.Move(d);
  1763. Server.Movement.MovementImpl.IgnoreMovableImpassables = false;
  1764. if (!res)
  1765. return false;
  1766. this.m_NextMovementTime += speed;
  1767. return true;
  1768. }
  1769. public override bool CheckMovement(Direction d, out int newZ)
  1770. {
  1771. DesignContext context = this.m_DesignContext;
  1772. if (context == null)
  1773. return base.CheckMovement(d, out newZ);
  1774. HouseFoundation foundation = context.Foundation;
  1775. newZ = foundation.Z + HouseFoundation.GetLevelZ(context.Level, context.Foundation);
  1776. int newX = this.X, newY = this.Y;
  1777. Movement.Movement.Offset(d, ref newX, ref newY);
  1778. int startX = foundation.X + foundation.Components.Min.X + 1;
  1779. int startY = foundation.Y + foundation.Components.Min.Y + 1;
  1780. int endX = startX + foundation.Components.Width - 1;
  1781. int endY = startY + foundation.Components.Height - 2;
  1782. return (newX >= startX && newY >= startY && newX < endX && newY < endY && this.Map == foundation.Map);
  1783. }
  1784. public override bool AllowItemUse(Item item)
  1785. {
  1786. #region Dueling
  1787. if (this.m_DuelContext != null && !this.m_DuelContext.AllowItemUse(this, item))
  1788. return false;
  1789. #endregion
  1790. return DesignContext.Check(this);
  1791. }
  1792. public SkillName[] AnimalFormRestrictedSkills
  1793. {
  1794. get
  1795. {
  1796. return this.m_AnimalFormRestrictedSkills;
  1797. }
  1798. }
  1799. private SkillName[] m_AnimalFormRestrictedSkills = new SkillName[]
  1800. {
  1801. SkillName.ArmsLore, SkillName.Begging, SkillName.Discordance, SkillName.Forensics,
  1802. SkillName.Inscribe, SkillName.ItemID, SkillName.Meditation, SkillName.Peacemaking,
  1803. SkillName.Provocation, SkillName.RemoveTrap, SkillName.SpiritSpeak, SkillName.Stealing,
  1804. SkillName.TasteID
  1805. };
  1806. public override bool AllowSkillUse(SkillName skill)
  1807. {
  1808. if (AnimalForm.UnderTransformation(this))
  1809. {
  1810. for (int i = 0; i < this.m_AnimalFormRestrictedSkills.Length; i++)
  1811. {
  1812. if (this.m_AnimalFormRestrictedSkills[i] == skill)
  1813. {
  1814. #region Mondain's Legacy
  1815. AnimalFormContext context = AnimalForm.GetContext(this);
  1816. if (skill == SkillName.Stealing && context.StealingMod.Value > 0)
  1817. continue;
  1818. #endregion
  1819. this.SendLocalizedMessage(1070771); // You cannot use that skill in this form.
  1820. return false;
  1821. }
  1822. }
  1823. }
  1824. #region Dueling
  1825. if (this.m_DuelContext != null && !this.m_DuelContext.AllowSkillUse(this, skill))
  1826. return false;
  1827. #endregion
  1828. return DesignContext.Check(this);
  1829. }
  1830. private bool m_LastProtectedMessage;
  1831. private int m_NextProtectionCheck = 10;
  1832. public virtual void RecheckTownProtection()
  1833. {
  1834. this.m_NextProtectionCheck = 10;
  1835. Regions.GuardedRegion reg = (Regions.GuardedRegion)this.Region.GetRegion(typeof(Regions.GuardedRegion));
  1836. bool isProtected = (reg != null && !reg.IsDisabled());
  1837. if (isProtected != this.m_LastProtectedMessage)
  1838. {
  1839. if (isProtected)
  1840. this.SendLocalizedMessage(500112); // You are now under the protection of the town guards.
  1841. else
  1842. this.SendLocalizedMessage(500113); // You have left the protection of the town guards.
  1843. this.m_LastProtectedMessage = isProtected;
  1844. }
  1845. }
  1846. public override void MoveToWorld(Point3D loc, Map map)
  1847. {
  1848. base.MoveToWorld(loc, map);
  1849. this.RecheckTownProtection();
  1850. }
  1851. public override void SetLocation(Point3D loc, bool isTeleport)
  1852. {
  1853. if (!isTeleport && this.IsPlayer())
  1854. {
  1855. // moving, not teleporting
  1856. int zDrop = (this.Location.Z - loc.Z);
  1857. if (zDrop > 20) // we fell more than one story
  1858. this.Hits -= ((zDrop / 20) * 10) - 5; // deal some damage; does not kill, disrupt, etc
  1859. }
  1860. base.SetLocation(loc, isTeleport);
  1861. if (isTeleport || --this.m_NextProtectionCheck == 0)
  1862. this.RecheckTownProtection();
  1863. }
  1864. public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
  1865. {
  1866. base.GetContextMenuEntries(from, list);
  1867. if (from == this)
  1868. {
  1869. if (this.m_Quest != null)
  1870. this.m_Quest.GetContextMenuEntries(list);
  1871. if (this.Alive && InsuranceEnabled)
  1872. {
  1873. list.Add(new CallbackEntry(6201, new ContextCallback(ToggleItemInsurance)));
  1874. if (this.AutoRenewInsurance)
  1875. list.Add(new CallbackEntry(6202, new ContextCallback(CancelRenewInventoryInsurance)));
  1876. else
  1877. list.Add(new CallbackEntry(6200, new ContextCallback(AutoRenewInventoryInsurance)));
  1878. }
  1879. BaseHouse house = BaseHouse.FindHouseAt(this);
  1880. if (house != null)
  1881. {
  1882. if (this.Alive && house.InternalizedVendors.Count > 0 && house.IsOwner(this))
  1883. list.Add(new CallbackEntry(6204, new ContextCallback(GetVendor)));
  1884. if (house.IsAosRules && !this.Region.IsPartOf(typeof(Engines.ConPVP.SafeZone))) // Dueling
  1885. list.Add(new CallbackEntry(6207, new ContextCallback(LeaveHouse)));
  1886. }
  1887. if (this.m_JusticeProtectors.Count > 0)
  1888. list.Add(new CallbackEntry(6157, new ContextCallback(CancelProtection)));
  1889. if (this.Alive)
  1890. list.Add(new CallbackEntry(6210, new ContextCallback(ToggleChampionTitleDisplay)));
  1891. #region Mondain's Legacy
  1892. if (this.Alive)
  1893. {
  1894. QuestHelper.GetContextMenuEntries(list);
  1895. if (this.m_CollectionTitles.Count > 0)
  1896. list.Add(new CallbackEntry(6229, new ContextCallback(ShowChangeTitle)));
  1897. }
  1898. #endregion
  1899. }
  1900. if (from != this)
  1901. {
  1902. if (this.Alive && Core.Expansion >= Expansion.AOS)
  1903. {
  1904. Party theirParty = from.Party as Party;
  1905. Party ourParty = this.Party as Party;
  1906. if (theirParty == null && ourParty == null)
  1907. {
  1908. list.Add(new AddToPartyEntry(from, this));
  1909. }
  1910. else if (theirParty != null && theirParty.Leader == from)
  1911. {
  1912. if (ourParty == null)
  1913. {
  1914. list.Add(new AddToPartyEntry(from, this));
  1915. }
  1916. else if (ourParty == theirParty)
  1917. {
  1918. list.Add(new RemoveFromPartyEntry(from, this));
  1919. }
  1920. }
  1921. }
  1922. BaseHouse curhouse = BaseHouse.FindHouseAt(this);
  1923. if (curhouse != null)
  1924. {
  1925. if (this.Alive && Core.Expansion >= Expansion.AOS && curhouse.IsAosRules && curhouse.IsFriend(from))
  1926. list.Add(new EjectPlayerEntry(from, this));
  1927. }
  1928. }
  1929. }
  1930. private void CancelProtection()
  1931. {
  1932. for (int i = 0; i < this.m_JusticeProtectors.Count; ++i)
  1933. {
  1934. Mobile prot = this.m_JusticeProtectors[i];
  1935. string args = String.Format("{0}\t{1}", this.Name, prot.Name);
  1936. prot.SendLocalizedMessage(1049371, args); // The protective relationship between ~1_PLAYER1~ and ~2_PLAYER2~ has been ended.
  1937. this.SendLocalizedMessage(1049371, args); // The protective relationship between ~1_PLAYER1~ and ~2_PLAYER2~ has been ended.
  1938. }
  1939. this.m_JusticeProtectors.Clear();
  1940. }
  1941. #region Insurance
  1942. private void ToggleItemInsurance()
  1943. {
  1944. if (!this.CheckAlive())
  1945. return;
  1946. this.BeginTarget(-1, false, TargetFlags.None, new TargetCallback(ToggleItemInsurance_Callback));
  1947. this.SendLocalizedMessage(1060868); // Target the item you wish to toggle insurance status on <ESC> to cancel
  1948. }
  1949. private bool CanInsure(Item item)
  1950. {
  1951. #region Mondain's Legacy
  1952. if (item is BaseQuiver && item.LootType == LootType.Regular)
  1953. return true;
  1954. #endregion
  1955. if (((item is Container) && !(item is BaseQuiver)) || item is BagOfSending || item is KeyRing)
  1956. return false;
  1957. if ((item is Spellbook && item.LootType == LootType.Blessed) || item is Runebook || item is PotionKeg || item is Sigil)
  1958. return false;
  1959. if (item.Stackable)
  1960. return false;
  1961. if (item.LootType == LootType.Cursed)
  1962. return false;
  1963. if (item.ItemID == 0x204E) // death shroud
  1964. return false;
  1965. return true;
  1966. }
  1967. private void ToggleItemInsurance_Callback(Mobile from, object obj)
  1968. {
  1969. if (!this.CheckAlive())
  1970. return;
  1971. Item item = obj as Item;
  1972. if (item == null || !item.IsChildOf(this))
  1973. {
  1974. this.BeginTarget(-1, false, TargetFlags.None, new TargetCallback(ToggleItemInsurance_Callback));
  1975. this.SendLocalizedMessage(1060871, "", 0x23); // You can only insure items that you have equipped or that are in your backpack
  1976. }
  1977. else if (item.Insured)
  1978. {
  1979. item.Insured = false;
  1980. this.SendLocalizedMessage(1060874, "", 0x35); // You cancel the insurance on the item
  1981. this.BeginTarget(-1, false, TargetFlags.None, new TargetCallback(ToggleItemInsurance_Callback));
  1982. this.SendLocalizedMessage(1060868, "", 0x23); // Target the item you wish to toggle insurance status on <ESC> to cancel
  1983. }
  1984. else if (!this.CanInsure(item))
  1985. {
  1986. this.BeginTarget(-1, false, TargetFlags.None, new TargetCallback(ToggleItemInsurance_Callback));
  1987. this.SendLocalizedMessage(1060869, "", 0x23); // You cannot insure that
  1988. }
  1989. else if (item.LootType == LootType.Blessed || item.LootType == LootType.Newbied || item.BlessedFor == from)
  1990. {
  1991. this.BeginTarget(-1, false, TargetFlags.None, new TargetCallback(ToggleItemInsurance_Callback));
  1992. this.SendLocalizedMessage(1060870, "", 0x23); // That item is blessed and does not need to be insured
  1993. this.SendLocalizedMessage(1060869, "", 0x23); // You cannot insure that
  1994. }
  1995. else
  1996. {
  1997. if (!item.PayedInsurance)
  1998. {
  1999. if (Banker.Withdraw(from, 600))
  2000. {
  2001. this.SendLocalizedMessage(1060398, "600"); // ~1_AMOUNT~ gold has been withdrawn from your bank box.
  2002. item.PayedInsurance = true;
  2003. }
  2004. else
  2005. {
  2006. this.SendLocalizedMessage(1061079, "", 0x23); // You lack the funds to purchase the insurance
  2007. return;
  2008. }
  2009. }
  2010. item.Insured = true;
  2011. this.SendLocalizedMessage(1060873, "", 0x23); // You have insured the item
  2012. this.BeginTarget(-1, false, TargetFlags.None, new TargetCallback(ToggleItemInsurance_Callback));
  2013. this.SendLocalizedMessage(1060868, "", 0x23); // Target the item you wish to toggle insurance status on <ESC> to cancel
  2014. }
  2015. }
  2016. private void AutoRenewInventoryInsurance()
  2017. {
  2018. if (!this.CheckAlive())
  2019. return;
  2020. this.SendLocalizedMessage(1060881, "", 0x23); // You have selected to automatically reinsure all insured items upon death
  2021. this.AutoRenewInsurance = true;
  2022. }
  2023. private void CancelRenewInventoryInsurance()
  2024. {
  2025. if (!this.CheckAlive())
  2026. return;
  2027. if (Core.SE)
  2028. {
  2029. if (!this.HasGump(typeof(CancelRenewInventoryInsuranceGump)))
  2030. this.SendGump(new CancelRenewInventoryInsuranceGump(this));
  2031. }
  2032. else
  2033. {
  2034. this.SendLocalizedMessage(1061075, "", 0x23); // You have cancelled automatically reinsuring all insured items upon death
  2035. this.AutoRenewInsurance = false;
  2036. }
  2037. }
  2038. private class CancelRenewInventoryInsuranceGump : Gump
  2039. {
  2040. private PlayerMobile m_Player;
  2041. public CancelRenewInventoryInsuranceGump(PlayerMobile player)
  2042. : base(250, 200)
  2043. {
  2044. this.m_Player = player;
  2045. this.AddBackground(0, 0, 240, 142, 0x13BE);
  2046. this.AddImageTiled(6, 6, 228, 100, 0xA40);
  2047. this.AddImageTiled(6, 116, 228, 20, 0xA40);
  2048. this.AddAlphaRegion(6, 6, 228, 142);
  2049. this.AddHtmlLocalized(8, 8, 228, 100, 1071021, 0x7FFF, false, false); // You are about to disable inventory insurance auto-renewal.
  2050. this.AddButton(6, 116, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0);
  2051. this.AddHtmlLocalized(40, 118, 450, 20, 1060051, 0x7FFF, false, false); // CANCEL
  2052. this.AddButton(114, 116, 0xFA5, 0xFA7, 1, GumpButtonType.Reply, 0);
  2053. this.AddHtmlLocalized(148, 118, 450, 20, 1071022, 0x7FFF, false, false); // DISABLE IT!
  2054. }
  2055. public override void OnResponse(NetState sender, RelayInfo info)
  2056. {
  2057. if (!this.m_Player.CheckAlive())
  2058. return;
  2059. if (info.ButtonID == 1)
  2060. {
  2061. this.m_Player.SendLocalizedMessage(1061075, "", 0x23); // You have cancelled automatically reinsuring all insured items upon death
  2062. this.m_Player.AutoRenewInsurance = false;
  2063. }
  2064. else
  2065. {
  2066. this.m_Player.SendLocalizedMessage(1042021); // Cancelled.
  2067. }
  2068. }
  2069. }
  2070. #endregion
  2071. private void GetVendor()
  2072. {
  2073. BaseHouse house = BaseHouse.FindHouseAt(this);
  2074. if (this.CheckAlive() && house != null && house.IsOwner(this) && house.InternalizedVendors.Count > 0)
  2075. {
  2076. this.CloseGump(typeof(ReclaimVendorGump));
  2077. this.SendGump(new ReclaimVendorGump(house));
  2078. }
  2079. }
  2080. private void LeaveHouse()
  2081. {
  2082. BaseHouse house = BaseHouse.FindHouseAt(this);
  2083. if (house != null)
  2084. this.Location = house.BanLocation;
  2085. }
  2086. private delegate void ContextCallback();
  2087. private class CallbackEntry : ContextMenuEntry
  2088. {
  2089. private ContextCallback m_Callback;
  2090. public CallbackEntry(int number, ContextCallback callback)
  2091. : this(number, -1, callback)
  2092. {
  2093. }
  2094. public CallbackEntry(int number, int range, ContextCallback callback)
  2095. : base(number, range)
  2096. {
  2097. this.m_Callback = callback;
  2098. }
  2099. public override void OnClick()
  2100. {
  2101. if (this.m_Callback != null)
  2102. this.m_Callback();
  2103. }
  2104. }
  2105. public override void DisruptiveAction()
  2106. {
  2107. if (this.Meditating)
  2108. {
  2109. this.RemoveBuff(BuffIcon.ActiveMeditation);
  2110. }
  2111. base.DisruptiveAction();
  2112. }
  2113. public override void OnDoubleClick(Mobile from)
  2114. {
  2115. if (this == from && !this.Warmode)
  2116. {
  2117. IMount mount = this.Mount;
  2118. if (mount != null && !DesignContext.Check(this))
  2119. return;
  2120. }
  2121. base.OnDoubleClick(from);
  2122. }
  2123. public override void DisplayPaperdollTo(Mobile to)
  2124. {
  2125. if (DesignContext.Check(this))
  2126. base.DisplayPaperdollTo(to);
  2127. }
  2128. private static bool m_NoRecursion;
  2129. public override bool CheckEquip(Item item)
  2130. {
  2131. if (!base.CheckEquip(item))
  2132. return false;
  2133. #region Dueling
  2134. if (this.m_DuelContext != null && !this.m_DuelContext.AllowItemEquip(this, item))
  2135. return false;
  2136. #endregion
  2137. #region Factions
  2138. FactionItem factionItem = FactionItem.Find(item);
  2139. if (factionItem != null)
  2140. {
  2141. Faction faction = Faction.Find(this);
  2142. if (faction == null)
  2143. {
  2144. this.SendLocalizedMessage(1010371); // You cannot equip a faction item!
  2145. return false;
  2146. }
  2147. else if (faction != factionItem.Faction)
  2148. {
  2149. this.SendLocalizedMessage(1010372); // You cannot equip an opposing faction's item!
  2150. return false;
  2151. }
  2152. else
  2153. {
  2154. int maxWearables = FactionItem.GetMaxWearables(this);
  2155. for (int i = 0; i < this.Items.Count; ++i)
  2156. {
  2157. Item equiped = this.Items[i];
  2158. if (item != equiped && FactionItem.Find(equiped) != null)
  2159. {
  2160. if (--maxWearables == 0)
  2161. {
  2162. this.SendLocalizedMessage(1010373); // You do not have enough rank to equip more faction items!
  2163. return false;
  2164. }
  2165. }
  2166. }
  2167. }
  2168. }
  2169. #endregion
  2170. if (this.AccessLevel < AccessLevel.GameMaster && item.Layer != Layer.Mount && this.HasTrade)
  2171. {
  2172. BounceInfo bounce = item.GetBounce();
  2173. if (bounce != null)
  2174. {
  2175. if (bounce.m_Parent is Item)
  2176. {
  2177. Item parent = (Item)bounce.m_Parent;
  2178. if (parent == this.Backpack || parent.IsChildOf(this.Backpack))
  2179. return true;
  2180. }
  2181. else if (bounce.m_Parent == this)
  2182. {
  2183. return true;
  2184. }
  2185. }
  2186. this.SendLocalizedMessage(1004042); // You can only equip what you are already carrying while you have a trade pending.
  2187. return false;
  2188. }
  2189. return true;
  2190. }
  2191. public override bool CheckTrade(Mobile to, Item item, SecureTradeContainer cont, bool message, bool checkItems, int plusItems, int plusWeight)
  2192. {
  2193. int msgNum = 0;
  2194. if (cont == null)
  2195. {
  2196. if (to.Holding != null)
  2197. msgNum = 1062727; // You cannot trade with someone who is dragging something.
  2198. else if (this.HasTrade)
  2199. msgNum = 1062781; // You are already trading with someone else!
  2200. else if (to.HasTrade)
  2201. msgNum = 1062779; // That person is already involved in a trade
  2202. }
  2203. if (msgNum == 0)
  2204. {
  2205. if (cont != null)
  2206. {
  2207. plusItems += cont.TotalItems;
  2208. plusWeight += cont.TotalWeight;
  2209. }
  2210. if (this.Backpack == null || !this.Backpack.CheckHold(this, item, false, checkItems, plusItems, plusWeight))
  2211. msgNum = 1004040; // You would not be able to hold this if the trade failed.
  2212. else if (to.Backpack == null || !to.Backpack.CheckHold(to, item, false, checkItems, plusItems, plusWeight))
  2213. msgNum = 1004039; // The recipient of this trade would not be able to carry this.
  2214. else
  2215. msgNum = CheckContentForTrade(item);
  2216. }
  2217. if (msgNum != 0)
  2218. {
  2219. if (message)
  2220. this.SendLocalizedMessage(msgNum);
  2221. return false;
  2222. }
  2223. return true;
  2224. }
  2225. private static int CheckContentForTrade(Item item)
  2226. {
  2227. if (item is TrapableContainer && ((TrapableContainer)item).TrapType != TrapType.None)
  2228. return 1004044; // You may not trade trapped items.
  2229. if (SkillHandlers.StolenItem.IsStolen(item))
  2230. return 1004043; // You may not trade recently stolen items.
  2231. if (item is Container)
  2232. {
  2233. foreach (Item subItem in item.Items)
  2234. {
  2235. int msg = CheckContentForTrade(subItem);
  2236. if (msg != 0)
  2237. return msg;
  2238. }
  2239. }
  2240. return 0;
  2241. }
  2242. public override bool CheckNonlocalDrop(Mobile from, Item item, Item target)
  2243. {
  2244. if (!base.CheckNonlocalDrop(from, item, target))
  2245. return false;
  2246. if (from.AccessLevel >= AccessLevel.GameMaster)
  2247. return true;
  2248. Container pack = this.Backpack;
  2249. if (from == this && this.HasTrade && (target == pack || target.IsChildOf(pack)))
  2250. {
  2251. BounceInfo bounce = item.GetBounce();
  2252. if (bounce != null && bounce.m_Parent is Item)
  2253. {
  2254. Item parent = (Item)bounce.m_Parent;
  2255. if (parent == pack || parent.IsChildOf(pack))
  2256. return true;
  2257. }
  2258. this.SendLocalizedMessage(1004041); // You can't do that while you have a trade pending.
  2259. return false;
  2260. }
  2261. return true;
  2262. }
  2263. protected override void OnLocationChange(Point3D oldLocation)
  2264. {
  2265. this.CheckLightLevels(false);
  2266. #region Dueling
  2267. if (this.m_DuelContext != null)
  2268. this.m_DuelContext.OnLocationChanged(this);
  2269. #endregion
  2270. DesignContext context = this.m_DesignContext;
  2271. if (context == null || m_NoRecursion)
  2272. return;
  2273. m_NoRecursion = true;
  2274. HouseFoundation foundation = context.Foundation;
  2275. int newX = this.X, newY = this.Y;
  2276. int newZ = foundation.Z + HouseFoundation.GetLevelZ(context.Level, context.Foundation);
  2277. int startX = foundation.X + foundation.Components.Min.X + 1;
  2278. int startY = foundation.Y + foundation.Components.Min.Y + 1;
  2279. int endX = startX + foundation.Components.Width - 1;
  2280. int endY = startY + foundation.Components.Height - 2;
  2281. if (newX >= startX && newY >= startY && newX < endX && newY < endY && this.Map == foundation.Map)
  2282. {
  2283. if (this.Z != newZ)
  2284. this.Location = new Point3D(this.X, this.Y, newZ);
  2285. m_NoRecursion = false;
  2286. return;
  2287. }
  2288. this.Location = new Point3D(foundation.X, foundation.Y, newZ);
  2289. this.Map = foundation.Map;
  2290. m_NoRecursion = false;
  2291. }
  2292. public override bool OnMoveOver(Mobile m)
  2293. {
  2294. if (m is BaseCreature && !((BaseCreature)m).Controlled)
  2295. return (!this.Alive || !m.Alive || this.IsDeadBondedPet || m.IsDeadBondedPet) || (this.Hidden && this.IsStaff());
  2296. #region Dueling
  2297. if (this.Region.IsPartOf(typeof(Engines.ConPVP.SafeZone)) && m is PlayerMobile)
  2298. {
  2299. PlayerMobile pm = (PlayerMobile)m;
  2300. if (pm.DuelContext == null || pm.DuelPlayer == null || !pm.DuelContext.Started || pm.DuelContext.Finished || pm.DuelPlayer.Eliminated)
  2301. return true;
  2302. }
  2303. #endregion
  2304. return base.OnMoveOver(m);
  2305. }
  2306. public override bool CheckShove(Mobile shoved)
  2307. {
  2308. if (this.m_IgnoreMobiles || TransformationSpellHelper.UnderTransformation(shoved, typeof(WraithFormSpell)))
  2309. return true;
  2310. else
  2311. return base.CheckShove(shoved);
  2312. }
  2313. protected override void OnMapChange(Map oldMap)
  2314. {
  2315. if ((this.Map != Faction.Facet && oldMap == Faction.Facet) || (this.Map == Faction.Facet && oldMap != Faction.Facet))
  2316. this.InvalidateProperties();
  2317. #region Dueling
  2318. if (this.m_DuelContext != null)
  2319. this.m_DuelContext.OnMapChanged(this);
  2320. #endregion
  2321. DesignContext context = this.m_DesignContext;
  2322. if (context == null || m_NoRecursion)
  2323. return;
  2324. m_NoRecursion = true;
  2325. HouseFoundation foundation = context.Foundation;
  2326. if (this.Map != foundation.Map)
  2327. this.Map = foundation.Map;
  2328. m_NoRecursion = false;
  2329. }
  2330. public override void OnBeneficialAction(Mobile target, bool isCriminal)
  2331. {
  2332. if (this.m_SentHonorContext != null)
  2333. this.m_SentHonorContext.OnSourceBeneficialAction(target);
  2334. base.OnBeneficialAction(target, isCriminal);
  2335. }
  2336. public override void OnDamage(int amount, Mobile from, bool willKill)
  2337. {
  2338. int disruptThreshold;
  2339. if (!Core.AOS)
  2340. disruptThreshold = 0;
  2341. else if (from != null && from.Player)
  2342. disruptThreshold = 18;
  2343. else
  2344. disruptThreshold = 25;
  2345. if (amount > disruptThreshold)
  2346. {
  2347. BandageContext c = BandageContext.GetContext(this);
  2348. if (c != null)
  2349. c.Slip();
  2350. }
  2351. if (Confidence.IsRegenerating(this))
  2352. Confidence.StopRegenerating(this);
  2353. WeightOverloading.FatigueOnDamage(this, amount);
  2354. if (this.m_ReceivedHonorContext != null)
  2355. this.m_ReceivedHonorContext.OnTargetDamaged(from, amount);
  2356. if (this.m_SentHonorContext != null)
  2357. this.m_SentHonorContext.OnSourceDamaged(from, amount);
  2358. if (willKill && from is PlayerMobile)
  2359. Timer.DelayCall(TimeSpan.FromSeconds(10), new TimerCallback(((PlayerMobile)from).RecoverAmmo));
  2360. #region Mondain's Legacy
  2361. if (InvisibilityPotion.HasTimer(this))
  2362. InvisibilityPotion.Iterrupt(this);
  2363. #endregion
  2364. base.OnDamage(amount, from, willKill);
  2365. }
  2366. public override void Resurrect()
  2367. {
  2368. bool wasAlive = this.Alive;
  2369. base.Resurrect();
  2370. if (this.Alive && !wasAlive)
  2371. {
  2372. Item deathRobe = new DeathRobe();
  2373. if (!this.EquipItem(deathRobe))
  2374. deathRobe.Delete();
  2375. #region Scroll of Alacrity
  2376. if (this.AcceleratedStart > DateTime.Now)
  2377. {
  2378. BuffInfo.AddBuff(this, new BuffInfo(BuffIcon.ArcaneEmpowerment, 1078511, 1078512, this.AcceleratedSkill.ToString()));
  2379. }
  2380. #endregion
  2381. }
  2382. }
  2383. public override double RacialSkillBonus
  2384. {
  2385. get
  2386. {
  2387. if (Core.ML && this.Race == Race.Human)
  2388. return 20.0;
  2389. return 0;
  2390. }
  2391. }
  2392. public override void OnWarmodeChanged()
  2393. {
  2394. if (!this.Warmode)
  2395. Timer.DelayCall(TimeSpan.FromSeconds(10), new TimerCallback(RecoverAmmo));
  2396. }
  2397. private Mobile m_InsuranceAward;
  2398. private int m_InsuranceCost;
  2399. private int m_InsuranceBonus;
  2400. private List<Item> m_EquipSnapshot;
  2401. public List<Item> EquipSnapshot
  2402. {
  2403. get
  2404. {
  2405. return this.m_EquipSnapshot;
  2406. }
  2407. }
  2408. private bool FindItems_Callback(Item item)
  2409. {
  2410. if (!item.Deleted && (item.LootType == LootType.Blessed || item.Insured))
  2411. {
  2412. if (this.Backpack != item.ParentEntity)
  2413. {
  2414. return true;
  2415. }
  2416. }
  2417. return false;
  2418. }
  2419. public override bool OnBeforeDeath()
  2420. {
  2421. NetState state = this.NetState;
  2422. if (state != null)
  2423. state.CancelAllTrades();
  2424. this.DropHolding();
  2425. if (Core.AOS && this.Backpack != null && !this.Backpack.Deleted)
  2426. {
  2427. List<Item> ilist = this.Backpack.FindItemsByType<Item>(FindItems_Callback);
  2428. for (int i = 0; i < ilist.Count; i++)
  2429. {
  2430. this.Backpack.AddItem(ilist[i]);
  2431. }
  2432. }
  2433. this.m_EquipSnapshot = new List<Item>(this.Items);
  2434. this.m_NonAutoreinsuredItems = 0;
  2435. this.m_InsuranceCost = 0;
  2436. this.m_InsuranceAward = base.FindMostRecentDamager(false);
  2437. if (this.m_InsuranceAward is BaseCreature)
  2438. {
  2439. Mobile master = ((BaseCreature)this.m_InsuranceAward).GetMaster();
  2440. if (master != null)
  2441. this.m_InsuranceAward = master;
  2442. }
  2443. if (this.m_InsuranceAward != null && (!this.m_InsuranceAward.Player || this.m_InsuranceAward == this))
  2444. this.m_InsuranceAward = null;
  2445. if (this.m_InsuranceAward is PlayerMobile)
  2446. ((PlayerMobile)this.m_InsuranceAward).m_InsuranceBonus = 0;
  2447. if (this.m_ReceivedHonorContext != null)
  2448. this.m_ReceivedHonorContext.OnTargetKilled();
  2449. if (this.m_SentHonorContext != null)
  2450. this.m_SentHonorContext.OnSourceKilled();
  2451. this.RecoverAmmo();
  2452. return base.OnBeforeDeath();
  2453. }
  2454. private bool CheckInsuranceOnDeath(Item item)
  2455. {
  2456. if (InsuranceEnabled && item.Insured)
  2457. {
  2458. if (XmlPoints.InsuranceIsFree(this, this.m_InsuranceAward))
  2459. {
  2460. item.PayedInsurance = true;
  2461. return true;
  2462. }
  2463. #region Dueling
  2464. if (this.m_DuelPlayer != null && this.m_DuelContext != null && this.m_DuelContext.Registered && this.m_DuelContext.Started && !this.m_DuelPlayer.Eliminated)
  2465. return true;
  2466. #endregion
  2467. if (this.AutoRenewInsurance)
  2468. {
  2469. int cost = (this.m_InsuranceAward == null ? 600 : 300);
  2470. if (Banker.Withdraw(this, cost))
  2471. {
  2472. this.m_InsuranceCost += cost;
  2473. item.PayedInsurance = true;
  2474. this.SendLocalizedMessage(1060398, cost.ToString()); // ~1_AMOUNT~ gold has been withdrawn from your bank box.
  2475. }
  2476. else
  2477. {
  2478. this.SendLocalizedMessage(1061079, "", 0x23); // You lack the funds to purchase the insurance
  2479. item.PayedInsurance = false;
  2480. item.Insured = false;
  2481. this.m_NonAutoreinsuredItems++;
  2482. }
  2483. }
  2484. else
  2485. {
  2486. item.PayedInsurance = false;
  2487. item.Insured = false;
  2488. }
  2489. if (this.m_InsuranceAward != null)
  2490. {
  2491. if (Banker.Deposit(this.m_InsuranceAward, 300))
  2492. {
  2493. if (this.m_InsuranceAward is PlayerMobile)
  2494. ((PlayerMobile)this.m_InsuranceAward).m_InsuranceBonus += 300;
  2495. }
  2496. }
  2497. return true;
  2498. }
  2499. return false;
  2500. }
  2501. public override DeathMoveResult GetParentMoveResultFor(Item item)
  2502. {
  2503. if (this.CheckInsuranceOnDeath(item) && !this.Young)
  2504. return DeathMoveResult.MoveToBackpack;
  2505. DeathMoveResult res = base.GetParentMoveResultFor(item);
  2506. if (res == DeathMoveResult.MoveToCorpse && item.Movable && this.Young)
  2507. res = DeathMoveResult.MoveToBackpack;
  2508. return res;
  2509. }
  2510. public override DeathMoveResult GetInventoryMoveResultFor(Item item)
  2511. {
  2512. if (this.CheckInsuranceOnDeath(item) && !this.Young)
  2513. return DeathMoveResult.MoveToBackpack;
  2514. DeathMoveResult res = base.GetInventoryMoveResultFor(item);
  2515. if (res == DeathMoveResult.MoveToCorpse && item.Movable && this.Young)
  2516. res = DeathMoveResult.MoveToBackpack;
  2517. return res;
  2518. }
  2519. public override void OnDeath(Container c)
  2520. {
  2521. if (this.m_NonAutoreinsuredItems > 0)
  2522. {
  2523. this.SendLocalizedMessage(1061115);
  2524. }
  2525. base.OnDeath(c);
  2526. this.m_EquipSnapshot = null;
  2527. this.HueMod = -1;
  2528. this.NameMod = null;
  2529. this.SavagePaintExpiration = TimeSpan.Zero;
  2530. this.SetHairMods(-1, -1);
  2531. PolymorphSpell.StopTimer(this);
  2532. IncognitoSpell.StopTimer(this);
  2533. DisguiseTimers.RemoveTimer(this);
  2534. this.EndAction(typeof(PolymorphSpell));
  2535. this.EndAction(typeof(IncognitoSpell));
  2536. MeerMage.StopEffect(this, false);
  2537. #region Stygian Abyss
  2538. if (this.Flying == true)
  2539. {
  2540. this.Flying = false;
  2541. BuffInfo.RemoveBuff(this, BuffIcon.Fly);
  2542. }
  2543. #endregion
  2544. SkillHandlers.StolenItem.ReturnOnDeath(this, c);
  2545. if (this.m_PermaFlags.Count > 0)
  2546. {
  2547. this.m_PermaFlags.Clear();
  2548. if (c is Corpse)
  2549. ((Corpse)c).Criminal = true;
  2550. if (SkillHandlers.Stealing.ClassicMode)
  2551. this.Criminal = true;
  2552. }
  2553. if (this.Kills >= 5 && DateTime.Now >= this.m_NextJustAward)
  2554. {
  2555. Mobile m = this.FindMostRecentDamager(false);
  2556. if (m is BaseCreature)
  2557. m = ((BaseCreature)m).GetMaster();
  2558. if (m != null && m is PlayerMobile && m != this)
  2559. {
  2560. bool gainedPath = false;
  2561. int pointsToGain = 0;
  2562. pointsToGain += (int)Math.Sqrt(this.GameTime.TotalSeconds * 4);
  2563. pointsToGain *= 5;
  2564. pointsToGain += (int)Math.Pow(this.Skills.Total / 250, 2);
  2565. if (VirtueHelper.Award(m, VirtueName.Justice, pointsToGain, ref gainedPath))
  2566. {
  2567. if (gainedPath)
  2568. m.SendLocalizedMessage(1049367); // You have gained a path in Justice!
  2569. else
  2570. m.SendLocalizedMessage(1049363); // You have gained in Justice.
  2571. m.FixedParticles(0x375A, 9, 20, 5027, EffectLayer.Waist);
  2572. m.PlaySound(0x1F7);
  2573. this.m_NextJustAward = DateTime.Now + TimeSpan.FromMinutes(pointsToGain / 3);
  2574. }
  2575. }
  2576. }
  2577. if (this.m_InsuranceAward is PlayerMobile)
  2578. {
  2579. PlayerMobile pm = (PlayerMobile)this.m_InsuranceAward;
  2580. if (pm.m_InsuranceBonus > 0)
  2581. pm.SendLocalizedMessage(1060397, pm.m_InsuranceBonus.ToString()); // ~1_AMOUNT~ gold has been deposited into your bank box.
  2582. }
  2583. Mobile killer = this.FindMostRecentDamager(true);
  2584. #region QueensLoyaltySystem
  2585. if (killer is PlayerMobile)
  2586. {
  2587. this.m_Exp -= (long)(this.m_LevelExp / 100);
  2588. if (this.m_Exp < 0)
  2589. {
  2590. if (this.m_Level == 0)
  2591. this.m_Exp = 0;
  2592. else
  2593. {
  2594. this.m_Exp += (long)(this.m_LevelExp / 1.4);
  2595. this.m_Level -= 1;
  2596. this.SendMessage("Due to your death you have lost a level of Loyalty to the Queen");
  2597. }
  2598. }
  2599. }
  2600. else
  2601. {
  2602. this.m_Exp -= (long)(this.m_LevelExp / 50);
  2603. if (this.m_Exp < 0)
  2604. {
  2605. if (this.m_Level == 0)
  2606. this.Exp = 0;
  2607. else
  2608. {
  2609. this.m_Exp += (long)(this.m_LevelExp / 1.4);
  2610. this.m_Level -= 1;
  2611. this.SendMessage("Due to your death you have lost a level of Loyalty to the Queen");
  2612. }
  2613. }
  2614. }
  2615. #endregion // End Queen's Loyalty System
  2616. if (killer is BaseCreature)
  2617. {
  2618. BaseCreature bc = (BaseCreature)killer;
  2619. Mobile master = bc.GetMaster();
  2620. if (master != null)
  2621. killer = master;
  2622. }
  2623. if (this.Young && this.m_DuelContext == null)
  2624. {
  2625. if (this.YoungDeathTeleport())
  2626. Timer.DelayCall(TimeSpan.FromSeconds(2.5), new TimerCallback(SendYoungDeathNotice));
  2627. }
  2628. if (this.m_DuelContext == null || !this.m_DuelContext.Registered || !this.m_DuelContext.Started || this.m_DuelPlayer == null || this.m_DuelPlayer.Eliminated || !XmlPoints.AreChallengers(this, killer))
  2629. Faction.HandleDeath(this, killer);
  2630. Server.Guilds.Guild.HandleDeath(this, killer);
  2631. #region Dueling
  2632. if (this.m_DuelContext != null)
  2633. this.m_DuelContext.OnDeath(this, c);
  2634. #endregion
  2635. if (this.m_BuffTable != null)
  2636. {
  2637. List<BuffInfo> list = new List<BuffInfo>();
  2638. foreach (BuffInfo buff in this.m_BuffTable.Values)
  2639. {
  2640. if (!buff.RetainThroughDeath)
  2641. {
  2642. list.Add(buff);
  2643. }
  2644. }
  2645. for (int i = 0; i < list.Count; i++)
  2646. {
  2647. this.RemoveBuff(list[i]);
  2648. }
  2649. }
  2650. #region Stygian Abyss
  2651. if (this.Region.IsPartOf("Abyss") && this.SSSeedExpire > DateTime.Now)
  2652. this.SendGump(new ResurrectGump(this, ResurrectMessage.SilverSapling));
  2653. #endregion
  2654. }
  2655. private List<Mobile> m_PermaFlags;
  2656. private List<Mobile> m_VisList;
  2657. private Hashtable m_AntiMacroTable;
  2658. private TimeSpan m_GameTime;
  2659. private TimeSpan m_ShortTermElapse;
  2660. private TimeSpan m_LongTermElapse;
  2661. private DateTime m_SessionStart;
  2662. private DateTime m_LastEscortTime;
  2663. private DateTime m_LastPetBallTime;
  2664. private DateTime m_NextSmithBulkOrder;
  2665. private DateTime m_NextTailorBulkOrder;
  2666. private DateTime m_SavagePaintExpiration;
  2667. private SkillName m_Learning = (SkillName)(-1);
  2668. public SkillName Learning
  2669. {
  2670. get
  2671. {
  2672. return this.m_Learning;
  2673. }
  2674. set
  2675. {
  2676. this.m_Learning = value;
  2677. }
  2678. }
  2679. [CommandProperty(AccessLevel.GameMaster)]
  2680. public TimeSpan SavagePaintExpiration
  2681. {
  2682. get
  2683. {
  2684. TimeSpan ts = this.m_SavagePaintExpiration - DateTime.Now;
  2685. if (ts < TimeSpan.Zero)
  2686. ts = TimeSpan.Zero;
  2687. return ts;
  2688. }
  2689. set
  2690. {
  2691. this.m_SavagePaintExpiration = DateTime.Now + value;
  2692. }
  2693. }
  2694. [CommandProperty(AccessLevel.GameMaster)]
  2695. public TimeSpan NextSmithBulkOrder
  2696. {
  2697. get
  2698. {
  2699. TimeSpan ts = this.m_NextSmithBulkOrder - DateTime.Now;
  2700. if (ts < TimeSpan.Zero)
  2701. ts = TimeSpan.Zero;
  2702. return ts;
  2703. }
  2704. set
  2705. {
  2706. try
  2707. {
  2708. this.m_NextSmithBulkOrder = DateTime.Now + value;
  2709. }
  2710. catch
  2711. {
  2712. }
  2713. }
  2714. }
  2715. [CommandProperty(AccessLevel.GameMaster)]
  2716. public TimeSpan NextTailorBulkOrder
  2717. {
  2718. get
  2719. {
  2720. TimeSpan ts = this.m_NextTailorBulkOrder - DateTime.Now;
  2721. if (ts < TimeSpan.Zero)
  2722. ts = TimeSpan.Zero;
  2723. return ts;
  2724. }
  2725. set
  2726. {
  2727. try
  2728. {
  2729. this.m_NextTailorBulkOrder = DateTime.Now + value;
  2730. }
  2731. catch
  2732. {
  2733. }
  2734. }
  2735. }
  2736. [CommandProperty(AccessLevel.GameMaster)]
  2737. public DateTime LastEscortTime
  2738. {
  2739. get
  2740. {
  2741. return this.m_LastEscortTime;
  2742. }
  2743. set
  2744. {
  2745. this.m_LastEscortTime = value;
  2746. }
  2747. }
  2748. [CommandProperty(AccessLevel.GameMaster)]
  2749. public DateTime LastPetBallTime
  2750. {
  2751. get
  2752. {
  2753. return this.m_LastPetBallTime;
  2754. }
  2755. set
  2756. {
  2757. this.m_LastPetBallTime = value;
  2758. }
  2759. }
  2760. public PlayerMobile()
  2761. {
  2762. this.m_AutoStabled = new List<Mobile>();
  2763. #region Mondain's Legacy
  2764. this.m_Quests = new List<BaseQuest>();
  2765. this.m_Chains = new Dictionary<QuestChain, BaseChain>();
  2766. this.m_DoneQuests = new List<QuestRestartInfo>();
  2767. this.m_Collections = new Dictionary<Collection, int>();
  2768. this.m_CollectionTitles = new List<object>();
  2769. this.m_PeacedUntil = DateTime.Now;
  2770. #endregion
  2771. this.m_VisList = new List<Mobile>();
  2772. this.m_PermaFlags = new List<Mobile>();
  2773. this.m_AntiMacroTable = new Hashtable();
  2774. this.m_RecentlyReported = new List<Mobile>();
  2775. this.m_BOBFilter = new Engines.BulkOrders.BOBFilter();
  2776. this.m_GameTime = TimeSpan.Zero;
  2777. this.m_ShortTermElapse = TimeSpan.FromHours(8.0);
  2778. this.m_LongTermElapse = TimeSpan.FromHours(40.0);
  2779. this.m_JusticeProtectors = new List<Mobile>();
  2780. this.m_GuildRank = Guilds.RankDefinition.Lowest;
  2781. this.m_ChampionTitles = new ChampionTitleInfo();
  2782. this.InvalidateMyRunUO();
  2783. }
  2784. public override bool MutateSpeech(List<Mobile> hears, ref string text, ref object context)
  2785. {
  2786. if (this.Alive)
  2787. return false;
  2788. if (Core.ML && this.Skills[SkillName.SpiritSpeak].Value >= 100.0)
  2789. return false;
  2790. if (Core.AOS)
  2791. {
  2792. for (int i = 0; i < hears.Count; ++i)
  2793. {
  2794. Mobile m = hears[i];
  2795. if (m != this && m.Skills[SkillName.SpiritSpeak].Value >= 100.0)
  2796. return false;
  2797. }
  2798. }
  2799. return base.MutateSpeech(hears, ref text, ref context);
  2800. }
  2801. public override void DoSpeech(string text, int[] keywords, MessageType type, int hue)
  2802. {
  2803. if (Guilds.Guild.NewGuildSystem && (type == MessageType.Guild || type == MessageType.Alliance))
  2804. {
  2805. Guilds.Guild g = this.Guild as Guilds.Guild;
  2806. if (g == null)
  2807. {
  2808. this.SendLocalizedMessage(1063142); // You are not in a guild!
  2809. }
  2810. else if (type == MessageType.Alliance)
  2811. {
  2812. if (g.Alliance != null && g.Alliance.IsMember(g))
  2813. {
  2814. //g.Alliance.AllianceTextMessage( hue, "[Alliance][{0}]: {1}", this.Name, text );
  2815. g.Alliance.AllianceChat(this, text);
  2816. SendToStaffMessage(this, "[Alliance]: {0}", text);
  2817. this.m_AllianceMessageHue = hue;
  2818. }
  2819. else
  2820. {
  2821. this.SendLocalizedMessage(1071020); // You are not in an alliance!
  2822. }
  2823. }
  2824. else //Type == MessageType.Guild
  2825. {
  2826. this.m_GuildMessageHue = hue;
  2827. g.GuildChat(this, text);
  2828. SendToStaffMessage(this, "[Guild]: {0}", text);
  2829. }
  2830. }
  2831. else
  2832. {
  2833. base.DoSpeech(text, keywords, type, hue);
  2834. }
  2835. }
  2836. private static void SendToStaffMessage(Mobile from, string text)
  2837. {
  2838. Packet p = null;
  2839. foreach (NetState ns in from.GetClientsInRange(8))
  2840. {
  2841. Mobile mob = ns.Mobile;
  2842. if (mob != null && mob.AccessLevel >= AccessLevel.GameMaster && mob.AccessLevel > from.AccessLevel)
  2843. {
  2844. if (p == null)
  2845. p = Packet.Acquire(new UnicodeMessage(from.Serial, from.Body, MessageType.Regular, from.SpeechHue, 3, from.Language, from.Name, text));
  2846. ns.Send(p);
  2847. }
  2848. }
  2849. Packet.Release(p);
  2850. }
  2851. private static void SendToStaffMessage(Mobile from, string format, params object[] args)
  2852. {
  2853. SendToStaffMessage(from, String.Format(format, args));
  2854. }
  2855. public override void Damage(int amount, Mobile from)
  2856. {
  2857. if (Spells.Necromancy.EvilOmenSpell.TryEndEffect(this))
  2858. amount = (int)(amount * 1.25);
  2859. Mobile oath = Spells.Necromancy.BloodOathSpell.GetBloodOath(from);
  2860. /* Per EA's UO Herald Pub48 (ML):
  2861. * ((resist spellsx10)/20 + 10=percentage of damage resisted)
  2862. */
  2863. if (oath == this)
  2864. {
  2865. amount = (int)(amount * 1.1);
  2866. if (amount > 35 && from is PlayerMobile) /* capped @ 35, seems no expansion */
  2867. {
  2868. amount = 35;
  2869. }
  2870. if (Core.ML)
  2871. {
  2872. from.Damage((int)(amount * (1 - (((from.Skills.MagicResist.Value * .5) + 10) / 100))), this);
  2873. }
  2874. else
  2875. {
  2876. from.Damage(amount, this);
  2877. }
  2878. }
  2879. if (from != null && this.Talisman is BaseTalisman)
  2880. {
  2881. BaseTalisman talisman = (BaseTalisman)this.Talisman;
  2882. if (talisman.Protection != null && talisman.Protection.Type != null)
  2883. {
  2884. Type type = talisman.Protection.Type;
  2885. if (type.IsAssignableFrom(from.GetType()))
  2886. amount = (int)(amount * (1 - (double)talisman.Protection.Amount / 100));
  2887. }
  2888. }
  2889. base.Damage(amount, from);
  2890. }
  2891. #region Poison
  2892. public override ApplyPoisonResult ApplyPoison(Mobile from, Poison poison)
  2893. {
  2894. if (!this.Alive)
  2895. return ApplyPoisonResult.Immune;
  2896. if (Spells.Necromancy.EvilOmenSpell.TryEndEffect(this))
  2897. poison = PoisonImpl.IncreaseLevel(poison);
  2898. ApplyPoisonResult result = base.ApplyPoison(from, poison);
  2899. if (from != null && result == ApplyPoisonResult.Poisoned && this.PoisonTimer is PoisonImpl.PoisonTimer)
  2900. (this.PoisonTimer as PoisonImpl.PoisonTimer).From = from;
  2901. return result;
  2902. }
  2903. public override bool CheckPoisonImmunity(Mobile from, Poison poison)
  2904. {
  2905. if (this.Young && (this.DuelContext == null || !this.DuelContext.Started || this.DuelContext.Finished))
  2906. return true;
  2907. return base.CheckPoisonImmunity(from, poison);
  2908. }
  2909. public override void OnPoisonImmunity(Mobile from, Poison poison)
  2910. {
  2911. if (this.Young && (this.DuelContext == null || !this.DuelContext.Started || this.DuelContext.Finished))
  2912. this.SendLocalizedMessage(502808); // You would have been poisoned, were you not new to the land of Britannia. Be careful in the future.
  2913. else
  2914. base.OnPoisonImmunity(from, poison);
  2915. }
  2916. #endregion
  2917. public PlayerMobile(Serial s)
  2918. : base(s)
  2919. {
  2920. this.m_VisList = new List<Mobile>();
  2921. this.m_AntiMacroTable = new Hashtable();
  2922. this.InvalidateMyRunUO();
  2923. }
  2924. public List<Mobile> VisibilityList
  2925. {
  2926. get
  2927. {
  2928. return this.m_VisList;
  2929. }
  2930. }
  2931. public List<Mobile> PermaFlags
  2932. {
  2933. get
  2934. {
  2935. return this.m_PermaFlags;
  2936. }
  2937. }
  2938. public override int Luck
  2939. {
  2940. get
  2941. {
  2942. return AosAttributes.GetValue(this, AosAttribute.Luck);
  2943. }
  2944. }
  2945. public override bool IsHarmfulCriminal(Mobile target)
  2946. {
  2947. if (SkillHandlers.Stealing.ClassicMode && target is PlayerMobile && ((PlayerMobile)target).m_PermaFlags.Count > 0)
  2948. {
  2949. int noto = Notoriety.Compute(this, target);
  2950. if (noto == Notoriety.Innocent)
  2951. target.Delta(MobileDelta.Noto);
  2952. return false;
  2953. }
  2954. if (target is BaseCreature && ((BaseCreature)target).InitialInnocent && !((BaseCreature)target).Controlled)
  2955. return false;
  2956. if (Core.ML && target is BaseCreature && ((BaseCreature)target).Controlled && this == ((BaseCreature)target).ControlMaster)
  2957. return false;
  2958. return base.IsHarmfulCriminal(target);
  2959. }
  2960. public bool AntiMacroCheck(Skill skill, object obj)
  2961. {
  2962. if (obj == null || this.m_AntiMacroTable == null || this.IsStaff())
  2963. return true;
  2964. Hashtable tbl = (Hashtable)this.m_AntiMacroTable[skill];
  2965. if (tbl == null)
  2966. this.m_AntiMacroTable[skill] = tbl = new Hashtable();
  2967. CountAndTimeStamp count = (CountAndTimeStamp)tbl[obj];
  2968. if (count != null)
  2969. {
  2970. if (count.TimeStamp + SkillCheck.AntiMacroExpire <= DateTime.Now)
  2971. {
  2972. count.Count = 1;
  2973. return true;
  2974. }
  2975. else
  2976. {
  2977. ++count.Count;
  2978. if (count.Count <= SkillCheck.Allowance)
  2979. return true;
  2980. else
  2981. return false;
  2982. }
  2983. }
  2984. else
  2985. {
  2986. tbl[obj] = count = new CountAndTimeStamp();
  2987. count.Count = 1;
  2988. return true;
  2989. }
  2990. }
  2991. private void RevertHair()
  2992. {
  2993. this.SetHairMods(-1, -1);
  2994. }
  2995. private Engines.BulkOrders.BOBFilter m_BOBFilter;
  2996. public Engines.BulkOrders.BOBFilter BOBFilter
  2997. {
  2998. get
  2999. {
  3000. return this.m_BOBFilter;
  3001. }
  3002. }
  3003. public override void Deserialize(GenericReader reader)
  3004. {
  3005. base.Deserialize(reader);
  3006. int version = reader.ReadInt();
  3007. switch (version)
  3008. {
  3009. case 29:
  3010. {
  3011. this.m_GauntletPoints = reader.ReadDouble();
  3012. this.m_SSNextSeed = reader.ReadDateTime();
  3013. this.m_SSSeedExpire = reader.ReadDateTime();
  3014. this.m_SSSeedLocation = reader.ReadPoint3D();
  3015. this.m_SSSeedMap = reader.ReadMap();
  3016. this.m_LevelExp = reader.ReadLong();
  3017. this.m_Exp = reader.ReadLong();
  3018. this.m_Level = reader.ReadInt();
  3019. this.m_ExpTitle = reader.ReadString();
  3020. this.m_VASTotalMonsterFame = reader.ReadInt();
  3021. this.m_Quests = QuestReader.Quests(reader, this);
  3022. this.m_Chains = QuestReader.Chains(reader);
  3023. this.m_Collections = new Dictionary<Collection, int>();
  3024. this.m_CollectionTitles = new List<object>();
  3025. for (int i = reader.ReadInt(); i > 0; i--)
  3026. this.m_Collections.Add((Collection)reader.ReadInt(), reader.ReadInt());
  3027. for (int i = reader.ReadInt(); i > 0; i--)
  3028. this.m_CollectionTitles.Add(QuestReader.Object(reader));
  3029. this.m_SelectedTitle = reader.ReadInt();
  3030. goto case 28;
  3031. }
  3032. case 28:
  3033. {
  3034. this.m_PeacedUntil = reader.ReadDateTime();
  3035. goto case 27;
  3036. }
  3037. case 27:
  3038. {
  3039. this.m_AnkhNextUse = reader.ReadDateTime();
  3040. goto case 26;
  3041. }
  3042. case 26:
  3043. {
  3044. this.m_AutoStabled = reader.ReadStrongMobileList();
  3045. goto case 25;
  3046. }
  3047. case 25:
  3048. {
  3049. int recipeCount = reader.ReadInt();
  3050. if (recipeCount > 0)
  3051. {
  3052. this.m_AcquiredRecipes = new Dictionary<int, bool>();
  3053. for (int i = 0; i < recipeCount; i++)
  3054. {
  3055. int r = reader.ReadInt();
  3056. if (reader.ReadBool()) //Don't add in recipies which we haven't gotten or have been removed
  3057. this.m_AcquiredRecipes.Add(r, true);
  3058. }
  3059. }
  3060. goto case 24;
  3061. }
  3062. case 24:
  3063. {
  3064. this.m_LastHonorLoss = reader.ReadDeltaTime();
  3065. goto case 23;
  3066. }
  3067. case 23:
  3068. {
  3069. this.m_ChampionTitles = new ChampionTitleInfo(reader);
  3070. goto case 22;
  3071. }
  3072. case 22:
  3073. {
  3074. this.m_LastValorLoss = reader.ReadDateTime();
  3075. goto case 21;
  3076. }
  3077. case 21:
  3078. {
  3079. this.m_ToTItemsTurnedIn = reader.ReadEncodedInt();
  3080. this.m_ToTTotalMonsterFame = reader.ReadInt();
  3081. goto case 20;
  3082. }
  3083. case 20:
  3084. {
  3085. this.m_AllianceMessageHue = reader.ReadEncodedInt();
  3086. this.m_GuildMessageHue = reader.ReadEncodedInt();
  3087. goto case 19;
  3088. }
  3089. case 19:
  3090. {
  3091. int rank = reader.ReadEncodedInt();
  3092. int maxRank = Guilds.RankDefinition.Ranks.Length - 1;
  3093. if (rank > maxRank)
  3094. rank = maxRank;
  3095. this.m_GuildRank = Guilds.RankDefinition.Ranks[rank];
  3096. this.m_LastOnline = reader.ReadDateTime();
  3097. goto case 18;
  3098. }
  3099. case 18:
  3100. {
  3101. this.m_SolenFriendship = (SolenFriendship)reader.ReadEncodedInt();
  3102. goto case 17;
  3103. }
  3104. case 17: // changed how DoneQuests is serialized
  3105. case 16:
  3106. {
  3107. this.m_Quest = QuestSerializer.DeserializeQuest(reader);
  3108. if (this.m_Quest != null)
  3109. this.m_Quest.From = this;
  3110. int count = reader.ReadEncodedInt();
  3111. if (count > 0)
  3112. {
  3113. this.m_DoneQuests = new List<QuestRestartInfo>();
  3114. for (int i = 0; i < count; ++i)
  3115. {
  3116. Type questType = QuestSerializer.ReadType(QuestSystem.QuestTypes, reader);
  3117. DateTime restartTime;
  3118. if (version < 17)
  3119. restartTime = DateTime.MaxValue;
  3120. else
  3121. restartTime = reader.ReadDateTime();
  3122. this.m_DoneQuests.Add(new QuestRestartInfo(questType, restartTime));
  3123. }
  3124. }
  3125. this.m_Profession = reader.ReadEncodedInt();
  3126. goto case 15;
  3127. }
  3128. case 15:
  3129. {
  3130. this.m_LastCompassionLoss = reader.ReadDeltaTime();
  3131. goto case 14;
  3132. }
  3133. case 14:
  3134. {
  3135. this.m_CompassionGains = reader.ReadEncodedInt();
  3136. if (this.m_CompassionGains > 0)
  3137. this.m_NextCompassionDay = reader.ReadDeltaTime();
  3138. goto case 13;
  3139. }
  3140. case 13: // just removed m_PayedInsurance list
  3141. case 12:
  3142. {
  3143. this.m_BOBFilter = new Engines.BulkOrders.BOBFilter(reader);
  3144. goto case 11;
  3145. }
  3146. case 11:
  3147. {
  3148. if (version < 13)
  3149. {
  3150. List<Item> payed = reader.ReadStrongItemList();
  3151. for (int i = 0; i < payed.Count; ++i)
  3152. payed[i].PayedInsurance = true;
  3153. }
  3154. goto case 10;
  3155. }
  3156. case 10:
  3157. {
  3158. if (reader.ReadBool())
  3159. {
  3160. this.m_HairModID = reader.ReadInt();
  3161. this.m_HairModHue = reader.ReadInt();
  3162. this.m_BeardModID = reader.ReadInt();
  3163. this.m_BeardModHue = reader.ReadInt();
  3164. }
  3165. goto case 9;
  3166. }
  3167. case 9:
  3168. {
  3169. this.SavagePaintExpiration = reader.ReadTimeSpan();
  3170. if (this.SavagePaintExpiration > TimeSpan.Zero)
  3171. {
  3172. this.BodyMod = (this.Female ? 184 : 183);
  3173. this.HueMod = 0;
  3174. }
  3175. goto case 8;
  3176. }
  3177. case 8:
  3178. {
  3179. this.m_NpcGuild = (NpcGuild)reader.ReadInt();
  3180. this.m_NpcGuildJoinTime = reader.ReadDateTime();
  3181. this.m_NpcGuildGameTime = reader.ReadTimeSpan();
  3182. goto case 7;
  3183. }
  3184. case 7:
  3185. {
  3186. this.m_PermaFlags = reader.ReadStrongMobileList();
  3187. goto case 6;
  3188. }
  3189. case 6:
  3190. {
  3191. this.NextTailorBulkOrder = reader.ReadTimeSpan();
  3192. goto case 5;
  3193. }
  3194. case 5:
  3195. {
  3196. this.NextSmithBulkOrder = reader.ReadTimeSpan();
  3197. goto case 4;
  3198. }
  3199. case 4:
  3200. {
  3201. this.m_LastJusticeLoss = reader.ReadDeltaTime();
  3202. this.m_JusticeProtectors = reader.ReadStrongMobileList();
  3203. goto case 3;
  3204. }
  3205. case 3:
  3206. {
  3207. this.m_LastSacrificeGain = reader.ReadDeltaTime();
  3208. this.m_LastSacrificeLoss = reader.ReadDeltaTime();
  3209. this.m_AvailableResurrects = reader.ReadInt();
  3210. goto case 2;
  3211. }
  3212. case 2:
  3213. {
  3214. this.m_Flags = (PlayerFlag)reader.ReadInt();
  3215. goto case 1;
  3216. }
  3217. case 1:
  3218. {
  3219. this.m_LongTermElapse = reader.ReadTimeSpan();
  3220. this.m_ShortTermElapse = reader.ReadTimeSpan();
  3221. this.m_GameTime = reader.ReadTimeSpan();
  3222. goto case 0;
  3223. }
  3224. case 0:
  3225. {
  3226. if (version < 26)
  3227. this.m_AutoStabled = new List<Mobile>();
  3228. break;
  3229. }
  3230. }
  3231. if (version < 29)
  3232. {
  3233. this.m_SSNextSeed = this.m_SSSeedExpire = DateTime.Now;
  3234. this.m_SSSeedLocation = Point3D.Zero;
  3235. }
  3236. if (this.m_RecentlyReported == null)
  3237. this.m_RecentlyReported = new List<Mobile>();
  3238. #region QueensLoyaltySystem
  3239. if (version < 29)
  3240. {
  3241. this.m_LevelExp = 1000;
  3242. this.m_Exp = -1000;
  3243. this.m_Level = 0;
  3244. this.m_ExpTitle = "TerMur-guest";
  3245. }
  3246. #endregion
  3247. #region Mondain's Legacy
  3248. if (this.m_Quests == null)
  3249. this.m_Quests = new List<BaseQuest>();
  3250. if (this.m_Chains == null)
  3251. this.m_Chains = new Dictionary<QuestChain, BaseChain>();
  3252. if (this.m_DoneQuests == null)
  3253. this.m_DoneQuests = new List<QuestRestartInfo>();
  3254. if (this.m_Collections == null)
  3255. this.m_Collections = new Dictionary<Collection, int>();
  3256. if (this.m_CollectionTitles == null)
  3257. this.m_CollectionTitles = new List<object>();
  3258. #endregion
  3259. // Professions weren't verified on 1.0 RC0
  3260. if (!CharacterCreation.VerifyProfession(this.m_Profession))
  3261. this.m_Profession = 0;
  3262. if (this.m_PermaFlags == null)
  3263. this.m_PermaFlags = new List<Mobile>();
  3264. if (this.m_JusticeProtectors == null)
  3265. this.m_JusticeProtectors = new List<Mobile>();
  3266. if (this.m_BOBFilter == null)
  3267. this.m_BOBFilter = new Engines.BulkOrders.BOBFilter();
  3268. if (this.m_GuildRank == null)
  3269. this.m_GuildRank = Guilds.RankDefinition.Member; //Default to member if going from older version to new version (only time it should be null)
  3270. if (this.m_LastOnline == DateTime.MinValue && this.Account != null)
  3271. this.m_LastOnline = ((Account)this.Account).LastLogin;
  3272. if (this.m_ChampionTitles == null)
  3273. this.m_ChampionTitles = new ChampionTitleInfo();
  3274. if (this.IsPlayer())
  3275. this.m_IgnoreMobiles = true;
  3276. List<Mobile> list = this.Stabled;
  3277. for (int i = 0; i < list.Count; ++i)
  3278. {
  3279. BaseCreature bc = list[i] as BaseCreature;
  3280. if (bc != null)
  3281. {
  3282. bc.IsStabled = true;
  3283. bc.StabledBy = this;
  3284. }
  3285. }
  3286. CheckAtrophies(this);
  3287. if (this.Hidden) //Hiding is the only buff where it has an effect that's serialized.
  3288. this.AddBuff(new BuffInfo(BuffIcon.HidingAndOrStealth, 1075655));
  3289. }
  3290. public override void Serialize(GenericWriter writer)
  3291. {
  3292. //cleanup our anti-macro table
  3293. foreach (Hashtable t in this.m_AntiMacroTable.Values)
  3294. {
  3295. ArrayList remove = new ArrayList();
  3296. foreach (CountAndTimeStamp time in t.Values)
  3297. {
  3298. if (time.TimeStamp + SkillCheck.AntiMacroExpire <= DateTime.Now)
  3299. remove.Add(time);
  3300. }
  3301. for (int i = 0; i < remove.Count; ++i)
  3302. t.Remove(remove[i]);
  3303. }
  3304. this.CheckKillDecay();
  3305. CheckAtrophies(this);
  3306. base.Serialize(writer);
  3307. writer.Write(29); // version old 28
  3308. // Version 29
  3309. writer.Write(this.m_GauntletPoints);
  3310. #region Plant System
  3311. writer.Write((DateTime)this.m_SSNextSeed);
  3312. writer.Write((DateTime)this.m_SSSeedExpire);
  3313. writer.Write((Point3D)this.m_SSSeedLocation);
  3314. writer.Write((Map)this.m_SSSeedMap);
  3315. #endregion
  3316. #region QueensLoyaltySystem
  3317. writer.Write((long)this.m_LevelExp);
  3318. writer.Write((long)this.m_Exp);
  3319. writer.Write((int)this.m_Level);
  3320. writer.Write((string)this.m_ExpTitle);
  3321. #endregion
  3322. writer.Write(this.m_VASTotalMonsterFame);
  3323. #region Mondain's Legacy
  3324. QuestWriter.Quests(writer, this.m_Quests);
  3325. QuestWriter.Chains(writer, this.m_Chains);
  3326. if (this.m_Collections == null)
  3327. {
  3328. writer.Write((int)0);
  3329. }
  3330. else
  3331. {
  3332. writer.Write((int)this.m_Collections.Count);
  3333. foreach (KeyValuePair<Collection, int> pair in this.m_Collections)
  3334. {
  3335. writer.Write((int)pair.Key);
  3336. writer.Write((int)pair.Value);
  3337. }
  3338. }
  3339. if (this.m_CollectionTitles == null)
  3340. {
  3341. writer.Write((int)0);
  3342. }
  3343. else
  3344. {
  3345. writer.Write((int)this.m_CollectionTitles.Count);
  3346. for (int i = 0; i < this.m_CollectionTitles.Count; i++)
  3347. QuestWriter.Object(writer, this.m_CollectionTitles[i]);
  3348. }
  3349. writer.Write((int)this.m_SelectedTitle);
  3350. #endregion
  3351. // Version 28
  3352. writer.Write((DateTime)this.m_PeacedUntil);
  3353. writer.Write((DateTime)this.m_AnkhNextUse);
  3354. writer.Write(this.m_AutoStabled, true);
  3355. if (this.m_AcquiredRecipes == null)
  3356. {
  3357. writer.Write((int)0);
  3358. }
  3359. else
  3360. {
  3361. writer.Write(this.m_AcquiredRecipes.Count);
  3362. foreach (KeyValuePair<int, bool> kvp in this.m_AcquiredRecipes)
  3363. {
  3364. writer.Write(kvp.Key);
  3365. writer.Write(kvp.Value);
  3366. }
  3367. }
  3368. writer.WriteDeltaTime(this.m_LastHonorLoss);
  3369. ChampionTitleInfo.Serialize(writer, this.m_ChampionTitles);
  3370. writer.Write(this.m_LastValorLoss);
  3371. writer.WriteEncodedInt(this.m_ToTItemsTurnedIn);
  3372. writer.Write(this.m_ToTTotalMonsterFame); //This ain't going to be a small #.
  3373. writer.WriteEncodedInt(this.m_AllianceMessageHue);
  3374. writer.WriteEncodedInt(this.m_GuildMessageHue);
  3375. writer.WriteEncodedInt(this.m_GuildRank.Rank);
  3376. writer.Write(this.m_LastOnline);
  3377. writer.WriteEncodedInt((int)this.m_SolenFriendship);
  3378. QuestSerializer.Serialize(this.m_Quest, writer);
  3379. if (this.m_DoneQuests == null)
  3380. {
  3381. writer.WriteEncodedInt((int)0);
  3382. }
  3383. else
  3384. {
  3385. writer.WriteEncodedInt((int)this.m_DoneQuests.Count);
  3386. for (int i = 0; i < this.m_DoneQuests.Count; ++i)
  3387. {
  3388. QuestRestartInfo restartInfo = this.m_DoneQuests[i];
  3389. QuestSerializer.Write((Type)restartInfo.QuestType, QuestSystem.QuestTypes, writer);
  3390. writer.Write((DateTime)restartInfo.RestartTime);
  3391. }
  3392. }
  3393. writer.WriteEncodedInt((int)this.m_Profession);
  3394. writer.WriteDeltaTime(this.m_LastCompassionLoss);
  3395. writer.WriteEncodedInt(this.m_CompassionGains);
  3396. if (this.m_CompassionGains > 0)
  3397. writer.WriteDeltaTime(this.m_NextCompassionDay);
  3398. this.m_BOBFilter.Serialize(writer);
  3399. bool useMods = (this.m_HairModID != -1 || this.m_BeardModID != -1);
  3400. writer.Write(useMods);
  3401. if (useMods)
  3402. {
  3403. writer.Write((int)this.m_HairModID);
  3404. writer.Write((int)this.m_HairModHue);
  3405. writer.Write((int)this.m_BeardModID);
  3406. writer.Write((int)this.m_BeardModHue);
  3407. }
  3408. writer.Write(this.SavagePaintExpiration);
  3409. writer.Write((int)this.m_NpcGuild);
  3410. writer.Write((DateTime)this.m_NpcGuildJoinTime);
  3411. writer.Write((TimeSpan)this.m_NpcGuildGameTime);
  3412. writer.Write(this.m_PermaFlags, true);
  3413. writer.Write(this.NextTailorBulkOrder);
  3414. writer.Write(this.NextSmithBulkOrder);
  3415. writer.WriteDeltaTime(this.m_LastJusticeLoss);
  3416. writer.Write(this.m_JusticeProtectors, true);
  3417. writer.WriteDeltaTime(this.m_LastSacrificeGain);
  3418. writer.WriteDeltaTime(this.m_LastSacrificeLoss);
  3419. writer.Write(this.m_AvailableResurrects);
  3420. writer.Write((int)this.m_Flags);
  3421. writer.Write(this.m_LongTermElapse);
  3422. writer.Write(this.m_ShortTermElapse);
  3423. writer.Write(this.GameTime);
  3424. }
  3425. public static void CheckAtrophies(Mobile m)
  3426. {
  3427. SacrificeVirtue.CheckAtrophy(m);
  3428. JusticeVirtue.CheckAtrophy(m);
  3429. CompassionVirtue.CheckAtrophy(m);
  3430. ValorVirtue.CheckAtrophy(m);
  3431. if (m is PlayerMobile)
  3432. ChampionTitleInfo.CheckAtrophy((PlayerMobile)m);
  3433. }
  3434. public void CheckKillDecay()
  3435. {
  3436. if (this.m_ShortTermElapse < this.GameTime)
  3437. {
  3438. this.m_ShortTermElapse += TimeSpan.FromHours(8);
  3439. if (this.ShortTermMurders > 0)
  3440. --this.ShortTermMurders;
  3441. }
  3442. if (this.m_LongTermElapse < this.GameTime)
  3443. {
  3444. this.m_LongTermElapse += TimeSpan.FromHours(40);
  3445. if (this.Kills > 0)
  3446. --this.Kills;
  3447. }
  3448. }
  3449. public void ResetKillTime()
  3450. {
  3451. this.m_ShortTermElapse = this.GameTime + TimeSpan.FromHours(8);
  3452. this.m_LongTermElapse = this.GameTime + TimeSpan.FromHours(40);
  3453. }
  3454. [CommandProperty(AccessLevel.GameMaster)]
  3455. public DateTime SessionStart
  3456. {
  3457. get
  3458. {
  3459. return this.m_SessionStart;
  3460. }
  3461. }
  3462. [CommandProperty(AccessLevel.GameMaster)]
  3463. public TimeSpan GameTime
  3464. {
  3465. get
  3466. {
  3467. if (this.NetState != null)
  3468. return this.m_GameTime + (DateTime.Now - this.m_SessionStart);
  3469. else
  3470. return this.m_GameTime;
  3471. }
  3472. }
  3473. public override bool CanSee(Mobile m)
  3474. {
  3475. if (m is CharacterStatue)
  3476. ((CharacterStatue)m).OnRequestedAnimation(this);
  3477. if (m is PlayerMobile && ((PlayerMobile)m).m_VisList.Contains(this))
  3478. return true;
  3479. if (this.m_DuelContext != null && this.m_DuelPlayer != null && !this.m_DuelContext.Finished && this.m_DuelContext.m_Tournament != null && !this.m_DuelPlayer.Eliminated)
  3480. {
  3481. Mobile owner = m;
  3482. if (owner is BaseCreature)
  3483. {
  3484. BaseCreature bc = (BaseCreature)owner;
  3485. Mobile master = bc.GetMaster();
  3486. if (master != null)
  3487. owner = master;
  3488. }
  3489. if (m.IsPlayer() && owner is PlayerMobile && ((PlayerMobile)owner).DuelContext != this.m_DuelContext)
  3490. return false;
  3491. }
  3492. return base.CanSee(m);
  3493. }
  3494. public override bool CanSee(Item item)
  3495. {
  3496. if (this.m_DesignContext != null && this.m_DesignContext.Foundation.IsHiddenToCustomizer(item))
  3497. return false;
  3498. return base.CanSee(item);
  3499. }
  3500. public override void OnAfterDelete()
  3501. {
  3502. base.OnAfterDelete();
  3503. Faction faction = Faction.Find(this);
  3504. if (faction != null)
  3505. faction.RemoveMember(this);
  3506. BaseHouse.HandleDeletion(this);
  3507. DisguiseTimers.RemoveTimer(this);
  3508. }
  3509. public override bool NewGuildDisplay
  3510. {
  3511. get
  3512. {
  3513. return Server.Guilds.Guild.NewGuildSystem;
  3514. }
  3515. }
  3516. public delegate void PlayerPropertiesEventHandler(PlayerPropertiesEventArgs e);
  3517. public static event PlayerPropertiesEventHandler PlayerProperties;
  3518. public override void AddNameProperties(ObjectPropertyList list)
  3519. {
  3520. base.AddNameProperties(list);
  3521. XmlPoints a = (XmlPoints)XmlAttach.FindAttachment(this, typeof(XmlPoints));
  3522. XmlData XmlPointsTitle = (XmlData)XmlAttach.FindAttachment(this, typeof(XmlData), "XmlPointsTitle");
  3523. if ((XmlPointsTitle != null && XmlPointsTitle.Data == "True") || a == null)
  3524. {
  3525. return;
  3526. }
  3527. else if (this.IsPlayer())
  3528. {
  3529. list.Add(1070722, "Kills {0} / Deaths {1} : Rank={2}", a.Kills, a.Deaths, a.Rank);
  3530. }
  3531. }
  3532. public class PlayerPropertiesEventArgs : EventArgs
  3533. {
  3534. public PlayerMobile Player = null;
  3535. public ObjectPropertyList PropertyList = null;
  3536. public PlayerPropertiesEventArgs(PlayerMobile player, ObjectPropertyList list)
  3537. {
  3538. this.Player = player;
  3539. this.PropertyList = list;
  3540. }
  3541. }
  3542. public override void GetProperties(ObjectPropertyList list)
  3543. {
  3544. base.GetProperties(list);
  3545. #region Mondain's Legacy
  3546. if (this.m_CollectionTitles != null && this.m_SelectedTitle > -1)
  3547. {
  3548. if (this.m_SelectedTitle < this.m_CollectionTitles.Count)
  3549. {
  3550. if (this.m_CollectionTitles[this.m_SelectedTitle] is int)
  3551. list.Add((int)this.m_CollectionTitles[this.m_SelectedTitle]);
  3552. else if (this.m_CollectionTitles[this.m_SelectedTitle] is string)
  3553. list.Add(1049644, (string)this.m_CollectionTitles[this.m_SelectedTitle]);
  3554. }
  3555. }
  3556. #endregion
  3557. if (this.Map == Faction.Facet)
  3558. {
  3559. PlayerState pl = PlayerState.Find(this);
  3560. if (pl != null)
  3561. {
  3562. Faction faction = pl.Faction;
  3563. if (faction.Commander == this)
  3564. list.Add(1042733, faction.Definition.PropName); // Commanding Lord of the ~1_FACTION_NAME~
  3565. else if (pl.Sheriff != null)
  3566. list.Add(1042734, "{0}\t{1}", pl.Sheriff.Definition.FriendlyName, faction.Definition.PropName); // The Sheriff of ~1_CITY~, ~2_FACTION_NAME~
  3567. else if (pl.Finance != null)
  3568. list.Add(1042735, "{0}\t{1}", pl.Finance.Definition.FriendlyName, faction.Definition.PropName); // The Finance Minister of ~1_CITY~, ~2_FACTION_NAME~
  3569. else if (pl.MerchantTitle != MerchantTitle.None)
  3570. list.Add(1060776, "{0}\t{1}", MerchantTitles.GetInfo(pl.MerchantTitle).Title, faction.Definition.PropName); // ~1_val~, ~2_val~
  3571. else
  3572. list.Add(1060776, "{0}\t{1}", pl.Rank.Title, faction.Definition.PropName); // ~1_val~, ~2_val~
  3573. }
  3574. }
  3575. if (Core.ML)
  3576. {
  3577. for (int i = this.AllFollowers.Count - 1; i >= 0; i--)
  3578. {
  3579. BaseCreature c = this.AllFollowers[i] as BaseCreature;
  3580. if (c != null && c.ControlOrder == OrderType.Guard)
  3581. {
  3582. list.Add(501129); // guarded
  3583. break;
  3584. }
  3585. }
  3586. }
  3587. if (this.IsPlayer())
  3588. {
  3589. #region QueensLoyaltySystem
  3590. if (this.m_Exp >= this.m_LevelExp)
  3591. {
  3592. while (this.m_Exp >= this.m_LevelExp)
  3593. {
  3594. this.m_Exp -= this.m_LevelExp;
  3595. this.m_Level += 1;
  3596. this.m_LevelExp = (long)(1000 * (Math.Pow(1.4, this.m_Level)));
  3597. }
  3598. }
  3599. if (this.m_Exp < 0)
  3600. {
  3601. while (this.m_Exp < 0)
  3602. {
  3603. if (this.m_Level == 0)
  3604. this.m_Exp = 0;
  3605. else
  3606. {
  3607. this.m_LevelExp = (long)(1000 * (Math.Pow(1.4, this.m_Level - 1)));
  3608. this.m_Exp += (long)(this.m_LevelExp);
  3609. this.m_Level -= 1;
  3610. }
  3611. }
  3612. }
  3613. this.m_LevelExp = (long)(1000 * (Math.Pow(1.4, this.m_Level)));
  3614. if (this.m_Level == 0)
  3615. this.m_ExpTitle = "TerMur-guest";
  3616. else if (this.m_Level >= 1 && this.m_Level <= 5)
  3617. this.m_ExpTitle = "Friend of TerMur";
  3618. else if (this.m_Level >= 6 && this.m_Level <= 10)
  3619. this.m_ExpTitle = "Friend of TerMur";
  3620. else if (this.m_Level >= 11 && this.m_Level <= 15)
  3621. this.m_ExpTitle = "Friend of TerMur";
  3622. else if (this.m_Level >= 16 && this.m_Level <= 20)
  3623. this.m_ExpTitle = "Friend of TerMur";
  3624. else if (this.m_Level >= 21 && this.m_Level <= 25)
  3625. this.m_ExpTitle = "Friend of TerMur";
  3626. else if (this.m_Level >= 26 && this.m_Level <= 30)
  3627. this.m_ExpTitle = "A Citizen of TerMur";
  3628. else if (this.m_Level >= 31 && this.m_Level <= 35)
  3629. this.m_ExpTitle = "A Citizen of TerMur";
  3630. else if (this.m_Level >= 36 && this.m_Level <= 40)
  3631. this.m_ExpTitle = "A Citizen of TerMur";
  3632. else if (this.m_Level >= 41 && this.m_Level <= 45)
  3633. this.m_ExpTitle = "A Citizen of TerMur";
  3634. else if (this.m_Level >= 46 && this.m_Level <= 50)
  3635. this.m_ExpTitle = "A Citizen of TerMur";
  3636. else if (this.m_Level >= 51 && this.m_Level <= 60)
  3637. this.m_ExpTitle = "A Citizen of TerMur";
  3638. else if (this.m_Level >= 61 && this.m_Level <= 70)
  3639. this.m_ExpTitle = "A Noble of Termur";
  3640. else if (this.m_Level >= 71 && this.m_Level <= 80)
  3641. this.m_ExpTitle = "A Noble of Termur";
  3642. else if (this.m_Level >= 80 && this.m_Level <= 100)
  3643. this.m_ExpTitle = "A Noble of Termur";
  3644. else if (this.m_Level >= 101)
  3645. this.m_ExpTitle = "A Noble of Termur";
  3646. // Xml spawner 3.26c QueensLoyaltyTitle
  3647. XmlData QueenTitle = (XmlData)XmlAttach.FindAttachment(this, typeof(XmlData), "QueenTitle");
  3648. if (QueenTitle != null && QueenTitle.Data == "True")
  3649. {
  3650. return;
  3651. }
  3652. else
  3653. {
  3654. list.Add(String.Concat("Queens Loyalty Level: ", String.Format("<BASEFONT COLOR={0}>{1}", "#FF0000", this.m_Level), " ", String.Format("<BASEFONT COLOR={0}>{1}", "#000FFF", (int)(100 * this.m_Exp / this.m_LevelExp)), " % ", String.Format("<BASEFONT COLOR={0}>{1}", "#0FFF00", this.m_ExpTitle)));
  3655. this.InvalidateMyRunUO();
  3656. }
  3657. // Xml Spawner 3.26c QueensLoyaltyTitle
  3658. #endregion
  3659. }
  3660. if (this.AccessLevel > AccessLevel.Player)
  3661. {
  3662. string color = "";
  3663. switch (this.AccessLevel)
  3664. {
  3665. case AccessLevel.VIP:
  3666. color = "#1EFF00";
  3667. break;
  3668. case AccessLevel.Counselor:
  3669. color = "#00BFFF";
  3670. break; //Deep Sky Blue
  3671. case AccessLevel.Decorator:
  3672. color = "#FF8000";
  3673. break;
  3674. case AccessLevel.Spawner:
  3675. color = "#E6CC80";
  3676. break;
  3677. case AccessLevel.GameMaster:
  3678. color = "#FF0000";
  3679. break; //Red
  3680. case AccessLevel.Seer:
  3681. color = "#00FF00";
  3682. break; //Green
  3683. case AccessLevel.Administrator:
  3684. color = "#0070FF";
  3685. break;
  3686. case AccessLevel.Developer:
  3687. color = "#A335EE";
  3688. break;
  3689. case AccessLevel.CoOwner:
  3690. color = "#FFD700";
  3691. break;
  3692. case AccessLevel.Owner:
  3693. color = "#FFD700";
  3694. break;
  3695. }
  3696. if (this.IsStaff())
  3697. list.Add(1060658, "{0}\t{1}", "Staff", String.Format("<BASEFONT COLOR={0}>{1}", color, GetAccessLevelName(this.AccessLevel)));
  3698. else
  3699. list.Add(1060658, "VIP");
  3700. }
  3701. if (PlayerProperties != null)
  3702. PlayerProperties(new PlayerPropertiesEventArgs(this, list));
  3703. }
  3704. public override void OnSingleClick(Mobile from)
  3705. {
  3706. if (this.Map == Faction.Facet)
  3707. {
  3708. PlayerState pl = PlayerState.Find(this);
  3709. if (pl != null)
  3710. {
  3711. string text;
  3712. bool ascii = false;
  3713. Faction faction = pl.Faction;
  3714. if (faction.Commander == this)
  3715. text = String.Concat(this.Female ? "(Commanding Lady of the " : "(Commanding Lord of the ", faction.Definition.FriendlyName, ")");
  3716. else if (pl.Sheriff != null)
  3717. text = String.Concat("(The Sheriff of ", pl.Sheriff.Definition.FriendlyName, ", ", faction.Definition.FriendlyName, ")");
  3718. else if (pl.Finance != null)
  3719. text = String.Concat("(The Finance Minister of ", pl.Finance.Definition.FriendlyName, ", ", faction.Definition.FriendlyName, ")");
  3720. else
  3721. {
  3722. ascii = true;
  3723. if (pl.MerchantTitle != MerchantTitle.None)
  3724. text = String.Concat("(", MerchantTitles.GetInfo(pl.MerchantTitle).Title.String, ", ", faction.Definition.FriendlyName, ")");
  3725. else
  3726. text = String.Concat("(", pl.Rank.Title.String, ", ", faction.Definition.FriendlyName, ")");
  3727. }
  3728. int hue = (Faction.Find(from) == faction ? 98 : 38);
  3729. this.PrivateOverheadMessage(MessageType.Label, hue, ascii, text, from.NetState);
  3730. }
  3731. }
  3732. base.OnSingleClick(from);
  3733. }
  3734. protected override bool OnMove(Direction d)
  3735. {
  3736. if (!Core.SE)
  3737. return base.OnMove(d);
  3738. if (this.IsStaff())
  3739. return true;
  3740. if (this.Hidden && DesignContext.Find(this) == null) //Hidden & NOT customizing a house
  3741. {
  3742. if (!this.Mounted && this.Skills.Stealth.Value >= 25.0)
  3743. {
  3744. bool running = (d & Direction.Running) != 0;
  3745. if (running)
  3746. {
  3747. if ((this.AllowedStealthSteps -= 2) <= 0)
  3748. this.RevealingAction();
  3749. }
  3750. else if (this.AllowedStealthSteps-- <= 0)
  3751. {
  3752. Server.SkillHandlers.Stealth.OnUse(this);
  3753. }
  3754. }
  3755. else
  3756. {
  3757. this.RevealingAction();
  3758. }
  3759. }
  3760. #region Mondain's Legacy
  3761. if (InvisibilityPotion.HasTimer(this))
  3762. InvisibilityPotion.Iterrupt(this);
  3763. #endregion
  3764. return true;
  3765. }
  3766. private bool m_BedrollLogout;
  3767. public bool BedrollLogout
  3768. {
  3769. get
  3770. {
  3771. return this.m_BedrollLogout;
  3772. }
  3773. set
  3774. {
  3775. this.m_BedrollLogout = value;
  3776. }
  3777. }
  3778. [CommandProperty(AccessLevel.GameMaster)]
  3779. public override bool Paralyzed
  3780. {
  3781. get
  3782. {
  3783. return base.Paralyzed;
  3784. }
  3785. set
  3786. {
  3787. base.Paralyzed = value;
  3788. if (value)
  3789. this.AddBuff(new BuffInfo(BuffIcon.Paralyze, 1075827)); //Paralyze/You are frozen and can not move
  3790. else
  3791. this.RemoveBuff(BuffIcon.Paralyze);
  3792. }
  3793. }
  3794. #region Mysticism
  3795. [CommandProperty(AccessLevel.GameMaster)]
  3796. public override bool Asleep
  3797. {
  3798. get
  3799. {
  3800. return base.Asleep;
  3801. }
  3802. set
  3803. {
  3804. base.Asleep = value;
  3805. if (value)
  3806. this.AddBuff(new BuffInfo(BuffIcon.Sleep, 1080139)); //Paralyze/You are frozen and can not move
  3807. else
  3808. this.RemoveBuff(BuffIcon.Sleep);
  3809. }
  3810. }
  3811. #endregion
  3812. #region Ethics
  3813. private Ethics.Player m_EthicPlayer;
  3814. [CommandProperty(AccessLevel.GameMaster)]
  3815. public Ethics.Player EthicPlayer
  3816. {
  3817. get
  3818. {
  3819. return this.m_EthicPlayer;
  3820. }
  3821. set
  3822. {
  3823. this.m_EthicPlayer = value;
  3824. }
  3825. }
  3826. #endregion
  3827. #region Factions
  3828. private PlayerState m_FactionPlayerState;
  3829. public PlayerState FactionPlayerState
  3830. {
  3831. get
  3832. {
  3833. return this.m_FactionPlayerState;
  3834. }
  3835. set
  3836. {
  3837. this.m_FactionPlayerState = value;
  3838. }
  3839. }
  3840. #endregion
  3841. #region Dueling
  3842. private Engines.ConPVP.DuelContext m_DuelContext;
  3843. private Engines.ConPVP.DuelPlayer m_DuelPlayer;
  3844. public Engines.ConPVP.DuelContext DuelContext
  3845. {
  3846. get
  3847. {
  3848. return this.m_DuelContext;
  3849. }
  3850. }
  3851. public Engines.ConPVP.DuelPlayer DuelPlayer
  3852. {
  3853. get
  3854. {
  3855. return this.m_DuelPlayer;
  3856. }
  3857. set
  3858. {
  3859. bool wasInTourny = (this.m_DuelContext != null && !this.m_DuelContext.Finished && this.m_DuelContext.m_Tournament != null);
  3860. this.m_DuelPlayer = value;
  3861. if (this.m_DuelPlayer == null)
  3862. this.m_DuelContext = null;
  3863. else
  3864. this.m_DuelContext = this.m_DuelPlayer.Participant.Context;
  3865. bool isInTourny = (this.m_DuelContext != null && !this.m_DuelContext.Finished && this.m_DuelContext.m_Tournament != null);
  3866. if (wasInTourny != isInTourny)
  3867. this.SendEverything();
  3868. }
  3869. }
  3870. #endregion
  3871. #region Quests
  3872. private QuestSystem m_Quest;
  3873. private List<QuestRestartInfo> m_DoneQuests;
  3874. private SolenFriendship m_SolenFriendship;
  3875. public QuestSystem Quest
  3876. {
  3877. get
  3878. {
  3879. return this.m_Quest;
  3880. }
  3881. set
  3882. {
  3883. this.m_Quest = value;
  3884. }
  3885. }
  3886. public List<QuestRestartInfo> DoneQuests
  3887. {
  3888. get
  3889. {
  3890. return this.m_DoneQuests;
  3891. }
  3892. set
  3893. {
  3894. this.m_DoneQuests = value;
  3895. }
  3896. }
  3897. [CommandProperty(AccessLevel.GameMaster)]
  3898. public SolenFriendship SolenFriendship
  3899. {
  3900. get
  3901. {
  3902. return this.m_SolenFriendship;
  3903. }
  3904. set
  3905. {
  3906. this.m_SolenFriendship = value;
  3907. }
  3908. }
  3909. #endregion
  3910. #region Mondain's Legacy
  3911. private List<BaseQuest> m_Quests;
  3912. private Dictionary<QuestChain, BaseChain> m_Chains;
  3913. public List<BaseQuest> Quests
  3914. {
  3915. get
  3916. {
  3917. return this.m_Quests;
  3918. }
  3919. }
  3920. public Dictionary<QuestChain, BaseChain> Chains
  3921. {
  3922. get
  3923. {
  3924. return this.m_Chains;
  3925. }
  3926. }
  3927. [CommandProperty(AccessLevel.GameMaster)]
  3928. public bool Peaced
  3929. {
  3930. get
  3931. {
  3932. if (this.m_PeacedUntil > DateTime.Now)
  3933. return true;
  3934. return false;
  3935. }
  3936. }
  3937. private Dictionary<Collection, int> m_Collections;
  3938. private List<object> m_CollectionTitles;
  3939. private int m_SelectedTitle;
  3940. public Dictionary<Collection, int> Collections
  3941. {
  3942. get
  3943. {
  3944. return this.m_Collections;
  3945. }
  3946. }
  3947. public List<object> CollectionTitles
  3948. {
  3949. get
  3950. {
  3951. return this.m_CollectionTitles;
  3952. }
  3953. }
  3954. public int GetCollectionPoints(Collection collection)
  3955. {
  3956. if (this.m_Collections == null)
  3957. this.m_Collections = new Dictionary<Collection, int>();
  3958. int points = 0;
  3959. if (this.m_Collections.ContainsKey(collection))
  3960. this.m_Collections.TryGetValue(collection, out points);
  3961. return points;
  3962. }
  3963. public void AddCollectionPoints(Collection collection, int points)
  3964. {
  3965. if (this.m_Collections == null)
  3966. this.m_Collections = new Dictionary<Collection, int>();
  3967. if (this.m_Collections.ContainsKey(collection))
  3968. this.m_Collections[collection] += points;
  3969. else
  3970. this.m_Collections.Add(collection, points);
  3971. }
  3972. public void SelectCollectionTitle(int num)
  3973. {
  3974. if (num == -1)
  3975. {
  3976. this.m_SelectedTitle = num;
  3977. this.SendLocalizedMessage(1074010); // You elect to hide your Reward Title.
  3978. }
  3979. else if (num < this.m_CollectionTitles.Count && num >= -1)
  3980. {
  3981. if (this.m_SelectedTitle != num)
  3982. {
  3983. this.m_SelectedTitle = num;
  3984. if (this.m_CollectionTitles[num] is int)
  3985. this.SendLocalizedMessage(1074008, "#" + (int)this.m_CollectionTitles[num]); // You change your Reward Title to "~1_TITLE~".
  3986. else if (this.m_CollectionTitles[num] is string)
  3987. this.SendLocalizedMessage(1074008, (string)this.m_CollectionTitles[num]); // You change your Reward Title to "~1_TITLE~".
  3988. }
  3989. else
  3990. this.SendLocalizedMessage(1074009); // You decide to leave your title as it is.
  3991. }
  3992. this.InvalidateProperties();
  3993. }
  3994. public bool AddCollectionTitle(object title)
  3995. {
  3996. if (this.m_CollectionTitles == null)
  3997. this.m_CollectionTitles = new List<object>();
  3998. if (title != null && !this.m_CollectionTitles.Contains(title))
  3999. {
  4000. this.m_CollectionTitles.Add(title);
  4001. this.m_SelectedTitle = this.m_CollectionTitles.Count - 1;
  4002. this.InvalidateProperties();
  4003. return true;
  4004. }
  4005. return false;
  4006. }
  4007. public void ShowChangeTitle()
  4008. {
  4009. this.SendGump(new SelectTitleGump(this, this.m_SelectedTitle));
  4010. }
  4011. #endregion
  4012. #region MyRunUO Invalidation
  4013. private bool m_ChangedMyRunUO;
  4014. public bool ChangedMyRunUO
  4015. {
  4016. get
  4017. {
  4018. return this.m_ChangedMyRunUO;
  4019. }
  4020. set
  4021. {
  4022. this.m_ChangedMyRunUO = value;
  4023. }
  4024. }
  4025. public void InvalidateMyRunUO()
  4026. {
  4027. if (!this.Deleted && !this.m_ChangedMyRunUO)
  4028. {
  4029. this.m_ChangedMyRunUO = true;
  4030. Engines.MyRunUO.MyRunUO.QueueMobileUpdate(this);
  4031. }
  4032. }
  4033. public override void OnKillsChange(int oldValue)
  4034. {
  4035. if (this.Young && this.Kills > oldValue)
  4036. {
  4037. Account acc = this.Account as Account;
  4038. if (acc != null)
  4039. acc.RemoveYoungStatus(0);
  4040. }
  4041. this.InvalidateMyRunUO();
  4042. }
  4043. public override void OnGenderChanged(bool oldFemale)
  4044. {
  4045. this.InvalidateMyRunUO();
  4046. }
  4047. public override void OnGuildChange(Server.Guilds.BaseGuild oldGuild)
  4048. {
  4049. this.InvalidateMyRunUO();
  4050. }
  4051. public override void OnGuildTitleChange(string oldTitle)
  4052. {
  4053. this.InvalidateMyRunUO();
  4054. }
  4055. public override void OnKarmaChange(int oldValue)
  4056. {
  4057. this.InvalidateMyRunUO();
  4058. }
  4059. public override void OnFameChange(int oldValue)
  4060. {
  4061. this.InvalidateMyRunUO();
  4062. }
  4063. public override void OnSkillChange(SkillName skill, double oldBase)
  4064. {
  4065. if (this.Young && this.SkillsTotal >= 4500)
  4066. {
  4067. Account acc = this.Account as Account;
  4068. if (acc != null)
  4069. acc.RemoveYoungStatus(1019036); // You have successfully obtained a respectable skill level, and have outgrown your status as a young player!
  4070. }
  4071. this.InvalidateMyRunUO();
  4072. }
  4073. public override void OnAccessLevelChanged(AccessLevel oldLevel)
  4074. {
  4075. if (this.IsPlayer())
  4076. this.IgnoreMobiles = false;
  4077. else
  4078. this.IgnoreMobiles = true;
  4079. this.InvalidateMyRunUO();
  4080. }
  4081. public override void OnRawStatChange(StatType stat, int oldValue)
  4082. {
  4083. this.InvalidateMyRunUO();
  4084. }
  4085. public override void OnDelete()
  4086. {
  4087. if (this.m_ReceivedHonorContext != null)
  4088. this.m_ReceivedHonorContext.Cancel();
  4089. if (this.m_SentHonorContext != null)
  4090. this.m_SentHonorContext.Cancel();
  4091. this.InvalidateMyRunUO();
  4092. }
  4093. #endregion
  4094. #region Fastwalk Prevention
  4095. private static bool FastwalkPrevention = true; // Is fastwalk prevention enabled?
  4096. private static TimeSpan FastwalkThreshold = TimeSpan.FromSeconds(0.4); // Fastwalk prevention will become active after 0.4 seconds
  4097. private DateTime m_NextMovementTime;
  4098. public virtual bool UsesFastwalkPrevention
  4099. {
  4100. get
  4101. {
  4102. return (this.IsPlayer()) & !this.Flying;
  4103. }
  4104. }
  4105. public override TimeSpan ComputeMovementSpeed(Direction dir, bool checkTurning)
  4106. {
  4107. if (checkTurning && (dir & Direction.Mask) != (this.Direction & Direction.Mask))
  4108. return Mobile.RunMount; // We are NOT actually moving (just a direction change)
  4109. TransformContext context = TransformationSpellHelper.GetContext(this);
  4110. if (context != null && context.Type == typeof(ReaperFormSpell))
  4111. return Mobile.WalkFoot;
  4112. bool running = ((dir & Direction.Running) != 0);
  4113. bool onHorse = (this.Mount != null);
  4114. AnimalFormContext animalContext = AnimalForm.GetContext(this);
  4115. if (onHorse || (animalContext != null && animalContext.SpeedBoost))
  4116. return (running ? Mobile.RunMount : Mobile.WalkMount);
  4117. return (running ? Mobile.RunFoot : Mobile.WalkFoot);
  4118. }
  4119. public static bool MovementThrottle_Callback(NetState ns)
  4120. {
  4121. PlayerMobile pm = ns.Mobile as PlayerMobile;
  4122. if (pm == null || !pm.UsesFastwalkPrevention)
  4123. return true;
  4124. if (pm.m_NextMovementTime == DateTime.MinValue)
  4125. {
  4126. // has not yet moved
  4127. pm.m_NextMovementTime = DateTime.Now;
  4128. return true;
  4129. }
  4130. TimeSpan ts = pm.m_NextMovementTime - DateTime.Now;
  4131. if (ts < TimeSpan.Zero)
  4132. {
  4133. // been a while since we've last moved
  4134. pm.m_NextMovementTime = DateTime.Now;
  4135. return true;
  4136. }
  4137. return (ts < FastwalkThreshold);
  4138. }
  4139. #endregion
  4140. #region Enemy of One
  4141. private Type m_EnemyOfOneType;
  4142. private bool m_WaitingForEnemy;
  4143. public Type EnemyOfOneType
  4144. {
  4145. get
  4146. {
  4147. return this.m_EnemyOfOneType;
  4148. }
  4149. set
  4150. {
  4151. Type oldType = this.m_EnemyOfOneType;
  4152. Type newType = value;
  4153. if (oldType == newType)
  4154. return;
  4155. this.m_EnemyOfOneType = value;
  4156. this.DeltaEnemies(oldType, newType);
  4157. }
  4158. }
  4159. public bool WaitingForEnemy
  4160. {
  4161. get
  4162. {
  4163. return this.m_WaitingForEnemy;
  4164. }
  4165. set
  4166. {
  4167. this.m_WaitingForEnemy = value;
  4168. }
  4169. }
  4170. private void DeltaEnemies(Type oldType, Type newType)
  4171. {
  4172. foreach (Mobile m in this.GetMobilesInRange(18))
  4173. {
  4174. Type t = m.GetType();
  4175. if (t == oldType || t == newType)
  4176. {
  4177. NetState ns = this.NetState;
  4178. if (ns != null)
  4179. {
  4180. if (ns.StygianAbyss)
  4181. {
  4182. ns.Send(new MobileMoving(m, Notoriety.Compute(this, m)));
  4183. }
  4184. else
  4185. {
  4186. ns.Send(new MobileMovingOld(m, Notoriety.Compute(this, m)));
  4187. }
  4188. }
  4189. }
  4190. }
  4191. }
  4192. #endregion
  4193. #region Hair and beard mods
  4194. private int m_HairModID = -1, m_HairModHue;
  4195. private int m_BeardModID = -1, m_BeardModHue;
  4196. public void SetHairMods(int hairID, int beardID)
  4197. {
  4198. if (hairID == -1)
  4199. this.InternalRestoreHair(true, ref this.m_HairModID, ref this.m_HairModHue);
  4200. else if (hairID != -2)
  4201. this.InternalChangeHair(true, hairID, ref this.m_HairModID, ref this.m_HairModHue);
  4202. if (beardID == -1)
  4203. this.InternalRestoreHair(false, ref this.m_BeardModID, ref this.m_BeardModHue);
  4204. else if (beardID != -2)
  4205. this.InternalChangeHair(false, beardID, ref this.m_BeardModID, ref this.m_BeardModHue);
  4206. }
  4207. private void CreateHair(bool hair, int id, int hue)
  4208. {
  4209. if (hair)
  4210. {
  4211. //TODO Verification?
  4212. this.HairItemID = id;
  4213. this.HairHue = hue;
  4214. }
  4215. else
  4216. {
  4217. this.FacialHairItemID = id;
  4218. this.FacialHairHue = hue;
  4219. }
  4220. }
  4221. private void InternalRestoreHair(bool hair, ref int id, ref int hue)
  4222. {
  4223. if (id == -1)
  4224. return;
  4225. if (hair)
  4226. this.HairItemID = 0;
  4227. else
  4228. this.FacialHairItemID = 0;
  4229. //if( id != 0 )
  4230. this.CreateHair(hair, id, hue);
  4231. id = -1;
  4232. hue = 0;
  4233. }
  4234. private void InternalChangeHair(bool hair, int id, ref int storeID, ref int storeHue)
  4235. {
  4236. if (storeID == -1)
  4237. {
  4238. storeID = hair ? this.HairItemID : this.FacialHairItemID;
  4239. storeHue = hair ? this.HairHue : this.FacialHairHue;
  4240. }
  4241. this.CreateHair(hair, id, 0);
  4242. }
  4243. #endregion
  4244. #region Virtues
  4245. private DateTime m_LastSacrificeGain;
  4246. private DateTime m_LastSacrificeLoss;
  4247. private int m_AvailableResurrects;
  4248. public DateTime LastSacrificeGain
  4249. {
  4250. get
  4251. {
  4252. return this.m_LastSacrificeGain;
  4253. }
  4254. set
  4255. {
  4256. this.m_LastSacrificeGain = value;
  4257. }
  4258. }
  4259. public DateTime LastSacrificeLoss
  4260. {
  4261. get
  4262. {
  4263. return this.m_LastSacrificeLoss;
  4264. }
  4265. set
  4266. {
  4267. this.m_LastSacrificeLoss = value;
  4268. }
  4269. }
  4270. [CommandProperty(AccessLevel.GameMaster)]
  4271. public int AvailableResurrects
  4272. {
  4273. get
  4274. {
  4275. return this.m_AvailableResurrects;
  4276. }
  4277. set
  4278. {
  4279. this.m_AvailableResurrects = value;
  4280. }
  4281. }
  4282. private DateTime m_NextJustAward;
  4283. private DateTime m_LastJusticeLoss;
  4284. private List<Mobile> m_JusticeProtectors;
  4285. public DateTime LastJusticeLoss
  4286. {
  4287. get
  4288. {
  4289. return this.m_LastJusticeLoss;
  4290. }
  4291. set
  4292. {
  4293. this.m_LastJusticeLoss = value;
  4294. }
  4295. }
  4296. public List<Mobile> JusticeProtectors
  4297. {
  4298. get
  4299. {
  4300. return this.m_JusticeProtectors;
  4301. }
  4302. set
  4303. {
  4304. this.m_JusticeProtectors = value;
  4305. }
  4306. }
  4307. private DateTime m_LastCompassionLoss;
  4308. private DateTime m_NextCompassionDay;
  4309. private int m_CompassionGains;
  4310. public DateTime LastCompassionLoss
  4311. {
  4312. get
  4313. {
  4314. return this.m_LastCompassionLoss;
  4315. }
  4316. set
  4317. {
  4318. this.m_LastCompassionLoss = value;
  4319. }
  4320. }
  4321. public DateTime NextCompassionDay
  4322. {
  4323. get
  4324. {
  4325. return this.m_NextCompassionDay;
  4326. }
  4327. set
  4328. {
  4329. this.m_NextCompassionDay = value;
  4330. }
  4331. }
  4332. public int CompassionGains
  4333. {
  4334. get
  4335. {
  4336. return this.m_CompassionGains;
  4337. }
  4338. set
  4339. {
  4340. this.m_CompassionGains = value;
  4341. }
  4342. }
  4343. private DateTime m_LastValorLoss;
  4344. public DateTime LastValorLoss
  4345. {
  4346. get
  4347. {
  4348. return this.m_LastValorLoss;
  4349. }
  4350. set
  4351. {
  4352. this.m_LastValorLoss = value;
  4353. }
  4354. }
  4355. private DateTime m_LastHonorLoss;
  4356. private DateTime m_LastHonorUse;
  4357. private bool m_HonorActive;
  4358. private HonorContext m_ReceivedHonorContext;
  4359. private HonorContext m_SentHonorContext;
  4360. public DateTime m_hontime;
  4361. public DateTime LastHonorLoss
  4362. {
  4363. get
  4364. {
  4365. return this.m_LastHonorLoss;
  4366. }
  4367. set
  4368. {
  4369. this.m_LastHonorLoss = value;
  4370. }
  4371. }
  4372. public DateTime LastHonorUse
  4373. {
  4374. get
  4375. {
  4376. return this.m_LastHonorUse;
  4377. }
  4378. set
  4379. {
  4380. this.m_LastHonorUse = value;
  4381. }
  4382. }
  4383. public bool HonorActive
  4384. {
  4385. get
  4386. {
  4387. return this.m_HonorActive;
  4388. }
  4389. set
  4390. {
  4391. this.m_HonorActive = value;
  4392. }
  4393. }
  4394. public HonorContext ReceivedHonorContext
  4395. {
  4396. get
  4397. {
  4398. return this.m_ReceivedHonorContext;
  4399. }
  4400. set
  4401. {
  4402. this.m_ReceivedHonorContext = value;
  4403. }
  4404. }
  4405. public HonorContext SentHonorContext
  4406. {
  4407. get
  4408. {
  4409. return this.m_SentHonorContext;
  4410. }
  4411. set
  4412. {
  4413. this.m_SentHonorContext = value;
  4414. }
  4415. }
  4416. #endregion
  4417. #region Young system
  4418. [CommandProperty(AccessLevel.GameMaster)]
  4419. public bool Young
  4420. {
  4421. get
  4422. {
  4423. return this.GetFlag(PlayerFlag.Young);
  4424. }
  4425. set
  4426. {
  4427. this.SetFlag(PlayerFlag.Young, value);
  4428. this.InvalidateProperties();
  4429. }
  4430. }
  4431. public override string ApplyNameSuffix(string suffix)
  4432. {
  4433. if (this.Young)
  4434. {
  4435. if (suffix.Length == 0)
  4436. suffix = "(Young)";
  4437. else
  4438. suffix = String.Concat(suffix, " (Young)");
  4439. }
  4440. #region Ethics
  4441. if (this.m_EthicPlayer != null)
  4442. {
  4443. if (suffix.Length == 0)
  4444. suffix = this.m_EthicPlayer.Ethic.Definition.Adjunct.String;
  4445. else
  4446. suffix = String.Concat(suffix, " ", this.m_EthicPlayer.Ethic.Definition.Adjunct.String);
  4447. }
  4448. #endregion
  4449. if (Core.ML && this.Map == Faction.Facet)
  4450. {
  4451. Faction faction = Faction.Find(this);
  4452. if (faction != null)
  4453. {
  4454. string adjunct = String.Format("[{0}]", faction.Definition.Abbreviation);
  4455. if (suffix.Length == 0)
  4456. suffix = adjunct;
  4457. else
  4458. suffix = String.Concat(suffix, " ", adjunct);
  4459. }
  4460. }
  4461. return base.ApplyNameSuffix(suffix);
  4462. }
  4463. public override TimeSpan GetLogoutDelay()
  4464. {
  4465. if (this.Young || this.BedrollLogout || TestCenter.Enabled)
  4466. return TimeSpan.Zero;
  4467. return base.GetLogoutDelay();
  4468. }
  4469. private DateTime m_LastYoungMessage = DateTime.MinValue;
  4470. public bool CheckYoungProtection(Mobile from)
  4471. {
  4472. if (!this.Young)
  4473. return false;
  4474. if (this.Region is BaseRegion && !((BaseRegion)this.Region).YoungProtected)
  4475. return false;
  4476. if (from is BaseCreature && ((BaseCreature)from).IgnoreYoungProtection)
  4477. return false;
  4478. if (this.Quest != null && this.Quest.IgnoreYoungProtection(from))
  4479. return false;
  4480. if (DateTime.Now - this.m_LastYoungMessage > TimeSpan.FromMinutes(1.0))
  4481. {
  4482. this.m_LastYoungMessage = DateTime.Now;
  4483. this.SendLocalizedMessage(1019067); // A monster looks at you menacingly but does not attack. You would be under attack now if not for your status as a new citizen of Britannia.
  4484. }
  4485. return true;
  4486. }
  4487. private DateTime m_LastYoungHeal = DateTime.MinValue;
  4488. public bool CheckYoungHealTime()
  4489. {
  4490. if (DateTime.Now - this.m_LastYoungHeal > TimeSpan.FromMinutes(5.0))
  4491. {
  4492. this.m_LastYoungHeal = DateTime.Now;
  4493. return true;
  4494. }
  4495. return false;
  4496. }
  4497. private static Point3D[] m_TrammelDeathDestinations = new Point3D[]
  4498. {
  4499. new Point3D(1481, 1612, 20),
  4500. new Point3D(2708, 2153, 0),
  4501. new Point3D(2249, 1230, 0),
  4502. new Point3D(5197, 3994, 37),
  4503. new Point3D(1412, 3793, 0),
  4504. new Point3D(3688, 2232, 20),
  4505. new Point3D(2578, 604, 0),
  4506. new Point3D(4397, 1089, 0),
  4507. new Point3D(5741, 3218, -2),
  4508. new Point3D(2996, 3441, 15),
  4509. new Point3D(624, 2225, 0),
  4510. new Point3D(1916, 2814, 0),
  4511. new Point3D(2929, 854, 0),
  4512. new Point3D(545, 967, 0),
  4513. new Point3D(3665, 2587, 0)
  4514. };
  4515. private static Point3D[] m_IlshenarDeathDestinations = new Point3D[]
  4516. {
  4517. new Point3D(1216, 468, -13),
  4518. new Point3D(723, 1367, -60),
  4519. new Point3D(745, 725, -28),
  4520. new Point3D(281, 1017, 0),
  4521. new Point3D(986, 1011, -32),
  4522. new Point3D(1175, 1287, -30),
  4523. new Point3D(1533, 1341, -3),
  4524. new Point3D(529, 217, -44),
  4525. new Point3D(1722, 219, 96)
  4526. };
  4527. private static Point3D[] m_MalasDeathDestinations = new Point3D[]
  4528. {
  4529. new Point3D(2079, 1376, -70),
  4530. new Point3D(944, 519, -71)
  4531. };
  4532. private static Point3D[] m_TokunoDeathDestinations = new Point3D[]
  4533. {
  4534. new Point3D(1166, 801, 27),
  4535. new Point3D(782, 1228, 25),
  4536. new Point3D(268, 624, 15)
  4537. };
  4538. public bool YoungDeathTeleport()
  4539. {
  4540. if (this.Region.IsPartOf(typeof(Jail)) ||
  4541. this.Region.IsPartOf("Samurai start location") ||
  4542. this.Region.IsPartOf("Ninja start location") ||
  4543. this.Region.IsPartOf("Ninja cave"))
  4544. return false;
  4545. Point3D loc;
  4546. Map map;
  4547. DungeonRegion dungeon = (DungeonRegion)this.Region.GetRegion(typeof(DungeonRegion));
  4548. if (dungeon != null && dungeon.EntranceLocation != Point3D.Zero)
  4549. {
  4550. loc = dungeon.EntranceLocation;
  4551. map = dungeon.EntranceMap;
  4552. }
  4553. else
  4554. {
  4555. loc = this.Location;
  4556. map = this.Map;
  4557. }
  4558. Point3D[] list;
  4559. if (map == Map.Trammel)
  4560. list = m_TrammelDeathDestinations;
  4561. else if (map == Map.Ilshenar)
  4562. list = m_IlshenarDeathDestinations;
  4563. else if (map == Map.Malas)
  4564. list = m_MalasDeathDestinations;
  4565. else if (map == Map.Tokuno)
  4566. list = m_TokunoDeathDestinations;
  4567. else
  4568. return false;
  4569. Point3D dest = Point3D.Zero;
  4570. int sqDistance = int.MaxValue;
  4571. for (int i = 0; i < list.Length; i++)
  4572. {
  4573. Point3D curDest = list[i];
  4574. int width = loc.X - curDest.X;
  4575. int height = loc.Y - curDest.Y;
  4576. int curSqDistance = width * width + height * height;
  4577. if (curSqDistance < sqDistance)
  4578. {
  4579. dest = curDest;
  4580. sqDistance = curSqDistance;
  4581. }
  4582. }
  4583. this.MoveToWorld(dest, map);
  4584. return true;
  4585. }
  4586. private void SendYoungDeathNotice()
  4587. {
  4588. this.SendGump(new YoungDeathNotice());
  4589. }
  4590. #endregion
  4591. #region Speech log
  4592. private SpeechLog m_SpeechLog;
  4593. public SpeechLog SpeechLog
  4594. {
  4595. get
  4596. {
  4597. return this.m_SpeechLog;
  4598. }
  4599. }
  4600. public override void OnSpeech(SpeechEventArgs e)
  4601. {
  4602. if (SpeechLog.Enabled && this.NetState != null)
  4603. {
  4604. if (this.m_SpeechLog == null)
  4605. this.m_SpeechLog = new SpeechLog();
  4606. this.m_SpeechLog.Add(e.Mobile, e.Speech);
  4607. }
  4608. }
  4609. #endregion
  4610. #region Champion Titles
  4611. [CommandProperty(AccessLevel.GameMaster)]
  4612. public bool DisplayChampionTitle
  4613. {
  4614. get
  4615. {
  4616. return this.GetFlag(PlayerFlag.DisplayChampionTitle);
  4617. }
  4618. set
  4619. {
  4620. this.SetFlag(PlayerFlag.DisplayChampionTitle, value);
  4621. }
  4622. }
  4623. private ChampionTitleInfo m_ChampionTitles;
  4624. [CommandProperty(AccessLevel.GameMaster)]
  4625. public ChampionTitleInfo ChampionTitles
  4626. {
  4627. get
  4628. {
  4629. return this.m_ChampionTitles;
  4630. }
  4631. set
  4632. {
  4633. }
  4634. }
  4635. private void ToggleChampionTitleDisplay()
  4636. {
  4637. if (!this.CheckAlive())
  4638. return;
  4639. if (this.DisplayChampionTitle)
  4640. this.SendLocalizedMessage(1062419, "", 0x23); // You have chosen to hide your monster kill title.
  4641. else
  4642. this.SendLocalizedMessage(1062418, "", 0x23); // You have chosen to display your monster kill title.
  4643. this.DisplayChampionTitle = !this.DisplayChampionTitle;
  4644. }
  4645. [PropertyObject]
  4646. public class ChampionTitleInfo
  4647. {
  4648. public static TimeSpan LossDelay = TimeSpan.FromDays(1.0);
  4649. public const int LossAmount = 90;
  4650. private class TitleInfo
  4651. {
  4652. private int m_Value;
  4653. private DateTime m_LastDecay;
  4654. public int Value
  4655. {
  4656. get
  4657. {
  4658. return this.m_Value;
  4659. }
  4660. set
  4661. {
  4662. this.m_Value = value;
  4663. }
  4664. }
  4665. public DateTime LastDecay
  4666. {
  4667. get
  4668. {
  4669. return this.m_LastDecay;
  4670. }
  4671. set
  4672. {
  4673. this.m_LastDecay = value;
  4674. }
  4675. }
  4676. public TitleInfo()
  4677. {
  4678. }
  4679. public TitleInfo(GenericReader reader)
  4680. {
  4681. int version = reader.ReadEncodedInt();
  4682. switch( version )
  4683. {
  4684. case 0:
  4685. {
  4686. this.m_Value = reader.ReadEncodedInt();
  4687. this.m_LastDecay = reader.ReadDateTime();
  4688. break;
  4689. }
  4690. }
  4691. }
  4692. public static void Serialize(GenericWriter writer, TitleInfo info)
  4693. {
  4694. writer.WriteEncodedInt((int)0); // version
  4695. writer.WriteEncodedInt(info.m_Value);
  4696. writer.Write(info.m_LastDecay);
  4697. }
  4698. }
  4699. private TitleInfo[] m_Values;
  4700. private int m_Harrower; //Harrower titles do NOT decay
  4701. public int GetValue(ChampionSpawnType type)
  4702. {
  4703. return this.GetValue((int)type);
  4704. }
  4705. public void SetValue(ChampionSpawnType type, int value)
  4706. {
  4707. this.SetValue((int)type, value);
  4708. }
  4709. public void Award(ChampionSpawnType type, int value)
  4710. {
  4711. this.Award((int)type, value);
  4712. }
  4713. public int GetValue(int index)
  4714. {
  4715. if (this.m_Values == null || index < 0 || index >= this.m_Values.Length)
  4716. return 0;
  4717. if (this.m_Values[index] == null)
  4718. this.m_Values[index] = new TitleInfo();
  4719. return this.m_Values[index].Value;
  4720. }
  4721. public DateTime GetLastDecay(int index)
  4722. {
  4723. if (this.m_Values == null || index < 0 || index >= this.m_Values.Length)
  4724. return DateTime.MinValue;
  4725. if (this.m_Values[index] == null)
  4726. this.m_Values[index] = new TitleInfo();
  4727. return this.m_Values[index].LastDecay;
  4728. }
  4729. public void SetValue(int index, int value)
  4730. {
  4731. if (this.m_Values == null)
  4732. this.m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length];
  4733. if (value < 0)
  4734. value = 0;
  4735. if (index < 0 || index >= this.m_Values.Length)
  4736. return;
  4737. if (this.m_Values[index] == null)
  4738. this.m_Values[index] = new TitleInfo();
  4739. this.m_Values[index].Value = value;
  4740. }
  4741. public void Award(int index, int value)
  4742. {
  4743. if (this.m_Values == null)
  4744. this.m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length];
  4745. if (index < 0 || index >= this.m_Values.Length || value <= 0)
  4746. return;
  4747. if (this.m_Values[index] == null)
  4748. this.m_Values[index] = new TitleInfo();
  4749. this.m_Values[index].Value += value;
  4750. }
  4751. public void Atrophy(int index, int value)
  4752. {
  4753. if (this.m_Values == null)
  4754. this.m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length];
  4755. if (index < 0 || index >= this.m_Values.Length || value <= 0)
  4756. return;
  4757. if (this.m_Values[index] == null)
  4758. this.m_Values[index] = new TitleInfo();
  4759. int before = this.m_Values[index].Value;
  4760. if ((this.m_Values[index].Value - value) < 0)
  4761. this.m_Values[index].Value = 0;
  4762. else
  4763. this.m_Values[index].Value -= value;
  4764. if (before != this.m_Values[index].Value)
  4765. this.m_Values[index].LastDecay = DateTime.Now;
  4766. }
  4767. public override string ToString()
  4768. {
  4769. return "...";
  4770. }
  4771. [CommandProperty(AccessLevel.GameMaster)]
  4772. public int Abyss
  4773. {
  4774. get
  4775. {
  4776. return this.GetValue(ChampionSpawnType.Abyss);
  4777. }
  4778. set
  4779. {
  4780. this.SetValue(ChampionSpawnType.Abyss, value);
  4781. }
  4782. }
  4783. [CommandProperty(AccessLevel.GameMaster)]
  4784. public int Arachnid
  4785. {
  4786. get
  4787. {
  4788. return this.GetValue(ChampionSpawnType.Arachnid);
  4789. }
  4790. set
  4791. {
  4792. this.SetValue(ChampionSpawnType.Arachnid, value);
  4793. }
  4794. }
  4795. [CommandProperty(AccessLevel.GameMaster)]
  4796. public int ColdBlood
  4797. {
  4798. get
  4799. {
  4800. return this.GetValue(ChampionSpawnType.ColdBlood);
  4801. }
  4802. set
  4803. {
  4804. this.SetValue(ChampionSpawnType.ColdBlood, value);
  4805. }
  4806. }
  4807. [CommandProperty(AccessLevel.GameMaster)]
  4808. public int ForestLord
  4809. {
  4810. get
  4811. {
  4812. return this.GetValue(ChampionSpawnType.ForestLord);
  4813. }
  4814. set
  4815. {
  4816. this.SetValue(ChampionSpawnType.ForestLord, value);
  4817. }
  4818. }
  4819. [CommandProperty(AccessLevel.GameMaster)]
  4820. public int SleepingDragon
  4821. {
  4822. get
  4823. {
  4824. return this.GetValue(ChampionSpawnType.SleepingDragon);
  4825. }
  4826. set
  4827. {
  4828. this.SetValue(ChampionSpawnType.SleepingDragon, value);
  4829. }
  4830. }
  4831. [CommandProperty(AccessLevel.GameMaster)]
  4832. public int UnholyTerror
  4833. {
  4834. get
  4835. {
  4836. return this.GetValue(ChampionSpawnType.UnholyTerror);
  4837. }
  4838. set
  4839. {
  4840. this.SetValue(ChampionSpawnType.UnholyTerror, value);
  4841. }
  4842. }
  4843. [CommandProperty(AccessLevel.GameMaster)]
  4844. public int VerminHorde
  4845. {
  4846. get
  4847. {
  4848. return this.GetValue(ChampionSpawnType.VerminHorde);
  4849. }
  4850. set
  4851. {
  4852. this.SetValue(ChampionSpawnType.VerminHorde, value);
  4853. }
  4854. }
  4855. [CommandProperty(AccessLevel.GameMaster)]
  4856. public int Harrower
  4857. {
  4858. get
  4859. {
  4860. return this.m_Harrower;
  4861. }
  4862. set
  4863. {
  4864. this.m_Harrower = value;
  4865. }
  4866. }
  4867. #region Mondain's Legacy Peerless Champion
  4868. [CommandProperty(AccessLevel.GameMaster)]
  4869. public int Glade
  4870. {
  4871. get
  4872. {
  4873. return this.GetValue(ChampionSpawnType.Glade);
  4874. }
  4875. set
  4876. {
  4877. this.SetValue(ChampionSpawnType.Glade, value);
  4878. }
  4879. }
  4880. [CommandProperty(AccessLevel.GameMaster)]
  4881. public int Corrupt
  4882. {
  4883. get
  4884. {
  4885. return this.GetValue(ChampionSpawnType.Corrupt);
  4886. }
  4887. set
  4888. {
  4889. this.SetValue(ChampionSpawnType.Corrupt, value);
  4890. }
  4891. }
  4892. #endregion
  4893. public ChampionTitleInfo()
  4894. {
  4895. }
  4896. public ChampionTitleInfo(GenericReader reader)
  4897. {
  4898. int version = reader.ReadEncodedInt();
  4899. switch( version )
  4900. {
  4901. case 0:
  4902. {
  4903. this.m_Harrower = reader.ReadEncodedInt();
  4904. int length = reader.ReadEncodedInt();
  4905. this.m_Values = new TitleInfo[length];
  4906. for (int i = 0; i < length; i++)
  4907. {
  4908. this.m_Values[i] = new TitleInfo(reader);
  4909. }
  4910. if (this.m_Values.Length != ChampionSpawnInfo.Table.Length)
  4911. {
  4912. TitleInfo[] oldValues = this.m_Values;
  4913. this.m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length];
  4914. for (int i = 0; i < this.m_Values.Length && i < oldValues.Length; i++)
  4915. {
  4916. this.m_Values[i] = oldValues[i];
  4917. }
  4918. }
  4919. break;
  4920. }
  4921. }
  4922. }
  4923. public static void Serialize(GenericWriter writer, ChampionTitleInfo titles)
  4924. {
  4925. writer.WriteEncodedInt((int)0); // version
  4926. writer.WriteEncodedInt(titles.m_Harrower);
  4927. int length = titles.m_Values.Length;
  4928. writer.WriteEncodedInt(length);
  4929. for (int i = 0; i < length; i++)
  4930. {
  4931. if (titles.m_Values[i] == null)
  4932. titles.m_Values[i] = new TitleInfo();
  4933. TitleInfo.Serialize(writer, titles.m_Values[i]);
  4934. }
  4935. }
  4936. public static void CheckAtrophy(PlayerMobile pm)
  4937. {
  4938. ChampionTitleInfo t = pm.m_ChampionTitles;
  4939. if (t == null)
  4940. return;
  4941. if (t.m_Values == null)
  4942. t.m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length];
  4943. for (int i = 0; i < t.m_Values.Length; i++)
  4944. {
  4945. if ((t.GetLastDecay(i) + LossDelay) < DateTime.Now)
  4946. {
  4947. t.Atrophy(i, LossAmount);
  4948. }
  4949. }
  4950. }
  4951. public static void AwardHarrowerTitle(PlayerMobile pm) //Called when killing a harrower. Will give a minimum of 1 point.
  4952. {
  4953. ChampionTitleInfo t = pm.m_ChampionTitles;
  4954. if (t == null)
  4955. return;
  4956. if (t.m_Values == null)
  4957. t.m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length];
  4958. int count = 1;
  4959. for (int i = 0; i < t.m_Values.Length; i++)
  4960. {
  4961. if (t.m_Values[i].Value > 900)
  4962. count++;
  4963. }
  4964. t.m_Harrower = Math.Max(count, t.m_Harrower); //Harrower titles never decay.
  4965. }
  4966. }
  4967. #endregion
  4968. #region Recipes
  4969. private Dictionary<int, bool> m_AcquiredRecipes;
  4970. public virtual bool HasRecipe(Recipe r)
  4971. {
  4972. if (r == null)
  4973. return false;
  4974. return this.HasRecipe(r.ID);
  4975. }
  4976. public virtual bool HasRecipe(int recipeID)
  4977. {
  4978. if (this.m_AcquiredRecipes != null && this.m_AcquiredRecipes.ContainsKey(recipeID))
  4979. return this.m_AcquiredRecipes[recipeID];
  4980. return false;
  4981. }
  4982. public virtual void AcquireRecipe(Recipe r)
  4983. {
  4984. if (r != null)
  4985. this.AcquireRecipe(r.ID);
  4986. }
  4987. public virtual void AcquireRecipe(int recipeID)
  4988. {
  4989. if (this.m_AcquiredRecipes == null)
  4990. this.m_AcquiredRecipes = new Dictionary<int, bool>();
  4991. this.m_AcquiredRecipes[recipeID] = true;
  4992. }
  4993. public virtual void ResetRecipes()
  4994. {
  4995. this.m_AcquiredRecipes = null;
  4996. }
  4997. [CommandProperty(AccessLevel.GameMaster)]
  4998. public int KnownRecipes
  4999. {
  5000. get
  5001. {
  5002. if (this.m_AcquiredRecipes == null)
  5003. return 0;
  5004. return this.m_AcquiredRecipes.Count;
  5005. }
  5006. }
  5007. #endregion
  5008. #region Buff Icons
  5009. public void ResendBuffs()
  5010. {
  5011. if (!BuffInfo.Enabled || this.m_BuffTable == null)
  5012. return;
  5013. NetState state = this.NetState;
  5014. if (state != null && state.BuffIcon)
  5015. {
  5016. foreach (BuffInfo info in this.m_BuffTable.Values)
  5017. {
  5018. state.Send(new AddBuffPacket(this, info));
  5019. }
  5020. }
  5021. }
  5022. private Dictionary<BuffIcon, BuffInfo> m_BuffTable;
  5023. public void AddBuff(BuffInfo b)
  5024. {
  5025. if (!BuffInfo.Enabled || b == null)
  5026. return;
  5027. this.RemoveBuff(b); //Check & subsequently remove the old one.
  5028. if (this.m_BuffTable == null)
  5029. this.m_BuffTable = new Dictionary<BuffIcon, BuffInfo>();
  5030. this.m_BuffTable.Add(b.ID, b);
  5031. NetState state = this.NetState;
  5032. if (state != null && state.BuffIcon)
  5033. {
  5034. state.Send(new AddBuffPacket(this, b));
  5035. }
  5036. }
  5037. public void RemoveBuff(BuffInfo b)
  5038. {
  5039. if (b == null)
  5040. return;
  5041. this.RemoveBuff(b.ID);
  5042. }
  5043. public void RemoveBuff(BuffIcon b)
  5044. {
  5045. if (this.m_BuffTable == null || !this.m_BuffTable.ContainsKey(b))
  5046. return;
  5047. BuffInfo info = this.m_BuffTable[b];
  5048. if (info.Timer != null && info.Timer.Running)
  5049. info.Timer.Stop();
  5050. this.m_BuffTable.Remove(b);
  5051. NetState state = this.NetState;
  5052. if (state != null && state.BuffIcon)
  5053. {
  5054. state.Send(new RemoveBuffPacket(this, b));
  5055. }
  5056. if (this.m_BuffTable.Count <= 0)
  5057. this.m_BuffTable = null;
  5058. }
  5059. #endregion
  5060. #region XML PVP Dismount Pet
  5061. public void DismountAndStable()
  5062. {
  5063. BaseCreature bc = Mount as BaseCreature;
  5064. if (Mount != null)
  5065. {
  5066. Mount.Rider = null;
  5067. }
  5068. if (bc != null)
  5069. {
  5070. bc.ControlTarget = null;
  5071. bc.ControlOrder = OrderType.Stay;
  5072. bc.Internalize();
  5073. bc.SetControlMaster(null);
  5074. bc.SummonMaster = null;
  5075. bc.IsStabled = true;
  5076. Stabled.Add(bc);
  5077. m_AutoStabled.Add(bc);
  5078. this.SendMessage("Your Mount has been Stabled !.");
  5079. }
  5080. }
  5081. public void RetrivePet()
  5082. {
  5083. if (m_AutoStabled.Count < 1)
  5084. return;
  5085. for (int k = 0; k < m_AutoStabled.Count; ++k)
  5086. {
  5087. BaseCreature bc = (BaseCreature)m_AutoStabled[k];
  5088. if (Stabled.Contains(bc))
  5089. {
  5090. bc.ControlTarget = null;
  5091. bc.ControlOrder = OrderType.Follow;
  5092. bc.SetControlMaster(this);
  5093. bc.SummonMaster = null;
  5094. if (bc.Summoned)
  5095. bc.SummonMaster = this;
  5096. bc.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully happy
  5097. bc.MoveToWorld(Location, Map);
  5098. bc.IsStabled = false;
  5099. if (m_AutoStabled.Contains(bc))
  5100. m_AutoStabled.Remove(bc);
  5101. this.SendMessage("Your Mount return to You !.");
  5102. }
  5103. }
  5104. m_AutoStabled.Clear();
  5105. }
  5106. #endregion
  5107. public void AutoStablePets()
  5108. {
  5109. if (Core.SE && this.AllFollowers.Count > 0)
  5110. {
  5111. for (int i = this.m_AllFollowers.Count - 1; i >= 0; --i)
  5112. {
  5113. BaseCreature pet = this.AllFollowers[i] as BaseCreature;
  5114. if (pet == null || pet.ControlMaster == null)
  5115. continue;
  5116. if (pet.Summoned)
  5117. {
  5118. if (pet.Map != this.Map)
  5119. {
  5120. pet.PlaySound(pet.GetAngerSound());
  5121. Timer.DelayCall(TimeSpan.Zero, new TimerCallback(pet.Delete));
  5122. }
  5123. continue;
  5124. }
  5125. if (pet is IMount && ((IMount)pet).Rider != null)
  5126. continue;
  5127. if ((pet is PackLlama || pet is PackHorse || pet is Beetle) && (pet.Backpack != null && pet.Backpack.Items.Count > 0))
  5128. continue;
  5129. if (pet is BaseEscortable)
  5130. continue;
  5131. pet.ControlTarget = null;
  5132. pet.ControlOrder = OrderType.Stay;
  5133. pet.Internalize();
  5134. pet.SetControlMaster(null);
  5135. pet.SummonMaster = null;
  5136. pet.IsStabled = true;
  5137. pet.StabledBy = this;
  5138. pet.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully happy
  5139. this.Stabled.Add(pet);
  5140. this.m_AutoStabled.Add(pet);
  5141. }
  5142. }
  5143. }
  5144. public void ClaimAutoStabledPets()
  5145. {
  5146. if (!Core.SE || this.m_AutoStabled.Count <= 0)
  5147. return;
  5148. if (!this.Alive)
  5149. {
  5150. this.SendLocalizedMessage(1076251); // Your pet was unable to join you while you are a ghost. Please re-login once you have ressurected to claim your pets.
  5151. return;
  5152. }
  5153. for (int i = this.m_AutoStabled.Count - 1; i >= 0; --i)
  5154. {
  5155. BaseCreature pet = this.m_AutoStabled[i] as BaseCreature;
  5156. if (pet == null || pet.Deleted)
  5157. {
  5158. pet.IsStabled = false;
  5159. pet.StabledBy = null;
  5160. if (this.Stabled.Contains(pet))
  5161. this.Stabled.Remove(pet);
  5162. continue;
  5163. }
  5164. if ((this.Followers + pet.ControlSlots) <= this.FollowersMax)
  5165. {
  5166. pet.SetControlMaster(this);
  5167. if (pet.Summoned)
  5168. pet.SummonMaster = this;
  5169. pet.ControlTarget = this;
  5170. pet.ControlOrder = OrderType.Follow;
  5171. pet.MoveToWorld(this.Location, this.Map);
  5172. pet.IsStabled = false;
  5173. pet.StabledBy = null;
  5174. pet.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully Happy
  5175. if (this.Stabled.Contains(pet))
  5176. this.Stabled.Remove(pet);
  5177. }
  5178. else
  5179. {
  5180. this.SendLocalizedMessage(1049612, pet.Name); // ~1_NAME~ remained in the stables because you have too many followers.
  5181. }
  5182. }
  5183. this.m_AutoStabled.Clear();
  5184. }
  5185. }
  5186. }