Пример #1
0
        public virtual bool Attack(MirDirection D)
        {
            if (!CanAttack)
            {
                return(false);
            }

            Direction = D;
            Broadcast(new S.ObjectAttack {
                ObjectID = ObjectID, Direction = Direction
            });


            Point     P = Functions.PointMove(Location, D, 1);
            MapObject M = null;

            List <MapObject> TempList = CurrentMap.GetNearbyObjects(this, P, 0);

            for (int I = 0; I < TempList.Count; I++)
            {
                M = TempList[I];
                if (!M.Dead && M.IsAttackTarget(this))
                {
                    break;
                }
                else
                {
                    M = null;
                }
            }

            Attack(M);

            AttackTime = Main.Time + AttackSpeed;

            return(true);
        }
Пример #2
0
        protected List <MapObject> FindAllTargets(int dist, Point location, bool needSight = true)
        {
            List <MapObject> targets = new List <MapObject>();

            for (int d = 0; d <= dist; d++)
            {
                for (int y = location.Y - d; y <= location.Y + d; y++)
                {
                    if (y < 0)
                    {
                        continue;
                    }
                    if (y >= CurrentMap.Height)
                    {
                        break;
                    }

                    for (int x = location.X - d; x <= location.X + d; x += Math.Abs(y - location.Y) == d ? 1 : d * 2)
                    {
                        if (x < 0)
                        {
                            continue;
                        }
                        if (x >= CurrentMap.Width)
                        {
                            break;
                        }

                        Cell cell = CurrentMap.GetCell(x, y);
                        if (!cell.Valid || cell.Objects == null)
                        {
                            continue;
                        }

                        for (int i = 0; i < cell.Objects.Count; i++)
                        {
                            MapObject ob = cell.Objects[i];
                            switch (ob.Race)
                            {
                            case ObjectType.Monster:
                            case ObjectType.Player:
                            case ObjectType.Hero:
                                if (!ob.IsAttackTarget(this))
                                {
                                    continue;
                                }
                                if (ob.Hidden && (!CoolEye || Level < ob.Level) && needSight)
                                {
                                    continue;
                                }
                                if (ob.Race == ObjectType.Player)
                                {
                                    PlayerObject player = ((PlayerObject)ob);
                                    if (player.GMGameMaster)
                                    {
                                        continue;
                                    }
                                }
                                targets.Add(ob);
                                continue;

                            default:
                                continue;
                            }
                        }
                    }
                }
            }
            return(targets);
        }
Пример #3
0
        public void ProcessSpell(MapObject ob)
        {
            if (Envir.Time < StartTime)
            {
                return;
            }
            switch (Spell)
            {
            case Spell.FireWall:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                break;

            case Spell.Healing:     //SafeZone
                if (ob.Race != ObjectType.Player && (ob.Race != ObjectType.Monster || ob.Master == null || ob.Master.Race != ObjectType.Player))
                {
                    return;
                }
                if (ob.Dead || ob.HealAmount != 0 || ob.PercentHealth == 100)
                {
                    return;
                }

                ob.HealAmount += 25;
                Broadcast(new S.ObjectEffect {
                    ObjectID = ob.ObjectID, Effect = SpellEffect.Healing
                });
                break;

            case Spell.PoisonCloud:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.None, false);
                if (!ob.Dead)
                {
                    ob.ApplyPoison(new Poison
                    {
                        Duration  = 15,
                        Owner     = Caster,
                        PType     = PoisonType.Green,
                        TickSpeed = 2000,
                        Value     = Value / 20
                    }, Caster);
                }
                break;

            case Spell.Blizzard:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster.ActiveBlizzard == false)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MACAgility, false);
                if (!ob.Dead && Envir.Random.Next(8) == 0)
                {
                    ob.ApplyPoison(new Poison
                    {
                        Duration  = 5 + Envir.Random.Next(Caster.Freezing),
                        Owner     = Caster,
                        PType     = PoisonType.Slow,
                        TickSpeed = 2000,
                    }, Caster);
                }
                break;

            case Spell.MeteorStrike:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster.ActiveBlizzard == false)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MACAgility, false);
                break;

            case Spell.ExplosiveTrap:    //ArcherSpells - Explosive Trap
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                if (DetonatedTrap)
                {
                    return;                   //make sure explosion happens only once
                }
                DetonateTrapNow();
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                break;
            }
        }
Пример #4
0
        public void ArcherSummon(UserMagic magic, MapObject target, Point location)
        {
            if (target != null && target.IsAttackTarget(this))
                location = target.CurrentLocation;
            if (!CanFly(location)) return;

            uint duration = (uint)((magic.Level * 5 + 10) * 1000);
            int value = (int)duration;
            int delay = Functions.MaxDistance(CurrentLocation, location) * 50 + 500; //50 MS per Step

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + delay, magic, value, location, target);
            ActionList.Add(action);
        }
Пример #5
0
        public void SpecialArrowShot(MapObject target, UserMagic magic)
        {
            if (target == null || !target.IsAttackTarget(this)) return;
            if ((Info.MentalState != 1) && !CanFly(target.CurrentLocation)) return;
            int distance = Functions.MaxDistance(CurrentLocation, target.CurrentLocation);
            int damage = (GetAttackPower(MinMC, MaxMC) + magic.GetPower());
            if (magic.Spell != Spell.CrippleShot)
                damage = (int)(damage * Math.Max(1, (distance * 0.4)));//range boost
            damage = ApplyArcherState(damage);

            int delay = distance * 50 + 500; //50 MS per Step

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + delay, magic, damage, target);
            ActionList.Add(action);
        }
Пример #6
0
        public void DoKnockback(MapObject target, UserMagic magic)//ElementalShot - knockback
        {
            Cell cell = CurrentMap.GetCell(target.CurrentLocation);
            if (!cell.Valid || cell.Objects == null) return;

            if (target.CurrentLocation.Y < 0 || target.CurrentLocation.Y >= CurrentMap.Height || target.CurrentLocation.X < 0 || target.CurrentLocation.X >= CurrentMap.Height) return;

            if (target.Race != ObjectType.Monster && target.Race != ObjectType.Player) return;
            if (!target.IsAttackTarget(this) || target.Level >= Level) return;

            if (Envir.Random.Next(20) >= 6 + magic.Level * 3 + ElementsLevel + Level - target.Level) return;
            int distance = 1 + Math.Max(0, magic.Level - 1) + Envir.Random.Next(2);
            MirDirection dir = Functions.DirectionFromPoint(CurrentLocation, target.CurrentLocation);

            target.Pushed(this, dir, distance);
        }
Пример #7
0
        private bool DoubleShot(MapObject target, UserMagic magic)
        {
            if (target == null || !target.IsAttackTarget(this)) return false;
            if ((Info.MentalState != 1) && !CanFly(target.CurrentLocation)) return false;
            int distance = Functions.MaxDistance(CurrentLocation, target.CurrentLocation);
            int damage = (GetAttackPower(MinMC, MaxMC) + magic.GetPower());
            damage = (int)(damage * Math.Max(1, (distance * 0.25)));//range boost
            damage = ApplyArcherState(damage);
            int delay = distance * 50 + 500; //50 MS per Step

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + delay, magic, damage, target);

            ActionList.Add(action);

            action = new DelayedAction(DelayedType.Magic, Envir.Time + delay + 50, magic, damage, target);

            ActionList.Add(action);

            return true;
        }
