예제 #1
0
        public override void OnThink()
        {
            base.OnThink();

            if (Combatant != null && DateTime.UtcNow > m_NextMeteorRainAllowed && DateTime.UtcNow > m_NextAbilityAllowed)
            {
                double spawnPercent = (double)intervalCount / (double)totalIntervals;

                int meteors = 30 + (int)(Math.Ceiling(50 * spawnPercent));

                int loops = (int)(Math.Ceiling((double)meteors / 10));

                double stationaryDelay = loops + 2.5;

                m_NextMeteorRainAllowed = DateTime.UtcNow + NextMeteorRainDelay + TimeSpan.FromSeconds(stationaryDelay);
                m_NextAbilityAllowed    = DateTime.UtcNow + NextAbilityAllowedDelay + TimeSpan.FromSeconds(stationaryDelay);

                PlaySound(GetAngerSound());

                AIObject.NextMove = DateTime.UtcNow + TimeSpan.FromSeconds(stationaryDelay);
                LastSwingTime     = LastSwingTime + TimeSpan.FromSeconds(stationaryDelay);

                NextSpellTime = NextSpellTime + TimeSpan.FromSeconds(stationaryDelay);
                NextCombatHealActionAllowed    = NextCombatHealActionAllowed + TimeSpan.FromSeconds(stationaryDelay);
                NextCombatSpecialActionAllowed = NextCombatSpecialActionAllowed + TimeSpan.FromSeconds(stationaryDelay);
                NextCombatEpicActionAllowed    = NextCombatEpicActionAllowed + TimeSpan.FromSeconds(stationaryDelay);

                Animate(23, 10, 1, true, false, 0);

                PublicOverheadMessage(MessageType.Regular, 0, false, "*rains down hellfire*");

                Point3D location = Location;
                Map     map      = Map;

                Timer.DelayCall(TimeSpan.FromSeconds(1.0), delegate
                {
                    if (this == null)
                    {
                        return;
                    }
                    if (this.Deleted)
                    {
                        return;
                    }

                    for (int a = 0; a < loops; a++)
                    {
                        Timer.DelayCall(TimeSpan.FromSeconds(a * 1), delegate
                        {
                            if (this == null)
                            {
                                return;
                            }
                            if (Deleted || !Alive)
                            {
                                return;
                            }

                            Animate(23, 10, 1, true, false, 0);

                            PlaySound(GetAngerSound());
                            Effects.PlaySound(location, map, 0x5CF);
                        });
                    }

                    for (int a = 0; a < meteors; a++)
                    {
                        Timer.DelayCall(TimeSpan.FromSeconds(a * .1), delegate
                        {
                            if (this == null)
                            {
                                return;
                            }
                            if (Deleted || !Alive)
                            {
                                return;
                            }

                            Point3D meteorLocation = new Point3D(location.X + Utility.RandomMinMax(-8, 8), location.Y + Utility.RandomMinMax(-8, 8), location.Z);

                            IEntity startLocation = new Entity(Serial.Zero, new Point3D(meteorLocation.X - 1, meteorLocation.Y - 1, meteorLocation.Z + 100), map);
                            IEntity endLocation   = new Entity(Serial.Zero, new Point3D(meteorLocation.X, meteorLocation.Y, meteorLocation.Z + 5), map);

                            int particleSpeed = 8 + (int)(Math.Round(8 * (double)spawnPercent));

                            Effects.SendMovingParticles(startLocation, endLocation, 0x36D4, particleSpeed, 0, false, false, 2613, 0, 9501, 0, 0, 0x100);

                            double impactDelay = .75 - (.375 * spawnPercent);

                            Timer.DelayCall(TimeSpan.FromSeconds(impactDelay), delegate
                            {
                                if (this == null)
                                {
                                    return;
                                }
                                if (Deleted || !Alive)
                                {
                                    return;
                                }

                                Effects.PlaySound(endLocation, map, 0x56E);
                                Effects.SendLocationParticles(endLocation, 0x3709, 10, 20, 2613, 0, 5029, 0);

                                Blood rocks  = new Blood();
                                rocks.Name   = "rocks";
                                rocks.Hue    = 2615;
                                rocks.ItemID = Utility.RandomList(4967, 4970, 4973);

                                Point3D rockLocation = new Point3D(meteorLocation.X, meteorLocation.Y, meteorLocation.Z);

                                rocks.MoveToWorld(rockLocation, map);

                                double firefieldChance = .20 + (.20 * spawnPercent);

                                if (Utility.RandomDouble() <= firefieldChance)
                                {
                                    Timer.DelayCall(TimeSpan.FromSeconds(.25), delegate
                                    {
                                        SingleFireField singleFireField = new SingleFireField(null, 2613, 1, 30, 3, 5, false, false, true, -1, true);
                                        singleFireField.MoveToWorld(rockLocation, map);
                                    });
                                }

                                IPooledEnumerable mobilesOnTile = map.GetMobilesInRange(meteorLocation, 1);

                                Queue m_Queue = new Queue();

                                foreach (Mobile mobile in mobilesOnTile)
                                {
                                    if (!mobile.CanBeDamaged() || !mobile.Alive || mobile.AccessLevel > AccessLevel.Player)
                                    {
                                        continue;
                                    }

                                    bool validTarget = false;

                                    PlayerMobile pm_Target = mobile as PlayerMobile;
                                    BaseCreature bc_Target = mobile as BaseCreature;

                                    if (pm_Target != null)
                                    {
                                        validTarget = true;
                                    }

                                    if (bc_Target != null)
                                    {
                                        if (bc_Target.Controlled && bc_Target.ControlMaster is PlayerMobile)
                                        {
                                            validTarget = true;
                                        }
                                    }

                                    if (validTarget)
                                    {
                                        m_Queue.Enqueue(mobile);
                                    }
                                }

                                mobilesOnTile.Free();

                                while (m_Queue.Count > 0)
                                {
                                    Mobile mobile = (Mobile)m_Queue.Dequeue();

                                    double damage = Utility.RandomMinMax((int)(Math.Round((double)DamageMin / 2)), DamageMin);

                                    if (mobile is BaseCreature)
                                    {
                                        damage *= 1.5;
                                    }

                                    new Blood().MoveToWorld(mobile.Location, mobile.Map);
                                    AOS.Damage(mobile, (int)damage, 0, 100, 0, 0, 0);
                                }
                            });
                        });
                    }
                });

                return;
            }

            if (Combatant != null && DateTime.UtcNow > m_NextFireBlastAllowed && DateTime.UtcNow > m_NextAbilityAllowed)
            {
                if (Combatant.Alive && !Combatant.Hidden && InLOS(Combatant) && GetDistanceToSqrt(Combatant) <= 12)
                {
                    m_NextFireBlastAllowed = DateTime.UtcNow + NextFireBlastDelay;
                    m_NextAbilityAllowed   = DateTime.UtcNow + NextAbilityAllowedDelay;

                    double effectTime      = 1.5;
                    double actionsCooldown = 3;

                    PlaySound(GetAngerSound());

                    AIObject.NextMove = DateTime.UtcNow + TimeSpan.FromSeconds(effectTime);
                    LastSwingTime     = LastSwingTime + TimeSpan.FromSeconds(effectTime);

                    NextSpellTime = NextSpellTime + TimeSpan.FromSeconds(actionsCooldown);
                    NextCombatHealActionAllowed    = NextCombatHealActionAllowed + TimeSpan.FromSeconds(actionsCooldown);
                    NextCombatSpecialActionAllowed = NextCombatSpecialActionAllowed + TimeSpan.FromSeconds(actionsCooldown);
                    NextCombatEpicActionAllowed    = NextCombatEpicActionAllowed + TimeSpan.FromSeconds(actionsCooldown);

                    Animate(6, 10, 1, true, false, 0);

                    int itemId  = 0x573E;
                    int itemHue = 0;

                    Point3D location       = Location;
                    Point3D targetLocation = Combatant.Location;
                    Map     map            = Combatant.Map;

                    Timer.DelayCall(TimeSpan.FromSeconds(.5), delegate
                    {
                        if (this == null)
                        {
                            return;
                        }
                        if (Deleted || !Alive)
                        {
                            return;
                        }

                        Effects.PlaySound(targetLocation, map, 0x5FC);

                        IEntity startLocation = new Entity(Serial.Zero, new Point3D(location.X, location.Y, location.Z + 20), map);
                        IEntity endLocation   = new Entity(Serial.Zero, new Point3D(targetLocation.X, targetLocation.Y, targetLocation.Z + 10), map);

                        Effects.SendMovingParticles(startLocation, endLocation, 0x36D4, 8, 0, false, false, 2613, 0, 9501, 0, 0, 0x100);

                        double distance         = GetDistanceToSqrt(targetLocation);
                        double destinationDelay = (double)distance * .06;

                        Timer.DelayCall(TimeSpan.FromSeconds(destinationDelay), delegate
                        {
                            double spawnPercent = (double)intervalCount / (double)totalIntervals;

                            Effects.PlaySound(targetLocation, map, 0x357);

                            Dictionary <Point3D, double> m_ExplosionLocations = new Dictionary <Point3D, double>();

                            m_ExplosionLocations.Add(targetLocation, 0);

                            int radius = 2 + (int)(Math.Ceiling(6 * spawnPercent));

                            int minRange = -1 * radius;
                            int maxRange = radius + 1;

                            for (int a = minRange; a < maxRange; a++)
                            {
                                for (int b = minRange; b < maxRange; b++)
                                {
                                    Point3D explosionPoint = new Point3D(targetLocation.X + a, targetLocation.Y + b, targetLocation.Z);

                                    int distanceFromCenter = Utility.GetDistance(targetLocation, explosionPoint);

                                    double fireburstChance = .25 + (.25 * spawnPercent);

                                    if (Utility.RandomDouble() <= fireburstChance)
                                    {
                                        if (!m_ExplosionLocations.ContainsKey(explosionPoint))
                                        {
                                            m_ExplosionLocations.Add(explosionPoint, distance);
                                        }
                                    }
                                }
                            }

                            foreach (KeyValuePair <Point3D, double> pair in m_ExplosionLocations)
                            {
                                Timer.DelayCall(TimeSpan.FromSeconds(pair.Value * .10), delegate
                                {
                                    Point3D explosionLocation = pair.Key;
                                    SpellHelper.AdjustField(ref explosionLocation, map, 12, false);

                                    Effects.PlaySound(pair.Key, map, 0x56D);
                                    Effects.SendLocationParticles(EffectItem.Create(explosionLocation, map, TimeSpan.FromSeconds(0.5)), 0x36BD, 20, 10, 2613, 0, 5044, 0);

                                    IPooledEnumerable mobilesOnTile = map.GetMobilesInRange(pair.Key, 0);

                                    Queue m_Queue = new Queue();

                                    foreach (Mobile mobile in mobilesOnTile)
                                    {
                                        if (!mobile.CanBeDamaged() || !mobile.Alive || mobile.AccessLevel > AccessLevel.Player)
                                        {
                                            continue;
                                        }

                                        bool validTarget = false;

                                        PlayerMobile pm_Target = mobile as PlayerMobile;
                                        BaseCreature bc_Target = mobile as BaseCreature;

                                        if (pm_Target != null)
                                        {
                                            validTarget = true;
                                        }

                                        if (bc_Target != null)
                                        {
                                            if (bc_Target.Controlled && bc_Target.ControlMaster is PlayerMobile)
                                            {
                                                validTarget = true;
                                            }
                                        }

                                        if (validTarget)
                                        {
                                            m_Queue.Enqueue(mobile);
                                        }
                                    }

                                    mobilesOnTile.Free();

                                    while (m_Queue.Count > 0)
                                    {
                                        Mobile mobile = (Mobile)m_Queue.Dequeue();

                                        double damage = DamageMin;

                                        if (mobile is BaseCreature)
                                        {
                                            damage *= 1.5;
                                        }

                                        new Blood().MoveToWorld(mobile.Location, mobile.Map);
                                        AOS.Damage(mobile, (int)damage, 0, 100, 0, 0, 0);
                                    }
                                });
                            }
                        });
                    });
                }

                return;
            }

            if (Utility.RandomDouble() < .01 && DateTime.UtcNow > m_NextAIChangeAllowed)
            {
                Effects.PlaySound(Location, Map, GetAngerSound());

                switch (Utility.RandomMinMax(1, 5))
                {
                case 1:
                    DictCombatTargetingWeight[CombatTargetingWeight.Player]           = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.Closest]          = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.HighestHitPoints] = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.LowestHitPoints]  = 0;
                    break;

                case 2:
                    DictCombatTargetingWeight[CombatTargetingWeight.Player]           = 10;
                    DictCombatTargetingWeight[CombatTargetingWeight.Closest]          = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.HighestHitPoints] = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.LowestHitPoints]  = 0;
                    break;

                case 3:
                    DictCombatTargetingWeight[CombatTargetingWeight.Player]           = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.Closest]          = 10;
                    DictCombatTargetingWeight[CombatTargetingWeight.HighestHitPoints] = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.LowestHitPoints]  = 0;
                    break;

                case 4:
                    DictCombatTargetingWeight[CombatTargetingWeight.Player]           = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.Closest]          = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.HighestHitPoints] = 10;
                    DictCombatTargetingWeight[CombatTargetingWeight.LowestHitPoints]  = 0;
                    break;

                case 5:
                    DictCombatTargetingWeight[CombatTargetingWeight.Player]           = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.Closest]          = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.HighestHitPoints] = 0;
                    DictCombatTargetingWeight[CombatTargetingWeight.LowestHitPoints]  = 10;
                    break;
                }

                m_NextAIChangeAllowed = DateTime.UtcNow + NextAIChangeDelay;
            }
        }
