ModernUO/Scripts/Misc/RegenRates.cs
2018-09-14 14:32:04 -07:00

220 lines
6.1 KiB
C#

using System;
using Server.Items;
using Server.Spells;
using Server.Spells.Necromancy;
using Server.Spells.Ninjitsu;
using Server.Mobiles;
namespace Server.Misc
{
public class RegenRates
{
[CallPriority( 10 )]
public static void Configure()
{
Mobile.DefaultHitsRate = TimeSpan.FromSeconds( 11.0 );
Mobile.DefaultStamRate = TimeSpan.FromSeconds( 7.0 );
Mobile.DefaultManaRate = TimeSpan.FromSeconds( 7.0 );
Mobile.ManaRegenRateHandler = Mobile_ManaRegenRate;
if ( Core.AOS )
{
Mobile.StamRegenRateHandler = Mobile_StamRegenRate;
Mobile.HitsRegenRateHandler = Mobile_HitsRegenRate;
}
}
private static void CheckBonusSkill( Mobile m, int cur, int max, SkillName skill )
{
if ( !m.Alive )
return;
double n = (double)cur / max;
double v = Math.Sqrt( m.Skills[skill].Value * 0.005 );
n *= (1.0 - v);
n += v;
m.CheckSkill( skill, n );
}
private static bool CheckTransform( Mobile m, Type type )
{
return TransformationSpellHelper.UnderTransformation( m, type );
}
private static bool CheckAnimal( Mobile m, Type type )
{
return AnimalForm.UnderTransformation( m, type );
}
private static TimeSpan Mobile_HitsRegenRate( Mobile from )
{
int points = AosAttributes.GetValue( from, AosAttribute.RegenHits );
BaseCreature bc = from as BaseCreature;
if ( bc != null && !bc.IsAnimatedDead )
points += 4;
if ( bc?.IsParagon == true || from is Leviathan )
points += 40;
if ( Core.ML && from.Race == Race.Human ) //Is this affected by the cap?
points += 2;
if ( points < 0 )
points = 0;
if ( Core.ML && from is PlayerMobile ) //does racial bonus go before/after?
points = Math.Min( points, 18 );
if ( CheckTransform( from, typeof( HorrificBeastSpell ) ) )
points += 20;
if ( CheckAnimal( from, typeof( Dog ) ) || CheckAnimal( from, typeof( Cat ) ) )
points += from.Skills[SkillName.Ninjitsu].Fixed / 30;
return TimeSpan.FromSeconds( 1.0 / (0.1 * (1 + points)) );
}
private static TimeSpan Mobile_StamRegenRate( Mobile from )
{
if ( from.Skills == null )
return Mobile.DefaultStamRate;
CheckBonusSkill( from, from.Stam, from.StamMax, SkillName.Focus );
int points =(int)(from.Skills[SkillName.Focus].Value * 0.1);
if ( (from is BaseCreature creature && creature.IsParagon) || from is Leviathan )
points += 40;
int cappedPoints = AosAttributes.GetValue( from, AosAttribute.RegenStam );
if ( CheckTransform( from, typeof( VampiricEmbraceSpell ) ) )
cappedPoints += 15;
if ( CheckAnimal( from, typeof( Kirin ) ) )
cappedPoints += 20;
if ( Core.ML && from is PlayerMobile )
cappedPoints = Math.Min( cappedPoints, 24 );
points += cappedPoints;
if ( points < -1 )
points = -1;
return TimeSpan.FromSeconds( 1.0 / (0.1 * (2 + points)) );
}
private static TimeSpan Mobile_ManaRegenRate( Mobile from )
{
if ( from.Skills == null )
return Mobile.DefaultManaRate;
if ( !from.Meditating )
CheckBonusSkill( from, from.Mana, from.ManaMax, SkillName.Meditation );
double rate;
double armorPenalty = GetArmorOffset( from );
if ( Core.AOS )
{
double medPoints = from.Int + (from.Skills[SkillName.Meditation].Value * 3);
medPoints *= ( from.Skills[SkillName.Meditation].Value < 100.0 ) ? 0.025 : 0.0275;
CheckBonusSkill( from, from.Mana, from.ManaMax, SkillName.Focus );
double focusPoints = (from.Skills[SkillName.Focus].Value * 0.05);
if ( armorPenalty > 0 )
medPoints = 0; // In AOS, wearing any meditation-blocking armor completely removes meditation bonus
double totalPoints = focusPoints + medPoints + (from.Meditating ? (medPoints > 13.0 ? 13.0 : medPoints) : 0.0);
if ( (from is BaseCreature creature && creature.IsParagon) || from is Leviathan )
totalPoints += 40;
int cappedPoints = AosAttributes.GetValue( from, AosAttribute.RegenMana );
if ( CheckTransform( from, typeof( VampiricEmbraceSpell ) ) )
cappedPoints += 3;
else if ( CheckTransform( from, typeof( LichFormSpell ) ) )
cappedPoints += 13;
if ( Core.ML && from is PlayerMobile )
cappedPoints = Math.Min( cappedPoints, 18 );
totalPoints += cappedPoints;
if ( totalPoints < -1 )
totalPoints = -1;
if ( Core.ML )
totalPoints = Math.Floor( totalPoints );
rate = 1.0 / (0.1 * (2 + totalPoints));
}
else
{
double medPoints = (from.Int + from.Skills[SkillName.Meditation].Value) * 0.5;
if ( medPoints <= 0 )
rate = 7.0;
else if ( medPoints <= 100 )
rate = 7.0 - (239*medPoints/2400) + (19*medPoints*medPoints/48000);
else if ( medPoints < 120 )
rate = 1.0;
else
rate = 0.75;
rate += armorPenalty;
if ( from.Meditating )
rate *= 0.5;
if ( rate < 0.5 )
rate = 0.5;
else if ( rate > 7.0 )
rate = 7.0;
}
return TimeSpan.FromSeconds( rate );
}
public static double GetArmorOffset( Mobile from )
{
double rating = 0.0;
if ( !Core.AOS )
rating += GetArmorMeditationValue( from.ShieldArmor as BaseArmor );
rating += GetArmorMeditationValue( from.NeckArmor as BaseArmor );
rating += GetArmorMeditationValue( from.HandArmor as BaseArmor );
rating += GetArmorMeditationValue( from.HeadArmor as BaseArmor );
rating += GetArmorMeditationValue( from.ArmsArmor as BaseArmor );
rating += GetArmorMeditationValue( from.LegsArmor as BaseArmor );
rating += GetArmorMeditationValue( from.ChestArmor as BaseArmor );
return rating / 4;
}
private static double GetArmorMeditationValue( BaseArmor ar )
{
if ( ar == null || ar.ArmorAttributes.MageArmor != 0 || ar.Attributes.SpellChanneling != 0 )
return 0.0;
switch ( ar.MeditationAllowance )
{
default:
case ArmorMeditationAllowance.None: return ar.BaseArmorRatingScaled;
case ArmorMeditationAllowance.Half: return ar.BaseArmorRatingScaled / 2.0;
case ArmorMeditationAllowance.All: return 0.0;
}
}
}
}