Пример #8
0
        private void Entrapment(MapObject target, UserMagic magic)
        {
            if (target == null || !target.IsAttackTarget(this)) return;

            int damage = 0;

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + 500, magic, damage, target);

            ActionList.Add(action);
        }
Пример #9
0
        public void ProcessSpell(MapObject ob)
        {
            if (Envir.Time < StartTime)
            {
                return;
            }
            switch (Spell)
            {
            case Spell.FireWall:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
            }
            break;

            case Spell.Healing:     //SafeZone
            {
                if (ob.Race != ObjectType.Player && (ob.Race != ObjectType.Monster || ob.Master == null || ob.Master.Race != ObjectType.Player))
                {
                    return;
                }
                if (ob.Dead || ob.HealAmount != 0 || ob.PercentHealth == 100)
                {
                    return;
                }

                ob.HealAmount += 25;
                Broadcast(new S.ObjectEffect {
                        ObjectID = ob.ObjectID, Effect = SpellEffect.Healing
                    });
            }
            break;

            case Spell.PoisonCloud:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                if (!ob.Dead)
                {
                    ob.ApplyPoison(new Poison
                        {
                            Duration  = 15,
                            Owner     = Caster,
                            PType     = PoisonType.Green,
                            TickSpeed = 2000,
                            Value     = Value / 20
                        }, Caster, false, false);
                }
            }
            break;

            case Spell.Blizzard:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && Caster.ActiveBlizzard == false)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                if (!ob.Dead && Envir.Random.Next(8) == 0)
                {
                    ob.ApplyPoison(new Poison
                        {
                            Duration  = 5 + Envir.Random.Next(Caster.Stats[Stat.Freezing]),
                            Owner     = Caster,
                            PType     = PoisonType.Slow,
                            TickSpeed = 2000,
                        }, Caster);
                }
            }
            break;

            case Spell.MeteorStrike:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && Caster.ActiveBlizzard == false)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
            }
            break;

            case Spell.ExplosiveTrap:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                if (DetonatedTrap)
                {
                    return;
                }
                DetonateTrapNow();
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
            }
            break;

            case Spell.MapLava:
            case Spell.MapLightning:
            {
                if (ob is PlayerObject player)
                {
                    if (player.Account.AdminAccount && player.Observer)
                    {
                        return;
                    }
                    player.Struck(Value, DefenceType.MAC);
                }
            }
            break;

            case Spell.MapQuake1:
            case Spell.MapQuake2:
            {
                if (Value == 0)
                {
                    return;
                }
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.MAC);
            }
            break;

            case Spell.Portal:
            {
                if (ob.Race != ObjectType.Player)
                {
                    return;
                }
                if (Caster != ob && (Caster == null || (Caster.GroupMembers == null) || (!Caster.GroupMembers.Contains((PlayerObject)ob))))
                {
                    return;
                }

                var portal = Envir.Objects.SingleOrDefault(ob => ob.Race == ObjectType.Spell &&
                                                           ob != this && ob.Node != null &&
                                                           ((SpellObject)ob).Spell == Spell.Portal &&
                                                           ((SpellObject)ob).Caster == Caster);

                if (portal != null)
                {
                    Point newExit = Functions.PointMove(portal.CurrentLocation, ob.Direction, 1);

                    if (!portal.CurrentMap.ValidPoint(newExit))
                    {
                        return;
                    }

                    ob.Teleport(portal.CurrentMap, newExit, false);
                }

                Value -= 1;

                if (Value < 1)
                {
                    ExpireTime = 0;
                }
            }
            break;
            }
        }
