All pastes #123791 Raw Edit

Someone

public text v1 · immutable
·published 2006-08-09 16:07 UTC
rendered paste body
using System;
using Server;
using Server.Mobiles;

namespace Server.Misc
{
    public class SkillCheck
    {
        private static readonly bool AntiMacroCode = false;		//Change this to false to disable anti-macro code

        public static TimeSpan AntiMacroExpire = TimeSpan.FromMinutes( 5.0 ); //How long do we remember targets/locations?
        public const int Allowance = 3;	//How many times may we use the same location/target for gain
        private const int LocationSize = 5; //The size of eeach location, make this smaller so players dont have to move as far
        private static bool[] UseAntiMacro = new bool[]
		{
			// true if this skill uses the anti-macro code, false if it does not
			false,// Alchemy = 0,
			true,// Anatomy = 1,
			true,// AnimalLore = 2,
			true,// ItemID = 3,
			true,// ArmsLore = 4,
			false,// Parry = 5,
			true,// Begging = 6,
			false,// Blacksmith = 7,
			false,// Fletching = 8,
			true,// Peacemaking = 9,
			true,// Camping = 10,
			false,// Carpentry = 11,
			false,// Cartography = 12,
			false,// Cooking = 13,
			true,// DetectHidden = 14,
			true,// Discordance = 15,
			true,// EvalInt = 16,
			true,// Healing = 17,
			true,// Fishing = 18,
			true,// Forensics = 19,
			true,// Herding = 20,
			true,// Hiding = 21,
			true,// Provocation = 22,
			false,// Inscribe = 23,
			true,// Lockpicking = 24,
			true,// Magery = 25,
			true,// MagicResist = 26,
			false,// Tactics = 27,
			true,// Snooping = 28,
			true,// Musicianship = 29,
			true,// Poisoning = 30,
			false,// Archery = 31,
			true,// SpiritSpeak = 32,
			true,// Stealing = 33,
			false,// Tailoring = 34,
			true,// AnimalTaming = 35,
			true,// TasteID = 36,
			false,// Tinkering = 37,
			true,// Tracking = 38,
			true,// Veterinary = 39,
			false,// Swords = 40,
			false,// Macing = 41,
			false,// Fencing = 42,
			false,// Wrestling = 43,
			true,// Lumberjacking = 44,
			true,// Mining = 45,
			true,// Meditation = 46,
			true,// Stealth = 47,
			true,// RemoveTrap = 48,
			true,// Necromancy = 49,
			false,// Focus = 50,
			true,// Chivalry = 51
			true,// Bushido = 52
			true,//Ninjitsu = 53
			true // Spellweaving
		};

        public static void Initialize()
        {
            Mobile.SkillCheckLocationHandler = new SkillCheckLocationHandler( Mobile_SkillCheckLocation );
            Mobile.SkillCheckDirectLocationHandler = new SkillCheckDirectLocationHandler( Mobile_SkillCheckDirectLocation );

            Mobile.SkillCheckTargetHandler = new SkillCheckTargetHandler( Mobile_SkillCheckTarget );
            Mobile.SkillCheckDirectTargetHandler = new SkillCheckDirectTargetHandler( Mobile_SkillCheckDirectTarget );
        }

        public static bool Mobile_SkillCheckLocation( Mobile from, SkillName skillName, double minSkill, double maxSkill )
        {
            Skill skill = from.Skills[skillName];

            if( skill == null )
                return false;

            double value = skill.Value;

            if( value < minSkill )
                return false; // Too difficult
            else if( value >= maxSkill )
                return true; // No challenge

            double chance = ( value - minSkill ) / ( maxSkill - minSkill );

            Point2D loc = new Point2D( from.Location.X / LocationSize, from.Location.Y / LocationSize );
            return CheckSkill( from, skill, loc, chance );
        }

