Beispiel #1
0
        public static void SiegeRepair_Callback(object state)
        {
            object[] args = (object[])state;

            Mobile   from  = (Mobile)args[0];
            XmlSiege a     = (XmlSiege)args[1];
            int      nhits = (int)args[2];

            if (a != null)
            {
                a.Hits += nhits;
                from.SendMessage("{0} hits repaired", nhits);
                a.BeingRepaired = false;
            }
        }
Beispiel #2
0
            protected override void OnTick()
            {
                ISiegeProjectile pitem = this.m_Projectile as ISiegeProjectile;

                if (this.m_weapon != null && !this.m_weapon.Deleted && pitem != null)
                {
                    int animationid  = pitem.AnimationID;
                    int animationhue = pitem.AnimationHue;

                    switch (this.m_step)
                    {
                    case 0:
                    case 4:
                        this.m_weapon.DisplayLaunch(0);
                        break;

                    case 1:
                    case 3:
                        this.m_weapon.DisplayLaunch(1);
                        break;

                    case 2:
                        this.m_weapon.DisplayLaunch(2);
                        // launch sounds
                        Effects.PlaySound(this.m_weapon, this.m_weapon.Map, 0x4C9);
                        Effects.PlaySound(this.m_weapon, this.m_weapon.Map, 0x2B2);

                        // show the projectile moving to the target
                        if (this.m_target is Mobile)
                        {
                            XmlSiege.SendMovingProjectileEffect(this.m_weapon, null, animationid, this.m_weapon.ProjectileLaunchPoint, this.m_targetloc, 7, 0, false, true, animationhue);
                        }
                        else
                        {
                            XmlSiege.SendMovingProjectileEffect(this.m_weapon, this.m_target, animationid, this.m_weapon.ProjectileLaunchPoint, this.m_targetloc, 7, 0, false, true, animationhue);
                        }
                        // delayed damage at the target to account for travel distance of the projectile
                        Timer.DelayCall(this.m_damagedelay, new TimerStateCallback(this.m_weapon.DamageTarget_Callback),
                                        new object[] { this.m_from, this.m_weapon, this.m_target, this.m_targetloc, this.m_Projectile });
                        break;
                    }

                    // advance to the next step
                    this.m_weapon.DoTimer(this.m_from, this.m_weapon, this.m_target, this.m_targetloc, this.m_Projectile, this.m_damagedelay, ++this.m_step);
                }
            }
        public virtual void LaunchProjectile(Mobile from, Item projectile, IEntity target, Point3D targetloc, TimeSpan delay)
        {
            ISiegeProjectile pitem = projectile as ISiegeProjectile;

            if (pitem == null)
            {
                return;
            }

            int animationid  = pitem.AnimationID;
            int animationhue = pitem.AnimationHue;

            // show the projectile moving to the target
            XmlSiege.SendMovingProjectileEffect(this, target, animationid, this.ProjectileLaunchPoint, targetloc, 7, 0, false, true, animationhue);

            // delayed damage at the target to account for travel distance of the projectile
            Timer.DelayCall(delay, new TimerStateCallback(DamageTarget_Callback),
                            new object[] { from, this, target, targetloc, projectile });

            return;
        }
        public virtual bool AttackTarget(Mobile from, IEntity target, Point3D targetloc, bool checkLOS)
        {
            ISiegeProjectile projectile = this.m_Projectile as ISiegeProjectile;

            if (from == null || from.Map == null || projectile == null)
            {
                return(false);
            }

            if (!this.HasFiringAngle(targetloc))
            {
                from.SendMessage("No firing angle");
                return(false);
            }

            // check the target range
            int distance = (int)XmlSiege.GetDistance(targetloc, this.Location);

            int projectilerange = (int)(projectile.Range * this.WeaponRangeFactor);

            if (projectilerange < distance)
            {
                from.SendMessage("Out of range");
                return(false);
            }

            if (distance <= this.MinTargetRange)
            {
                from.SendMessage("Target is too close");
                return(false);
            }

            // check the target line of sight
            int height = 1;

            if (target is Item)
            {
                height = ((Item)target).ItemData.Height;
            }
            else if (target is Mobile)
            {
                height = 14;
            }

            Point3D adjustedloc = new Point3D(targetloc.X, targetloc.Y, targetloc.Z + height);

            if (checkLOS && !this.Map.LineOfSight(this, adjustedloc))
            {
                from.SendMessage("Cannot see target");
                return(false);
            }

            // ok, the projectile is being fired
            // calculate attack parameters
            double firingspeedbonus = projectile.FiringSpeed / 10.0;
            double dexbonus         = (double)from.Dex / 30.0;
            int    weaponskill      = (int)from.Skills[SkillName.ArmsLore].Value;

            int accuracybonus = projectile.AccuracyBonus;

            // calculate the cooldown time with dexterity bonus and firing speed bonus on top of the base delay
            double loadingdelay = this.WeaponLoadingDelay - dexbonus - firingspeedbonus;

            this.m_NextFiringTime = DateTime.UtcNow + TimeSpan.FromSeconds(loadingdelay);

            // calculate the accuracy based on distance and weapon skill
            int accuracy = distance * 10 - weaponskill + accuracybonus;

            if (Utility.Random(100) < accuracy)
            {
                from.SendMessage("Target missed");
                // consume the ammunition
                this.m_Projectile.Consume(1);
                // update the properties display
                this.Projectile = this.m_Projectile;
                return(true);
            }

            this.LaunchProjectile(from, this.m_Projectile, target, targetloc, TimeSpan.FromSeconds((double)distance * 0.08));

            return(true);
        }
