RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

How to Cap SDI in PVP for Hit Spells (Solution)

Iraq-

Sorceror
How to Cap SDI in PVP for Hit Spells (Solution)
* This mod was created in RunUO 2.1, however the concept is still the same in all versions.

For those who don't know, SDI on Weapon Hit Spells in PvP is left Uncapped on both OSI and RunUO. However, with many custom servers now running systems such as Runecrafting, Imbueing, and Item Leveling, you may be interested in capping the amount of damage a hit spell can do to another player.

By following just a few simple steps, your server's PvP can be instantly balanced with a SDI cap of 15% for hit spells too. ;)

Step 1: [Add the defender to the mobile list]:
Change: (2/3rds of the way down in BaseWeapon.cs)
Code:
public virtual double GetAosDamage( Mobile attacker, int bonus, int dice, int sides )
To:
Code:
public virtual double GetAosDamage( Mobile attacker, int bonus, int dice, int sides, Mobile defender )

Step 2: [Pass the defender in the calling method of all for hitspell methods]
Change:
Code:
        #region Do<AoSEffect>
        public virtual void DoMagicArrow( Mobile attacker, Mobile defender )
        {
            if ( !attacker.CanBeHarmful( defender, false ) )
                return;

            attacker.DoHarmful( defender );

            double damage = GetAosDamage( attacker, 10, 1, 4 );

            attacker.MovingParticles( defender, 0x36E4, 5, 0, false, true, 3006, 4006, 0 );
            attacker.PlaySound( 0x1E5 );

            SpellHelper.Damage( TimeSpan.FromSeconds( 1.0 ), defender, attacker, damage, 0, 100, 0, 0, 0 );
        }

        public virtual void DoHarm( Mobile attacker, Mobile defender )
        {
            if ( !attacker.CanBeHarmful( defender, false ) )
                return;

            attacker.DoHarmful( defender );

            double damage = GetAosDamage( attacker, 17, 1, 5);

            if ( !defender.InRange( attacker, 2 ) )
                damage *= 0.25; // 1/4 damage at > 2 tile range
            else if ( !defender.InRange( attacker, 1 ) )
                damage *= 0.50; // 1/2 damage at 2 tile range

            defender.FixedParticles( 0x374A, 10, 30, 5013, 1153, 2, EffectLayer.Waist );
            defender.PlaySound( 0x0FC );

            SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 100, 0, 0 );
        }

        public virtual void DoFireball( Mobile attacker, Mobile defender )
        {
            if ( !attacker.CanBeHarmful( defender, false ) )
                return;

            attacker.DoHarmful( defender );

            double damage = GetAosDamage( attacker, 19, 1, 5 );

            attacker.MovingParticles( defender, 0x36D4, 7, 0, false, true, 9502, 4019, 0x160 );
            attacker.PlaySound( 0x15E );

            SpellHelper.Damage( TimeSpan.FromSeconds( 1.0 ), defender, attacker, damage, 0, 100, 0, 0, 0 );
        }

        public virtual void DoLightning( Mobile attacker, Mobile defender )
        {
            if ( !attacker.CanBeHarmful( defender, false ) )
                return;

            attacker.DoHarmful( defender );

            double damage = GetAosDamage( attacker, 23, 1, 4 );

            defender.BoltEffect( 0 );

            SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 0, 0, 100 );
        }