        public static bool Mobile_SkillCheckDirectLocation( Mobile from, SkillName skillName, double chance )
        {
            Skill skill = from.Skills[skillName];

            if( skill == null )
                return false;

            if( chance < 0.0 )
                return false; // Too difficult
            else if( chance >= 1.0 )
                return true; // No challenge

            Point2D loc = new Point2D( from.Location.X / LocationSize, from.Location.Y / LocationSize );
            return CheckSkill( from, skill, loc, chance );
        }

        public static bool CheckSkill( Mobile from, Skill skill, object amObj, double chance )
        {
            if( from.Skills.Cap == 0 )
                return false;

            bool success = ( chance >= Utility.RandomDouble() );
            double gc = ( double )( from.Skills.Cap - from.Skills.Total ) / from.Skills.Cap;
            gc += ( skill.Cap - skill.Base ) / skill.Cap;
            gc /= 2;

            gc += ( 1.0 - chance ) * ( success ? 0.5 : ( Core.AOS ? 0.0 : 0.2 ) );
            gc /= 2;

            gc *= skill.Info.GainFactor;

            if( gc < 0.01 )
                gc = 0.01;

            gc *= 2;

            if( from is BaseCreature && ( ( BaseCreature )from ).Controlled )
                gc *= 3;

            if( from.Alive && ( ( gc >= Utility.RandomDouble() && AllowGain( from, skill, amObj ) ) || skill.Base < 10.0 ) )
                Gain( from, skill );




            return success;
        }

        public static bool Mobile_SkillCheckTarget( Mobile from, SkillName skillName, object target, double minSkill, double maxSkill )
        {
            Skill skill = from.Skills[skillName];

            if( skill == null )
                return false;

            double value = skill.Value;

            if( value < minSkill )
                return false; // Too difficult
            else if( value >= maxSkill )
                return true; // No challenge

            double chance = ( value - minSkill ) / ( maxSkill - minSkill );

            return CheckSkill( from, skill, target, chance );
        }

        public static bool Mobile_SkillCheckDirectTarget( Mobile from, SkillName skillName, object target, double chance )
        {
            Skill skill = from.Skills[skillName];

            if( skill == null )
                return false;

            if( chance < 0.0 )
                return false; // Too difficult
            else if( chance >= 1.0 )
                return true; // No challenge

            return CheckSkill( from, skill, target, chance );
        }

        private static bool AllowGain( Mobile from, Skill skill, object obj )
        {
            if( from is PlayerMobile && AntiMacroCode && UseAntiMacro[skill.Info.SkillID] )
                return ( ( PlayerMobile )from ).AntiMacroCheck( skill, obj );
            else
                return true;
        }

        public enum Stat { Str, Dex, Int }

        public static void Gain( Mobile from, Skill skill )
        {
            if( from.Region.IsPartOf( typeof( Regions.Jail ) ) )
                return;

            if( from is BaseCreature && ( ( BaseCreature )from ).IsDeadPet )
                return;

            if( skill.SkillName == SkillName.Focus && from is BaseCreature )
                return;

            if( skill.Base < skill.Cap && skill.Lock == SkillLock.Up )
            {
                int toGain = 1;

                if( skill.Base <= 10.0 )
                    toGain = Utility.Random( 4 ) + 1;

                Skills skills = from.Skills;

                if( ( skills.Total / skills.Cap ) >= Utility.RandomDouble() )//( skills.Total >= skills.Cap )
                {
                    for( int i = 0; i < skills.Length; ++i )
                    {
                        Skill toLower = skills[i];

                        if( toLower != skill && toLower.Lock == SkillLock.Down && toLower.BaseFixedPoint >= toGain )
                        {
                            toLower.BaseFixedPoint -= toGain;
                            break;
                        }
                    }
                }

                if( ( skills.Total + toGain ) <= skills.Cap )
                {
                    skill.BaseFixedPoint += toGain;
                }
            }

            if( skill.Lock == SkillLock.Up )
            {
                SkillInfo info = skill.Info;

                if( from.StrLock == StatLockType.Up )
                    GainStat( from, Stat.Str );
                else if( from.DexLock == StatLockType.Up )
                    GainStat( from, Stat.Dex );
                else if( from.IntLock == StatLockType.Up )
                    GainStat( from, Stat.Int );
            }
        }

