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)
To:
Step 2: [Pass the defender in the calling method of all for hitspell methods]
Change:
To:
Step 3: [Adding the SDI cap for PvP]
Change: (in the GetAosDamage method)
To:
And there you have it.
~ 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:
* 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 )
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.
~ 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: