using System; using System.Collections; using System.Collections.Generic; using Server; using Server.Items; using Server.Misc; using Server.Mobiles; using Server.Network; using Server.Spells; using Server.Spells.Fifth; using Server.Spells.Seventh; using Server.Spells.Ninjitsu; namespace Server { public class AOS { public static void DisableStatInfluences() { for( int i = 0; i < SkillInfo.Table.Length; ++i ) { SkillInfo info = SkillInfo.Table[i]; info.StrScale = 0.0; info.DexScale = 0.0; info.IntScale = 0.0; info.StatTotal = 0.0; } } public static int Damage( Mobile m, int damage, bool ignoreArmor, int phys, int fire, int cold, int pois, int nrgy ) { return Damage( m, null, damage, ignoreArmor, phys, fire, cold, pois, nrgy ); } public static int Damage( Mobile m, int damage, int phys, int fire, int cold, int pois, int nrgy ) { return Damage( m, null, damage, phys, fire, cold, pois, nrgy ); } 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 ); } 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 ); } 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 ); } 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 ) { if( m == null || m.Deleted || !m.Alive || damage <= 0 ) return 0; if( phys == 0 && fire == 100 && cold == 0 && pois == 0 && nrgy == 0 ) Mobiles.MeerMage.StopEffect( m, true ); if( !Core.AOS ) { m.Damage( damage, from ); return damage; } Fix( ref phys ); Fix( ref fire ); Fix( ref cold ); Fix( ref pois ); Fix( ref nrgy ); Fix( ref chaos ); Fix( ref direct ); if ( Core.ML && chaos > 0 ) { switch ( Utility.Random( 5 ) ) { case 0: phys += chaos; break; case 1: fire += chaos; break; case 2: cold += chaos; break; case 3: pois += chaos; break; case 4: nrgy += chaos; break; } } BaseQuiver quiver = null; if ( archer && from != null ) quiver = from.FindItemOnLayer( Layer.Cloak ) as BaseQuiver; int totalDamage; if( !ignoreArmor ) { // Armor Ignore on OSI ignores all defenses, not just physical. int resPhys = m.PhysicalResistance; int resFire = m.FireResistance; int resCold = m.ColdResistance; int resPois = m.PoisonResistance; int resNrgy = m.EnergyResistance; totalDamage = damage * phys * (100 - resPhys); totalDamage += damage * fire * (100 - resFire); totalDamage += damage * cold * (100 - resCold); totalDamage += damage * pois * (100 - resPois); totalDamage += damage * nrgy * (100 - resNrgy); totalDamage /= 10000; if ( Core.ML ) { totalDamage += damage * direct / 100; if ( quiver != null ) totalDamage += totalDamage * quiver.DamageIncrease / 100; } if( totalDamage < 1 ) totalDamage = 1; } else if( Core.ML && m is PlayerMobile && from is PlayerMobile ) { if ( quiver != null ) damage += damage * quiver.DamageIncrease / 100; totalDamage = Math.Min( damage, 35 ); //Direct Damage cap of 35 } else { totalDamage = damage; if ( Core.ML && quiver != null ) totalDamage += totalDamage * quiver.DamageIncrease / 100; } #region Dragon Barding if( (from == null || !from.Player) && m.Player && m.Mount is SwampDragon ) { SwampDragon pet = m.Mount as SwampDragon; if( pet != null && pet.HasBarding ) { int percent = (pet.BardingExceptional ? 20 : 10); int absorbed = Scale( totalDamage, percent ); totalDamage -= absorbed; pet.BardingHP -= absorbed; if( pet.BardingHP < 0 ) { pet.HasBarding = false; pet.BardingHP = 0; m.SendLocalizedMessage( 1053031 ); // Your dragon's barding has been destroyed! } } } #endregion if( keepAlive && totalDamage > m.Hits ) totalDamage = m.Hits; if( from != null && !from.Deleted && from.Alive ) { int reflectPhys = AosAttributes.GetValue( m, AosAttribute.ReflectPhysical ); if( reflectPhys != 0 ) { if( from is ExodusMinion && ((ExodusMinion)from).FieldActive || from is ExodusOverseer && ((ExodusOverseer)from).FieldActive ) { from.FixedParticles( 0x376A, 20, 10, 0x2530, EffectLayer.Waist ); from.PlaySound( 0x2F4 ); m.SendAsciiMessage( "Your weapon cannot penetrate the creature's magical barrier" ); } else { from.Damage( Scale( (damage * phys * (100 - (ignoreArmor ? 0 : m.PhysicalResistance))) / 10000, reflectPhys ), m ); } } } m.Damage( totalDamage, from ); return totalDamage; } public static void Fix( ref int val ) { if( val < 0 ) val = 0; } public static int Scale( int input, int percent ) { return (input * percent) / 100; } } [Flags] public enum AosAttribute { RegenHits=0x00000001, RegenStam=0x00000002, RegenMana=0x00000004, DefendChance=0x00000008, AttackChance=0x00000010, BonusStr=0x00000020, BonusDex=0x00000040, BonusInt=0x00000080, BonusHits=0x00000100, BonusStam=0x00000200, BonusMana=0x00000400, WeaponDamage=0x00000800, WeaponSpeed=0x00001000, SpellDamage=0x00002000, CastRecovery=0x00004000, CastSpeed=0x00008000, LowerManaCost=0x00010000, LowerRegCost=0x00020000, ReflectPhysical=0x00040000, EnhancePotions=0x00080000, Luck=0x00100000, SpellChanneling=0x00200000, NightSight=0x00400000 } public sealed class AosAttributes : BaseAttributes { public AosAttributes( Item owner ) : base( owner ) { } public AosAttributes( Item owner, AosAttributes other ) : base( owner, other ) { } public AosAttributes( Item owner, GenericReader reader ) : base( owner, reader ) { } public static int GetValue( Mobile m, AosAttribute attribute ) { if( !Core.AOS ) return 0; List items = m.Items; int value = 0; for( int i = 0; i < items.Count; ++i ) { Item obj = items[i]; if( obj is BaseWeapon ) { AosAttributes attrs = ((BaseWeapon)obj).Attributes; if( attrs != null ) value += attrs[attribute]; if( attribute == AosAttribute.Luck ) value += ((BaseWeapon)obj).GetLuckBonus(); } else if( obj is BaseArmor ) { AosAttributes attrs = ((BaseArmor)obj).Attributes; if( attrs != null ) value += attrs[attribute]; if( attribute == AosAttribute.Luck ) value += ((BaseArmor)obj).GetLuckBonus(); } else if( obj is BaseJewel ) { AosAttributes attrs = ((BaseJewel)obj).Attributes; if( attrs != null ) value += attrs[attribute]; } else if( obj is BaseClothing ) { AosAttributes attrs = ((BaseClothing)obj).Attributes; if( attrs != null ) value += attrs[attribute]; } else if( obj is Spellbook ) { AosAttributes attrs = ((Spellbook)obj).Attributes; if( attrs != null ) value += attrs[attribute]; } else if( obj is BaseQuiver ) { AosAttributes attrs = ((BaseQuiver)obj).Attributes; if( attrs != null ) value += attrs[attribute]; } } return value; } public int this[AosAttribute attribute] { get { return GetValue( (int)attribute ); } set { SetValue( (int)attribute, value ); } } public override string ToString() { return "..."; } public void AddStatBonuses( Mobile to ) { int strBonus = BonusStr; int dexBonus = BonusDex; int intBonus = BonusInt; if ( strBonus != 0 || dexBonus != 0 || intBonus != 0 ) { string modName = Owner.Serial.ToString(); if ( strBonus != 0 ) to.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) ); if ( dexBonus != 0 ) to.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) ); if ( intBonus != 0 ) to.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) ); } to.CheckStatTimers(); } public void RemoveStatBonuses( Mobile from ) { string modName = Owner.Serial.ToString(); from.RemoveStatMod( modName + "Str" ); from.RemoveStatMod( modName + "Dex" ); from.RemoveStatMod( modName + "Int" ); from.CheckStatTimers(); } [CommandProperty( AccessLevel.GameMaster )] public int RegenHits { get { return this[AosAttribute.RegenHits]; } set { this[AosAttribute.RegenHits] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int RegenStam { get { return this[AosAttribute.RegenStam]; } set { this[AosAttribute.RegenStam] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int RegenMana { get { return this[AosAttribute.RegenMana]; } set { this[AosAttribute.RegenMana] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int DefendChance { get { return this[AosAttribute.DefendChance]; } set { this[AosAttribute.DefendChance] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int AttackChance { get { return this[AosAttribute.AttackChance]; } set { this[AosAttribute.AttackChance] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int BonusStr { get { return this[AosAttribute.BonusStr]; } set { this[AosAttribute.BonusStr] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int BonusDex { get { return this[AosAttribute.BonusDex]; } set { this[AosAttribute.BonusDex] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int BonusInt { get { return this[AosAttribute.BonusInt]; } set { this[AosAttribute.BonusInt] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int BonusHits { get { return this[AosAttribute.BonusHits]; } set { this[AosAttribute.BonusHits] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int BonusStam { get { return this[AosAttribute.BonusStam]; } set { this[AosAttribute.BonusStam] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int BonusMana { get { return this[AosAttribute.BonusMana]; } set { this[AosAttribute.BonusMana] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int WeaponDamage { get { return this[AosAttribute.WeaponDamage]; } set { this[AosAttribute.WeaponDamage] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int WeaponSpeed { get { return this[AosAttribute.WeaponSpeed]; } set { this[AosAttribute.WeaponSpeed] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int SpellDamage { get { return this[AosAttribute.SpellDamage]; } set { this[AosAttribute.SpellDamage] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int CastRecovery { get { return this[AosAttribute.CastRecovery]; } set { this[AosAttribute.CastRecovery] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int CastSpeed { get { return this[AosAttribute.CastSpeed]; } set { this[AosAttribute.CastSpeed] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int LowerManaCost { get { return this[AosAttribute.LowerManaCost]; } set { this[AosAttribute.LowerManaCost] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int LowerRegCost { get { return this[AosAttribute.LowerRegCost]; } set { this[AosAttribute.LowerRegCost] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int ReflectPhysical { get { return this[AosAttribute.ReflectPhysical]; } set { this[AosAttribute.ReflectPhysical] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int EnhancePotions { get { return this[AosAttribute.EnhancePotions]; } set { this[AosAttribute.EnhancePotions] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int Luck { get { return this[AosAttribute.Luck]; } set { this[AosAttribute.Luck] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int SpellChanneling { get { return this[AosAttribute.SpellChanneling]; } set { this[AosAttribute.SpellChanneling] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int NightSight { get { return this[AosAttribute.NightSight]; } set { this[AosAttribute.NightSight] = value; } } } [Flags] public enum AosWeaponAttribute { LowerStatReq=0x00000001, SelfRepair=0x00000002, HitLeechHits=0x00000004, HitLeechStam=0x00000008, HitLeechMana=0x00000010, HitLowerAttack=0x00000020, HitLowerDefend=0x00000040, HitMagicArrow=0x00000080, HitHarm=0x00000100, HitFireball=0x00000200, HitLightning=0x00000400, HitDispel=0x00000800, HitColdArea=0x00001000, HitFireArea=0x00002000, HitPoisonArea=0x00004000, HitEnergyArea=0x00008000, HitPhysicalArea=0x00010000, ResistPhysicalBonus=0x00020000, ResistFireBonus=0x00040000, ResistColdBonus=0x00080000, ResistPoisonBonus=0x00100000, ResistEnergyBonus=0x00200000, UseBestSkill=0x00400000, MageWeapon=0x00800000, DurabilityBonus=0x01000000 } public sealed class AosWeaponAttributes : BaseAttributes { public AosWeaponAttributes( Item owner ) : base( owner ) { } public AosWeaponAttributes( Item owner, AosWeaponAttributes other ) : base( owner, other ) { } public AosWeaponAttributes( Item owner, GenericReader reader ) : base( owner, reader ) { } public static int GetValue( Mobile m, AosWeaponAttribute attribute ) { if( !Core.AOS ) return 0; List items = m.Items; int value = 0; for( int i = 0; i < items.Count; ++i ) { Item obj = items[i]; if( obj is BaseWeapon ) { AosWeaponAttributes attrs = ((BaseWeapon)obj).WeaponAttributes; if( attrs != null ) value += attrs[attribute]; } } return value; } public int this[AosWeaponAttribute attribute] { get { return GetValue( (int)attribute ); } set { SetValue( (int)attribute, value ); } } public override string ToString() { return "..."; } [CommandProperty( AccessLevel.GameMaster )] public int LowerStatReq { get { return this[AosWeaponAttribute.LowerStatReq]; } set { this[AosWeaponAttribute.LowerStatReq] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int SelfRepair { get { return this[AosWeaponAttribute.SelfRepair]; } set { this[AosWeaponAttribute.SelfRepair] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitLeechHits { get { return this[AosWeaponAttribute.HitLeechHits]; } set { this[AosWeaponAttribute.HitLeechHits] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitLeechStam { get { return this[AosWeaponAttribute.HitLeechStam]; } set { this[AosWeaponAttribute.HitLeechStam] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitLeechMana { get { return this[AosWeaponAttribute.HitLeechMana]; } set { this[AosWeaponAttribute.HitLeechMana] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitLowerAttack { get { return this[AosWeaponAttribute.HitLowerAttack]; } set { this[AosWeaponAttribute.HitLowerAttack] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitLowerDefend { get { return this[AosWeaponAttribute.HitLowerDefend]; } set { this[AosWeaponAttribute.HitLowerDefend] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitMagicArrow { get { return this[AosWeaponAttribute.HitMagicArrow]; } set { this[AosWeaponAttribute.HitMagicArrow] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitHarm { get { return this[AosWeaponAttribute.HitHarm]; } set { this[AosWeaponAttribute.HitHarm] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitFireball { get { return this[AosWeaponAttribute.HitFireball]; } set { this[AosWeaponAttribute.HitFireball] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitLightning { get { return this[AosWeaponAttribute.HitLightning]; } set { this[AosWeaponAttribute.HitLightning] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitDispel { get { return this[AosWeaponAttribute.HitDispel]; } set { this[AosWeaponAttribute.HitDispel] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitColdArea { get { return this[AosWeaponAttribute.HitColdArea]; } set { this[AosWeaponAttribute.HitColdArea] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitFireArea { get { return this[AosWeaponAttribute.HitFireArea]; } set { this[AosWeaponAttribute.HitFireArea] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitPoisonArea { get { return this[AosWeaponAttribute.HitPoisonArea]; } set { this[AosWeaponAttribute.HitPoisonArea] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitEnergyArea { get { return this[AosWeaponAttribute.HitEnergyArea]; } set { this[AosWeaponAttribute.HitEnergyArea] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int HitPhysicalArea { get { return this[AosWeaponAttribute.HitPhysicalArea]; } set { this[AosWeaponAttribute.HitPhysicalArea] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int ResistPhysicalBonus { get { return this[AosWeaponAttribute.ResistPhysicalBonus]; } set { this[AosWeaponAttribute.ResistPhysicalBonus] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int ResistFireBonus { get { return this[AosWeaponAttribute.ResistFireBonus]; } set { this[AosWeaponAttribute.ResistFireBonus] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int ResistColdBonus { get { return this[AosWeaponAttribute.ResistColdBonus]; } set { this[AosWeaponAttribute.ResistColdBonus] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int ResistPoisonBonus { get { return this[AosWeaponAttribute.ResistPoisonBonus]; } set { this[AosWeaponAttribute.ResistPoisonBonus] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int ResistEnergyBonus { get { return this[AosWeaponAttribute.ResistEnergyBonus]; } set { this[AosWeaponAttribute.ResistEnergyBonus] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int UseBestSkill { get { return this[AosWeaponAttribute.UseBestSkill]; } set { this[AosWeaponAttribute.UseBestSkill] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int MageWeapon { get { return this[AosWeaponAttribute.MageWeapon]; } set { this[AosWeaponAttribute.MageWeapon] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int DurabilityBonus { get { return this[AosWeaponAttribute.DurabilityBonus]; } set { this[AosWeaponAttribute.DurabilityBonus] = value; } } } [Flags] public enum AosArmorAttribute { LowerStatReq=0x00000001, SelfRepair=0x00000002, MageArmor=0x00000004, DurabilityBonus=0x00000008 } public sealed class AosArmorAttributes : BaseAttributes { public AosArmorAttributes( Item owner ) : base( owner ) { } public AosArmorAttributes( Item owner, GenericReader reader ) : base( owner, reader ) { } public AosArmorAttributes( Item owner, AosArmorAttributes other ) : base( owner, other ) { } public static int GetValue( Mobile m, AosArmorAttribute attribute ) { if( !Core.AOS ) return 0; List items = m.Items; int value = 0; for( int i = 0; i < items.Count; ++i ) { Item obj = items[i]; if( obj is BaseArmor ) { AosArmorAttributes attrs = ((BaseArmor)obj).ArmorAttributes; if( attrs != null ) value += attrs[attribute]; } else if( obj is BaseClothing ) { AosArmorAttributes attrs = ((BaseClothing)obj).ClothingAttributes; if( attrs != null ) value += attrs[attribute]; } } return value; } public int this[AosArmorAttribute attribute] { get { return GetValue( (int)attribute ); } set { SetValue( (int)attribute, value ); } } public override string ToString() { return "..."; } [CommandProperty( AccessLevel.GameMaster )] public int LowerStatReq { get { return this[AosArmorAttribute.LowerStatReq]; } set { this[AosArmorAttribute.LowerStatReq] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int SelfRepair { get { return this[AosArmorAttribute.SelfRepair]; } set { this[AosArmorAttribute.SelfRepair] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int MageArmor { get { return this[AosArmorAttribute.MageArmor]; } set { this[AosArmorAttribute.MageArmor] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int DurabilityBonus { get { return this[AosArmorAttribute.DurabilityBonus]; } set { this[AosArmorAttribute.DurabilityBonus] = value; } } } public sealed class AosSkillBonuses : BaseAttributes { private List m_Mods; public AosSkillBonuses( Item owner ) : base( owner ) { } public AosSkillBonuses( Item owner, GenericReader reader ) : base( owner, reader ) { } public AosSkillBonuses( Item owner, AosSkillBonuses other ) : base( owner, other ) { } public void GetProperties( ObjectPropertyList list ) { for( int i = 0; i < 5; ++i ) { SkillName skill; double bonus; if( !GetValues( i, out skill, out bonus ) ) continue; list.Add( 1060451 + i, "#{0}\t{1}", 1044060 + (int)skill, bonus ); } } public void AddTo( Mobile m ) { Remove(); for( int i = 0; i < 5; ++i ) { SkillName skill; double bonus; if( !GetValues( i, out skill, out bonus ) ) continue; if( m_Mods == null ) m_Mods = new List(); SkillMod sk = new DefaultSkillMod( skill, true, bonus ); sk.ObeyCap = true; m.AddSkillMod( sk ); m_Mods.Add( sk ); } } public void Remove() { if( m_Mods == null ) return; for( int i = 0; i < m_Mods.Count; ++i ) { Mobile m = m_Mods[i].Owner; m_Mods[i].Remove(); if ( Core.ML ) CheckCancelMorph ( m ); } m_Mods = null; } public bool GetValues( int index, out SkillName skill, out double bonus ) { int v = GetValue( 1 << index ); int vSkill = 0; int vBonus = 0; for( int i = 0; i < 16; ++i ) { vSkill <<= 1; vSkill |= (v & 1); v >>= 1; vBonus <<= 1; vBonus |= (v & 1); v >>= 1; } skill = (SkillName)vSkill; bonus = (double)vBonus / 10; return (bonus != 0); } public void SetValues( int index, SkillName skill, double bonus ) { int v = 0; int vSkill = (int)skill; int vBonus = (int)(bonus * 10); for( int i = 0; i < 16; ++i ) { v <<= 1; v |= (vBonus & 1); vBonus >>= 1; v <<= 1; v |= (vSkill & 1); vSkill >>= 1; } SetValue( 1 << index, v ); } public SkillName GetSkill( int index ) { SkillName skill; double bonus; GetValues( index, out skill, out bonus ); return skill; } public void SetSkill( int index, SkillName skill ) { SetValues( index, skill, GetBonus( index ) ); } public double GetBonus( int index ) { SkillName skill; double bonus; GetValues( index, out skill, out bonus ); return bonus; } public void SetBonus( int index, double bonus ) { SetValues( index, GetSkill( index ), bonus ); } public override string ToString() { return "..."; } public void CheckCancelMorph ( Mobile m ) { if ( m == null ) return; double minSkill, maxSkill; AnimalFormContext acontext = AnimalForm.GetContext( m ); TransformContext context = TransformationSpellHelper.GetContext( m ); if ( context != null ) { Spell spell = context.Spell as Spell; spell.GetCastSkills ( out minSkill, out maxSkill ); if ( m.Skills[spell.CastSkill].Value < minSkill ) TransformationSpellHelper.RemoveContext( m, context, true ); } if ( acontext != null ) { int i; for ( i = 0; i < AnimalForm.Entries.Length; ++i ) if ( AnimalForm.Entries[i].Type == acontext.Type ) break; if ( m.Skills[SkillName.Ninjitsu].Value < AnimalForm.Entries[i].ReqSkill ) AnimalForm.RemoveContext( m, true ); } if ( !m.CanBeginAction ( typeof ( PolymorphSpell ) ) && m.Skills[SkillName.Magery].Value < 66.1 ) { m.BodyMod = 0; m.HueMod = -1; m.NameMod = null; m.EndAction( typeof( PolymorphSpell ) ); BaseArmor.ValidateMobile( m ); BaseClothing.ValidateMobile( m ); } if ( !m.CanBeginAction ( typeof ( IncognitoSpell ) ) && m.Skills[SkillName.Magery].Value < 38.1 ) { if ( m is PlayerMobile ) ((PlayerMobile)m).SetHairMods( -1, -1 ); m.BodyMod = 0; m.HueMod = -1; m.NameMod = null; m.EndAction( typeof( IncognitoSpell ) ); BaseArmor.ValidateMobile( m ); BaseClothing.ValidateMobile( m ); BuffInfo.RemoveBuff( m, BuffIcon.Incognito ); } return; } [CommandProperty( AccessLevel.GameMaster )] public double Skill_1_Value { get { return GetBonus( 0 ); } set { SetBonus( 0, value ); } } [CommandProperty( AccessLevel.GameMaster )] public SkillName Skill_1_Name { get { return GetSkill( 0 ); } set { SetSkill( 0, value ); } } [CommandProperty( AccessLevel.GameMaster )] public double Skill_2_Value { get { return GetBonus( 1 ); } set { SetBonus( 1, value ); } } [CommandProperty( AccessLevel.GameMaster )] public SkillName Skill_2_Name { get { return GetSkill( 1 ); } set { SetSkill( 1, value ); } } [CommandProperty( AccessLevel.GameMaster )] public double Skill_3_Value { get { return GetBonus( 2 ); } set { SetBonus( 2, value ); } } [CommandProperty( AccessLevel.GameMaster )] public SkillName Skill_3_Name { get { return GetSkill( 2 ); } set { SetSkill( 2, value ); } } [CommandProperty( AccessLevel.GameMaster )] public double Skill_4_Value { get { return GetBonus( 3 ); } set { SetBonus( 3, value ); } } [CommandProperty( AccessLevel.GameMaster )] public SkillName Skill_4_Name { get { return GetSkill( 3 ); } set { SetSkill( 3, value ); } } [CommandProperty( AccessLevel.GameMaster )] public double Skill_5_Value { get { return GetBonus( 4 ); } set { SetBonus( 4, value ); } } [CommandProperty( AccessLevel.GameMaster )] public SkillName Skill_5_Name { get { return GetSkill( 4 ); } set { SetSkill( 4, value ); } } } [Flags] public enum AosElementAttribute { Physical=0x00000001, Fire=0x00000002, Cold=0x00000004, Poison=0x00000008, Energy=0x00000010, Chaos=0x00000020, Direct=0x00000040 } public sealed class AosElementAttributes : BaseAttributes { public AosElementAttributes( Item owner ) : base( owner ) { } public AosElementAttributes( Item owner, AosElementAttributes other ) : base( owner, other ) { } public AosElementAttributes( Item owner, GenericReader reader ) : base( owner, reader ) { } public int this[AosElementAttribute attribute] { get { return GetValue( (int)attribute ); } set { SetValue( (int)attribute, value ); } } public override string ToString() { return "..."; } [CommandProperty( AccessLevel.GameMaster )] public int Physical { get { return this[AosElementAttribute.Physical]; } set { this[AosElementAttribute.Physical] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int Fire { get { return this[AosElementAttribute.Fire]; } set { this[AosElementAttribute.Fire] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int Cold { get { return this[AosElementAttribute.Cold]; } set { this[AosElementAttribute.Cold] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int Poison { get { return this[AosElementAttribute.Poison]; } set { this[AosElementAttribute.Poison] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int Energy { get { return this[AosElementAttribute.Energy]; } set { this[AosElementAttribute.Energy] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int Chaos { get { return this[AosElementAttribute.Chaos]; } set { this[AosElementAttribute.Chaos] = value; } } [CommandProperty( AccessLevel.GameMaster )] public int Direct { get { return this[AosElementAttribute.Direct]; } set { this[AosElementAttribute.Direct] = value; } } } [PropertyObject] public abstract class BaseAttributes { private Item m_Owner; private uint m_Names; private int[] m_Values; private static int[] m_Empty = new int[0]; public bool IsEmpty { get { return (m_Names == 0); } } public Item Owner { get { return m_Owner; } } public BaseAttributes( Item owner ) { m_Owner = owner; m_Values = m_Empty; } public BaseAttributes( Item owner, BaseAttributes other ) { m_Owner = owner; m_Values = new int[other.m_Values.Length]; other.m_Values.CopyTo( m_Values, 0 ); m_Names = other.m_Names; } public BaseAttributes( Item owner, GenericReader reader ) { m_Owner = owner; int version = reader.ReadByte(); switch( version ) { case 1: { m_Names = reader.ReadUInt(); m_Values = new int[reader.ReadEncodedInt()]; for( int i = 0; i < m_Values.Length; ++i ) m_Values[i] = reader.ReadEncodedInt(); break; } case 0: { m_Names = reader.ReadUInt(); m_Values = new int[reader.ReadInt()]; for( int i = 0; i < m_Values.Length; ++i ) m_Values[i] = reader.ReadInt(); break; } } } public void Serialize( GenericWriter writer ) { writer.Write( (byte)1 ); // version; writer.Write( (uint)m_Names ); writer.WriteEncodedInt( (int)m_Values.Length ); for( int i = 0; i < m_Values.Length; ++i ) writer.WriteEncodedInt( (int)m_Values[i] ); } public int GetValue( int bitmask ) { if( !Core.AOS ) return 0; uint mask = (uint)bitmask; if( (m_Names & mask) == 0 ) return 0; int index = GetIndex( mask ); if( index >= 0 && index < m_Values.Length ) return m_Values[index]; return 0; } public void SetValue( int bitmask, int value ) { if( (bitmask == (int)AosWeaponAttribute.DurabilityBonus) && (this is AosWeaponAttributes) ) { if( m_Owner is BaseWeapon ) ((BaseWeapon)m_Owner).UnscaleDurability(); } else if( (bitmask == (int)AosArmorAttribute.DurabilityBonus) && (this is AosArmorAttributes) ) { if( m_Owner is BaseArmor ) ((BaseArmor)m_Owner).UnscaleDurability(); else if( m_Owner is BaseClothing ) ((BaseClothing)m_Owner).UnscaleDurability(); } uint mask = (uint)bitmask; if( value != 0 ) { if( (m_Names & mask) != 0 ) { int index = GetIndex( mask ); if( index >= 0 && index < m_Values.Length ) m_Values[index] = value; } else { int index = GetIndex( mask ); if( index >= 0 && index <= m_Values.Length ) { int[] old = m_Values; m_Values = new int[old.Length + 1]; for( int i = 0; i < index; ++i ) m_Values[i] = old[i]; m_Values[index] = value; for( int i = index; i < old.Length; ++i ) m_Values[i + 1] = old[i]; m_Names |= mask; } } } else if( (m_Names & mask) != 0 ) { int index = GetIndex( mask ); if( index >= 0 && index < m_Values.Length ) { m_Names &= ~mask; if( m_Values.Length == 1 ) { m_Values = m_Empty; } else { int[] old = m_Values; m_Values = new int[old.Length - 1]; for( int i = 0; i < index; ++i ) m_Values[i] = old[i]; for( int i = index + 1; i < old.Length; ++i ) m_Values[i - 1] = old[i]; } } } if( (bitmask == (int)AosWeaponAttribute.DurabilityBonus) && (this is AosWeaponAttributes) ) { if( m_Owner is BaseWeapon ) ((BaseWeapon)m_Owner).ScaleDurability(); } else if( (bitmask == (int)AosArmorAttribute.DurabilityBonus) && (this is AosArmorAttributes) ) { if( m_Owner is BaseArmor ) ((BaseArmor)m_Owner).ScaleDurability(); else if( m_Owner is BaseClothing ) ((BaseClothing)m_Owner).ScaleDurability(); } if( m_Owner.Parent is Mobile ) { Mobile m = (Mobile)m_Owner.Parent; m.CheckStatTimers(); m.UpdateResistances(); m.Delta( MobileDelta.Stat | MobileDelta.WeaponDamage | MobileDelta.Hits | MobileDelta.Stam | MobileDelta.Mana ); if( this is AosSkillBonuses ) { ((AosSkillBonuses)this).Remove(); ((AosSkillBonuses)this).AddTo( m ); } } m_Owner.InvalidateProperties(); } private int GetIndex( uint mask ) { int index = 0; uint ourNames = m_Names; uint currentBit = 1; while( currentBit != mask ) { if( (ourNames & currentBit) != 0 ) ++index; if( currentBit == 0x80000000 ) return -1; currentBit <<= 1; } return index; } } }