        public static bool CanLower( Mobile from, Stat stat )
        {
            switch( stat )
            {
                case Stat.Str: return ( from.StrLock == StatLockType.Down && from.RawStr > 10 );
                case Stat.Dex: return ( from.DexLock == StatLockType.Down && from.RawDex > 10 );
                case Stat.Int: return ( from.IntLock == StatLockType.Down && from.RawInt > 10 );
            }

            return false;
        }

        public static bool CanRaise( Mobile from, Stat stat )
        {
            if( !( from is BaseCreature && ( ( BaseCreature )from ).Controlled ) )
            {
                if( from.RawStatTotal >= from.StatCap )
                    return false;
            }

            switch( stat )
            {
                case Stat.Str: return ( from.StrLock == StatLockType.Up && from.RawStr < 100 );
                case Stat.Dex: return ( from.DexLock == StatLockType.Up && from.RawDex < 100 );
                case Stat.Int: return ( from.IntLock == StatLockType.Up && from.RawInt < 100 );
            }

            return false;
        }

        public static void IncreaseStat( Mobile from, Stat stat, bool atrophy )
        {
            atrophy = atrophy || ( from.RawStatTotal >= from.StatCap );

            switch( stat )
            {
                case Stat.Str:
                    {
                        if( atrophy )
                        {
                            if( CanLower( from, Stat.Dex ) && ( from.RawDex < from.RawInt || !CanLower( from, Stat.Int ) ) )
                                --from.RawDex;
                            else if( CanLower( from, Stat.Int ) )
                                --from.RawInt;
                        }

                        if( CanRaise( from, Stat.Str ) )
                            ++from.RawStr;

                        break;
                    }
                case Stat.Dex:
                    {
                        if( atrophy )
                        {
                            if( CanLower( from, Stat.Str ) && ( from.RawStr < from.RawInt || !CanLower( from, Stat.Int ) ) )
                                --from.RawStr;
                            else if( CanLower( from, Stat.Int ) )
                                --from.RawInt;
                        }

                        if( CanRaise( from, Stat.Dex ) )
                            ++from.RawDex;

                        break;
                    }
                case Stat.Int:
                    {
                        if( atrophy )
                        {
                            if( CanLower( from, Stat.Str ) && ( from.RawStr < from.RawDex || !CanLower( from, Stat.Dex ) ) )
                                --from.RawStr;
                            else if( CanLower( from, Stat.Dex ) )
                                --from.RawDex;
                        }

                        if( CanRaise( from, Stat.Int ) )
                            ++from.RawInt;

                        break;
                    }
            }
        }

        private static TimeSpan m_StatGainDelay = TimeSpan.FromSeconds( 15.0 );

        public static void GainStat( Mobile from, Stat stat )
        {
            switch( stat )
            {
                case Stat.Str:
                    {
                        if( ( from.LastStrGain + m_StatGainDelay ) >= DateTime.Now )
                            return;

                        from.LastStrGain = DateTime.Now;
                        break;
                    }
                case Stat.Dex:
                    {
                        if( ( from.LastDexGain + m_StatGainDelay ) >= DateTime.Now )
                            return;

                        from.LastDexGain = DateTime.Now;
                        break;
                    }
                case Stat.Int:
                    {
                        if( ( from.LastIntGain + m_StatGainDelay ) >= DateTime.Now )
                            return;

                        from.LastIntGain = DateTime.Now;
                        break;
                    }
            }

            bool atrophy = ( ( from.RawStatTotal / ( double )from.StatCap ) >= Utility.RandomDouble() );

            IncreaseStat( from, stat, atrophy );
        }
    }
}