skillcaps and things that exceed it Possible threading issue Addition of Generic FindItemsByType - List<T> findItemsByType<T>() Change to make polymorph not have a timer and instead a toggle skill KiAttack no longer works with ranged weapons Poison strike speed and damage changed Necro spells now affected by FC Must have atleast 50 weapon skill if no shield equipped to use Evasion Stalking bonus capped at 10 + skill/10 Stalking bonus now Clears Bugfix w/Guilds Crashguard Exception message moved closer to the top of the file. Character creation of Pallys and necros using advanced skills now gives skill items Honor no longer works on Players Pre-ML area HitArea attacks nolonger require LoS Serialization fix for BladeOfTheRighteous RidingSwipe now has paralyzation immunity as with NerveStrike and ParaBlow AnkhEast renamed to AnkhNorth LeggingsOfBane no longer have 510 HP ElvenWashBasinEastAddon Fixed AnsellaGryen won't be renamed each time the server Restarts DiseasedCats are properly named Localization fixes in DefBlacksmithy BearMasks/DearMAsks and things that extend from them now can be repaired
205 lines
No EOL
5.8 KiB
C#
205 lines
No EOL
5.8 KiB
C#
using System;
|
|
using Server;
|
|
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 );
|
|
//TODO: Pub 42 regen limits
|
|
|
|
Mobile.ManaRegenRateHandler = new RegenRateHandler( Mobile_ManaRegenRate );
|
|
|
|
if ( Core.AOS )
|
|
{
|
|
Mobile.StamRegenRateHandler = new RegenRateHandler( Mobile_StamRegenRate );
|
|
Mobile.HitsRegenRateHandler = new RegenRateHandler( 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 TransformationSpell.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 );
|
|
|
|
if ( from is BaseCreature && !((BaseCreature)from).IsAnimatedDead )
|
|
points += 4;
|
|
|
|
if ( (from is BaseCreature && ((BaseCreature)from).IsParagon) || from is Leviathan )
|
|
points += 40;
|
|
|
|
if ( CheckTransform( from, typeof( HorrificBeastSpell ) ) )
|
|
points += 20;
|
|
|
|
if ( CheckAnimal( from, typeof( Dog ) ) || CheckAnimal( from, typeof( Cat ) ) )
|
|
points += from.Skills[SkillName.Ninjitsu].Fixed / 300;
|
|
//TODO: What's the new increased rate?
|
|
|
|
if( Core.ML && from.Race == Race.Human )
|
|
points += 2;
|
|
|
|
if ( points < 0 )
|
|
points = 0;
|
|
|
|
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);
|
|
|
|
points += AosAttributes.GetValue( from, AosAttribute.RegenStam );
|
|
|
|
if ( CheckTransform( from, typeof( VampiricEmbraceSpell ) ) )
|
|
points += 15;
|
|
|
|
if ( CheckAnimal( from, typeof( Kirin ) ) )
|
|
points += 20;
|
|
|
|
if ( (from is BaseCreature && ((BaseCreature)from).IsParagon) || from is Leviathan )
|
|
points += 40;
|
|
|
|
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 = (int)(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);
|
|
|
|
totalPoints += AosAttributes.GetValue( from, AosAttribute.RegenMana );
|
|
|
|
if ( CheckTransform( from, typeof( VampiricEmbraceSpell ) ) )
|
|
totalPoints += 3;
|
|
else if ( CheckTransform( from, typeof( LichFormSpell ) ) )
|
|
totalPoints += 13;
|
|
|
|
if ( (from is BaseCreature && ((BaseCreature)from).IsParagon) || from is Leviathan )
|
|
totalPoints += 40;
|
|
|
|
if ( totalPoints < -1 )
|
|
totalPoints = -1;
|
|
|
|
rate = 1.0 / (0.1 * (2 + (int)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;
|
|
}
|
|
}
|
|
}
|
|
} |