Пример #10
0
        public void ProcessSpell(MapObject ob)
        {
            if (Envir.Time < StartTime)
            {
                return;
            }
            List <MapObject> listtargets = new List <MapObject>();

            switch (Spell)
            {
            case Spell.FireWall:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                break;

            case Spell.Healing:     //SafeZone
                if (ob.Race != ObjectType.Player && (ob.Race != ObjectType.Monster || ob.Master == null || ob.Master.Race != ObjectType.Player))
                {
                    return;
                }
                if (ob.Dead || ob.HealAmount != 0 || ob.PercentHealth == 100)
                {
                    return;
                }

                ob.HealAmount += 25;
                Broadcast(new S.ObjectEffect {
                    ObjectID = ob.ObjectID, Effect = SpellEffect.Healing
                });
                break;

            case Spell.PoisonCloud:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                if (!ob.Dead)
                {
                    ob.ApplyPoison(new Poison
                    {
                        Duration  = 15,
                        Owner     = Caster,
                        PType     = PoisonType.Green,
                        TickSpeed = 2000,
                        Value     = Value / 20
                    }, Caster, false, false);
                }
                break;

            case Spell.HealingCircle:    //五行阵
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                //伤害敌军
                if (ob.IsAttackTarget(Caster))
                {
                    ob.Attacked(Caster, Value * 10 / 8, DefenceType.MAC, false);
                }
                else if (ob.IsFriendlyTarget(Caster))    //治疗友军
                {
                    //if (ob.HealAmount != 0 || ob.PercentHealth == 100) return;
                    if (ob.HealAmount > Value * 2 || ob.PercentHealth == 100)
                    {
                        return;
                    }
                    ob.HealAmount += (ushort)(Value * 2);
                    Broadcast(new S.ObjectEffect {
                        ObjectID = ob.ObjectID, Effect = SpellEffect.Healing
                    });
                }
                break;

            case Spell.MoonMist:    //月影雾
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                //伤害敌军
                if (ob.IsAttackTarget(Caster))
                {
                    ob.Attacked(Caster, Value * 10 / 8, DefenceType.MAC, false);
                }

                break;

            case Spell.Blizzard:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && Caster.ActiveBlizzard == false)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                if (!ob.Dead && Envir.Random.Next(8) == 0)
                {
                    ob.ApplyPoison(new Poison
                    {
                        Duration  = 5 + Envir.Random.Next(Caster.Freezing),
                        Owner     = Caster,
                        PType     = PoisonType.Slow,
                        TickSpeed = 2000,
                    }, Caster);
                }
                break;

            case Spell.MeteorStrike:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && Caster.ActiveBlizzard == false)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                break;

            case Spell.ExplosiveTrap:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                if (DetonatedTrap)
                {
                    return;                   //make sure explosion happens only once
                }
                DetonateTrapNow();
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                break;

            case Spell.MapLava:
                if (ob is PlayerObject)
                {
                    PlayerObject pOb = (PlayerObject)ob;
                    if (pOb.Observer)
                    {
                        return;
                    }
                    //这里要有伤害啊
                    ob.Struck(Value, DefenceType.MAC);
                }
                break;

            case Spell.MapLightning:
            {
                if (ob is PlayerObject player)
                {
                    if (player.Account.AdminAccount && player.Observer)
                    {
                        return;
                    }
                    player.Struck(Value, DefenceType.MAC);
                }
            }
            break;

            case Spell.MapQuake1:
            case Spell.MapQuake2:
                if (Value == 0)
                {
                    return;
                }
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.MAC);
                break;

            case Spell.Portal:
                if (ob.Race != ObjectType.Player)
                {
                    return;
                }
                if (Caster != ob && (Caster == null || (Caster.GroupMembers == null) || (!Caster.GroupMembers.Contains((PlayerObject)ob))))
                {
                    return;
                }

                if (ExitMap == null)
                {
                    return;
                }

                MirDirection dir = ob.Direction;

                Point newExit = Functions.PointMove(ExitCoord, dir, 1);

                if (!ExitMap.ValidPoint(newExit))
                {
                    return;
                }

                ob.Teleport(ExitMap, newExit, false);

                Value = Value - 1;

                if (Value < 1)
                {
                    ExpireTime = Envir.Time;
                    return;
                }

                break;


            case Spell.MonKITO:
                if (Tick == 2)
                {
                    Param = true;
                    Broadcast(GetInfo());
                    ExpireTime  = Envir.Time;
                    listtargets = CurrentMap.getMapObjects(CurrentLocation.X, CurrentLocation.Y, 2);
                    for (int o = 0; o < listtargets.Count; o++)
                    {
                        MapObject _ob = listtargets[o];
                        if (_ob.Race != ObjectType.Player && _ob.Race != ObjectType.Monster)
                        {
                            continue;
                        }
                        if (!_ob.IsAttackTarget(MonCaster))
                        {
                            continue;
                        }
                        _ob.Attacked(MonCaster, Value, DefenceType.MAC);
                    }
                }
                break;

            case Spell.MonFireCircle:
                if (Tick >= 6)
                {
                    ExpireTime = Envir.Time;
                }
                if (Tick > 1)
                {
                    Param = true;
                    Broadcast(GetInfo());
                    Param       = false;
                    listtargets = CurrentMap.getMapObjects(CurrentLocation.X, CurrentLocation.Y, 2);
                    for (int o = 0; o < listtargets.Count; o++)
                    {
                        MapObject _ob = listtargets[o];
                        if (_ob.Race != ObjectType.Player && _ob.Race != ObjectType.Monster)
                        {
                            continue;
                        }
                        if (!_ob.IsAttackTarget(MonCaster))
                        {
                            continue;
                        }
                        _ob.Attacked(MonCaster, Value, DefenceType.MAC);
                    }
                }
                break;

            case Spell.MonPoisonFog:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(MonCaster))
                {
                    return;
                }
                ob.Attacked(MonCaster, Value, DefenceType.MAC);
                break;

            case Spell.MonRotateAxe:
                if (Tick > 1)
                {
                    listtargets = CurrentMap.getMapObjects(CurrentLocation.X, CurrentLocation.Y, 2);
                    for (int o = 0; o < listtargets.Count; o++)
                    {
                        MapObject _ob = listtargets[o];
                        if (_ob.Race != ObjectType.Player && _ob.Race != ObjectType.Monster)
                        {
                            continue;
                        }
                        if (!_ob.IsAttackTarget(MonCaster))
                        {
                            continue;
                        }
                        _ob.Attacked(MonCaster, Value, DefenceType.MAC);
                    }
                }
                break;

            case Spell.MonGhostFlag1:    //鬼旗,附近5格的友军,解毒,加血
                if (Tick > 1)
                {
                    listtargets = CurrentMap.getMapObjects(CurrentLocation.X, CurrentLocation.Y, 5);
                    for (int o = 0; o < listtargets.Count; o++)
                    {
                        MapObject _ob = listtargets[o];
                        if (_ob.Race != ObjectType.Player && _ob.Race != ObjectType.Monster)
                        {
                            continue;
                        }
                        if (!_ob.IsFriendlyTarget(MonCaster))
                        {
                            continue;
                        }
                        _ob.PoisonList.Clear();
                        _ob.HealAmount = (ushort)Math.Min(ushort.MaxValue, _ob.HealAmount + Value);
                    }
                }
                break;

            case Spell.MonGhostHead:
                if (Tick >= RandomUtils.Next(2, 5))
                {
                    Param = true;
                    Broadcast(GetInfo());
                    ExpireTime  = Envir.Time;
                    listtargets = CurrentMap.getMapObjects(CurrentLocation.X, CurrentLocation.Y, 2);
                    for (int o = 0; o < listtargets.Count; o++)
                    {
                        MapObject _ob = listtargets[o];
                        if (_ob.Race != ObjectType.Player && _ob.Race != ObjectType.Monster)
                        {
                            continue;
                        }
                        if (!_ob.IsAttackTarget(MonCaster))
                        {
                            continue;
                        }
                        _ob.Attacked(MonCaster, Value, DefenceType.MAC);
                    }
                }
                break;
            }
        }
Пример #11
0
        public void ProcessSpell(MapObject ob)
        {
            if (Envir.Time < StartTime) return;
            switch (Spell)
            {
                case Spell.FireWall:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;

                    if (!ob.IsAttackTarget(Caster)) return;
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                    break;
                case Spell.Healing: //SafeZone
                    if (ob.Race != ObjectType.Player && (ob.Race != ObjectType.Monster || ob.Master == null || ob.Master.Race != ObjectType.Player)) return;
                    if (ob.Dead || ob.HealAmount != 0 || ob.PercentHealth == 100) return;

                    ob.HealAmount += 25;
                    Broadcast(new S.ObjectEffect {ObjectID = ob.ObjectID, Effect = SpellEffect.Healing});
                    break;
                case Spell.PoisonField:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;

                    if (!ob.IsAttackTarget(Caster)) return;
                    ob.Attacked(Caster, Value, DefenceType.None, false);
                    if (!ob.Dead)
                    ob.ApplyPoison(new Poison
                        {
                            Duration = 15,
                            Owner = Caster,
                            PType = PoisonType.Green,
                            TickSpeed = 2000,
                            Value = Value/20
                        }, Caster);
                    break;
                case Spell.Blizzard:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;
                    if (Caster.ActiveBlizzard == false) return;
                    if (!ob.IsAttackTarget(Caster)) return;
                    ob.Attacked(Caster, Value, DefenceType.MACAgility, false);
                    if (!ob.Dead && Envir.Random.Next(8) == 0)
                        ob.ApplyPoison(new Poison
                        {
                            Duration = 5 + Envir.Random.Next(Caster.Freezing),
                            Owner = Caster,
                            PType = PoisonType.Slow,
                            TickSpeed = 2000,
                        }, Caster);
                    break;
                case Spell.MeteorStrike:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;
                    if (Caster.ActiveBlizzard == false) return;
                    if (!ob.IsAttackTarget(Caster)) return;
                    ob.Attacked(Caster, Value, DefenceType.MACAgility, false);
                    break;
            }
        }
