EarthGolem.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using System.Drawing;
  2. using Server.MirDatabase;
  3. using Server.MirEnvir;
  4. using S = ServerPackets;
  5. namespace Server.MirObjects.Monsters
  6. {
  7. public class EarthGolem : ZumaMonster
  8. {
  9. public long FearTime;
  10. protected virtual byte AttackRange
  11. {
  12. get
  13. {
  14. return 6;
  15. }
  16. }
  17. protected internal EarthGolem(MonsterInfo info)
  18. : base(info)
  19. {
  20. }
  21. protected override bool InAttackRange()
  22. {
  23. return CurrentMap == Target.CurrentMap && Functions.InRange(CurrentLocation, Target.CurrentLocation, AttackRange);
  24. }
  25. protected override void ProcessAI()
  26. {
  27. if (!Dead && Envir.Time > ActionTime)
  28. {
  29. bool stoned = !FindNearby(4);
  30. if (Stoned && !stoned)
  31. {
  32. Wake();
  33. AttackTime = Envir.Time + 1500;
  34. ActionTime = Envir.Time + 1500;
  35. MoveTime = Envir.Time + 1500;
  36. }
  37. }
  38. base.ProcessAI();
  39. }
  40. protected override void Attack()
  41. {
  42. if (!Target.IsAttackTarget(this))
  43. {
  44. Target = null;
  45. return;
  46. }
  47. ShockTime = 0;
  48. Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation);
  49. bool ranged = CurrentLocation == Target.CurrentLocation || !Functions.InRange(CurrentLocation, Target.CurrentLocation, 1);
  50. ActionTime = Envir.Time + 300;
  51. AttackTime = Envir.Time + AttackSpeed;
  52. if (!ranged && Envir.Random.Next(3) > 0)
  53. {
  54. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation });
  55. int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC]);
  56. if (damage == 0) return;
  57. DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 500, Target, damage, DefenceType.MAC);
  58. ActionList.Add(action);
  59. }
  60. else
  61. {
  62. Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, TargetID = Target.ObjectID });
  63. var location = Target.CurrentLocation;
  64. for (int y = location.Y - 1; y <= location.Y + 1; y++)
  65. {
  66. if (y < 0) continue;
  67. if (y >= CurrentMap.Height) break;
  68. for (int x = location.X - 1; x <= location.X + 1; x++)
  69. {
  70. if (x < 0) continue;
  71. if (x >= CurrentMap.Width) break;
  72. if (x == CurrentLocation.X && y == CurrentLocation.Y) continue;
  73. var cell = CurrentMap.GetCell(x, y);
  74. if (!cell.Valid) continue;
  75. int damage = GetAttackPower(Stats[Stat.MinMC], Stats[Stat.MaxMC]);
  76. var start = 500;
  77. SpellObject ob = new SpellObject
  78. {
  79. Spell = Spell.EarthGolemPile,
  80. Value = damage,
  81. ExpireTime = Envir.Time + 1200 + start,
  82. TickSpeed = 1000,
  83. CurrentLocation = new Point(x, y),
  84. CastLocation = location,
  85. Show = location.X == x && location.Y == y,
  86. CurrentMap = CurrentMap,
  87. Caster = this
  88. };
  89. DelayedAction action = new DelayedAction(DelayedType.Spawn, Envir.Time + start, ob);
  90. CurrentMap.ActionList.Add(action);
  91. }
  92. }
  93. }
  94. }
  95. protected override void ProcessTarget()
  96. {
  97. if (Target == null || !CanAttack) return;
  98. if (InAttackRange() && Envir.Time < FearTime)
  99. {
  100. Attack();
  101. return;
  102. }
  103. FearTime = Envir.Time + 2000;
  104. if (Envir.Time < ShockTime)
  105. {
  106. Target = null;
  107. return;
  108. }
  109. int dist = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation);
  110. if (dist >= AttackRange)
  111. MoveTo(Target.CurrentLocation);
  112. else
  113. {
  114. MirDirection dir = Functions.DirectionFromPoint(Target.CurrentLocation, CurrentLocation);
  115. if (Walk(dir)) return;
  116. switch (Envir.Random.Next(2)) //No favour
  117. {
  118. case 0:
  119. for (int i = 0; i < 7; i++)
  120. {
  121. dir = Functions.NextDir(dir);
  122. if (Walk(dir))
  123. return;
  124. }
  125. break;
  126. default:
  127. for (int i = 0; i < 7; i++)
  128. {
  129. dir = Functions.PreviousDir(dir);
  130. if (Walk(dir))
  131. return;
  132. }
  133. break;
  134. }
  135. }
  136. }
  137. }
  138. }