DemonWolf.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. using Server.MirDatabase;
  2. using Server.MirEnvir;
  3. using S = ServerPackets;
  4. namespace Server.MirObjects.Monsters
  5. {
  6. public class DemonWolf : MonsterObject
  7. {
  8. private readonly int _MaxPackSize = 5;
  9. public List<MonsterObject> Pack = new List<MonsterObject>();
  10. protected internal DemonWolf(MonsterInfo info)
  11. : base(info)
  12. {
  13. }
  14. protected override bool InAttackRange()
  15. {
  16. if (Target.CurrentMap != CurrentMap) return false;
  17. if (Target.CurrentLocation == CurrentLocation) return false;
  18. int x = Math.Abs(Target.CurrentLocation.X - CurrentLocation.X);
  19. int y = Math.Abs(Target.CurrentLocation.Y - CurrentLocation.Y);
  20. if (x > 2 || y > 2) return false;
  21. return (x <= 1 && y <= 1) || (x == y || x % 2 == y % 2);
  22. }
  23. protected override void ProcessSearch()
  24. {
  25. if (Envir.Time < SearchTime) return;
  26. base.ProcessSearch();
  27. Pack = FindPackNearby(5);
  28. }
  29. protected override void Attack()
  30. {
  31. if (!Target.IsAttackTarget(this))
  32. {
  33. Target = null;
  34. return;
  35. }
  36. Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation);
  37. bool ranged = CurrentLocation == Target.CurrentLocation || !Functions.InRange(CurrentLocation, Target.CurrentLocation, 1);
  38. ShockTime = 0;
  39. ActionTime = Envir.Time + 300;
  40. AttackTime = Envir.Time + AttackSpeed;
  41. int damageMultiplier = (Pack.Count > _MaxPackSize ? _MaxPackSize : Pack.Count) + 1;
  42. if (Info.Effect == 1)
  43. {
  44. if (!ranged && Envir.Random.Next(4) > 0)
  45. {
  46. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 });
  47. int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC] * damageMultiplier);
  48. if (damage == 0) return;
  49. DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 500, Target, damage, DefenceType.MACAgility);
  50. ActionList.Add(action);
  51. }
  52. else
  53. {
  54. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 });
  55. int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC]);
  56. if (damage == 0) return;
  57. LineAttack(damage, 3);
  58. MoveTo(Target.CurrentLocation);
  59. }
  60. }
  61. else
  62. {
  63. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 });
  64. int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC] * damageMultiplier);
  65. if (damage == 0) return;
  66. DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 300, Target, damage, DefenceType.MACAgility);
  67. ActionList.Add(action);
  68. }
  69. }
  70. protected override void CompleteAttack(IList<object> data)
  71. {
  72. MapObject target = (MapObject)data[0];
  73. int damage = (int)data[1];
  74. DefenceType defence = (DefenceType)data[2];
  75. if (target == null || !target.IsAttackTarget(this) || target.CurrentMap != CurrentMap || target.Node == null) return;
  76. if (target.Attacked(this, damage, defence) <= 0) return;
  77. if (Info.Effect == 1)
  78. {
  79. PoisonTarget(target, 4, 5, PoisonType.Bleeding, 1000);
  80. }
  81. }
  82. public List<MonsterObject> FindPackNearby(int distance)
  83. {
  84. List<MonsterObject> pack = new List<MonsterObject>();
  85. for (int d = 0; d <= distance; d++)
  86. {
  87. for (int y = CurrentLocation.Y - d; y <= CurrentLocation.Y + d; y++)
  88. {
  89. if (y < 0) continue;
  90. if (y >= CurrentMap.Height) break;
  91. for (int x = CurrentLocation.X - d; x <= CurrentLocation.X + d; x += Math.Abs(y - CurrentLocation.Y) == d ? 1 : d * 2)
  92. {
  93. if (x < 0) continue;
  94. if (x >= CurrentMap.Width) break;
  95. if (!CurrentMap.ValidPoint(x, y)) continue;
  96. Cell cell = CurrentMap.GetCell(x, y);
  97. if (cell.Objects == null) continue;
  98. for (int i = 0; i < cell.Objects.Count; i++)
  99. {
  100. MapObject ob = cell.Objects[i];
  101. switch (ob.Race)
  102. {
  103. case ObjectType.Monster:
  104. if (ob == this || ob.Dead) continue;
  105. if (ob.IsAttackTarget(this)) continue;
  106. if (((MonsterObject)ob).Info.AI != Info.AI) continue;
  107. pack.Add((MonsterObject)ob);
  108. continue;
  109. }
  110. }
  111. }
  112. }
  113. }
  114. return pack;
  115. }
  116. }
  117. }