Пример #12
0
        public void ProcessSpell(MapObject ob)
        {
            if (Envir.Time < StartTime)
            {
                return;
            }
            switch (Spell)
            {
            case Spell.FireWall:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(((PlayerObject)Caster), Value, DefenceType.MAC, false);
            }
            break;

            case Spell.Healing:     //SafeZone
            {
                if (ob.Race != ObjectType.Player && (ob.Race != ObjectType.Monster || ob.Master == null || ob.Master.Race != ObjectType.Player))
                {
                    return;
                }
                if (ob.Dead || ob.HealAmount != 0 || ob.PercentHealth == 100)
                {
                    return;
                }

                ob.HealAmount += 25;
                Broadcast(new S.ObjectEffect {
                        ObjectID = ob.ObjectID, Effect = SpellEffect.Healing
                    });
            }
            break;

            case Spell.PoisonCloud:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(((PlayerObject)Caster), Value, DefenceType.MAC, false);
                if (!ob.Dead)
                {
                    ob.ApplyPoison(new Poison
                        {
                            Duration  = 12,
                            Owner     = Caster,
                            PType     = PoisonType.Green,
                            TickSpeed = TickSpeed,
                            Value     = (Caster.Stats[Stat.MinSC] + Caster.Stats[Stat.MaxSC]) / 2 + BonusDmg
                        }, Caster, false, false);
                }
            }
            break;

            case Spell.Blizzard:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && ((PlayerObject)Caster).ActiveBlizzard == false)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(((PlayerObject)Caster), Value, DefenceType.MAC, false);
                if (!ob.Dead && Envir.Random.Next(8) == 0)
                {
                    ob.ApplyPoison(new Poison
                        {
                            Duration  = 5 + Envir.Random.Next(Caster.Stats[Stat.Freezing]),
                            Owner     = Caster,
                            PType     = PoisonType.Slow,
                            TickSpeed = 2000,
                        }, Caster);
                }
            }
            break;

            case Spell.MeteorStrike:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && ((PlayerObject)Caster).ActiveBlizzard == false)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(((PlayerObject)Caster), Value, DefenceType.MAC, false);
            }
            break;

            case Spell.ExplosiveTrap:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                if (DetonatedTrap)
                {
                    return;
                }
                DetonateTrapNow();
                ob.Attacked(((PlayerObject)Caster), Value, DefenceType.MAC, false);
            }
            break;

            case Spell.MapLava:
            case Spell.MapLightning:
            {
                if (ob is PlayerObject player)
                {
                    if (player.Account.AdminAccount && player.Observer)
                    {
                        return;
                    }
                    player.Struck(Value, DefenceType.MAC);
                }
            }
            break;

            case Spell.MapQuake1:
            case Spell.MapQuake2:
            {
                if (Value == 0)
                {
                    return;
                }
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.MAC);
            }
            break;

            case Spell.GeneralMeowMeowThunder:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                if (Value == 0)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.MAC);
            }
            break;

            case Spell.TreeQueenRoot:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                if (Value == 0)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.MAC);
            }
            break;

            case Spell.TreeQueenMassRoots:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                if (Value == 0)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.MAC);
            }
            break;

            case Spell.TreeQueenGroundRoots:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                ob.Struck(Value, DefenceType.MAC);

                if (Envir.Random.Next(3) > 0)
                {
                    ob.ApplyPoison(new Poison {
                            PType = PoisonType.Paralysis, Duration = 5, TickSpeed = 1000
                        }, this);
                }
            }
            break;

            case Spell.StoneGolemQuake:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                if (Value == 0)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.AC);
            }
            break;

            case Spell.EarthGolemPile:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                if (Value == 0)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.AC);
            }
            break;

            case Spell.TucsonGeneralRock:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                if (Value == 0)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.AC);
            }
            break;

            case Spell.Portal:
            {
                if (ob.Race != ObjectType.Player)
                {
                    return;
                }
                if (Caster != ob && (Caster == null || (Caster.GroupMembers == null) || (!Caster.GroupMembers.Contains((PlayerObject)ob))))
                {
                    return;
                }

                var portal = Envir.Spells.SingleOrDefault(ob => ob != this && ob.Node != null &&
                                                          ob.Spell == Spell.Portal &&
                                                          ob.Caster == Caster);

                if (portal != null)
                {
                    Point newExit = Functions.PointMove(portal.CurrentLocation, ob.Direction, 1);

                    if (!portal.CurrentMap.ValidPoint(newExit))
                    {
                        return;
                    }

                    ob.Teleport(portal.CurrentMap, newExit, false);
                }

                Value -= 1;

                if (Value < 1)
                {
                    ExpireTime = 0;
                }
            }
            break;

            case Spell.FlyingStatueIceTornado:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                ob.Struck(Value, DefenceType.MAC);

                if (Envir.Random.Next(8) == 0)
                {
                    ob.ApplyPoison(new Poison {
                            PType = PoisonType.Slow, Duration = 5, TickSpeed = 1000
                        }, this);
                }
            }
            break;

            case Spell.DarkOmaKingNuke:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                ob.Struck(Value, DefenceType.AC);
                ob.ApplyPoison(new Poison {
                        PType = PoisonType.Dazed, Duration = 5, TickSpeed = 1000
                    }, this);
            }
            break;

            case Spell.HornedSorcererDustTornado:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                if (Value == 0)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.AC);
            }
            break;

            case Spell.HornedCommanderRockFall:
            case Spell.HornedCommanderRockSpike:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (ob == Caster)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                if (Value == 0)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.AC);
            }
            break;
            }
        }
Пример #13
0
        public void ProcessSpell(MapObject ob)
        {
            switch (Spell)
            {
                case Spell.FireWall:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;

                    if (!ob.IsAttackTarget(Caster)) return;
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                    break;
                case Spell.Healing: //SafeZone
                    if (ob.Race != ObjectType.Player && (ob.Race != ObjectType.Monster || ob.Master == null || ob.Master.Race != ObjectType.Player)) return;
                    if (ob.Dead || ob.HealAmount != 0 || ob.PercentHealth == 100) return;

                    ob.HealAmount += 25;
                    Broadcast(new S.ObjectEffect {ObjectID = ob.ObjectID, Effect = SpellEffect.Healing});
                    break;
                case Spell.PoisonField:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;

                    if (!ob.IsAttackTarget(Caster)) return;
                    ob.Attacked(Caster, Value, DefenceType.None, false);
                    if (!ob.Dead)
                    ob.ApplyPoison(new Poison
                        {
                            Duration = 15,
                            Owner = Caster,
                            PType = PoisonType.Green,
                            TickSpeed = 2000,
                            Value = Value/20
                        });
                    break;
            }
        }