Beispiel #5
0
        private void Explode(Mobile from, Point3D loc, Map map)
        {
            if (map == null)
            {
                return;
            }

            IPooledEnumerable eable     = map.GetObjectsInRange(loc, 2);
            ArrayList         toExplode = new ArrayList();

            foreach (object o in eable)
            {
                if (o is Mobile || o is BaseMulti || o is BaseAddon || o is PelopsItem)
                {
                    toExplode.Add(o);
                }
            }

            eable.Free();
            int d         = 0;     // Damage scalar
            int damage    = 0;
            int MinDamage = 6;
            int MaxDamage = 60;

            for (int i = 0; i < toExplode.Count; ++i)
            {
                object o;
                o = toExplode[i];

                if (o is Mobile)
                {
                    Mobile m = (Mobile)o;
                    if (m.InRange(loc, 0))
                    {
                        d = 1;
                    }
                    else if (m.InRange(loc, 1))
                    {
                        d = 2;
                    }
                    else if (m.InRange(loc, 2))
                    {
                        d = 3;
                    }
                    if (from != null || (SpellHelper.ValidIndirectTarget(from, m) && from.CanBeHarmful(m, false)))
                    {
                        if (from != null)
                        {
                            from.DoHarmful(m);
                        }
                        damage = Utility.RandomMinMax((MinDamage / d), (MaxDamage / d));
                        if (d == 1)
                        {
                            AOS.Damage(m, from, damage, 50, 50, 0, 0, 0);                               // Same tile 50% physical 50% fire
                        }
                        else
                        {
                            AOS.Damage(m, from, damage, 0, 100, 0, 0, 0);                               // 2 tile radius 100% fire damage
                        }
                    }
                }
                else if (o is BaseMulti || o is BaseAddon /*|| o is PelopsItem*/)
                {
                    // apply siege damage, all physical
                    XmlSiege.Attack(from, o, 60, 0);
                }
            }
        }
        public void OnHit(Mobile from, ISiegeWeapon weapon, IEntity target, Point3D targetloc)
        {
            if (weapon == null || from == null)
            {
                return;
            }

            // play explosion sound at target

            Effects.PlaySound(targetloc, weapon.Map, 0x11D);

            ArrayList damagelist = new ArrayList();

            // deal with the fact that for multis, the targetloc and the actual multi location may differ
            // so deal the multi damage first
            if (target is BaseMulti)
            {
                XmlSiege a = (XmlSiege)XmlAttach.FindAttachment(target, typeof(XmlSiege));

                if (a != null)
                {
                    damagelist.Add(a);
                }
            }

            // apply splash damage to objects with a siege attachment
            IPooledEnumerable itemlist = from.Map.GetItemsInRange(targetloc, this.Area);

            if (itemlist != null)
            {
                foreach (Item item in itemlist)
                {
                    if (item == null || item.Deleted)
                    {
                        continue;
                    }

                    XmlSiege a = (XmlSiege)XmlAttach.FindAttachment(item, typeof(XmlSiege));

                    if (a != null && !damagelist.Contains(a))
                    {
                        damagelist.Add(a);
                    }
                    else if (item is AddonComponent)
                    {
                        a = (XmlSiege)XmlAttach.FindAttachment(((AddonComponent)item).Addon, typeof(XmlSiege));

                        if (a != null && !damagelist.Contains(a))
                        {
                            damagelist.Add(a);
                        }
                    }
                }
            }

            int scaledfiredamage     = (int)(this.FireDamage * this.StructureDamageMultiplier * weapon.WeaponDamageFactor);
            int scaledphysicaldamage = (int)(this.PhysicalDamage * this.StructureDamageMultiplier * weapon.WeaponDamageFactor);

            foreach (XmlSiege a in damagelist)
            {
                // apply siege damage
                a.ApplyScaledDamage(from, scaledfiredamage, scaledphysicaldamage);
            }

            // apply splash damage to mobiles
            ArrayList mobdamage = new ArrayList();

            IPooledEnumerable moblist = from.Map.GetMobilesInRange(targetloc, this.Area);

            if (moblist != null)
            {
                foreach (Mobile m in moblist)
                {
                    if (m == null || m.Deleted || !from.CanBeHarmful(m, false))
                    {
                        continue;
                    }

                    mobdamage.Add(m);
                }
            }

            int totaldamage = this.FireDamage + this.PhysicalDamage;

            if (totaldamage > 0)
            {
                int scaledmobdamage = (int)(totaldamage * this.MobDamageMultiplier * weapon.WeaponDamageFactor);
                int phys            = 100 * this.PhysicalDamage / totaldamage;
                int fire            = 100 * this.FireDamage / totaldamage;
                foreach (Mobile m in mobdamage)
                {
                    // AOS.Damage( Mobile m, Mobile from, int damage, int phys, int fire, int cold, int pois, int nrgy )
                    AOS.Damage(m, from, scaledmobdamage, phys, fire, 0, 0, 0);
                }
            }

            // consume the ammunition
            this.Consume(1);
            weapon.Projectile = this;
        }