예제 #2
0
        protected override void OnThrownAt(Mobile m, IEntity target)
        {
            if (m == null || m.Deleted || target == null)
            {
                return;
            }

            if (ImpactSound >= 0)
            {
                Effects.PlaySound(target.Location, target.Map, ImpactSound);
            }

            ThrownLast = DateTime.UtcNow;

            LastUsed = DateTime.UtcNow + ThrowRecovery;

            if (target is BaseCreature)
            {
                var creature = target as BaseCreature;
                if (creature.Alive)
                {
                    m.DoHarmful(creature);
                    creature.Damage(Utility.RandomMinMax(5, 20), m);
                }

                int range   = 1;
                int zOffset = 10;

                Point3D src    = target.Location.Clone3D(0, 0, zOffset);
                var     points = src.GetAllPointsInRange(target.Map, range, range);

                Effects.PlaySound(target.Location, target.Map, 0x19C);

                Timer.DelayCall(
                    TimeSpan.FromMilliseconds(100),
                    () =>
                {
                    foreach (Point3D trg in points)
                    {
                        int bloodID = Utility.RandomMinMax(4650, 4655);

                        new MovingEffectInfo(src, trg.Clone3D(0, 0, 2), target.Map, bloodID).MovingImpact(
                            info =>
                        {
                            var blood = new Blood
                            {
                                ItemID = bloodID
                            };
                            blood.MoveToWorld(info.Target.Location, info.Map);

                            Effects.PlaySound(info.Target, info.Map, 0x028);
                        });
                    }
                });
            }

            if (ThrowRecovery > TimeSpan.Zero)
            {
                if (UpdateTimer == null)
                {
                    UpdateTimer = PollTimer.FromSeconds(
                        1.0,
                        () =>
                    {
                        ClearProperties();
                        Delta(ItemDelta.Properties);

                        DateTime readyWhen = ThrownLast + ThrowRecovery;

                        if (DateTime.UtcNow < readyWhen)
                        {
                            return;
                        }

                        m.EndAction(GetType());

                        if (UpdateTimer == null)
                        {
                            return;
                        }

                        UpdateTimer.Running = false;
                        UpdateTimer         = null;
                    });
                }
                else
                {
                    UpdateTimer.Running = true;
                }
            }
            else
            {
                if (UpdateTimer != null)
                {
                    UpdateTimer.Running = false;
                    UpdateTimer         = null;
                }

                ClearProperties();
                Delta(ItemDelta.Properties);
                m.EndAction(GetType());
            }
        }