Пример #14
0
        protected virtual void FindTarget()
        {
            Map Current = CurrentMap;

            for (int d = 0; d <= ViewRange; d++)
            {
                for (int y = CurrentLocation.Y - d; y <= CurrentLocation.Y + d; y++)
                {
                    if (y < 0)
                    {
                        continue;
                    }
                    if (y >= Current.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 >= Current.Width)
                        {
                            break;
                        }
                        Cell cell = Current.Cells[x, y];
                        if (cell.Objects == null || !cell.Valid)
                        {
                            continue;
                        }
                        for (int i = 0; i < cell.Objects.Count; i++)
                        {
                            MapObject ob = cell.Objects[i];
                            switch (ob.Race)
                            {
                            case ObjectType.Monster:
                            case ObjectType.Hero:
                                if (ob is TownArcher)
                                {
                                    continue;
                                }
                                if (!ob.IsAttackTarget(Owner))
                                {
                                    continue;
                                }
                                if (ob.Hidden && (!CoolEye || Level < ob.Level))
                                {
                                    continue;
                                }
                                if (ob.Master != null && Target != ob)
                                {
                                    continue;
                                }
                                if (Owner.Info.HeroBehaviour == HeroBehaviour.CounterAttack && ob.Target != this && ob.Target != Owner)
                                {
                                    continue;
                                }

                                Target = ob;
                                return;

                            case ObjectType.Player:
                                PlayerObject playerob = (PlayerObject)ob;
                                if (!ob.IsAttackTarget(Owner))
                                {
                                    continue;
                                }
                                if (playerob.GMGameMaster || ob.Hidden && (!CoolEye || Level < ob.Level))
                                {
                                    continue;
                                }
                                if (Target != ob && Owner.LastHitter != ob && ob.LastHitter != Owner)
                                {
                                    continue;
                                }

                                Target = ob;

                                if (Owner != null)
                                {
                                    for (int j = 0; j < playerob.Pets.Count; j++)
                                    {
                                        MonsterObject pet = playerob.Pets[j];

                                        if (!pet.IsAttackTarget(this))
                                        {
                                            continue;
                                        }
                                        Target = pet;
                                        break;
                                    }
                                }
                                return;

                            default:
                                continue;
                            }
                        }
                    }
                }
            }
        }
Пример #15
0
        private void TrapHexagon(UserMagic magic, MapObject target, out bool cast)
        {
            cast = false;

            if (target == null || !target.IsAttackTarget(this) || !(target is MonsterObject)) return;
            if (target.Level > Level + 2) return;

            UserItem item = GetAmulet(1);
            Point location = target.CurrentLocation;

            if (item == null) return;

            LevelMagic(magic);
            uint duration = (uint)((magic.Level * 5 + 10) * 1000);
            int value = (int)duration;

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + 500, this, magic, value, location);
            CurrentMap.ActionList.Add(action);

            ConsumeItem(item, 1);
            cast = true;
        }
Пример #16
0
        private bool ElementalShot(MapObject target, UserMagic magic)
        {
            if (HasElemental)
            {
                if (target == null || !target.IsAttackTarget(this)) return false;
                if ((Info.MentalState != 1) && !CanFly(target.CurrentLocation)) return false;

                int orbPower = magic.GetPower() + GetElementalOrbPower(false);//base power + orbpower

                int damage = GetAttackPower(MinMC, MaxMC) + orbPower;
                int delay = Functions.MaxDistance(CurrentLocation, target.CurrentLocation) * 50 + 500; //50 MS per Step

                DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + delay, magic, damage, target);
                ActionList.Add(action);
            }
            else
            {
                ObtainElement(true);//gather orb through casting
                LevelMagic(magic);
                return false;
            }
            return true;
        }
Пример #17
0
        private void Hallucination(MapObject target, UserMagic magic)
        {
            if (target == null || target.Race != ObjectType.Monster || !target.IsAttackTarget(this)) return;

            int damage = 0;
            int delay = Functions.MaxDistance(CurrentLocation, target.CurrentLocation) * 50 + 500; //50 MS per Step

            DelayedAction action = new DelayedAction(DelayedType.Magic, delay, magic, damage, target);

            ActionList.Add(action);
        }
Пример #18
0
        private bool Fireball(MapObject target, UserMagic magic)
        {
            if (target == null || !target.IsAttackTarget(this) || !CanFly(target.CurrentLocation)) return false;

            int damage = GetAttackPower(MinMC, MaxMC) + magic.GetPower();

            int delay = Functions.MaxDistance(CurrentLocation, target.CurrentLocation) * 50 + 500; //50 MS per Step

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + delay, magic, damage, target);

            //if(magic.Info.Spell == Spell.GreatFireBall && magic.Level >= 3 && target.Race == ObjectType.Monster)
            //{
            //    List<MapObject> targets = ((MonsterObject)target).FindAllNearby(3, target.CurrentLocation);

            //    int secondaryTargetCount = targets.Count > 3 ? 3 : targets.Count;

            //    for (int i = 0; i < secondaryTargetCount; i++)
            //    {
            //        if (!target.IsAttackTarget(this)) continue;
            //        DelayedAction action2 = new DelayedAction(DelayedType.Magic, Envir.Time + delay + 200, magic, damage / 2, targets[i]);
            //        ActionList.Add(action2);

            //        Enqueue(new S.Magic { Spell = magic.Info.Spell, TargetID = targets[i].ObjectID, Target = targets[i].CurrentLocation, Cast = true, Level = magic.Level });
            //        Broadcast(new S.ObjectMagic { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Spell = magic.Info.Spell, TargetID = targets[i].ObjectID, Target = targets[i].CurrentLocation, Cast = true, Level = magic.Level });
            //    }
            //}

            ActionList.Add(action);

            return true;
        }
Пример #19
0
        private void Trap(UserMagic magic, MapObject target, out bool cast)
        {
            cast = false;

            if (target == null || !target.IsAttackTarget(this) || !(target is MonsterObject)) return;
            if (target.Level >= Level + 2) return;

            Point location = target.CurrentLocation;

            LevelMagic(magic);
            uint duration = 60000;
            int value = (int)duration;

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + 500, this, magic, value, location);
            CurrentMap.ActionList.Add(action);
            cast = true;
        }
Пример #20
0
        private void Vampirism(MapObject target, UserMagic magic)
        {
            if (target == null || !target.IsAttackTarget(this)) return;

            int damage = GetAttackPower(MinMC, MaxMC) + magic.GetPower();

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + 500, magic, damage, target);

            ActionList.Add(action);
        }
Пример #21
0
        private bool DelayedExplosion(MapObject target, UserMagic magic)
        {
            if (target == null || !target.IsAttackTarget(this) || !CanFly(target.CurrentLocation)) return false;

            int power = GetAttackPower(MinMC, MaxMC) + magic.GetPower();
            int delay = Functions.MaxDistance(CurrentLocation, target.CurrentLocation) * 50 + 500; //50 MS per Step

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + delay, magic, power, target);
            ActionList.Add(action);
            return true;
        }
Пример #22
0
        private void TurnUndead(MapObject target, UserMagic magic)
        {
            if (target == null || target.Race != ObjectType.Monster || !target.Undead || !target.IsAttackTarget(this)) return;
            if (Envir.Random.Next(2) + Level - 1 <= target.Level)
            {
                target.Target = this;
                return;
            }

            int dif = Level - target.Level + 15;

            if (Envir.Random.Next(100) >= (magic.Level + 1 << 3) + dif)
            {
                target.Target = this;
                return;
            }

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + 500, magic, target);
            ActionList.Add(action);
        }
