HornedWarrior.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. using Server.MirDatabase;
  2. using S = ServerPackets;
  3. namespace Server.MirObjects.Monsters
  4. {
  5. public class HornedWarrior : MonsterObject
  6. {
  7. private long _ShieldTime;
  8. protected byte AttackRange = 4;
  9. protected internal HornedWarrior(MonsterInfo info)
  10. : 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 > AttackRange || y > AttackRange) return false;
  20. return (x <= 1 && y <= 1) || (x == y || x % 2 == y % 2);
  21. }
  22. protected override void Attack()
  23. {
  24. if (!Target.IsAttackTarget(this))
  25. {
  26. Target = null;
  27. return;
  28. }
  29. Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation);
  30. bool ranged = CurrentLocation == Target.CurrentLocation || !Functions.InRange(CurrentLocation, Target.CurrentLocation, 1);
  31. ActionTime = Envir.Time + 300;
  32. AttackTime = Envir.Time + AttackSpeed;
  33. ShockTime = 0;
  34. if (HasBuff(BuffType.HornedWarriorShield, out _))
  35. {
  36. return;
  37. }
  38. var hpPercent = (HP * 100) / MaxHealth;
  39. if (Envir.Time > _ShieldTime && hpPercent < 50)
  40. {
  41. _ShieldTime = Envir.Time + 15000 + Envir.Random.Next(0, 5000);
  42. var stats = new Stats
  43. {
  44. [Stat.MaxAC] = 500,
  45. [Stat.MinAC] = 500
  46. };
  47. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 2 });
  48. AddBuff(BuffType.HornedWarriorShield, this, Settings.Second * 10, stats);
  49. return;
  50. }
  51. int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC]);
  52. if (damage == 0) return;
  53. if (!ranged && Envir.Random.Next(3) > 0)
  54. {
  55. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 });
  56. DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 300, Target, damage, DefenceType.ACAgility);
  57. ActionList.Add(action);
  58. }
  59. else
  60. {
  61. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 });
  62. WideLineAttack(damage, 4, 500, DefenceType.ACAgility, false, 3);
  63. }
  64. }
  65. protected override void ProcessTarget()
  66. {
  67. if (Target == null || !CanAttack) return;
  68. var buff = HasBuff(BuffType.HornedWarriorShield, out _);
  69. if (InAttackRange() && !buff)
  70. {
  71. Attack();
  72. return;
  73. }
  74. if (Envir.Time < ShockTime)
  75. {
  76. Target = null;
  77. return;
  78. }
  79. if (!buff)
  80. MoveTo(Target.CurrentLocation);
  81. else
  82. {
  83. MirDirection dir = Functions.DirectionFromPoint(Target.CurrentLocation, CurrentLocation);
  84. if (Walk(dir)) return;
  85. switch (Envir.Random.Next(2)) //No favour
  86. {
  87. case 0:
  88. for (int i = 0; i < 7; i++)
  89. {
  90. dir = Functions.NextDir(dir);
  91. if (Walk(dir))
  92. return;
  93. }
  94. break;
  95. default:
  96. for (int i = 0; i < 7; i++)
  97. {
  98. dir = Functions.PreviousDir(dir);
  99. if (Walk(dir))
  100. return;
  101. }
  102. break;
  103. }
  104. }
  105. }
  106. }
  107. }