MapObject.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. using Client.MirControls;
  2. using Client.MirGraphics;
  3. using Client.MirScenes;
  4. using Client.MirSounds;
  5. using Client.MirScenes.Dialogs;
  6. using SlimDX;
  7. namespace Client.MirObjects
  8. {
  9. public abstract class MapObject
  10. {
  11. public static Font ChatFont = new Font(Settings.FontName, 10F);
  12. public static List<MirLabel> LabelList = new List<MirLabel>();
  13. public static UserObject User;
  14. public static UserHeroObject Hero;
  15. public static HeroObject HeroObject;
  16. public static MapObject MouseObject, TargetObject, MagicObject;
  17. private static uint mouseObjectID;
  18. public static uint MouseObjectID
  19. {
  20. get => mouseObjectID;
  21. set
  22. {
  23. if (mouseObjectID == value) return;
  24. mouseObjectID = value;
  25. MouseObject = MapControl.Objects.TryGetValue(value, out var obj) ? obj : null;
  26. }
  27. }
  28. private static uint lastTargetObjectId;
  29. private static uint targetObjectID;
  30. public static uint TargetObjectID
  31. {
  32. get => targetObjectID;
  33. set
  34. {
  35. if (targetObjectID == value) return;
  36. lastTargetObjectId = value;
  37. targetObjectID = value;
  38. TargetObject = MapControl.Objects.TryGetValue(value, out var obj) ? obj : null;
  39. }
  40. }
  41. private static uint magicObjectID;
  42. public static uint MagicObjectID
  43. {
  44. get => magicObjectID;
  45. set
  46. {
  47. if (magicObjectID == value) return;
  48. magicObjectID = value;
  49. MagicObject = MapControl.Objects.TryGetValue(value, out var obj) ? obj : null;
  50. }
  51. }
  52. public abstract ObjectType Race { get; }
  53. public abstract bool Blocking { get; }
  54. public uint ObjectID;
  55. public string Name = string.Empty;
  56. public Point CurrentLocation, MapLocation;
  57. public MirDirection Direction;
  58. public bool Dead, Hidden, SitDown, Sneaking;
  59. public PoisonType Poison;
  60. public long DeadTime;
  61. public byte AI;
  62. public bool InTrapRock;
  63. public int JumpDistance;
  64. public bool Blend = true;
  65. public long BlindTime;
  66. public byte BlindCount;
  67. private byte percentHealth;
  68. public virtual byte PercentHealth
  69. {
  70. get { return percentHealth; }
  71. set
  72. {
  73. if (percentHealth == value) return;
  74. percentHealth = value;
  75. }
  76. }
  77. public long HealthTime;
  78. private byte percentMana;
  79. public virtual byte PercentMana
  80. {
  81. get { return percentMana; }
  82. set
  83. {
  84. if (percentMana == value) return;
  85. percentMana = value;
  86. }
  87. }
  88. public uint LastTargetObjectId => lastTargetObjectId;
  89. public List<QueuedAction> ActionFeed = new List<QueuedAction>();
  90. public QueuedAction NextAction
  91. {
  92. get { return ActionFeed.Count > 0 ? ActionFeed[0] : null; }
  93. }
  94. public List<Effect> Effects = new List<Effect>();
  95. public List<BuffType> Buffs = new List<BuffType>();
  96. public MLibrary BodyLibrary;
  97. public Color DrawColour = Color.White, NameColour = Color.White, LightColour = Color.White;
  98. public MirLabel NameLabel, ChatLabel, GuildLabel;
  99. public long ChatTime;
  100. public int DrawFrame, DrawWingFrame;
  101. public Point DrawLocation, Movement, FinalDrawLocation, OffSetMove;
  102. public Rectangle DisplayRectangle;
  103. public int Light, DrawY;
  104. public long NextMotion, NextMotion2;
  105. public MirAction CurrentAction;
  106. public byte CurrentActionLevel;
  107. public bool SkipFrames;
  108. public FrameLoop FrameLoop = null;
  109. //Sound
  110. public int StruckWeapon;
  111. public MirLabel TempLabel;
  112. public static List<MirLabel> DamageLabelList = new List<MirLabel>();
  113. public List<Damage> Damages = new List<Damage>();
  114. protected Point GlobalDisplayLocationOffset
  115. {
  116. get { return new Point(0, 0); }
  117. }
  118. protected MapObject() { }
  119. protected MapObject(uint objectID)
  120. {
  121. ObjectID = objectID;
  122. if (MapControl.Objects.TryGetValue(ObjectID, out var existingObject))
  123. existingObject.Remove();
  124. MapControl.Objects[ObjectID] = this;
  125. MapControl.ObjectsList.Add(this);
  126. RestoreTargetStates();
  127. }
  128. public void Remove()
  129. {
  130. if (MouseObject == this) MouseObjectID = 0;
  131. if (TargetObject == this)
  132. {
  133. TargetObjectID = 0;
  134. lastTargetObjectId = ObjectID;
  135. }
  136. if (MagicObject == this) MagicObjectID = 0;
  137. if (this == User.NextMagicObject)
  138. User.ClearMagic();
  139. MapControl.Objects.Remove(ObjectID);
  140. MapControl.ObjectsList.Remove(this);
  141. GameScene.Scene.MapControl.RemoveObject(this);
  142. if (ObjectID == Hero?.ObjectID)
  143. HeroObject = null;
  144. if (ObjectID != GameScene.NPCID) return;
  145. GameScene.NPCID = 0;
  146. GameScene.Scene.NPCDialog.Hide();
  147. }
  148. public abstract void Process();
  149. public abstract void Draw();
  150. public abstract bool MouseOver(Point p);
  151. private void RestoreTargetStates()
  152. {
  153. if (MouseObjectID == ObjectID)
  154. MouseObject = this;
  155. if (TargetObjectID == ObjectID)
  156. TargetObject = this;
  157. if (MagicObjectID == ObjectID)
  158. MagicObject = this;
  159. if (!this.Dead &&
  160. TargetObject == null &&
  161. LastTargetObjectId == ObjectID)
  162. {
  163. switch (Race)
  164. {
  165. case ObjectType.Player:
  166. case ObjectType.Monster:
  167. case ObjectType.Hero:
  168. targetObjectID = ObjectID;
  169. TargetObject = this;
  170. break;
  171. }
  172. }
  173. }
  174. public void AddBuffEffect(BuffType type)
  175. {
  176. for (int i = 0; i < Effects.Count; i++)
  177. {
  178. if (!(Effects[i] is BuffEffect)) continue;
  179. if (((BuffEffect)(Effects[i])).BuffType == type) return;
  180. }
  181. PlayerObject ob = null;
  182. if (Race == ObjectType.Player)
  183. {
  184. ob = (PlayerObject)this;
  185. }
  186. switch (type)
  187. {
  188. case BuffType.Fury:
  189. Effects.Add(new BuffEffect(Libraries.Magic3, 190, 7, 1400, this, true, type) { Repeat = true });
  190. break;
  191. case BuffType.ImmortalSkin:
  192. Effects.Add(new BuffEffect(Libraries.Magic3, 570, 5, 1400, this, true, type) { Repeat = true });
  193. break;
  194. case BuffType.SwiftFeet:
  195. if (ob != null) ob.Sprint = true;
  196. break;
  197. case BuffType.MoonLight:
  198. case BuffType.DarkBody:
  199. if (ob != null) ob.Sneaking = true;
  200. break;
  201. case BuffType.VampireShot:
  202. Effects.Add(new BuffEffect(Libraries.Magic3, 2110, 6, 1400, this, true, type) { Repeat = false });
  203. break;
  204. case BuffType.PoisonShot:
  205. Effects.Add(new BuffEffect(Libraries.Magic3, 2310, 7, 1400, this, true, type) { Repeat = false });
  206. break;
  207. case BuffType.EnergyShield:
  208. BuffEffect effect;
  209. Effects.Add(effect = new BuffEffect(Libraries.Magic2, 1880, 9, 900, this, true, type) { Repeat = false });
  210. SoundManager.PlaySound(20000 + (ushort)Spell.EnergyShield * 10 + 0);
  211. effect.Complete += (o, e) =>
  212. {
  213. Effects.Add(new BuffEffect(Libraries.Magic2, 1900, 2, 800, this, true, type) { Repeat = true });
  214. };
  215. break;
  216. case BuffType.MagicBooster:
  217. Effects.Add(new BuffEffect(Libraries.Magic3, 90, 6, 1200, this, true, type) { Repeat = true });
  218. break;
  219. case BuffType.PetEnhancer:
  220. Effects.Add(new BuffEffect(Libraries.Magic3, 230, 6, 1200, this, true, type) { Repeat = true });
  221. break;
  222. case BuffType.GameMaster:
  223. Effects.Add(new BuffEffect(Libraries.CHumEffect[5], 0, 1, 1200, this, true, type) { Repeat = true });
  224. break;
  225. case BuffType.GeneralMeowMeowShield:
  226. Effects.Add(new BuffEffect(Libraries.Monsters[(ushort)Monster.GeneralMeowMeow], 529, 7, 700, this, true, type) { Repeat = true, Light = 1 });
  227. MirSounds.SoundManager.PlaySound(8322);
  228. break;
  229. case BuffType.PowerBeadBuff:
  230. Effects.Add(new BuffEffect(Libraries.Monsters[(ushort)Monster.PowerUpBead], 64, 6, 600, this, true, type) { Blend = true, Repeat = true });
  231. break;
  232. case BuffType.HornedArcherBuff:
  233. Effects.Add(effect = new BuffEffect(Libraries.Monsters[(ushort)Monster.HornedArcher], 468, 6, 600, this, true, type) { Repeat = false });
  234. effect.Complete += (o, e) =>
  235. {
  236. Effects.Add(new BuffEffect(Libraries.Monsters[(ushort)Monster.HornedArcher], 474, 3, 1000, this, true, type) { Blend = true, Repeat = true });
  237. };
  238. break;
  239. case BuffType.ColdArcherBuff:
  240. Effects.Add(effect = new BuffEffect(Libraries.Monsters[(ushort)Monster.HornedArcher], 477, 7, 700, this, true, type) { Repeat = false });
  241. effect.Complete += (o, e) =>
  242. {
  243. Effects.Add(new BuffEffect(Libraries.Monsters[(ushort)Monster.HornedArcher], 484, 3, 1000, this, true, type) { Blend = true, Repeat = true });
  244. };
  245. break;
  246. case BuffType.HornedWarriorShield:
  247. Effects.Add(new BuffEffect(Libraries.Monsters[(ushort)Monster.HornedWarrior], 912, 18, 1800, this, true, type) { Repeat = true });
  248. break;
  249. case BuffType.HornedCommanderShield:
  250. Effects.Add(effect = new BuffEffect(Libraries.Monsters[(ushort)Monster.HornedCommander], 1173, 1, 100, this, true, type) { Repeat = false, Light = 1 });
  251. effect.Complete += (o, e) =>
  252. {
  253. Effects.Add(new BuffEffect(Libraries.Monsters[(ushort)Monster.HornedCommander], 1174, 16, 1600, this, true, type) { Repeat = true, Light = 1 });
  254. };
  255. break;
  256. }
  257. }
  258. public void RemoveBuffEffect(BuffType type)
  259. {
  260. PlayerObject ob = null;
  261. if (Race == ObjectType.Player)
  262. {
  263. ob = (PlayerObject)this;
  264. }
  265. for (int i = 0; i < Effects.Count; i++)
  266. {
  267. if (!(Effects[i] is BuffEffect)) continue;
  268. if (((BuffEffect)(Effects[i])).BuffType != type) continue;
  269. Effects[i].Repeat = false;
  270. }
  271. switch (type)
  272. {
  273. case BuffType.SwiftFeet:
  274. if (ob != null) ob.Sprint = false;
  275. break;
  276. case BuffType.MoonLight:
  277. case BuffType.DarkBody:
  278. if (ob != null) ob.Sneaking = false;
  279. break;
  280. }
  281. }
  282. public Color ApplyDrawColour()
  283. {
  284. Color drawColour = DrawColour;
  285. if (drawColour == Color.Gray)
  286. {
  287. drawColour = Color.White;
  288. DXManager.SetGrayscale(true);
  289. }
  290. return drawColour;
  291. }
  292. public virtual Missile CreateProjectile(int baseIndex, MLibrary library, bool blend, int count, int interval, int skip, int lightDistance = 6, bool direction16 = true, Color? lightColour = null, uint targetID = 0)
  293. {
  294. return null;
  295. }
  296. public void Chat(string text)
  297. {
  298. if (ChatLabel != null && !ChatLabel.IsDisposed)
  299. {
  300. ChatLabel.Dispose();
  301. ChatLabel = null;
  302. }
  303. const int chatWidth = 200;
  304. List<string> chat = new List<string>();
  305. int index = 0;
  306. for (int i = 1; i < text.Length; i++)
  307. if (TextRenderer.MeasureText(CMain.Graphics, text.Substring(index, i - index), ChatFont).Width > chatWidth)
  308. {
  309. chat.Add(text.Substring(index, i - index - 1));
  310. index = i - 1;
  311. }
  312. chat.Add(text.Substring(index, text.Length - index));
  313. text = chat[0];
  314. for (int i = 1; i < chat.Count; i++)
  315. text += string.Format("\n{0}", chat[i]);
  316. ChatLabel = new MirLabel
  317. {
  318. AutoSize = true,
  319. BackColour = Color.Transparent,
  320. ForeColour = Color.White,
  321. OutLine = true,
  322. OutLineColour = Color.Black,
  323. DrawFormat = TextFormatFlags.HorizontalCenter,
  324. Text = text,
  325. };
  326. ChatTime = CMain.Time + 5000;
  327. }
  328. public virtual void DrawChat()
  329. {
  330. if (ChatLabel == null || ChatLabel.IsDisposed) return;
  331. if (CMain.Time > ChatTime)
  332. {
  333. ChatLabel.Dispose();
  334. ChatLabel = null;
  335. return;
  336. }
  337. ChatLabel.ForeColour = Dead ? Color.Gray : Color.White;
  338. ChatLabel.Location = new Point(DisplayRectangle.X + (48 - ChatLabel.Size.Width) / 2, DisplayRectangle.Y - (60 + ChatLabel.Size.Height) - (Dead ? 35 : 0));
  339. ChatLabel.Draw();
  340. }
  341. public virtual void CreateLabel()
  342. {
  343. NameLabel = null;
  344. for (int i = 0; i < LabelList.Count; i++)
  345. {
  346. if (LabelList[i].Text != Name || LabelList[i].ForeColour != NameColour) continue;
  347. NameLabel = LabelList[i];
  348. break;
  349. }
  350. if (NameLabel != null && !NameLabel.IsDisposed) return;
  351. NameLabel = new MirLabel
  352. {
  353. AutoSize = true,
  354. BackColour = Color.Transparent,
  355. ForeColour = NameColour,
  356. OutLine = true,
  357. OutLineColour = Color.Black,
  358. Text = Name,
  359. };
  360. NameLabel.Disposing += (o, e) => LabelList.Remove(NameLabel);
  361. LabelList.Add(NameLabel);
  362. }
  363. public virtual void DrawName()
  364. {
  365. CreateLabel();
  366. if (NameLabel == null) return;
  367. //NameLabel.Text = Name; //When CreateLabel() is called, the name is already determined, so there's no need to assign it every time in DrawName.
  368. NameLabel.Location = new Point(DisplayRectangle.X + (50 - NameLabel.Size.Width) / 2, DisplayRectangle.Y - (32 - NameLabel.Size.Height / 2) + (Dead ? 35 : 8)); //was 48 -
  369. NameLabel.Draw();
  370. }
  371. public virtual void DrawBlend()
  372. {
  373. DXManager.SetBlend(true, 0.3F); //0.8
  374. Draw();
  375. DXManager.SetBlend(false);
  376. }
  377. public void DrawDamages()
  378. {
  379. for (int i = Damages.Count - 1; i >= 0; i--)
  380. {
  381. Damage info = Damages[i];
  382. if (CMain.Time > info.ExpireTime)
  383. {
  384. if (info.DamageLabel != null)
  385. {
  386. info.DamageLabel.Dispose();
  387. }
  388. Damages.RemoveAt(i);
  389. }
  390. else
  391. {
  392. info.Draw(DisplayRectangle.Location);
  393. }
  394. }
  395. }
  396. public virtual bool ShouldDrawHealth()
  397. {
  398. return false;
  399. }
  400. public void DrawHealth()
  401. {
  402. string name = Name;
  403. if (Name.Contains("(")) name = Name.Substring(Name.IndexOf("(") + 1, Name.Length - Name.IndexOf("(") - 2);
  404. if (Dead) return;
  405. if (Race != ObjectType.Player && Race != ObjectType.Monster && Race != ObjectType.Hero) return;
  406. if (CMain.Time >= HealthTime)
  407. {
  408. if (!ShouldDrawHealth()) return;
  409. }
  410. Libraries.Prguse2.Draw(0, DisplayRectangle.X + 8, DisplayRectangle.Y - 64);
  411. int index = 1;
  412. switch (Race)
  413. {
  414. case ObjectType.Player:
  415. index = 12;
  416. if (GroupDialog.GroupList.Contains(name) && name != User.Name) index = 10;
  417. break;
  418. case ObjectType.Monster:
  419. if (GroupDialog.GroupList.Contains(name) || name == User.Name) index = 11;
  420. break;
  421. case ObjectType.Hero:
  422. if (GroupDialog.GroupList.Contains(MapObject.HeroObject?.OwnerName)) // Fails but not game breaking
  423. {
  424. index = 11;
  425. }
  426. if (HeroObject.HeroObject?.OwnerName == User.Name)
  427. {
  428. index = 1;
  429. if ((MapObject.HeroObject.Class != MirClass.Warrior && HeroObject.Level > 7) || (MapObject.HeroObject.Class == MirClass.Warrior && HeroObject.Level > 25))
  430. {
  431. Libraries.Prguse2.Draw(10, new Rectangle(0, 0, (int)(32 * PercentMana / 100F), 4), new Point(DisplayRectangle.X + 8, DisplayRectangle.Y - 60), Color.White, false);
  432. }
  433. }
  434. break;
  435. }
  436. Libraries.Prguse2.Draw(index, new Rectangle(0, 0, (int)(32 * PercentHealth / 100F), 4), new Point(DisplayRectangle.X + 8, DisplayRectangle.Y - 64), Color.White, false);
  437. }
  438. public void DrawPoison()
  439. {
  440. byte poisoncount = 0;
  441. if (Poison != PoisonType.None)
  442. {
  443. if (Poison.HasFlag(PoisonType.Green))
  444. {
  445. DXManager.Draw(DXManager.PoisonDotBackground, new Rectangle(0, 0, 6, 6), new Vector3((float)(DisplayRectangle.X + 7 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 21), 0.0F), Color.Black);
  446. DXManager.Draw(DXManager.RadarTexture, new Rectangle(0, 0, 4, 4), new Vector3((float)(DisplayRectangle.X + 8 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 20), 0.0F), Color.Green);
  447. poisoncount++;
  448. }
  449. if (Poison.HasFlag(PoisonType.Red))
  450. {
  451. DXManager.Draw(DXManager.PoisonDotBackground, new Rectangle(0, 0, 6, 6), new Vector3((float)(DisplayRectangle.X + 7 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 21), 0.0F), Color.Black);
  452. DXManager.Draw(DXManager.RadarTexture, new Rectangle(0, 0, 4, 4), new Vector3((float)(DisplayRectangle.X + 8 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 20), 0.0F), Color.Red);
  453. poisoncount++;
  454. }
  455. if (Poison.HasFlag(PoisonType.Bleeding))
  456. {
  457. DXManager.Draw(DXManager.PoisonDotBackground, new Rectangle(0, 0, 6, 6), new Vector3((float)(DisplayRectangle.X + 7 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 21), 0.0F), Color.Black);
  458. DXManager.Draw(DXManager.RadarTexture, new Rectangle(0, 0, 4, 4), new Vector3((float)(DisplayRectangle.X + 8 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 20), 0.0F), Color.DarkRed);
  459. poisoncount++;
  460. }
  461. if (Poison.HasFlag(PoisonType.Slow))
  462. {
  463. DXManager.Draw(DXManager.PoisonDotBackground, new Rectangle(0, 0, 6, 6), new Vector3((float)(DisplayRectangle.X + 7 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 21), 0.0F), Color.Black);
  464. DXManager.Draw(DXManager.RadarTexture, new Rectangle(0, 0, 4, 4), new Vector3((float)(DisplayRectangle.X + 8 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 20), 0.0F), Color.Purple);
  465. poisoncount++;
  466. }
  467. if (Poison.HasFlag(PoisonType.Stun) || Poison.HasFlag(PoisonType.Dazed))
  468. {
  469. DXManager.Draw(DXManager.PoisonDotBackground, new Rectangle(0, 0, 6, 6), new Vector3((float)(DisplayRectangle.X + 7 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 21), 0.0F), Color.Black);
  470. DXManager.Draw(DXManager.RadarTexture, new Rectangle(0, 0, 4, 4), new Vector3((float)(DisplayRectangle.X + 8 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 20), 0.0F), Color.Yellow);
  471. poisoncount++;
  472. }
  473. if (Poison.HasFlag(PoisonType.Blindness))
  474. {
  475. DXManager.Draw(DXManager.PoisonDotBackground, new Rectangle(0, 0, 6, 6), new Vector3((float)(DisplayRectangle.X + 7 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 21), 0.0F), Color.Black);
  476. DXManager.Draw(DXManager.RadarTexture, new Rectangle(0, 0, 4, 4), new Vector3((float)(DisplayRectangle.X + 8 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 20), 0.0F), Color.MediumVioletRed);
  477. poisoncount++;
  478. }
  479. if (Poison.HasFlag(PoisonType.Frozen))
  480. {
  481. DXManager.Draw(DXManager.PoisonDotBackground, new Rectangle(0, 0, 6, 6), new Vector3((float)(DisplayRectangle.X + 7 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 21), 0.0F), Color.Black);
  482. DXManager.Draw(DXManager.RadarTexture, new Rectangle(0, 0, 4, 4), new Vector3((float)(DisplayRectangle.X + 8 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 20), 0.0F), Color.Blue);
  483. poisoncount++;
  484. }
  485. if (Poison.HasFlag(PoisonType.Paralysis) || Poison.HasFlag(PoisonType.LRParalysis))
  486. {
  487. DXManager.Draw(DXManager.PoisonDotBackground, new Rectangle(0, 0, 6, 6), new Vector3((float)(DisplayRectangle.X + 7 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 21), 0.0F), Color.Black);
  488. DXManager.Draw(DXManager.RadarTexture, new Rectangle(0, 0, 4, 4), new Vector3((float)(DisplayRectangle.X + 8 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 20), 0.0F), Color.Gray);
  489. poisoncount++;
  490. }
  491. if (Poison.HasFlag(PoisonType.DelayedExplosion))
  492. {
  493. DXManager.Draw(DXManager.PoisonDotBackground, new Rectangle(0, 0, 6, 6), new Vector3((float)(DisplayRectangle.X + 7 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 21), 0.0F), Color.Black);
  494. DXManager.Draw(DXManager.RadarTexture, new Rectangle(0, 0, 4, 4), new Vector3((float)(DisplayRectangle.X + 8 + (poisoncount * 5)), (float)(DisplayRectangle.Y - 20), 0.0F), Color.Orange);
  495. poisoncount++;
  496. }
  497. }
  498. }
  499. public abstract void DrawBehindEffects(bool effectsEnabled);
  500. public abstract void DrawEffects(bool effectsEnabled);
  501. protected void LoopFrame(int start, int frameCount, int frameInterval, int duration)
  502. {
  503. if (FrameLoop == null)
  504. {
  505. FrameLoop = new FrameLoop
  506. {
  507. Start = start,
  508. End = start + frameCount - 1,
  509. Loops = (duration / (frameInterval * frameCount)) - 1 //Remove 1 count as we've already done a loop before this is checked
  510. };
  511. }
  512. }
  513. }
  514. public class FrameLoop
  515. {
  516. public MirAction Action { get; set; }
  517. public int Start { get; set; }
  518. public int End { get; set; }
  519. public int Loops { get; set; }
  520. public int CurrentCount { get; set; }
  521. }
  522. }