To:
Code:
        #region Do<AoSEffect>
        public virtual void DoMagicArrow( Mobile attacker, Mobile defender )
        {
            if ( !attacker.CanBeHarmful( defender, false ) )
                return;

            attacker.DoHarmful( defender );

            double damage = GetAosDamage( attacker, 10, 1, 4, defender );

            attacker.MovingParticles( defender, 0x36E4, 5, 0, false, true, 3006, 4006, 0 );
            attacker.PlaySound( 0x1E5 );

            SpellHelper.Damage( TimeSpan.FromSeconds( 1.0 ), defender, attacker, damage, 0, 100, 0, 0, 0 );
        }

        public virtual void DoHarm( Mobile attacker, Mobile defender )
        {
            if ( !attacker.CanBeHarmful( defender, false ) )
                return;

            attacker.DoHarmful( defender );

            double damage = GetAosDamage( attacker, 17, 1, 5, defender );

            if ( !defender.InRange( attacker, 2 ) )
                damage *= 0.25; // 1/4 damage at > 2 tile range
            else if ( !defender.InRange( attacker, 1 ) )
                damage *= 0.50; // 1/2 damage at 2 tile range

            defender.FixedParticles( 0x374A, 10, 30, 5013, 1153, 2, EffectLayer.Waist );
            defender.PlaySound( 0x0FC );

            SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 100, 0, 0 );
        }

        public virtual void DoFireball( Mobile attacker, Mobile defender )
        {
            if ( !attacker.CanBeHarmful( defender, false ) )
                return;

            attacker.DoHarmful( defender );

            double damage = GetAosDamage( attacker, 19, 1, 5, defender );

            attacker.MovingParticles( defender, 0x36D4, 7, 0, false, true, 9502, 4019, 0x160 );
            attacker.PlaySound( 0x15E );

            SpellHelper.Damage( TimeSpan.FromSeconds( 1.0 ), defender, attacker, damage, 0, 100, 0, 0, 0 );
        }

        public virtual void DoLightning( Mobile attacker, Mobile defender )
        {
            if ( !attacker.CanBeHarmful( defender, false ) )
                return;

            attacker.DoHarmful( defender );

            double damage = GetAosDamage( attacker, 23, 1, 4, defender );

            defender.BoltEffect( 0 );

            SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 0, 0, 100 );
        }

Step 3: [Adding the SDI cap for PvP]
Change: (in the GetAosDamage method)
Code:
        public virtual double GetAosDamage( Mobile attacker, int bonus, int dice, int sides, Mobile defender )
        {
            int damage = Utility.Dice( dice, sides, bonus ) * 100;
            int damageBonus = 0;

            // Inscription bonus
            int inscribeSkill = attacker.Skills[SkillName.Inscribe].Fixed;

            damageBonus += inscribeSkill / 200;

            if ( inscribeSkill >= 1000 )
                damageBonus += 5;

            if ( attacker.Player )
            {
                // Int bonus
                damageBonus += (attacker.Int / 10);

                // SDI bonus
                damageBonus += AosAttributes.GetValue( attacker, AosAttribute.SpellDamage );

                TransformContext context = TransformationSpellHelper.GetContext( attacker );

                if( context != null && context.Spell is ReaperFormSpell )
                    damageBonus += ((ReaperFormSpell)context.Spell).SpellDamageBonus;
            }

            damage = AOS.Scale( damage, 100 + damageBonus );

            return damage / 100;
        }

To:
Code:
        public virtual double GetAosDamage( Mobile attacker, int bonus, int dice, int sides, Mobile defender )
        {
            int damage = Utility.Dice( dice, sides, bonus ) * 100;
            int damageBonus = 0;
            int sdiBonus = 0;

            // Inscription bonus
            int inscribeSkill = attacker.Skills[SkillName.Inscribe].Fixed;

            damageBonus += inscribeSkill / 200;

            if ( inscribeSkill >= 1000 )
                damageBonus += 5;

            if ( attacker.Player )
            {
                // Int bonus
                damageBonus += (attacker.Int / 10);

                // SDI bonus
                // PvP spell damage increase cap of 15% from an item’s magic property

                sdiBonus = AosAttributes.GetValue( attacker, AosAttribute.SpellDamage );

                if ( defender.Player && sdiBonus > 15 )
                    sdiBonus = 15;

                damageBonus += sdiBonus;

                TransformContext context = TransformationSpellHelper.GetContext( attacker );

                if( context != null && context.Spell is ReaperFormSpell )
                    damageBonus += ((ReaperFormSpell)context.Spell).SpellDamageBonus;
            }

            damage = AOS.Scale( damage, 100 + damageBonus );

            return damage / 100;
        }

And there you have it. :D
~ Iraq-

If you are running Runuo2.1 like I am, then here is my BaseWeapon.cs, you can just replace or merge yours with mine:
 

Attachments

  • BaseWeapon.cs
    104 KB · Views: 15
Top