Beispiel #7
0
        public virtual bool AttackTarget(Mobile from, IEntity target, Point3D targetloc, bool checkLOS)
        {
            ISiegeProjectile projectile = m_Projectile as ISiegeProjectile;

            if (from == null || from.Map == null || projectile == null)
            {
                return(false);
            }

            if (!HasFiringAngle(targetloc))
            {
                from.SendMessage("No firing angle");
                return(false);
            }

            // check the target range
            int distance = (int)XmlSiege.GetDistance(targetloc, Location);

            int projectilerange = (int)(projectile.Range * WeaponRangeFactor);

            if (projectilerange < distance)
            {
                from.SendMessage("Out of range");
                return(false);
            }

            if (distance <= MinTargetRange)
            {
                from.SendMessage("Target is too close");
                return(false);
            }

            // check the target line of sight
            int height = 1;

            if (target is Item)
            {
                height = ((Item)target).ItemData.Height;
            }
            else if (target is Mobile)
            {
                height = 14;
            }

            Point3D adjustedloc = new Point3D(targetloc.X, targetloc.Y, targetloc.Z + height);

            if (checkLOS && !Map.LineOfSight(this, adjustedloc))
            {
                from.SendMessage("Cannot see target");
                return(false);
            }

            // ok, the projectile is being fired
            // calculate attack parameters
            double firingspeedbonus = projectile.FiringSpeed / 10.0;
            double dexbonus         = (double)from.Dex / 30.0;

            // calculate the cooldown time with dexterity bonus and firing speed bonus on top of the base delay
            double loadingdelay = WeaponLoadingDelay - dexbonus - firingspeedbonus;

            m_NextFiringTime = DateTime.UtcNow + TimeSpan.FromSeconds(loadingdelay);

            LaunchProjectile(from, m_Projectile, target, targetloc, TimeSpan.FromSeconds((double)distance * 0.05));

            return(true);
        }
        public void OnHit(Mobile from, ISiegeWeapon weapon, IEntity target, Point3D targetloc)
        {
            if (weapon == null || from == null)
            {
                return;
            }

            // play explosion sound at target

            Effects.PlaySound(targetloc, weapon.Map, 0x11D);

            // show effects in the area around target
            int explosion  = 0x36b0;
            int firecolumn = 0x3709;
            var rectangle  = new Rectangle2D(targetloc.X - Area, targetloc.Y - Area, Area * 2 + 1, Area * 2 + 1);

            // iterate coordinates of rectangle
            for (int x = rectangle.Start.X; x < rectangle.End.X; x++)
            {
                for (int y = rectangle.Start.Y; y < rectangle.End.Y; y++)
                {
                    if (Utility.RandomBool())
                    {
                        Effects.SendLocationEffect(new Point3D(x, y, targetloc.Z), from.Map, explosion, 13);
                    }
                    else
                    {
                        Effects.SendLocationEffect(new Point3D(x, y, targetloc.Z), from.Map, firecolumn, 15);
                    }
                }
            }

            ArrayList damagelist = new ArrayList();

            // deal with the fact that for multis, the targetloc and the actual multi location may differ
            // so deal the multi damage first
            if (target is BaseMulti)
            {
                XmlSiege a = (XmlSiege)XmlAttach.FindAttachment(target, typeof(XmlSiege));

                if (a != null)
                {
                    damagelist.Add(a);
                }
            }

            // apply splash damage to objects with a siege attachment
            IPooledEnumerable itemlist = from.Map.GetItemsInRange(targetloc, Area);

            if (itemlist != null)
            {
                foreach (Item item in itemlist)
                {
                    if (item == null || item.Deleted)
                    {
                        continue;
                    }

                    XmlSiege a = (XmlSiege)XmlAttach.FindAttachment(item, typeof(XmlSiege));

                    if (a != null && !damagelist.Contains(a))
                    {
                        damagelist.Add(a);
                    }
                    else
                    // if it had no siege attachment and the item is an addoncomponent, then check the parent addon
                    if (item is AddonComponent)
                    {
                        a = (XmlSiege)XmlAttach.FindAttachment(((AddonComponent)item).Addon, typeof(XmlSiege));

                        if (a != null && !damagelist.Contains(a))
                        {
                            damagelist.Add(a);
                        }
                    }
                }
                itemlist.Free();
            }

            int scaledfiredamage     = (int)(FireDamage * StructureDamageMultiplier * weapon.WeaponDamageFactor);
            int scaledphysicaldamage = (int)(PhysicalDamage * StructureDamageMultiplier * weapon.WeaponDamageFactor);

            foreach (XmlSiege a in damagelist)
            {
                // apply siege damage
                a.ApplyScaledDamage(from, scaledfiredamage, scaledphysicaldamage);
            }

            // apply splash damage to mobiles
            ArrayList mobdamage = new ArrayList();

            IPooledEnumerable moblist = from.Map.GetMobilesInRange(targetloc, Area);

            if (moblist != null)
            {
                foreach (Mobile m in moblist)
                {
                    if (m == null || m.Deleted || !from.CanBeHarmful(m, false))
                    {
                        continue;
                    }

                    mobdamage.Add(m);
                }
                moblist.Free();
            }

            int totaldamage = FireDamage + PhysicalDamage;

            if (totaldamage > 0)
            {
                int scaledmobdamage = (int)(totaldamage * MobDamageMultiplier * weapon.WeaponDamageFactor);
                int phys            = 100 * PhysicalDamage / totaldamage;
                int fire            = 100 * FireDamage / totaldamage;
                foreach (Mobile m in mobdamage)
                {
                    // AOS.Damage( Mobile m, Mobile from, int damage, int phys, int fire, int cold, int pois, int nrgy )
                    AOS.Damage(m, from, scaledmobdamage, phys, fire, 0, 0, 0);
                }
            }

            // consume the ammunition
            if (!weapon.FreeConsume())
            {
                Consume(1);
            }
            weapon.Projectile = this;
        }