Пример #23
0
        public void BindingShot(UserMagic magic, MapObject target, out bool cast)
        {
            cast = false;

            if (target == null || !target.IsAttackTarget(this) || !(target is MonsterObject)) return;
            if ((Info.MentalState != 1) && !CanFly(target.CurrentLocation)) return;
            if (target.Level > Level + 2) return;
            if (((MonsterObject)target).ShockTime >= Envir.Time) return;//Already shocked


            uint duration = (uint)((magic.Level * 5 + 10) * 1000);
            int value = (int)duration;
            int delay = Functions.MaxDistance(CurrentLocation, target.CurrentLocation) * 50 + 500; //50 MS per Step

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + delay, magic, value, target);
            ActionList.Add(action);

            cast = true;
        }
Пример #24
0
        private void FlameDisruptor(MapObject target, UserMagic magic)
        {
            if (target == null || !target.IsAttackTarget(this)) return;

            int damage = GetAttackPower(MinMC, MaxMC) + magic.GetPower();

            if (!target.Undead) damage = (int)(damage * 1.5F);

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + 500, magic, damage, target);

            ActionList.Add(action);
        }
Пример #25
0
        public void NapalmShot(MapObject target, UserMagic magic)
        {
            if (target == null || !target.IsAttackTarget(this)) return;
            if ((Info.MentalState != 1) && !CanFly(target.CurrentLocation)) return;

            int distance = Functions.MaxDistance(CurrentLocation, target.CurrentLocation);
            int damage = (GetAttackPower(MinMC, MaxMC) + magic.GetPower());
            damage = ApplyArcherState(damage);

            int delay = distance * 50 + 500; //50 MS per Step

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + delay, this, magic, damage, target.CurrentLocation);
            CurrentMap.ActionList.Add(action);
        }
Пример #26
0
        private bool Poisoning(MapObject target, UserMagic magic)
        {
            if (target == null || !target.IsAttackTarget(this)) return false;

            UserItem item = GetPoison(1);
            if (item == null) return false;

            int power = GetAttackPower(MinSC, MaxSC);

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + 500, magic, power, target, item);
            ActionList.Add(action);
            ConsumeItem(item, 1);
            return true;
        }
Пример #27
0
        public void ProcessSpell(MapObject ob)
        {
            if (Envir.Time < StartTime)
            {
                return;
            }
            switch (Spell)
            {
            case Spell.FireWall:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                break;

            case Spell.Healing:     //SafeZone
                if (ob.Race != ObjectType.Player && (ob.Race != ObjectType.Monster || ob.Master == null || ob.Master.Race != ObjectType.Player))
                {
                    return;
                }
                if (ob.Dead || ob.HealAmount != 0 || ob.PercentHealth == 100)
                {
                    return;
                }

                ob.HealAmount += 25;
                Broadcast(new S.ObjectEffect {
                    ObjectID = ob.ObjectID, Effect = SpellEffect.Healing
                });
                break;

            case Spell.PoisonCloud:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.None, false);
                if (!ob.Dead)
                {
                    ob.ApplyPoison(new Poison
                    {
                        Duration  = 15,
                        Owner     = Caster,
                        PType     = PoisonType.Green,
                        TickSpeed = 2000,
                        Value     = Value / 20
                    }, Caster);
                }
                break;

            case Spell.Blizzard:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster.ActiveBlizzard == false)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MACAgility, false);
                if (!ob.Dead && Envir.Random.Next(8) == 0)
                {
                    ob.ApplyPoison(new Poison
                    {
                        Duration  = 5 + Envir.Random.Next(Caster.Freezing),
                        Owner     = Caster,
                        PType     = PoisonType.Slow,
                        TickSpeed = 2000,
                    }, Caster);
                }
                break;

            case Spell.MeteorStrike:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster.ActiveBlizzard == false)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                ob.Attacked(Caster, Value, DefenceType.MACAgility, false);
                break;

            case Spell.ExplosiveTrap:
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                if (DetonatedTrap)
                {
                    return;                   //make sure explosion happens only once
                }
                DetonateTrapNow();
                ob.Attacked(Caster, Value, DefenceType.MAC, false);
                break;

            case Spell.MapLava:
            case Spell.MapLightning:
                if (Value == 0)
                {
                    return;
                }
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.MAC);
                break;

            case Spell.Portal:
                if (ob.Race != ObjectType.Player)
                {
                    return;
                }
                if (Caster != ob && (Caster == null || (Caster.GroupMembers == null) || (!Caster.GroupMembers.Contains((PlayerObject)ob))))
                {
                    return;
                }

                if (ExitMap == null)
                {
                    return;
                }

                MirDirection dir = ob.Direction;

                Point newExit = Functions.PointMove(ExitCoord, dir, 1);

                if (!ExitMap.ValidPoint(newExit))
                {
                    return;
                }

                ob.Teleport(ExitMap, newExit, false);

                break;
            }
        }
Пример #28
0
        private bool SoulFireball(MapObject target, UserMagic magic, out bool cast)
        {
            cast = false;
            UserItem item = GetAmulet(1);
            if (item == null) return false;
            cast = true;

            if (target == null || !target.IsAttackTarget(this) || !CanFly(target.CurrentLocation)) return false;

            int damage = GetAttackPower(MinSC, MaxSC) + magic.GetPower();

            int delay = Functions.MaxDistance(CurrentLocation, target.CurrentLocation) * 50 + 500; //50 MS per Step

            DelayedAction action = new DelayedAction(DelayedType.Magic, Envir.Time + delay, magic, damage, target);

            ActionList.Add(action);
            ConsumeItem(item, 1);

            return true;
        }
Пример #29
0
        public void ProcessSpell(MapObject ob)
        {
            if (Envir.Time < StartTime) return;
            switch (Spell)
            {
                case Spell.FireWall:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;

                    if (!ob.IsAttackTarget(Caster)) return;
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                    break;
                case Spell.Healing: //SafeZone
                    if (ob.Race != ObjectType.Player && (ob.Race != ObjectType.Monster || ob.Master == null || ob.Master.Race != ObjectType.Player)) return;
                    if (ob.Dead || ob.HealAmount != 0 || ob.PercentHealth == 100) return;

                    ob.HealAmount += 25;
                    Broadcast(new S.ObjectEffect {ObjectID = ob.ObjectID, Effect = SpellEffect.Healing});
                    break;
                case Spell.PoisonCloud:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;

                    if (!ob.IsAttackTarget(Caster)) return;
                    ob.Attacked(Caster, Value, DefenceType.None, false);
                    if (!ob.Dead)
                    ob.ApplyPoison(new Poison
                        {
                            Duration = 15,
                            Owner = Caster,
                            PType = PoisonType.Green,
                            TickSpeed = 2000,
                            Value = Value/20
                        }, Caster, false, false);
                    break;
                case Spell.Blizzard:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;
                    if (Caster.ActiveBlizzard == false) return;
                    if (!ob.IsAttackTarget(Caster)) return;
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                    if (!ob.Dead && Envir.Random.Next(8) == 0)
                        ob.ApplyPoison(new Poison
                        {
                            Duration = 5 + Envir.Random.Next(Caster.Freezing),
                            Owner = Caster,
                            PType = PoisonType.Slow,
                            TickSpeed = 2000,
                        }, Caster);
                    break;
                case Spell.MeteorStrike:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;
                    if (Caster.ActiveBlizzard == false) return;
                    if (!ob.IsAttackTarget(Caster)) return;
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                    break;
                case Spell.ExplosiveTrap:
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;
                    if (!ob.IsAttackTarget(Caster)) return;
                    if (DetonatedTrap) return;//make sure explosion happens only once
                    DetonateTrapNow();
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                    break;
                case Spell.MapLava:
                case Spell.MapLightning:
                    if (Value == 0) return;
                    if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) return;
                    if (ob.Dead) return;
                    ob.Struck(Value, DefenceType.MAC);
                    break;

                case Spell.Portal:
                    if (ob.Race != ObjectType.Player) return;
                    if (Caster != ob && (Caster == null || (Caster.GroupMembers == null) || (!Caster.GroupMembers.Contains((PlayerObject)ob)))) return;

                    if (ExitMap == null) return;

                    MirDirection dir = ob.Direction;

                    Point newExit = Functions.PointMove(ExitCoord, dir, 1);

                    if (!ExitMap.ValidPoint(newExit)) return;

                    ob.Teleport(ExitMap, newExit, false);

                    break;
            }
        }
