EvilMir.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. using Server.MirDatabase;
  2. using S = ServerPackets;
  3. namespace Server.MirObjects.Monsters
  4. {
  5. public class EvilMir : MonsterObject
  6. {
  7. public bool Sleeping;
  8. private bool MassAttack;
  9. public long WakeUpTime;
  10. public override MapObject Target
  11. {
  12. get { return _target; }
  13. set
  14. {
  15. if (_target == value) return;
  16. _target = value;
  17. if (value == null && DragonLink) Envir.DragonSystem.DeLevelTime = Envir.Time + Envir.DragonSystem.DeLevelDelay;
  18. }
  19. }
  20. private bool _dragonlink;
  21. public bool DragonLink
  22. {
  23. get { return _dragonlink && Envir.DragonSystem != null; }
  24. set
  25. {
  26. if (_dragonlink == value) return;
  27. _dragonlink = value;
  28. }
  29. }
  30. protected override bool CanAttack
  31. {
  32. get
  33. {
  34. return !Sleeping && base.CanAttack;
  35. }
  36. }
  37. protected override bool CanMove { get { return false; } }
  38. protected internal EvilMir(MonsterInfo info)
  39. : base(info)
  40. {
  41. Direction = MirDirection.Up;
  42. }
  43. public override void Turn(MirDirection dir)
  44. {
  45. }
  46. public override bool Walk(MirDirection dir) { return false; }
  47. public override bool IsAttackTarget(MonsterObject attacker)
  48. {
  49. return !Sleeping && base.IsAttackTarget(attacker);
  50. }
  51. public override bool IsAttackTarget(HumanObject attacker)
  52. {
  53. return !Sleeping && base.IsAttackTarget(attacker);
  54. }
  55. protected override bool InAttackRange()
  56. {
  57. return CurrentMap == Target.CurrentMap && Functions.InRange(CurrentLocation, Target.CurrentLocation, Info.ViewRange);
  58. }
  59. protected override void ProcessRoam() { }
  60. protected override void ProcessSearch()
  61. {
  62. if (!Sleeping)
  63. base.ProcessSearch();
  64. }
  65. protected override void ProcessAI()
  66. {
  67. if (!Dead && Sleeping && Envir.Time > WakeUpTime)
  68. {
  69. Sleeping = false;
  70. HP = Stats[Stat.HP];
  71. return;
  72. }
  73. base.ProcessAI();
  74. }
  75. protected override void CompleteAttack(IList<object> data)
  76. {
  77. if (Target == null) return;
  78. if (!Target.IsAttackTarget(this) || Target.CurrentMap != CurrentMap || Target.Node == null) return;
  79. List<MapObject> targets = MassAttack ? FindAllTargets(17/*huge range so it even hits ppl with bigger resolutions*/, CurrentLocation, false) : FindAllTargets(2, Target.CurrentLocation, false);
  80. if (targets.Count == 0) return;
  81. for (int i = 0; i < targets.Count; i++)
  82. {
  83. Target = targets[i];
  84. Attack();
  85. }
  86. }
  87. protected override void ProcessTarget()
  88. {
  89. if (Target == null) return;
  90. if (!CanAttack || !InAttackRange()) return;
  91. ShockTime = 0;
  92. if (DragonLink)
  93. {
  94. if (Envir.DragonSystem.Info.Level < Globals.MaxDragonLevel)
  95. Envir.DragonSystem.DeLevelTime = Envir.Time + Envir.DragonSystem.DeLevelDelay;
  96. else
  97. Envir.DragonSystem.DeLevelTime = Envir.Time + (6 * Envir.DragonSystem.DeLevelDelay);
  98. }
  99. byte random = DragonLink ? (byte)(Envir.DragonSystem.MaxLevel + 3 - Envir.DragonSystem.Info.Level) : (byte)8;
  100. if (Envir.Random.Next(random) > 0 /*&& Target.CurrentLocation.Y >= CurrentLocation.Y - 1*/)//in theory it shouldnt fire 'behind' it, but it should shoot at stuff in it's top left corner (and this code made it only hit below him not 'infront' of him)
  101. {
  102. MassAttack = false;
  103. Direction = SetDirection(Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation));
  104. Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, TargetID = Target.ObjectID });
  105. int delay = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation) * 50 + 620; //50 MS per Step
  106. ActionList.Add(new DelayedAction(DelayedType.Damage, Envir.Time + delay));
  107. }
  108. else
  109. {
  110. MassAttack = true;
  111. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation });
  112. ActionList.Add(new DelayedAction(DelayedType.Damage, Envir.Time + 500));
  113. }
  114. ActionTime = Envir.Time + 300;
  115. AttackTime = Envir.Time + AttackSpeed;
  116. }
  117. protected override void Attack()
  118. {
  119. int damage = GetAttackPower(Stats[Stat.MinDC], DragonLink ? Stats[Stat.MaxDC] + (Envir.DragonSystem.Info.Level - 1 * 10) : Stats[Stat.MaxDC]);
  120. if (!MassAttack)
  121. damage = (int)(damage * 0.75);//make mass attacking do slightly more dmg then targeted
  122. if (damage == 0) return;
  123. if (Target.Attacked(this, damage, DefenceType.MAC) <= 0) return;
  124. PoisonTarget(Target, 5, 15, PoisonType.Green, 2000);
  125. PoisonTarget(Target, 5, 5, PoisonType.Paralysis, 1000);
  126. }
  127. public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
  128. {
  129. return Sleeping ? 0 : base.Attacked(attacker, damage, type);
  130. }
  131. public override int Attacked(HumanObject attacker, int damage, DefenceType type = DefenceType.ACAgility, bool damageWeapon = true)
  132. {
  133. return Sleeping ? 0 : base.Attacked(attacker, damage, type, damageWeapon);
  134. }
  135. public override int Struck(int damage, DefenceType type = DefenceType.ACAgility)
  136. {
  137. return 0;
  138. }
  139. public override void ChangeHP(int amount)
  140. {
  141. if (DragonLink && amount < 0) Envir.DragonSystem.GainExp(Envir.Random.Next(1, 40));
  142. base.ChangeHP(amount);
  143. }
  144. public override void Die()
  145. {
  146. if (Dead || Sleeping) return;
  147. if (!DragonLink) base.Die();
  148. else
  149. {
  150. if (Info.HasDieScript && (Envir.MonsterNPC != null))
  151. {
  152. Envir.MonsterNPC.Call(this,string.Format("[@_DIE({0})]", Info.Index));
  153. }
  154. Envir.DragonSystem.GainExp(250);//why would hitting em give you so little 'points', while hitting them gives so much
  155. Sleeping = true;
  156. WakeUpTime = Envir.Time + 5 * (60 * 1000);
  157. }
  158. }
  159. public MirDirection SetDirection(MirDirection dir)
  160. {
  161. switch (dir)
  162. {
  163. case MirDirection.DownRight:
  164. case MirDirection.Right:
  165. return MirDirection.Up;
  166. case MirDirection.Left:
  167. case MirDirection.UpLeft:
  168. return MirDirection.Right;
  169. default:
  170. return MirDirection.UpRight;
  171. }
  172. }
  173. }
  174. }