Beispiel #9
0
            protected override void OnTarget(Mobile from, object targeted)
            {
                if (from == null || m_tool == null || from.Map == null)
                {
                    return;
                }

                // find any xmlsiege attachment on the target
                XmlSiege a = (XmlSiege)XmlAttach.FindAttachment(targeted, typeof(XmlSiege));

                // if it isnt on the target, but the target is an addon, then check the addon
                if (a == null && targeted is AddonComponent)
                {
                    a = (XmlSiege)XmlAttach.FindAttachment(((AddonComponent)targeted).Addon, typeof(XmlSiege));
                }

                // if it still isnt found, the look for nearby targets
                if (a == null)
                {
                    Point3D loc = Point3D.Zero;
                    if (targeted is IEntity)
                    {
                        loc = ((IEntity)targeted).Location;
                    }
                    else
                    if (targeted is StaticTarget)
                    {
                        loc = ((StaticTarget)targeted).Location;
                    }
                    else
                    if (targeted is LandTarget)
                    {
                        loc = ((LandTarget)targeted).Location;
                    }

                    if (loc != Point3D.Zero)
                    {
                        foreach (Item p in from.Map.GetItemsInRange(loc, RepairRange))
                        {
                            a = (XmlSiege)XmlAttach.FindAttachment(p, typeof(XmlSiege));
                            if (a != null)
                            {
                                break;
                            }
                        }
                    }
                }

                // repair the target
                if (a != null)
                {
                    if (a.Hits >= a.HitsMax)
                    {
                        from.SendMessage("This does not require repair.");
                        return;
                    }

                    if (a.BeingRepaired)
                    {
                        from.SendMessage("You must wait to repair again.");
                        return;
                    }
                    Container pack = from.Backpack;

                    // does the player have it?
                    if (pack != null)
                    {
                        int nhits = 0;



                        double resourcepenalty = 1;

                        // require more resources for repairing destroyed structures
                        if (a.Hits == 0)
                        {
                            resourcepenalty = RepairDestroyedResourcePenalty;
                        }

                        // dont consume resources for staff
                        if (from.AccessLevel > AccessLevel.Player)
                        {
                            resourcepenalty = 0;
                        }

                        int requirediron  = (int)(a.Iron * resourcepenalty);
                        int requiredstone = (int)(a.Stone * resourcepenalty);
                        int requiredwood  = (int)(a.Wood * resourcepenalty);

                        int niron  = pack.ConsumeUpTo(typeof(IronIngot), requirediron);
                        int nstone = pack.ConsumeUpTo(typeof(BaseGranite), requiredstone);
                        int nwood  = pack.ConsumeUpTo(typeof(Board), requiredwood);

                        if (niron == requirediron && nstone == requiredstone && nwood == requiredwood)
                        {
                            nhits += m_tool.HitsPerRepair;
                        }



                        if (nhits == 0)
                        {
                            from.SendMessage("Insufficient resources to complete the repair. Resources lost.");
                            return;
                        }
                        from.PlaySound(0x2A);                         // play anvil sound
                        from.SendMessage("You begin your repair");

                        m_tool.UsesRemaining--;
                        if (m_tool.UsesRemaining == 0)
                        {
                            from.SendLocalizedMessage(1044038);                             // You have worn out your tool!
                            m_tool.Delete();
                        }

                        a.BeingRepaired = true;

                        double smithskill     = from.Skills[SkillName.Blacksmith].Value;
                        double carpentryskill = from.Skills[SkillName.Carpentry].Value;

                        double timepenalty = 1;
                        if (a.Hits == 0)
                        {
                            // repairing destroyed structures requires more time
                            timepenalty = RepairDestroyedTimePenalty;
                        }

                        // compute repair speed with modifiers
                        TimeSpan repairtime = TimeSpan.FromSeconds(m_tool.BaseRepairTime * timepenalty - from.Dex / 40.0 - smithskill / 50.0 - carpentryskill / 50.0);

                        // allow staff instant repair
                        if (from.AccessLevel > AccessLevel.Player)
                        {
                            repairtime = TimeSpan.Zero;
                        }

                        // setup for the delayed repair
                        Timer.DelayCall(repairtime, new TimerStateCallback(SiegeRepair_Callback), new object[] { from, a, nhits });
                    }
                }
                else
                {
                    from.SendMessage("Invalid target");
                    return;
                }
            }