Пример #30
0
        public void ProcessSpell(MapObject ob)
        {
            if (Envir.Time < StartTime)
            {
                return;
            }
            switch (Spell)
            {
            case Spell.MoonMist:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && !Caster.ActiveBlizzard)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                if (ob.Race == ObjectType.Player)
                {
                    ob.Attacked(Caster, PvPValue, DefenceType.ACAgility, false);
                }
                else
                {
                    ob.Attacked(Caster, Value, DefenceType.ACAgility, false);
                }
            }
            break;

            case Spell.FireWall:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }

                if (ob.Race == ObjectType.Player)
                {
                    ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                }
                else
                {
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                }
            }
            break;

            case Spell.HealingCircle:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && ob.ObjectID == Caster.ObjectID)
                {
                    return;
                }
                if (ob.Race == ObjectType.Player)
                {
                    if (Caster.AMode == AttackMode.All)
                    {
                        if (ob.IsAttackTarget(Caster))
                        {
                            ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                            return;
                        }
                    }
                    else if (Caster.AMode == AttackMode.Group)
                    {
                        if (Caster.GroupMembers != null &&
                            Caster.GroupMembers.Contains(ob))
                        {
                            if (ob.Health < ob.MaxHealth)
                            {
                                ob.HealAmount  = (ushort)Math.Min(ushort.MaxValue, ob.HealAmount + Value);
                                ob.OperateTime = 0;
                                return;
                            }
                        }
                        else
                        {
                            if (ob.IsAttackTarget(Caster))
                            {
                                ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                                return;
                            }
                        }
                    }
                    else if (Caster.AMode == AttackMode.Guild)
                    {
                        if (Caster.MyGuild != null)
                        {
                            if (ob.Race == ObjectType.Player)
                            {
                                PlayerObject tmp = (PlayerObject)ob;
                                if (tmp.MyGuild != null &&
                                    tmp.MyGuild == Caster.MyGuild)
                                {
                                    if (ob.Health < ob.MaxHealth)
                                    {
                                        ob.HealAmount  = (ushort)Math.Min(ushort.MaxValue, ob.HealAmount + Value);
                                        ob.OperateTime = 0;
                                        return;
                                    }
                                }
                                else
                                {
                                    if (ob.IsAttackTarget(Caster))
                                    {
                                        ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                                        return;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (ob.IsAttackTarget(Caster))
                            {
                                ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                                return;
                            }
                        }
                    }
                    else if (Caster.AMode == AttackMode.RedBrown)
                    {
                        if (ob.IsAttackTarget(Caster))
                        {
                            if (ob.Race == ObjectType.Player)
                            {
                                PlayerObject tmp = (PlayerObject)ob;        //PKPoints < 200 & Envir.Time > BrownTime
                                if (tmp.PKPoints > 200 && Envir.Time > ob.BrownTime)
                                {
                                    ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                                    return;
                                }
                            }
                        }
                    }
                    else if (ob.Race == ObjectType.Player)
                    {
                        if (ob.Health < ob.MaxHealth)
                        {
                            ob.HealAmount  = (ushort)Math.Min(ushort.MaxValue, ob.HealAmount + Value);
                            ob.OperateTime = 0;
                            return;
                        }
                    }
                }
                else
                {
                    if (ob.IsAttackTarget(Caster))
                    {
                        ob.Attacked(Caster, Value, DefenceType.MAC, false);
                    }
                    return;
                }
            }
            break;

            case Spell.Healing:     //SafeZone
            {
                if (ob.Race != ObjectType.Player && (ob.Race != ObjectType.Monster || ob.Master == null || ob.Master.Race != ObjectType.Player))
                {
                    return;
                }
                if (ob.Dead || ob.HealAmount != 0 || ob.PercentHealth == 100)
                {
                    return;
                }

                ob.HealAmount += 25;
                Broadcast(new S.ObjectEffect {
                        ObjectID = ob.ObjectID, Effect = SpellEffect.Healing
                    });
            }
            break;

            case Spell.MobFireWall:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(MobCaster))
                {
                    return;
                }

                ob.Attacked(MobCaster, Value, DefenceType.MAC);
            }
            break;

            case Spell.CrystalBeastBlizz:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(MobCaster))
                {
                    return;
                }
                ob.Attacked(MobCaster, Value, DefenceType.MAC);
                if (!ob.Dead && Envir.Random.Next(8) == 0)
                {
                    ob.ApplyPoison(new Poison
                        {
                            Duration  = Envir.Random.Next(5),
                            Owner     = MobCaster,
                            PType     = PoisonType.Slow,
                            TickSpeed = 2000,
                        }, MobCaster);
                }
            }
            break;

            case Spell.MobPoisonCloud:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(MobCaster))
                {
                    return;
                }
                ob.Attacked(MobCaster, Value, DefenceType.MAC);
                if (!ob.Dead)
                {
                    ob.ApplyPoison(new Poison
                        {
                            Duration  = 15,
                            Owner     = MobCaster,
                            PType     = PoisonType.Green,
                            TickSpeed = 2000,
                            Value     = Value / 20
                        }, MobCaster, false, false);
                }
            }
            break;

            case Spell.MobBlizzard:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(MobCaster))
                {
                    return;
                }
                ob.Attacked(MobCaster, Value, DefenceType.MAC);
                if (!ob.Dead && Envir.Random.Next(8) == 0)
                {
                    ob.ApplyPoison(new Poison
                        {
                            Duration  = 5,
                            Owner     = MobCaster,
                            PType     = PoisonType.Slow,
                            TickSpeed = 2000,
                        }, MobCaster);
                }
            }
            break;

            case Spell.MobMeteorStrike:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(MobCaster))
                {
                    return;
                }
                ob.Attacked(MobCaster, Value, DefenceType.MAC);
            }
            break;

            case Spell.PoisonCloud:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                if (ob.Race == ObjectType.Player)
                {
                    ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                }
                else
                {
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                }
                if (!ob.Dead)
                {
                    if (ob.Race == ObjectType.Player)
                    {
                        ob.ApplyPoison(new Poison
                            {
                                Duration  = 15,
                                Owner     = Caster,
                                PType     = PoisonType.Green,
                                TickSpeed = 2000,
                                Value     = PvPValue / 20,
                            }, Caster);
                    }
                    else
                    {
                        ob.ApplyPoison(new Poison
                            {
                                Duration  = 15,
                                Owner     = Caster,
                                PType     = PoisonType.Green,
                                TickSpeed = 2000,
                                Value     = Value / 20,
                            }, Caster);
                    }
                }
            }
            break;

            case Spell.Blizzard:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && !Caster.ActiveBlizzard)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                //  This is the map event, every time the Process is trigger it'll run this code until it's expired
                if (ob.Race == ObjectType.Player)
                {
                    ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                }
                else
                {
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                }


                if (!ob.Dead && Envir.Random.Next(8) == 0)
                {
                    ob.ApplyPoison(new Poison
                        {
                            Duration  = 5 + Envir.Random.Next(Caster.Freezing),
                            Owner     = Caster,
                            PType     = PoisonType.Slow,
                            TickSpeed = 2000,
                        }, Caster);
                }
            }
            break;

            case Spell.FrozenRains:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }

                if (Caster != null && !Caster.ActiveBlizzard)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                if (ob.Race == ObjectType.Player)
                {
                    ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                }
                else
                {
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                }

                if (!ob.Dead && Envir.Random.Next(8) == 0)
                {
                    ob.ApplyPoison(new Poison
                        {
                            Duration  = 5 + Envir.Random.Next(Caster.Freezing),
                            Owner     = Caster,
                            PType     = PoisonType.Slow,
                            TickSpeed = 2000,
                        }, Caster);
                }
            }
            break;

            case Spell.LavaKing:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && !Caster.ActiveBlizzard)
                {
                    return;
                }
                if (Caster != null)
                {
                    if (!ob.IsAttackTarget(Caster))
                    {
                        return;
                    }
                    byte magicLevel = 0;
                    int  poisonVal  = 2;

                    if (ob.Race == ObjectType.Player)
                    {
                        poisonVal =
                            magicLevel == 0 ? 2 :
                            magicLevel == 1 ? 3 :
                            magicLevel == 2 ? 4 : 6;
                    }
                    else
                    {
                        poisonVal =
                            magicLevel == 0 ? 2 :
                            magicLevel == 1 ? 4 :
                            magicLevel == 2 ? 6 : 8;
                    }
                    if (ob.Race == ObjectType.Player)
                    {
                        ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                    }
                    else
                    {
                        ob.Attacked(Caster, Value, DefenceType.MAC, false);
                    }
                    if (!ob.Dead && Envir.Random.Next(8) == 0)
                    {
                        ob.ApplyPoison(new Poison
                            {
                                Duration  = Envir.Random.Next(2, 8),
                                Owner     = Caster,
                                PType     = PoisonType.Burning,
                                TickSpeed = 2000,
                                Value     = poisonVal
                            }, Caster);
                    }
                }
                else if (MobCaster != null)
                {
                    if (!ob.IsAttackTarget(MobCaster))
                    {
                        return;
                    }
                    ob.Attacked(MobCaster, ob.Race == ObjectType.Player ? (int)(Value * 0.75f) : Value, DefenceType.MAC);
                    if (!ob.Dead && Envir.Random.Next(8) == 0)
                    {
                        ob.ApplyPoison(new Poison
                            {
                                Duration  = Envir.Random.Next(2, 8),
                                Owner     = MobCaster,
                                PType     = PoisonType.Burning,
                                TickSpeed = 2000,
                                Value     = ob.Race == ObjectType.Player ? 2 : 4
                            }, Caster);
                    }
                }
                else
                {
                    return;
                }
            }
            break;

            case Spell.MeteorStrike:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (Caster != null && !Caster.ActiveBlizzard)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                if (ob.Race == ObjectType.Player)
                {
                    ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                }
                else
                {
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                }
            }
            break;

            case Spell.SoulReaper:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (MobCaster == null)
                {
                    if (Caster == null)
                    {
                        return;
                    }
                    if (ob.IsAttackTarget(Caster))
                    {
                        if (ob.Race == ObjectType.Player)
                        {
                            if (ob.Attacked(Caster, PvPValue, DefenceType.MAC) > 0 &&
                                !ob.Dead && Envir.Random.Next(8) == 0)
                            {
                                ob.ApplyPoison(new Poison
                                    {
                                        Duration  = 3,
                                        Owner     = Caster,
                                        PType     = PoisonType.Frozen,
                                        TickSpeed = 2000
                                    }, Caster);
                            }
                        }
                        else
                        if (ob.Attacked(Caster, Value, DefenceType.MAC) > 0 &&
                            !ob.Dead && Envir.Random.Next(8) == 0)
                        {
                            ob.ApplyPoison(new Poison
                                {
                                    Duration  = 3,
                                    Owner     = Caster,
                                    PType     = PoisonType.Frozen,
                                    TickSpeed = 2000
                                }, Caster);
                        }
                    }
                }
                else
                {
                    if (MobCaster.Master == null)
                    {
                        return;
                    }
                    if (!ob.IsAttackTarget(((PlayerObject)MobCaster.Master)))
                    {
                        return;
                    }
                    ob.Attacked(MobCaster, Value, DefenceType.MAC);
                    if (!ob.Dead && Envir.Random.Next(8) == 0)
                    {
                        ob.ApplyPoison(new Poison
                            {
                                Duration  = 3,
                                Owner     = MobCaster,
                                PType     = PoisonType.Frozen,
                                TickSpeed = 2000,
                            }, MobCaster);
                    }
                }
            }
            break;

            case Spell.ExplosiveTrap:
            {
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                if (!ob.IsAttackTarget(Caster))
                {
                    return;
                }
                if (DetonatedTrap)
                {
                    return;                       //make sure explosion happens only once
                }
                DetonateTrapNow();
                if (ob.Race == ObjectType.Player)
                {
                    ob.Attacked(Caster, PvPValue, DefenceType.MAC, false);
                }
                else
                {
                    ob.Attacked(Caster, Value, DefenceType.MAC, false);
                }
            }
            break;

            case Spell.MapLava:
            case Spell.MapLightning:
            case Spell.MapQuake1:
            case Spell.MapQuake2:
            {
                if (Value == 0)
                {
                    return;
                }
                if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster && ob.Race != ObjectType.Hero)
                {
                    return;
                }
                if (ob.Dead)
                {
                    return;
                }
                ob.Struck(Value, DefenceType.MAC);
            }
            break;

            case Spell.Portal:
            {
                if (ob.Race != ObjectType.Player)
                {
                    return;
                }
                if (Caster != ob && (Caster == null || (Caster.GroupMembers == null) || (!Caster.GroupMembers.Contains((PlayerObject)ob))))
                {
                    return;
                }

                if (ExitMap == null)
                {
                    return;
                }

                MirDirection dir = ob.Direction;

                Point newExit = Functions.PointMove(ExitCoord, dir, 1);

                if (!ExitMap.ValidPoint(newExit))
                {
                    return;
                }

                ob.Teleport(ExitMap, newExit, false);

                Value = Value - 1;

                if (Value < 1)
                {
                    ExpireTime = Envir.Time;
                    return;
                }
            }
            break;
            }
        }