Dragon.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using System.Drawing;
  2. using Server.MirDatabase;
  3. using Server.MirObjects;
  4. using Server.MirObjects.Monsters;
  5. namespace Server.MirEnvir
  6. {
  7. public class Dragon
  8. {
  9. private readonly int ProcessDelay = 2000;
  10. public int DeLevelDelay = 60 * (60 * 1000);
  11. private long ProcessTime;
  12. public byte MaxLevel = Globals.MaxDragonLevel;
  13. private Rectangle DropArea;
  14. public long DeLevelTime;
  15. public bool Loaded;
  16. private static Envir Envir
  17. {
  18. get { return Envir.Main; }
  19. }
  20. protected static MessageQueue MessageQueue
  21. {
  22. get { return MessageQueue.Instance; }
  23. }
  24. private readonly Point[] BodyLocations = new[]
  25. {
  26. new Point(-3, -1),
  27. new Point(-3, -0),
  28. new Point(-2, -3),
  29. new Point(-2, -2),
  30. new Point(-2, -1),
  31. new Point(-2, 0),
  32. new Point(-2, 1),
  33. new Point(-1, -2),
  34. new Point(-1, -1),
  35. new Point(-1, 0),
  36. new Point(-1, 1),
  37. new Point(-1, 2),
  38. new Point(0, -2),
  39. new Point(0, -1),
  40. new Point(0, 1),
  41. new Point(0, 2),
  42. new Point(0, 3),
  43. new Point(1, -2),
  44. new Point(1, 0),
  45. new Point(1, 1),
  46. new Point(1, 2),
  47. new Point(1, 3),
  48. new Point(2, 1),
  49. new Point(2, 2),
  50. };
  51. public DragonInfo Info;
  52. public MonsterObject LinkedMonster;
  53. public Dragon(DragonInfo info)
  54. {
  55. Info = info;
  56. }
  57. public bool Load()
  58. {
  59. try
  60. {
  61. MonsterInfo info = Envir.GetMonsterInfo(Info.MonsterName);
  62. if (info == null)
  63. {
  64. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.FailedLoadDragonBadMonsterName) + Info.MonsterName);
  65. return false;
  66. }
  67. LinkedMonster = MonsterObject.GetMonster(info);
  68. Map map = Envir.GetMapByNameAndInstance(Info.MapFileName);
  69. if (map == null)
  70. {
  71. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.FailedToLoadDragonBadMapName) + Info.MapFileName);
  72. return false;
  73. }
  74. if (Info.Location.X > map.Width || Info.Location.Y > map.Height)
  75. {
  76. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.FailedToLoadDragonBadMapXY) + Info.MapFileName);
  77. return false;
  78. }
  79. if (LinkedMonster.Spawn(map, Info.Location))
  80. {
  81. if (LinkedMonster is EvilMir mob)
  82. {
  83. if (mob != null)
  84. {
  85. mob.DragonLink = true;
  86. }
  87. }
  88. MonsterInfo bodyinfo = Envir.GetMonsterInfo(Info.BodyName);
  89. if (bodyinfo != null)
  90. {
  91. MonsterObject bodymob;
  92. Point spawnlocation = Point.Empty;
  93. for (int i = 0; i <= BodyLocations.Length - 1; i++)
  94. {
  95. bodymob = MonsterObject.GetMonster(bodyinfo);
  96. spawnlocation = new Point(LinkedMonster.CurrentLocation.X + BodyLocations[i].X, LinkedMonster.CurrentLocation.Y + BodyLocations[i].Y);
  97. if (bodymob != null) bodymob.Spawn(LinkedMonster.CurrentMap, spawnlocation);
  98. }
  99. }
  100. DropArea = new Rectangle(Info.DropAreaTop.X, Info.DropAreaTop.Y, Info.DropAreaBottom.X - Info.DropAreaTop.X, Info.DropAreaBottom.Y - Info.DropAreaTop.Y);
  101. Loaded = true;
  102. return true;
  103. }
  104. }
  105. catch (Exception ex)
  106. {
  107. MessageQueue.Enqueue(ex);
  108. }
  109. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.FailedToLoadDragon));
  110. return false;
  111. }
  112. public void GainExp(int ammount)
  113. {
  114. if (ammount <= 0) return;
  115. Info.Experience += ammount;
  116. if (Info.Experience >= Info.Exps[Math.Min(11, Info.Level - 1)])
  117. {
  118. Info.Experience -= Info.Exps[Math.Min(11, Info.Level - 1)];
  119. LevelUp();
  120. }
  121. }
  122. public void LevelUp()
  123. {
  124. Drop(Info.Level);//i would suggest having the max level drop be empty or 'trash' > that way you stop ppl from exploiting it
  125. if (Info.Level < Globals.MaxDragonLevel) Info.Level = (byte)(Math.Max(1, (Info.Level + 1)));
  126. //if it reaches max level > make it stay that level for 6*deleveldelay and then reset to 0, rather then letting ppl farm it by making it drop every hour
  127. if (Info.Level == Globals.MaxDragonLevel)
  128. DeLevelTime = Envir.Time + (6 * DeLevelDelay);
  129. }
  130. public void LevelDown()
  131. {
  132. if (Info.Level > 1)
  133. {
  134. Info.Level = (byte)(Math.Max(1, (Info.Level - 1)));
  135. Info.Experience = 0;
  136. }
  137. }
  138. public void Drop(byte level)
  139. {
  140. if (level > Info.Drops.Length) return;
  141. if (Info.Drops[level - 1] == null) return;
  142. if (LinkedMonster == null) return;
  143. List<DragonInfo.DropInfo> droplist = new List<DragonInfo.DropInfo>(Info.Drops[level - 1]);
  144. for (int i = 0; i < droplist.Count; i++)
  145. {
  146. DragonInfo.DropInfo drop = droplist[i];
  147. int rate = (int)(drop.Chance / Settings.DropRate); if (rate < 1) rate = 1;
  148. if (Envir.Random.Next(rate) != 0) continue;
  149. if (drop.Gold > 0)
  150. {
  151. int gold = Envir.Random.Next((int)(drop.Gold / 2), (int)(drop.Gold + drop.Gold / 2)); //Messy
  152. if (gold <= 0) continue;
  153. if (!DropGold((uint)gold)) return;
  154. }
  155. else
  156. {
  157. UserItem item = Envir.CreateDropItem(drop.Item);
  158. if (item == null) continue;
  159. if (!DropItem(item)) return;
  160. }
  161. }
  162. }
  163. protected bool DropItem(UserItem item)
  164. {
  165. Point droplocation = new Point(DropArea.Left + (DropArea.Width / 2), DropArea.Top);
  166. ItemObject ob = new ItemObject(this.LinkedMonster, item, droplocation)
  167. {
  168. Owner = this.LinkedMonster.EXPOwner,
  169. OwnerTime = Envir.Time + Settings.Minute,
  170. };
  171. return ob.DragonDrop(DropArea.Width / 2);
  172. }
  173. protected bool DropGold(uint gold)
  174. {
  175. if (this.LinkedMonster.EXPOwner != null && this.LinkedMonster.EXPOwner.CanGainGold(gold))
  176. {
  177. this.LinkedMonster.EXPOwner.WinGold(gold);
  178. return true;
  179. }
  180. Point droplocation = new Point(DropArea.Left + (DropArea.Width / 2), DropArea.Top);
  181. ItemObject ob = new ItemObject(this.LinkedMonster, gold, droplocation)
  182. {
  183. Owner = this.LinkedMonster.EXPOwner,
  184. OwnerTime = Envir.Time + Settings.Minute,
  185. };
  186. return ob.DragonDrop(DropArea.Width / 2);
  187. }
  188. public void Process()
  189. {
  190. if (!Loaded) return;
  191. if (Envir.Time < ProcessTime) return;
  192. ProcessTime = Envir.Time + ProcessDelay;
  193. if ((Info.Level >= Globals.MaxDragonLevel) && (Envir.Time > DeLevelTime))
  194. {
  195. Info.Level = (byte)1;
  196. Info.Experience = 0;
  197. DeLevelTime = Envir.Time + DeLevelDelay;
  198. }
  199. if (Info.Level > 1 && Envir.Time > DeLevelTime)
  200. {
  201. LevelDown();
  202. DeLevelTime = Envir.Time + DeLevelDelay;
  203. }
  204. }
  205. }
  206. }