예제 #3
0
        public virtual void BeginTunnel()
        {
            if (this == null)
            {
                return;
            }
            if (Deleted || !Alive)
            {
                return;
            }

            int digSound = 0x247;

            CantWalk = true;

            Say("*begins to dig a tunnel back to its magical lair*");
            SpecialAbilities.HinderSpecialAbility(1.0, this, this, 1.0, 1, true, digSound, false, "", "", "-1");

            digging = true;

            //Dirt
            int dirtCount = Utility.RandomMinMax(2, 3);

            for (int b = 0; b < dirtCount; b++)
            {
                Blood dirt = new Blood();
                dirt.Name   = "dirt";
                dirt.ItemID = Utility.RandomList(7681, 7682);
                Point3D dirtLocation = new Point3D(Location.X + Utility.RandomList(-2, -1, 1, 2), Location.Y + Utility.RandomList(-2, -1, 1, 2), Z);
                dirt.MoveToWorld(dirtLocation, Map);
            }

            new BunnyHole().MoveToWorld(Location, Map);

            Animate(3, 5, 1, true, false, 0);

            for (int a = 1; a < 5; a++)
            {
                Timer.DelayCall(TimeSpan.FromSeconds(a), delegate
                {
                    if (this == null)
                    {
                        return;
                    }
                    if (Deleted || !Alive)
                    {
                        return;
                    }

                    Animate(3, 5, 1, true, false, 0);

                    Say("*digs*");
                    SpecialAbilities.HinderSpecialAbility(1.0, this, this, 1.0, 1, false, digSound, false, "", "", "-1");

                    //Dirt
                    int extraDirtCount = Utility.RandomMinMax(2, 3);

                    for (int b = 0; b < extraDirtCount; b++)
                    {
                        Blood extraDirt           = new Blood();
                        extraDirt.Name            = "dirt";
                        extraDirt.ItemID          = Utility.RandomList(7681, 7682);
                        Point3D extraDirtLocation = new Point3D(Location.X + Utility.RandomList(-2, -1, 1, 2), Location.Y + Utility.RandomList(-2, -1, 1, 2), Z);
                        extraDirt.MoveToWorld(extraDirtLocation, Map);
                    }
                });
            }

            Timer.DelayCall(TimeSpan.FromSeconds(5.0), delegate
            {
                if (this == null)
                {
                    return;
                }
                if (Deleted || !Alive)
                {
                    return;
                }

                Say("*poof*");

                Effects.PlaySound(Location, Map, 0x657);
                Effects.SendLocationParticles(EffectItem.Create(Location, Map, TimeSpan.FromSeconds(5)), 0x3728, 10, 10, 2023);

                Delete();
            });
        }