Kirin.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using System.Drawing;
  2. using Server.MirDatabase;
  3. using Server.MirEnvir;
  4. using S = ServerPackets;
  5. namespace Server.MirObjects.Monsters
  6. {
  7. class Kirin : MonsterObject
  8. {
  9. private byte AttackRange = 3;
  10. protected internal Kirin(MonsterInfo info) : base(info)
  11. {
  12. }
  13. protected override bool InAttackRange()
  14. {
  15. if (Target.CurrentMap != CurrentMap) return false;
  16. if (Target.CurrentLocation == CurrentLocation) return false;
  17. int x = Math.Abs(Target.CurrentLocation.X - CurrentLocation.X);
  18. int y = Math.Abs(Target.CurrentLocation.Y - CurrentLocation.Y);
  19. if (x > 2 || y > 2) return false;
  20. return (x <= 1 && y <= 1) || (x == y || x % 2 == y % 2);
  21. }
  22. protected bool InRangeAttackRange()
  23. {
  24. return CurrentMap == Target.CurrentMap && Functions.InRange(CurrentLocation, Target.CurrentLocation, AttackRange);
  25. }
  26. protected override void ProcessTarget()
  27. {
  28. if (Target == null || Dead) return;
  29. if (!InAttackRange())
  30. {
  31. if (CanAttack)
  32. {
  33. if (Envir.Random.Next(5) == 0)
  34. RangeAttack();
  35. }
  36. if (CurrentLocation == Target.CurrentLocation)
  37. {
  38. MirDirection direction = (MirDirection)Envir.Random.Next(8);
  39. int rotation = Envir.Random.Next(2) == 0 ? 1 : -1;
  40. for (int d = 0; d < 8; d++)
  41. {
  42. if (Walk(direction)) break;
  43. direction = Functions.ShiftDirection(direction, rotation);
  44. }
  45. }
  46. else
  47. MoveTo(Target.CurrentLocation);
  48. }
  49. if (!CanAttack) return;
  50. if (Envir.Random.Next(5) > 0)
  51. {
  52. if (InAttackRange())
  53. Attack();
  54. }
  55. else RangeAttack();
  56. if (Envir.Time < ShockTime)
  57. {
  58. Target = null;
  59. return;
  60. }
  61. //MoveTo(Target.CurrentLocation);
  62. }
  63. protected override void Attack()
  64. {
  65. if (!Target.IsAttackTarget(this))
  66. {
  67. Target = null;
  68. return;
  69. }
  70. Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation);
  71. ShockTime = 0;
  72. ActionTime = Envir.Time + 500;
  73. AttackTime = Envir.Time + AttackSpeed;
  74. int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC]);
  75. if (damage == 0) return;
  76. if (Envir.Random.Next(5) == 0)
  77. {
  78. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 });
  79. DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 500, Target, damage, DefenceType.AC);
  80. ActionList.Add(action);
  81. }
  82. else
  83. {
  84. base.Attack();
  85. }
  86. if (Target.Dead)
  87. FindTarget();
  88. }
  89. public void RangeAttack()
  90. {
  91. Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation);
  92. ShockTime = 0;
  93. ActionTime = Envir.Time + 500;
  94. AttackTime = Envir.Time + AttackSpeed;
  95. int damage = GetAttackPower(Stats[Stat.MinMC], Stats[Stat.MaxMC]);
  96. if (damage == 0) return;
  97. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 2 });
  98. IceThrust();
  99. }
  100. private void IceThrust()
  101. {
  102. Point location = CurrentLocation;
  103. MirDirection direction = Direction;
  104. Cell cell;
  105. int Damage = GetAttackPower(Stats[Stat.MinMC], Stats[Stat.MaxMC]);
  106. int col = 3;
  107. int row = 3;
  108. Point[] loc = new Point[col];
  109. loc[0] = Functions.PointMove(location, Functions.PreviousDir(direction), 1);
  110. loc[1] = Functions.PointMove(location, direction, 1);
  111. loc[2] = Functions.PointMove(location, Functions.NextDir(direction), 1);
  112. for (int i = 0; i < col; i++)
  113. {
  114. Point startPoint = loc[i];
  115. for (int j = 0; j < row; j++)
  116. {
  117. Point hitPoint = Functions.PointMove(startPoint, direction, j);
  118. if (!CurrentMap.ValidPoint(hitPoint)) continue;
  119. cell = CurrentMap.GetCell(hitPoint);
  120. if (cell.Objects == null) continue;
  121. for (int k = 0; k < cell.Objects.Count; k++)
  122. {
  123. MapObject target = cell.Objects[k];
  124. switch (target.Race)
  125. {
  126. case ObjectType.Monster:
  127. case ObjectType.Player:
  128. if (target.IsAttackTarget(this))
  129. {
  130. if (target.Attacked(this, Damage, DefenceType.MAC) > 0)
  131. {
  132. if (Envir.Random.Next(Settings.PoisonResistWeight) >= target.Stats[Stat.PoisonResist])
  133. {
  134. if (Envir.Random.Next(5) == 0)
  135. {
  136. target.ApplyPoison(new Poison
  137. {
  138. Owner = this,
  139. Duration = target.Race == ObjectType.Player ? 4 : 5 + Envir.Random.Next(5),
  140. PType = PoisonType.Slow,
  141. TickSpeed = 1000,
  142. }, this);
  143. target.OperateTime = 0;
  144. }
  145. }
  146. }
  147. }
  148. break;
  149. }
  150. }
  151. }
  152. }
  153. }
  154. }
  155. }