diff --git a/Scripts/Items/Weapons/BaseWeapon.cs b/Scripts/Items/Weapons/BaseWeapon.cs index 03daa639d..6b1c3a053 100644 --- a/Scripts/Items/Weapons/BaseWeapon.cs +++ b/Scripts/Items/Weapons/BaseWeapon.cs @@ -1581,7 +1581,7 @@ namespace Server.Items bool ignoreArmor = ( a is ArmorIgnore || (move != null && move.IgnoreArmor( attacker )) ); - damageGiven = AOS.Damage( defender, attacker, damage, ignoreArmor, phys, fire, cold, pois, nrgy, chaos, direct, false, this is BaseRanged ); + damageGiven = AOS.Damage( defender, attacker, damage, ignoreArmor, phys, fire, cold, pois, nrgy, chaos, direct, false, this is BaseRanged, false ); double propertyBonus = ( move == null ) ? 1.0 : move.GetPropertyBonus( attacker ); diff --git a/Scripts/Misc/AOS.cs b/Scripts/Misc/AOS.cs index 0feb941e7..8e1cdf7c6 100644 --- a/Scripts/Misc/AOS.cs +++ b/Scripts/Misc/AOS.cs @@ -40,20 +40,20 @@ namespace Server public static int Damage( Mobile m, Mobile from, int damage, int phys, int fire, int cold, int pois, int nrgy ) { - return Damage( m, from, damage, false, phys, fire, cold, pois, nrgy, 0, 0, false, false ); + return Damage( m, from, damage, false, phys, fire, cold, pois, nrgy, 0, 0, false, false, false ); } public static int Damage( Mobile m, Mobile from, int damage, bool ignoreArmor, int phys, int fire, int cold, int pois, int nrgy ) { - return Damage( m, from, damage, ignoreArmor, phys, fire, cold, pois, nrgy, 0, 0, false, false ); + return Damage( m, from, damage, ignoreArmor, phys, fire, cold, pois, nrgy, 0, 0, false, false, false ); } public static int Damage( Mobile m, Mobile from, int damage, int phys, int fire, int cold, int pois, int nrgy, bool keepAlive ) { - return Damage( m, from, damage, false, phys, fire, cold, pois, nrgy, 0, 0, keepAlive, false ); + return Damage( m, from, damage, false, phys, fire, cold, pois, nrgy, 0, 0, keepAlive, false, false ); } - public static int Damage( Mobile m, Mobile from, int damage, bool ignoreArmor, int phys, int fire, int cold, int pois, int nrgy, int chaos, int direct, bool keepAlive, bool archer ) + public static int Damage( Mobile m, Mobile from, int damage, bool ignoreArmor, int phys, int fire, int cold, int pois, int nrgy, int chaos, int direct, bool keepAlive, bool archer, bool deathStrike ) { if( m == null || m.Deleted || !m.Alive || damage <= 0 ) return 0; @@ -127,7 +127,10 @@ namespace Server if ( quiver != null ) damage += damage * quiver.DamageIncrease / 100; - totalDamage = Math.Min( damage, 35 ); //Direct Damage cap of 35 + if ( !deathStrike ) + totalDamage = Math.Min( damage, 35 ); // Direct Damage cap of 35 + else + totalDamage = Math.Min( damage, 70 ); // Direct Damage cap of 70 } else { diff --git a/Scripts/Spells/Ninjitsu/DeathStrike.cs b/Scripts/Spells/Ninjitsu/DeathStrike.cs index d0f74319c..3223095bf 100644 --- a/Scripts/Spells/Ninjitsu/DeathStrike.cs +++ b/Scripts/Spells/Ninjitsu/DeathStrike.cs @@ -34,6 +34,10 @@ namespace Server.Spells.Ninjitsu double ninjitsu = attacker.Skills[SkillName.Ninjitsu].Value; double chance; + bool isRanged = false; // should be defined onHit method, what if the player hit and remove the weapon before process? ;) + + if ( attacker.Weapon is BaseRanged ) + isRanged = true; if( ninjitsu < 100 ) //This formula is an approximation from OSI data. TODO: find correct formula chance = 30 + (ninjitsu - 85) * 2.2; @@ -75,7 +79,7 @@ namespace Server.Spells.Ninjitsu defender.FixedParticles( 0x374A, 1, 17, 0x26BC, EffectLayer.Waist ); attacker.PlaySound( attacker.Female ? 0x50D : 0x50E ); - info = new DeathStrikeInfo( defender, attacker, damageBonus ); + info = new DeathStrikeInfo( defender, attacker, damageBonus, isRanged ); info.m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), new TimerStateCallback( ProcessDeathStrike ), defender ); m_Table[defender] = info; @@ -93,12 +97,14 @@ namespace Server.Spells.Ninjitsu public int m_Steps; public int m_DamageBonus; public Timer m_Timer; + public bool m_isRanged; - public DeathStrikeInfo( Mobile target, Mobile attacker, int damageBonus ) + public DeathStrikeInfo( Mobile target, Mobile attacker, int damageBonus, bool isRanged ) { m_Target = target; m_Attacker = attacker; m_DamageBonus = damageBonus; + m_isRanged = isRanged; } } @@ -122,26 +128,40 @@ namespace Server.Spells.Ninjitsu if( info == null ) //sanity return; - double ninjitsu = info.m_Attacker.Skills[SkillName.Ninjitsu].Fixed; - int divisor = (info.m_Steps >= 5) ? 30 : 80; + int maxDamage, damage = 0; - double baseDamage = ninjitsu / divisor; + double ninjitsu = info.m_Attacker.Skills[SkillName.Ninjitsu].Value; double stalkingBonus = Tracking.GetStalkingBonus( info.m_Attacker, info.m_Target ); - int maxDamage = (info.m_Steps >= 5) ? 62 : 22; + if ( Core.ML ) + { + double scalar = ( info.m_Attacker.Skills[SkillName.Hiding].Value + info.m_Attacker.Skills[SkillName.Stealth].Value ) / 220; - int damage = Math.Max( 0, Math.Min( maxDamage, (int)(baseDamage + stalkingBonus) ) ); + if ( scalar > 1 ) + scalar = 1; - // This bonus is 8 at most. That brings the cap up to 70/30. - damage += info.m_DamageBonus; + // New formula doesn't apply DamageBonus anymore, caps must be, directly, 60/30. + if ( info.m_Steps >= 5 ) + damage = (int)Math.Floor( Math.Min( 60, ( ninjitsu / 3 ) * ( 0.3 + 0.7 * scalar ) + stalkingBonus ) ); + else + damage = (int)Math.Floor( Math.Min( 30, ( ninjitsu / 9 ) * ( 0.3 + 0.7 * scalar ) + stalkingBonus ) ); - if ( info.m_Attacker.Weapon is BaseWeapon && ((BaseWeapon)info.m_Attacker.Weapon).MaxRange > 1 ) - damage /= 2; + if ( info.m_isRanged ) + damage /= 2; + } + else + { + int divisor = (info.m_Steps >= 5) ? 30 : 80; + double baseDamage = ninjitsu / divisor * 10; - // Damage is direct. - //info.m_Target.Damage( damage, info.m_Attacker ); + maxDamage = (info.m_Steps >= 5) ? 62 : 22; // DamageBonus is 8 at most. That brings the cap up to 70/30. + damage = Math.Max( 0, Math.Min( maxDamage, (int)( baseDamage + stalkingBonus ) ) ) + info.m_DamageBonus; + } - AOS.Damage( info.m_Target, info.m_Attacker, damage, true, 100, 0, 0, 0, 0 ); + if ( Core.ML ) + info.m_Target.Damage( damage, info.m_Attacker ); // Damage is direct. + else + AOS.Damage( info.m_Target, info.m_Attacker, damage, true, 100, 0, 0, 0, 0, 0, 0, false, false, true ); // Damage is physical. if( info.m_Timer != null ) info.m_Timer.Stop();