diff --git a/Scripts/Commands/HelpInfo.cs b/Scripts/Commands/HelpInfo.cs index 4d2a29ece..3392ac08e 100644 --- a/Scripts/Commands/HelpInfo.cs +++ b/Scripts/Commands/HelpInfo.cs @@ -142,7 +142,7 @@ namespace Server.Commands sb.Append( "Modifiers: " ); if( (command.Supports & CommandSupport.Global) != 0 ) - sb.Append( ", " ); + sb.Append( "Global, " ); if( (command.Supports & CommandSupport.Online) != 0 ) sb.Append( "Online, " ); diff --git a/Scripts/Engines/Craft/Core/Repair.cs b/Scripts/Engines/Craft/Core/Repair.cs index 63f6a887c..f7c6c6448 100644 --- a/Scripts/Engines/Craft/Core/Repair.cs +++ b/Scripts/Engines/Craft/Core/Repair.cs @@ -105,8 +105,11 @@ namespace Server.Engines.Craft if ( m_CraftSystem is DefTailoring ) { - return (clothing is BearMask) - || (clothing is DeerMask); + return ( clothing is BearMask ) + || ( clothing is DeerMask ) + || ( clothing is TheMostKnowledgePerson ) + || ( clothing is TheRobeOfBritanniaAri ) + || ( clothing is EmbroideredOakLeafCloak ); } return false; diff --git a/Scripts/Items/Misc/Teleporter.cs b/Scripts/Items/Misc/Teleporter.cs index fccf6b462..b513ab9dc 100644 --- a/Scripts/Items/Misc/Teleporter.cs +++ b/Scripts/Items/Misc/Teleporter.cs @@ -72,7 +72,6 @@ namespace Server.Items set { m_Creatures = value; InvalidateProperties(); } } - [CommandProperty( AccessLevel.GameMaster )] public bool CombatCheck { @@ -702,4 +701,169 @@ namespace Server.Items } } } + + public class TimeoutTeleporter : Teleporter + { + private TimeSpan m_TimeoutDelay; + private Dictionary m_Teleporting; + + [CommandProperty( AccessLevel.GameMaster )] + public TimeSpan TimeoutDelay + { + get { return m_TimeoutDelay; } + set { m_TimeoutDelay = value; } + } + + [Constructable] + public TimeoutTeleporter() + : this( new Point3D( 0, 0, 0 ), null, false ) + { + } + + [Constructable] + public TimeoutTeleporter( Point3D pointDest, Map mapDest ) + : this( pointDest, mapDest, false ) + { + } + + [Constructable] + public TimeoutTeleporter( Point3D pointDest, Map mapDest, bool creatures ) + : base( pointDest, mapDest, creatures ) + { + m_Teleporting = new Dictionary(); + } + + public void StartTimer( Mobile m ) + { + StartTimer( m, m_TimeoutDelay ); + } + + private void StartTimer( Mobile m, TimeSpan delay ) + { + Timer t; + + if ( m_Teleporting.TryGetValue( m, out t ) ) + t.Stop(); + + m_Teleporting[m] = Timer.DelayCall( delay, StartTeleport, m ); + } + + public void StopTimer( Mobile m ) + { + Timer t; + + if ( m_Teleporting.TryGetValue( m, out t ) ) + { + t.Stop(); + m_Teleporting.Remove( m ); + } + } + + public override bool OnMoveOver( Mobile m ) + { + if ( Active && ( m.Player || Creatures ) ) + StartTimer( m ); + + return true; + } + + public TimeoutTeleporter( Serial serial ) + : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.Write( (int) 0 ); // version + + writer.Write( m_TimeoutDelay ); + writer.Write( m_Teleporting.Count ); + + foreach ( KeyValuePair kvp in m_Teleporting ) + { + writer.Write( kvp.Key ); + writer.Write( kvp.Value.Next ); + } + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadInt(); + + m_TimeoutDelay = reader.ReadTimeSpan(); + m_Teleporting = new Dictionary(); + + int count = reader.ReadInt(); + + for ( int i = 0; i < count; ++i ) + { + Mobile m = reader.ReadMobile(); + DateTime end = reader.ReadDateTime(); + + StartTimer( m, end - DateTime.Now ); + } + } + } + + public class TimeoutGoal : Item + { + private TimeoutTeleporter m_Teleporter; + + [CommandProperty( AccessLevel.GameMaster )] + public TimeoutTeleporter Teleporter + { + get { return m_Teleporter; } + set { m_Teleporter = value; } + } + + [Constructable] + public TimeoutGoal() + : base( 0x1822 ) + { + Movable = false; + Visible = false; + + Hue = 1154; + } + + public override bool OnMoveOver( Mobile m ) + { + if ( m_Teleporter != null ) + m_Teleporter.StopTimer( m ); + + return true; + } + + public override string DefaultName + { + get { return "timeout teleporter goal"; } + } + + public TimeoutGoal( Serial serial ) + : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.Write( (int) 0 ); // version + + writer.WriteItem( m_Teleporter ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadInt(); + + m_Teleporter = reader.ReadItem(); + } + } } \ No newline at end of file diff --git a/Scripts/Items/Weapons/BaseWeapon.cs b/Scripts/Items/Weapons/BaseWeapon.cs index bcc262532..bc0ebe600 100644 --- a/Scripts/Items/Weapons/BaseWeapon.cs +++ b/Scripts/Items/Weapons/BaseWeapon.cs @@ -1584,13 +1584,13 @@ namespace Server.Items int manaLeech = 0; int wraithLeech = 0; - if ( (int)(m_AosWeaponAttributes.HitLeechHits * propertyBonus) > Utility.Random( 100 ) ) + if ( (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitLeechHits ) * propertyBonus) > Utility.Random( 100 ) ) lifeLeech += 30; // HitLeechHits% chance to leech 30% of damage as hit points - if ( (int)(m_AosWeaponAttributes.HitLeechStam * propertyBonus) > Utility.Random( 100 ) ) + if ( (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitLeechStam ) * propertyBonus) > Utility.Random( 100 ) ) stamLeech += 100; // HitLeechStam% chance to leech 100% of damage as stamina - if ( (int)(m_AosWeaponAttributes.HitLeechMana * propertyBonus) > Utility.Random( 100 ) ) + if ( (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitLeechMana ) * propertyBonus) > Utility.Random( 100 ) ) manaLeech += 40; // HitLeechMana% chance to leech 40% of damage as mana if ( m_Cursed ) @@ -1669,11 +1669,11 @@ namespace Server.Items if ( Core.AOS ) { - int physChance = (int)(m_AosWeaponAttributes.HitPhysicalArea * propertyBonus); - int fireChance = (int)(m_AosWeaponAttributes.HitFireArea * propertyBonus); - int coldChance = (int)(m_AosWeaponAttributes.HitColdArea * propertyBonus); - int poisChance = (int)(m_AosWeaponAttributes.HitPoisonArea * propertyBonus); - int nrgyChance = (int)(m_AosWeaponAttributes.HitEnergyArea * propertyBonus); + int physChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitPhysicalArea ) * propertyBonus); + int fireChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitFireArea ) * propertyBonus); + int coldChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitColdArea ) * propertyBonus); + int poisChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitPoisonArea ) * propertyBonus); + int nrgyChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitEnergyArea ) * propertyBonus); if ( physChance != 0 && physChance > Utility.Random( 100 ) ) DoAreaAttack( attacker, defender, 0x10E, 50, 100, 0, 0, 0, 0 ); @@ -1690,11 +1690,11 @@ namespace Server.Items if ( nrgyChance != 0 && nrgyChance > Utility.Random( 100 ) ) DoAreaAttack( attacker, defender, 0x1F1, 120, 0, 0, 0, 0, 100 ); - int maChance = (int)(m_AosWeaponAttributes.HitMagicArrow * propertyBonus); - int harmChance = (int)(m_AosWeaponAttributes.HitHarm * propertyBonus); - int fireballChance = (int)(m_AosWeaponAttributes.HitFireball * propertyBonus); - int lightningChance = (int)(m_AosWeaponAttributes.HitLightning * propertyBonus); - int dispelChance = (int)(m_AosWeaponAttributes.HitDispel * propertyBonus); + int maChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitMagicArrow ) * propertyBonus); + int harmChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitHarm ) * propertyBonus); + int fireballChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitFireball ) * propertyBonus); + int lightningChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitLightning ) * propertyBonus); + int dispelChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitDispel ) * propertyBonus); if ( maChance != 0 && maChance > Utility.Random( 100 ) ) DoMagicArrow( attacker, defender ); @@ -1711,8 +1711,8 @@ namespace Server.Items if ( dispelChance != 0 && dispelChance > Utility.Random( 100 ) ) DoDispel( attacker, defender ); - int laChance = (int)(m_AosWeaponAttributes.HitLowerAttack * propertyBonus); - int ldChance = (int)(m_AosWeaponAttributes.HitLowerDefend * propertyBonus); + int laChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitLowerAttack ) * propertyBonus); + int ldChance = (int)(AosWeaponAttributes.GetValue( attacker, AosWeaponAttribute.HitLowerDefend ) * propertyBonus); if ( laChance != 0 && laChance > Utility.Random( 100 ) ) DoLowerAttack( attacker, defender ); diff --git a/Scripts/Misc/AOS.cs b/Scripts/Misc/AOS.cs index f588918b9..64b93c9f3 100644 --- a/Scripts/Misc/AOS.cs +++ b/Scripts/Misc/AOS.cs @@ -505,7 +505,6 @@ namespace Server if( attrs != null ) value += attrs[attribute]; } - else if ( obj is ElvenGlasses ) { AosWeaponAttributes attrs = ((ElvenGlasses)obj).WeaponAttributes; diff --git a/Scripts/Misc/MondainsLegacy.cs b/Scripts/Misc/MondainsLegacy.cs index 6be0eb44c..877ac698b 100644 --- a/Scripts/Misc/MondainsLegacy.cs +++ b/Scripts/Misc/MondainsLegacy.cs @@ -79,7 +79,8 @@ namespace Server || region.IsPartOf( "Bedlam" ) || region.IsPartOf( "Blighted Grove" ) || region.IsPartOf( "Painted Caves" ) - || region.IsPartOf( "Palace of Paroxysmus" ); + || region.IsPartOf( "Palace of Paroxysmus" ) + || region.IsPartOf( "Labyrinth" ); } } } \ No newline at end of file diff --git a/Scripts/Mobiles/Monsters/ML/Special/Ilhenir.cs b/Scripts/Mobiles/Monsters/ML/Special/Ilhenir.cs index 406b7da74..3ebb6a3b8 100644 --- a/Scripts/Mobiles/Monsters/ML/Special/Ilhenir.cs +++ b/Scripts/Mobiles/Monsters/ML/Special/Ilhenir.cs @@ -318,8 +318,10 @@ namespace Server.Mobiles public class StainedOoze : Item { private bool m_Corrosive; + private Timer m_Timer; + private int m_Ticks; - [CommandProperty(AccessLevel.GameMaster)] + [CommandProperty( AccessLevel.GameMaster )] public bool Corrosive { get { return m_Corrosive; } @@ -328,183 +330,116 @@ namespace Server.Mobiles [Constructable] public StainedOoze() - : this(false) + : this( false ) { } [Constructable] - public StainedOoze(bool corrosive) - : base(0x122A) + public StainedOoze( bool corrosive ) + : base( 0x122A ) { Movable = false; Hue = 0x95; m_Corrosive = corrosive; - Timer.DelayCall(TimeSpan.FromSeconds(30), new TimerCallback(Morph)); + m_Timer = Timer.DelayCall( TimeSpan.Zero, TimeSpan.FromSeconds( 1 ), OnTick ); + m_Ticks = 0; } - private Hashtable m_Table; - - public override bool OnMoveOver(Mobile m) + public override void OnAfterDelete() { - if( m != null && !m.Deleted ) + if ( m_Timer != null ) { - if( m_Table == null ) + m_Timer.Stop(); + m_Timer = null; + } + } + + private void OnTick() + { + List toDamage = new List(); + + foreach ( Mobile m in GetMobilesInRange( 0 ) ) + { + if ( m is BaseCreature ) { - m_Table = new Hashtable(); + BaseCreature bc = (BaseCreature)m; + + if ( !bc.Controlled && !bc.Summoned ) + continue; + } + else if ( !m.Player ) + { + continue; } - if( ( m is BaseCreature && ( (BaseCreature)m ).Controlled ) || m.Player ) + if ( m.Alive && !m.IsDeadBondedPet && m.CanBeDamaged() ) + toDamage.Add( m ); + } + + for ( int i = 0; i < toDamage.Count; ++i ) + Damage( toDamage[i] ); + + ++m_Ticks; + + if ( m_Ticks >= 35 ) + Delete(); + else if ( m_Ticks == 30 ) + ItemID = 0x122B; + } + + public void Damage( Mobile m ) + { + if ( m_Corrosive ) + { + List items = m.Items; + bool damaged = false; + + for ( int i = 0; i < items.Count; ++i ) { - m_Table[ m ] = Timer.DelayCall( TimeSpan.FromSeconds( 1 ), TimeSpan.FromSeconds( 1 ), new TimerStateCallback( Damage_Callback ), m ); + IDurability wearable = items[i] as IDurability; + + if ( wearable != null && wearable.HitPoints >= 10 && Utility.RandomDouble() < 0.25 ) + { + wearable.HitPoints -= ( wearable.HitPoints == 10 ) ? Utility.Random( 1, 5 ) : 10; + damaged = true; + } + } + + if ( damaged ) + { + m.LocalOverheadMessage( MessageType.Regular, 0x21, 1072070 ); // The infernal ooze scorches you, setting you and your equipment ablaze! + return; } } - return base.OnMoveOver( m ); + + AOS.Damage( m, 40, 0, 0, 0, 100, 0 ); } - public override bool OnMoveOff(Mobile m) - { - if (m_Table == null) - m_Table = new Hashtable(); - - if (m_Table[m] is Timer) - { - Timer timer = (Timer)m_Table[m]; - - timer.Stop(); - - m_Table[m] = null; - } - - return base.OnMoveOff(m); - } - - public StainedOoze(Serial serial) - : base(serial) + public StainedOoze( Serial serial ) + : base( serial ) { } - public override void Serialize(GenericWriter writer) + public override void Serialize( GenericWriter writer ) { - base.Serialize(writer); + base.Serialize( writer ); - writer.Write((int)0); // version + writer.Write( (int) 0 ); // version - writer.Write((bool)m_Corrosive); + writer.Write( m_Corrosive ); } - public override void Deserialize(GenericReader reader) + public override void Deserialize( GenericReader reader ) { - base.Deserialize(reader); + base.Deserialize( reader ); int version = reader.ReadInt(); m_Corrosive = reader.ReadBool(); - } - private void Damage_Callback(object state) - { - if (state is Mobile) - Damage((Mobile)state); - } - - /* Ode to ASayre .. perhaps a lil voodoo will summon his ghost :D */ - - private bool DamageSelector( ref bool z, ref int hp, ref int mhp ) - { - return ( ( ( mhp -= ( z ) ? ( ( mhp > 10 ) ? 10 : 1 ) : 0 ) > 0 ) && ( hp -= ( ( z ) ? 0 : ( ( hp > 10 ) ? 10 : 1 ) ) ) > 0 ); - } - - private bool ValidMobile( Mobile m ) - { - return ( !m.Deleted && m.Alive && m.AccessLevel == AccessLevel.Player ); - } - - private bool IsUsingDurability( IDurability item ) - { - return ( (item.HitPoints + item.MaxHitPoints ) > 0 ); - } - - private IDurability ValidDurabilityEquipment( Mobile m, Item item ) - { - return ( ( item != null && !item.Deleted && item.Parent == m && item is IDurability ) ? item as IDurability : null ); - } - - public virtual void Damage( Mobile m ) - { - if( m == null || m.Deleted || !m.Alive || m.Map == null || m.Map == Map.Internal ) /* cant have that happen again */ - { - StopTimer( m ); - } - else - { - if( ValidMobile( m ) ) - { - if( m_Corrosive && ( m.Items.Count > 0 ) ) - { - for( int i = 0; i < m.Items.Count; i++ ) - { - Item m_Item; IDurability item = ValidDurabilityEquipment( m, ( m_Item = m.Items[ i ] as Item ) ); - - if( item != null && ( IsUsingDurability( item ) ) && ( Utility.RandomDouble() < 0.25 ) ) - { - int hp; bool z = ( ( hp = item.HitPoints ) < 1 ); int mhp = item.MaxHitPoints; - - if( !( DamageSelector( ref z, ref hp, ref mhp ) ) && z ) - { - m.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1061121 ); // Your equipment is severely damaged. - - if( ( item.MaxHitPoints = mhp ) < 1 ) - { - m_Item.Delete(); - } - } - - item.HitPoints = hp; - } - } - } - else - { - AOS.Damage( m, 40, 0, 0, 0, 100, 0 ); - } - } - else - { - StopTimer( m ); - } - } - } - - public virtual void Morph() - { - ItemID += 1; - - Timer.DelayCall(TimeSpan.FromSeconds(5), new TimerCallback(Decay)); - } - - public virtual void StopTimer(Mobile m) - { - if (m_Table[m] is Timer) - { - Timer timer = (Timer)m_Table[m]; - timer.Stop(); - m_Table[m] = null; - } - } - - public virtual void Decay() - { - if (m_Table == null) - m_Table = new Hashtable(); - - foreach (DictionaryEntry entry in m_Table) - if (entry.Value is Timer) - ((Timer)entry.Value).Stop(); - - m_Table.Clear(); - - Delete(); + m_Timer = Timer.DelayCall( TimeSpan.Zero, TimeSpan.FromSeconds( 1 ), OnTick ); + m_Ticks = ( ItemID == 0x122A ) ? 0 : 30; } } } diff --git a/Scripts/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs b/Scripts/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs index 034bd4844..746262144 100644 --- a/Scripts/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs +++ b/Scripts/Mobiles/Monsters/ML/Twisted Weald/Changeling.cs @@ -24,7 +24,6 @@ namespace Server.Mobiles Name = DefaultName; Body = 264; Hue = DefaultHue; - BaseSoundID = 0x470; SetStr( 36, 105 ); SetDex( 212, 262 ); @@ -70,6 +69,12 @@ namespace Server.Mobiles AddLoot( LootPack.AosRich, 3 ); } + public override int GetAngerSound() { return 0x46E; } + public override int GetIdleSound() { return 0x470; } + public override int GetAttackSound() { return 0x46D; } + public override int GetHurtSound() { return 0x471; } + public override int GetDeathSound() { return 0x46F; } + private Mobile m_MorphedInto; private DateTime m_LastMorph; private DateTime m_NextFireRing; @@ -189,7 +194,7 @@ namespace Server.Mobiles protected virtual void Revert() { Body = 264; - Hue = IsParagon ? Paragon.Hue : DefaultHue; + Hue = ( IsParagon && DefaultHue == 0 ) ? Paragon.Hue : DefaultHue; Female = false; Name = DefaultName; NameHue = -1; @@ -200,6 +205,14 @@ namespace Server.Mobiles FacialHairItemID = 0; FacialHairHue = 0; + DeleteClonedItems(); + + PlaySound( 0x511 ); + FixedParticles( 0x376A, 1, 14, 5045, EffectLayer.Waist ); + } + + public void DeleteClonedItems() + { for ( int i = Items.Count - 1; i >= 0; --i ) { Item item = Items[i]; @@ -218,9 +231,13 @@ namespace Server.Mobiles item.Delete(); } } + } - PlaySound( 0x511 ); - FixedParticles( 0x376A, 1, 14, 5045, EffectLayer.Waist ); + public override void OnAfterDelete() + { + DeleteClonedItems(); + + base.OnAfterDelete(); } public override void ClearHands() diff --git a/Scripts/Mobiles/PlayerMobile.cs b/Scripts/Mobiles/PlayerMobile.cs index b7a74315a..6b079c0b6 100644 --- a/Scripts/Mobiles/PlayerMobile.cs +++ b/Scripts/Mobiles/PlayerMobile.cs @@ -2592,8 +2592,8 @@ namespace Server.Mobiles { Type type = talisman.Protection.Type; - if ( type == from.GetType() ) - amount *= 1 - (int) ( ( (double) talisman.Protection.Amount ) / 100 ); + if ( type.IsAssignableFrom( from.GetType() ) ) + amount = (int)( amount * ( 1 - (double)talisman.Protection.Amount / 100 ) ); } }