| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- using Server.MirDatabase;
- using Server.MirEnvir;
- using S = ServerPackets;
- namespace Server.MirObjects.Monsters
- {
- public class DemonWolf : MonsterObject
- {
- private readonly int _MaxPackSize = 5;
- public List<MonsterObject> Pack = new List<MonsterObject>();
- protected internal DemonWolf(MonsterInfo info)
- : base(info)
- {
- }
- protected override bool InAttackRange()
- {
- if (Target.CurrentMap != CurrentMap) return false;
- if (Target.CurrentLocation == CurrentLocation) return false;
- int x = Math.Abs(Target.CurrentLocation.X - CurrentLocation.X);
- int y = Math.Abs(Target.CurrentLocation.Y - CurrentLocation.Y);
- if (x > 2 || y > 2) return false;
- return (x <= 1 && y <= 1) || (x == y || x % 2 == y % 2);
- }
- protected override void ProcessSearch()
- {
- if (Envir.Time < SearchTime) return;
- base.ProcessSearch();
- Pack = FindPackNearby(5);
- }
- protected override void Attack()
- {
- if (!Target.IsAttackTarget(this))
- {
- Target = null;
- return;
- }
- Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation);
- bool ranged = CurrentLocation == Target.CurrentLocation || !Functions.InRange(CurrentLocation, Target.CurrentLocation, 1);
- ShockTime = 0;
- ActionTime = Envir.Time + 300;
- AttackTime = Envir.Time + AttackSpeed;
- int damageMultiplier = (Pack.Count > _MaxPackSize ? _MaxPackSize : Pack.Count) + 1;
- if (Info.Effect == 1)
- {
- if (!ranged && Envir.Random.Next(4) > 0)
- {
- Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 });
- int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC] * damageMultiplier);
- if (damage == 0) return;
- DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 500, Target, damage, DefenceType.MACAgility);
- ActionList.Add(action);
- }
- else
- {
- Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 });
- int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC]);
- if (damage == 0) return;
- LineAttack(damage, 3);
- MoveTo(Target.CurrentLocation);
- }
- }
- else
- {
- Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 });
- int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC] * damageMultiplier);
- if (damage == 0) return;
- DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 300, Target, damage, DefenceType.MACAgility);
- ActionList.Add(action);
- }
- }
- protected override void CompleteAttack(IList<object> data)
- {
- MapObject target = (MapObject)data[0];
- int damage = (int)data[1];
- DefenceType defence = (DefenceType)data[2];
- if (target == null || !target.IsAttackTarget(this) || target.CurrentMap != CurrentMap || target.Node == null) return;
- if (target.Attacked(this, damage, defence) <= 0) return;
- if (Info.Effect == 1)
- {
- PoisonTarget(target, 4, 5, PoisonType.Bleeding, 1000);
- }
- }
- public List<MonsterObject> FindPackNearby(int distance)
- {
- List<MonsterObject> pack = new List<MonsterObject>();
- for (int d = 0; d <= distance; d++)
- {
- for (int y = CurrentLocation.Y - d; y <= CurrentLocation.Y + d; y++)
- {
- if (y < 0) continue;
- if (y >= CurrentMap.Height) break;
- for (int x = CurrentLocation.X - d; x <= CurrentLocation.X + d; x += Math.Abs(y - CurrentLocation.Y) == d ? 1 : d * 2)
- {
- if (x < 0) continue;
- if (x >= CurrentMap.Width) break;
- if (!CurrentMap.ValidPoint(x, y)) continue;
- Cell cell = CurrentMap.GetCell(x, y);
- if (cell.Objects == null) continue;
- for (int i = 0; i < cell.Objects.Count; i++)
- {
- MapObject ob = cell.Objects[i];
- switch (ob.Race)
- {
- case ObjectType.Monster:
- if (ob == this || ob.Dead) continue;
- if (ob.IsAttackTarget(this)) continue;
- if (((MonsterObject)ob).Info.AI != Info.AI) continue;
- pack.Add((MonsterObject)ob);
- continue;
- }
- }
- }
- }
- }
- return pack;
- }
- }
- }
|