diff --git a/Scripts/Engines/Harvest/Lumberjacking.cs b/Scripts/Engines/Harvest/Lumberjacking.cs index c2a948ce5..2d4e409cc 100644 --- a/Scripts/Engines/Harvest/Lumberjacking.cs +++ b/Scripts/Engines/Harvest/Lumberjacking.cs @@ -1,6 +1,7 @@ using System; using Server; using Server.Items; +using Server.Network; namespace Server.Engines.Harvest { @@ -156,15 +157,9 @@ namespace Server.Engines.Harvest public override void OnBadHarvestTarget( Mobile from, Item tool, object toHarvest ) { if ( toHarvest is Mobile ) - { - Mobile obj = (Mobile)toHarvest; - obj.PublicOverheadMessage( Server.Network.MessageType.Regular, 0x3E9, 500450 ); // You can only skin dead creatures. - } + ( (Mobile)toHarvest ).PrivateOverheadMessage( MessageType.Regular, 0x3B2, 500450, from.NetState ); // You can only skin dead creatures. else if ( toHarvest is Item ) - { - Item obj = (Item)toHarvest; - obj.PublicOverheadMessage( Server.Network.MessageType.Regular, 0x3E9, 500464 ); // Use this on corpses to carve away meat and hide - } + ( (Item)toHarvest ).LabelTo( from, 500464 ); // Use this on corpses to carve away meat and hide else if ( toHarvest is Targeting.StaticTarget || toHarvest is Targeting.LandTarget ) from.SendLocalizedMessage( 500489 ); // You can't use an axe on that. else diff --git a/Scripts/Items/Aquarium/Aquarium.cs b/Scripts/Items/Aquarium/Aquarium.cs index 502ee30c9..ef1a2dc17 100644 --- a/Scripts/Items/Aquarium/Aquarium.cs +++ b/Scripts/Items/Aquarium/Aquarium.cs @@ -293,9 +293,28 @@ namespace Server.Items } } - public override void GetProperties( ObjectPropertyList list ) + public override bool CheckItemUse( Mobile from, Item item ) { - base.GetProperties( list ); + if ( item != this ) + return false; + + return base.CheckItemUse( from, item ); + } + + public override bool CheckLift( Mobile from, Item item, ref LRReason reject ) + { + if ( item != this ) + { + reject = LRReason.CannotLift; + return false; + } + + return base.CheckLift( from, item, ref reject ); + } + + public override void AddNameProperties( ObjectPropertyList list ) + { + base.AddNameProperties( list ); if ( m_VacationLeft > 0 ) list.Add( 1074430, m_VacationLeft.ToString() ); // Vacation days left: ~1_DAYS @@ -371,7 +390,7 @@ namespace Server.Items { base.Serialize( writer ); - writer.Write( 2 ); // Version + writer.Write( 3 ); // Version // version 1 if ( m_Timer != null ) @@ -402,6 +421,7 @@ namespace Server.Items switch ( version ) { + case 3: case 2: case 1: { @@ -443,6 +463,37 @@ namespace Server.Items Weight = DefaultWeight; Movable = false; } + + if ( version < 3 ) + m_Recount.Add( this ); + } + + private void RecountLiveCreatures() + { + m_LiveCreatures = 0; + List fish = FindItemsByType(); + + foreach ( BaseFish f in fish ) + { + if ( !f.Dead ) + ++m_LiveCreatures; + } + } + + private static List m_Recount; + + public static void Configure() + { + m_Recount = new List(); + } + + public static void Initialize() + { + foreach ( Aquarium aquarium in m_Recount ) + aquarium.RecountLiveCreatures(); + + m_Recount.Clear(); + m_Recount = null; } #region Members @@ -695,6 +746,12 @@ namespace Server.Items Item item = Items[ at ]; + if ( item.IsLockedDown ) // for legacy aquariums + { + from.SendLocalizedMessage( 1010449 ); // You may not use this object while it is locked down. + return false; + } + if ( item is BaseFish ) { BaseFish fish = (BaseFish) item; diff --git a/Scripts/Items/Aquarium/AquariumFishingNet.cs b/Scripts/Items/Aquarium/AquariumFishingNet.cs index 373cb1740..d540a709a 100644 --- a/Scripts/Items/Aquarium/AquariumFishingNet.cs +++ b/Scripts/Items/Aquarium/AquariumFishingNet.cs @@ -23,12 +23,11 @@ namespace Server.Items { } - // TODO - //public override bool RequireDeepWater { get { return false; } } + public override bool RequireDeepWater { get { return false; } } protected override void FinishEffect( Point3D p, Map map, Mobile from ) { - if ( Utility.RandomDouble() < 0.02 ) + if ( from.Skills.Fishing.Value < 10 ) { from.SendLocalizedMessage( 1074487 ); // The creatures are too quick for you! } diff --git a/Scripts/Items/Aquarium/FishBowl.cs b/Scripts/Items/Aquarium/FishBowl.cs index 81ee40b3e..3efc36a7e 100644 --- a/Scripts/Items/Aquarium/FishBowl.cs +++ b/Scripts/Items/Aquarium/FishBowl.cs @@ -1,8 +1,9 @@ using System; using System.Collections.Generic; using Server; -using Server.Mobiles; using Server.ContextMenus; +using Server.Mobiles; +using Server.Network; namespace Server.Items { @@ -48,6 +49,15 @@ namespace Server.Items { } + public override bool TryDropItem( Mobile from, Item dropped, bool sendFullMessage ) + { + if ( !CheckHold( from, dropped, sendFullMessage, true ) ) + return false; + + DropItem( dropped ); + return true; + } + public override bool OnDragDrop( Mobile from, Item dropped ) { if ( !IsAccessibleTo( from ) ) @@ -73,6 +83,25 @@ namespace Server.Items return false; } + public override bool CheckItemUse( Mobile from, Item item ) + { + if ( item != this ) + return false; + + return base.CheckItemUse( from, item ); + } + + public override bool CheckLift( Mobile from, Item item, ref LRReason reject ) + { + if ( item != this ) + { + reject = LRReason.CannotLift; + return false; + } + + return base.CheckLift( from, item, ref reject ); + } + public override void AddNameProperties( ObjectPropertyList list ) { base.AddNameProperties( list ); @@ -129,7 +158,7 @@ namespace Server.Items if ( fish != null ) { - if ( fish.IsLockedDown ) + if ( fish.IsLockedDown ) // for legacy fish bowls { Owner.From.SendLocalizedMessage( 1010449 ); // You may not use this object while it is locked down. } diff --git a/Scripts/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs b/Scripts/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs index 32c5996c2..5a868eb82 100644 --- a/Scripts/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs +++ b/Scripts/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs @@ -1,6 +1,8 @@ using System; using Server; using Server.Mobiles; +using Server.Multis; +using Server.Spells; using Server.Targeting; namespace Server.Items @@ -112,8 +114,7 @@ namespace Server.Items } } - // TODO - //public virtual bool RequireDeepWater{ get{ return true; } } + public virtual bool RequireDeepWater{ get{ return true; } } public void OnTarget( Mobile from, object obj ) { @@ -130,15 +131,19 @@ namespace Server.Items if ( map == null || map == Map.Internal ) return; - int x = p3D.X, y = p3D.Y; + int x = p3D.X, y = p3D.Y, z = map.GetAverageZ( x, y ); // OSI just takes the targeted Z if ( !from.InRange( p3D, 6 ) ) { from.SendLocalizedMessage( 500976 ); // You need to be closer to the water to fish! } - else if ( FullValidation( map, x, y ) ) + else if ( !from.InLOS( obj ) ) { - Point3D p = new Point3D( x, y, map.GetAverageZ( x, y ) ); + from.SendLocalizedMessage( 500979 ); // You cannot see that location. + } + else if ( RequireDeepWater ? FullValidation( map, x, y ) : ( ValidateDeepWater( map, x, y ) || ValidateUndeepWater( map, obj, ref z ) ) ) + { + Point3D p = new Point3D( x, y, z ); if ( GetType() == typeof( SpecialFishingNet ) ) { @@ -150,15 +155,19 @@ namespace Server.Items Movable = false; MoveToWorld( p, map ); + SpellHelper.Turn( from, p ); from.Animate( 12, 5, 1, true, false, 0 ); - Timer.DelayCall( TimeSpan.FromSeconds( 1.5 ), TimeSpan.FromSeconds( 1.0 ), 20, new TimerStateCallback( DoEffect ), new object[]{ p, 0, from } ); + Effects.SendLocationEffect( p, map, 0x352D, 16, 4 ); + Effects.PlaySound( p, map, 0x364 ); - from.SendLocalizedMessage( 1010487 ); // You plunge the net into the sea... + Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 1.25 ), 14, new TimerStateCallback( DoEffect ), new object[]{ p, 0, from } ); + + from.SendLocalizedMessage( RequireDeepWater ? 1010487 : 1074492 ); // You plunge the net into the sea... / You plunge the net into the water... } else { - from.SendLocalizedMessage( 1010485 ); // You can only use this net in deep water! + from.SendLocalizedMessage( RequireDeepWater ? 1010485 : 1074491 ); // You can only use this net in deep water! / You can only use this net in water! } } @@ -180,31 +189,39 @@ namespace Server.Items Effects.SendLocationEffect( p, Map, 0x352D, 16, 4 ); Effects.PlaySound( p, Map, 0x364 ); } - else if ( index <= 10 || index == 20 ) + else if ( index <= 7 || index == 14 ) { - for ( int i = 0; i < 3; ++i ) + if ( RequireDeepWater ) { - int x, y; - - switch ( Utility.Random( 8 ) ) + for ( int i = 0; i < 3; ++i ) { - default: - case 0: x = -1; y = -1; break; - case 1: x = -1; y = 0; break; - case 2: x = -1; y = +1; break; - case 3: x = 0; y = -1; break; - case 4: x = 0; y = +1; break; - case 5: x = +1; y = -1; break; - case 6: x = +1; y = 0; break; - case 7: x = +1; y = +1; break; - } + int x, y; - Effects.SendLocationEffect( new Point3D( p.X + x, p.Y + y, p.Z ), Map, 0x352D, 16, 4 ); + switch ( Utility.Random( 8 ) ) + { + default: + case 0: x = -1; y = -1; break; + case 1: x = -1; y = 0; break; + case 2: x = -1; y = +1; break; + case 3: x = 0; y = -1; break; + case 4: x = 0; y = +1; break; + case 5: x = +1; y = -1; break; + case 6: x = +1; y = 0; break; + case 7: x = +1; y = +1; break; + } + + Effects.SendLocationEffect( new Point3D( p.X + x, p.Y + y, p.Z ), Map, 0x352D, 16, 4 ); + } + } + else + { + Effects.SendLocationEffect( p, Map, 0x352D, 16, 4 ); } - Effects.PlaySound( p, Map, 0x364 ); + if ( Utility.RandomBool() ) + Effects.PlaySound( p, Map, 0x364 ); - if ( index == 20 ) + if ( index == 14 ) FinishEffect( p, Map, from ); else this.Z -= 1; @@ -309,11 +326,40 @@ namespace Server.Items int tileID = map.Tiles.GetLandTile( x, y ).ID; bool water = false; - for( int i = 0; !water && i < m_WaterTiles.Length; i += 2 ) - water = (tileID >= m_WaterTiles[i] && tileID <= m_WaterTiles[i + 1]); + for ( int i = 0; !water && i < m_WaterTiles.Length; i += 2 ) + water = ( tileID >= m_WaterTiles[i] && tileID <= m_WaterTiles[i + 1] ); return water; } + + private static int[] m_UndeepWaterTiles = new int[] + { + 0x1797, 0x179C + }; + + private static bool ValidateUndeepWater( Map map, object obj, ref int z ) + { + if ( !( obj is StaticTarget ) ) + return false; + + StaticTarget target = (StaticTarget)obj; + + if ( BaseHouse.FindHouseAt( target.Location, map, 0 ) != null ) + return false; + + int itemID = target.ItemID; + + for ( int i = 0; i < m_UndeepWaterTiles.Length; i += 2 ) + { + if ( itemID >= m_UndeepWaterTiles[i] && itemID <= m_UndeepWaterTiles[i + 1] ) + { + z = target.Z; + return true; + } + } + + return false; + } } public class FabledFishingNet : SpecialFishingNet diff --git a/Scripts/Items/Special/Veteran Rewards/FlamingHead.cs b/Scripts/Items/Special/Veteran Rewards/FlamingHead.cs index 3d638efbd..94ff4f68b 100644 --- a/Scripts/Items/Special/Veteran Rewards/FlamingHead.cs +++ b/Scripts/Items/Special/Veteran Rewards/FlamingHead.cs @@ -73,7 +73,7 @@ namespace Server.Items from.SendLocalizedMessage( 1018328 ); // You can only re-deed a skull if you placed it or you are the owner of the house. } else - from.Say( 1019045 ); // I can't reach that. + from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that. } public override void Serialize( GenericWriter writer ) diff --git a/Scripts/Items/Special/Veteran Rewards/StoneAnkh.cs b/Scripts/Items/Special/Veteran Rewards/StoneAnkh.cs index f4c19d398..c51c5cdd2 100644 --- a/Scripts/Items/Special/Veteran Rewards/StoneAnkh.cs +++ b/Scripts/Items/Special/Veteran Rewards/StoneAnkh.cs @@ -104,22 +104,22 @@ namespace Server.Items } public override void OnComponentUsed( AddonComponent c, Mobile from ) + { + if ( from.InRange( Location, 2 ) ) { - if ( from.InRange( Location, 2 ) ) - { BaseHouse house = BaseHouse.FindHouseAt( this ); - - if ( house != null && house.IsOwner( from ) ) - { - from.CloseGump( typeof( RewardDemolitionGump ) ); - from.SendGump( new RewardDemolitionGump( this, 1049783 ) ); // Do you wish to re-deed this decoration? - } - else - from.SendLocalizedMessage( 1049784 ); // You can only re-deed this decoration if you are the house owner or originally placed the decoration. + + if ( house != null && house.IsOwner( from ) ) + { + from.CloseGump( typeof( RewardDemolitionGump ) ); + from.SendGump( new RewardDemolitionGump( this, 1049783 ) ); // Do you wish to re-deed this decoration? } else - from.Say( 1019045 ); // I can't reach that. + from.SendLocalizedMessage( 1049784 ); // You can only re-deed this decoration if you are the house owner or originally placed the decoration. } + else + from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that. + } public override void Serialize( GenericWriter writer ) { diff --git a/Scripts/Items/Weapons/BaseWeapon.cs b/Scripts/Items/Weapons/BaseWeapon.cs index b60a4bc3f..bcc262532 100644 --- a/Scripts/Items/Weapons/BaseWeapon.cs +++ b/Scripts/Items/Weapons/BaseWeapon.cs @@ -706,6 +706,8 @@ namespace Server.Items if ( Core.AOS ) m_AosSkillBonuses.Remove(); + ImmolatingWeaponSpell.StopImmolating( this ); + m.CheckStatTimers(); m.Delta( MobileDelta.WeaponDamage ); @@ -1387,7 +1389,6 @@ namespace Server.Items * The following damage bonuses multiply damage by a factor. * Capped at x3 (300%). */ - //double factor = 1.0; int percentageBonus = 0; WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker ); @@ -1395,17 +1396,14 @@ namespace Server.Items if( a != null ) { - //factor *= a.DamageScalar; percentageBonus += (int)(a.DamageScalar * 100) - 100; } if( move != null ) { - //factor *= move.GetDamageScalar( attacker, defender ); percentageBonus += (int)(move.GetDamageScalar( attacker, defender ) * 100) - 100; } - //factor *= damageBonus; percentageBonus += (int)(damageBonus * 100) - 100; CheckSlayerResult cs = CheckSlayers( attacker, defender ); @@ -1415,7 +1413,6 @@ namespace Server.Items if ( cs == CheckSlayerResult.Slayer ) defender.FixedEffect( 0x37B9, 10, 5 ); - //factor *= 2.0; percentageBonus += 100; } @@ -1427,7 +1424,6 @@ namespace Server.Items if( pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType() ) { - //factor *= 2.0; percentageBonus += 100; } } @@ -1447,7 +1443,7 @@ namespace Server.Items if ( pm.EnemyOfOneType == defender.GetType() ) { defender.FixedEffect( 0x37B9, 10, 5, 1160, 0 ); - //factor *= 1.5; + percentageBonus += 50; } } @@ -1457,13 +1453,11 @@ namespace Server.Items if( packInstinctBonus != 0 ) { - //factor *= 1.0 + (double)packInstinctBonus / 100.0; percentageBonus += packInstinctBonus; } if( m_InDoubleStrike ) { - //factor *= 0.9; // 10% loss when attacking with double-strike percentageBonus -= 10; } @@ -1471,7 +1465,7 @@ namespace Server.Items if( (m_Slayer == SlayerName.Silver || m_Slayer2 == SlayerName.Silver) && context != null && context.Spell is NecromancerSpell && context.Type != typeof( HorrificBeastSpell ) ) { - //factor *= 1.25; // Every necromancer transformation other than horrific beast takes an additional 25% damage + // Every necromancer transformation other than horrific beast takes an additional 25% damage percentageBonus += 25; } @@ -1481,20 +1475,15 @@ namespace Server.Items if( pmAttacker.HonorActive && pmAttacker.InRange( defender, 1 ) ) { - //factor *= 1.25; percentageBonus += 25; } if( pmAttacker.SentHonorContext != null && pmAttacker.SentHonorContext.Target == defender ) { - //pmAttacker.SentHonorContext.ApplyPerfectionDamageBonus( ref factor ); percentageBonus += pmAttacker.SentHonorContext.PerfectionDamageBonus; } } - //if ( factor > 3.0 ) - // factor = 3.0; - BaseTalisman talisman = attacker.Talisman as BaseTalisman; if ( talisman != null && talisman.Killer != null ) @@ -1502,7 +1491,6 @@ namespace Server.Items percentageBonus = Math.Min( percentageBonus, 300 ); - //damage = (int)(damage * factor); damage = AOS.Scale( damage, 100 + percentageBonus ); #endregion @@ -1565,6 +1553,10 @@ namespace Server.Items else if ( type == 4 ) nrgy = 100; } + // TODO: Scale damage, alongside the leech effects below, to weapon speed. + if ( ImmolatingWeaponSpell.IsImmolating( this ) && damage > 0 ) + ImmolatingWeaponSpell.DoEffect( this, defender ); + int damageGiven = damage; if ( a != null && !a.OnBeforeDamage( attacker, defender ) ) @@ -3238,6 +3230,9 @@ namespace Server.Items if ( (prop = m_AosWeaponAttributes.HitLeechStam) != 0 ) list.Add( 1060430, prop.ToString() ); // hit stamina leech ~1_val~% + if ( ImmolatingWeaponSpell.IsImmolating( this ) ) + list.Add( 1111917 ); // Immolated + if ( Core.ML && this is BaseRanged && ( prop = ( (BaseRanged) this ).Velocity ) != 0 ) list.Add( 1072793, prop.ToString() ); // Velocity ~1_val~% diff --git a/Scripts/Multis/BaseHouse.cs b/Scripts/Multis/BaseHouse.cs index 896f20eb0..51b2a1070 100644 --- a/Scripts/Multis/BaseHouse.cs +++ b/Scripts/Multis/BaseHouse.cs @@ -1575,7 +1575,7 @@ namespace Server.Multis if ( !locked ) i.SetLastMoved(); - if ( (i is Container) && (!locked || !(i is BaseBoard)) ) + if ( (i is Container) && (!locked || !(i is BaseBoard || i is Aquarium || i is FishBowl)) ) { foreach ( Item c in i.Items ) SetLockdown( c, locked, checkContains ); @@ -2492,7 +2492,7 @@ namespace Server.Multis { Item item = (Item)m_LockDowns[i]; - if ( item is Container && !(item is BaseBoard) ) + if ( item is Container && !(item is BaseBoard || item is Aquarium || item is FishBowl) ) { Container cont = (Container)item; List children = cont.Items; diff --git a/Scripts/Spells/Initializer.cs b/Scripts/Spells/Initializer.cs index 25cefded4..a9adcc039 100644 --- a/Scripts/Spells/Initializer.cs +++ b/Scripts/Spells/Initializer.cs @@ -147,7 +147,7 @@ namespace Server.Spells { Register( 600, typeof( Spellweaving.ArcaneCircleSpell ) ); Register( 601, typeof( Spellweaving.GiftOfRenewalSpell ) ); - //Register( 602, typeof( Spellweaving.ImmolatingWeaponSpell ) ); + Register( 602, typeof( Spellweaving.ImmolatingWeaponSpell ) ); Register( 603, typeof( Spellweaving.AttuneWeaponSpell ) ); Register( 604, typeof( Spellweaving.ThunderstormSpell ) ); Register( 605, typeof( Spellweaving.NatureFurySpell ) ); diff --git a/Scripts/Spells/Spellweaving/ImmolatingWeapon.cs b/Scripts/Spells/Spellweaving/ImmolatingWeapon.cs new file mode 100644 index 000000000..400d564fd --- /dev/null +++ b/Scripts/Spells/Spellweaving/ImmolatingWeapon.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Server.Items; + +namespace Server.Spells.Spellweaving +{ + public class ImmolatingWeaponSpell : ArcanistSpell + { + private static SpellInfo m_Info = new SpellInfo( + "Immolating Weapon", "Thalshara", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } } + + public override double RequiredSkill { get { return 10.0; } } + public override int RequiredMana { get { return 32; } } + + public ImmolatingWeaponSpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) + { + } + + public override bool CheckCast() + { + BaseWeapon weapon = Caster.Weapon as BaseWeapon; + + if ( weapon == null || weapon is Fists || weapon is BaseRanged ) + { + Caster.SendLocalizedMessage( 1060179 ); // You must be wielding a weapon to use this ability! + return false; + } + + return base.CheckCast(); + } + + public override void OnCast() + { + BaseWeapon weapon = Caster.Weapon as BaseWeapon; + + if ( weapon == null || weapon is Fists || weapon is BaseRanged ) + { + Caster.SendLocalizedMessage( 1060179 ); // You must be wielding a weapon to use this ability! + } + else if ( CheckSequence() ) + { + Caster.PlaySound( 0x5CA ); + Caster.FixedParticles( 0x36BD, 20, 10, 5044, EffectLayer.Head ); + + if ( !IsImmolating( weapon ) ) // On OSI, the effect is not re-applied + { + double skill = Caster.Skills.Spellweaving.Value; + + int duration = 10 + (int)( skill / 24 ) + FocusLevel; + int damage = 5 + (int)( skill / 24 ) + FocusLevel; + + Timer stopTimer = Timer.DelayCall( TimeSpan.FromSeconds( duration ), StopImmolating, weapon ); + + m_WeaponDamageTable[weapon] = new ImmolatingWeaponEntry( damage, stopTimer, Caster ); + weapon.InvalidateProperties(); + } + } + + FinishSequence(); + } + + private static Dictionary m_WeaponDamageTable = new Dictionary(); + + public static bool IsImmolating( BaseWeapon weapon ) + { + return m_WeaponDamageTable.ContainsKey( weapon ); + } + + public static int GetImmolatingDamage( BaseWeapon weapon ) + { + ImmolatingWeaponEntry entry; + + if ( m_WeaponDamageTable.TryGetValue( weapon, out entry ) ) + return entry.m_Damage; + + return 0; + } + + public static void DoEffect( BaseWeapon weapon, Mobile target ) + { + Timer.DelayCall( TimeSpan.FromSeconds( 0.25 ), FinishEffect, new DelayedEffectEntry( weapon, target ) ); + } + + private static void FinishEffect( DelayedEffectEntry effect ) + { + ImmolatingWeaponEntry entry; + + if ( m_WeaponDamageTable.TryGetValue( effect.m_Weapon, out entry ) ) + AOS.Damage( effect.m_Target, entry.m_Caster, entry.m_Damage, 0, 100, 0, 0, 0 ); + } + + public static void StopImmolating( BaseWeapon weapon ) + { + ImmolatingWeaponEntry entry; + + if ( m_WeaponDamageTable.TryGetValue( weapon, out entry ) ) + { + if ( entry.m_Caster != null ) + entry.m_Caster.PlaySound( 0x27 ); + + entry.m_Timer.Stop(); + + m_WeaponDamageTable.Remove( weapon ); + + weapon.InvalidateProperties(); + } + } + + private class ImmolatingWeaponEntry + { + public int m_Damage; + public Timer m_Timer; + public Mobile m_Caster; + + public ImmolatingWeaponEntry( int damage, Timer stopTimer, Mobile caster ) + { + m_Damage = damage; + m_Timer = stopTimer; + m_Caster = caster; + } + } + + private class DelayedEffectEntry + { + public BaseWeapon m_Weapon; + public Mobile m_Target; + + public DelayedEffectEntry( BaseWeapon weapon, Mobile target ) + { + m_Weapon = weapon; + m_Target = target; + } + } + } +}