diff --git a/Scripts/Items/Addons/ArcaneCircleAddon.cs b/Scripts/Items/Addons/ArcaneCircleAddon.cs index 2905c5eed..c76bcda3f 100644 --- a/Scripts/Items/Addons/ArcaneCircleAddon.cs +++ b/Scripts/Items/Addons/ArcaneCircleAddon.cs @@ -10,6 +10,7 @@ namespace Server.Items [Constructable] public ArcaneCircleAddon() { + AddComponent( new AddonComponent( 0x3083 ), -1, -1, 0 ); AddComponent( new AddonComponent( 0x3080 ), -1, 0, 0 ); AddComponent( new AddonComponent( 0x3082 ), 0, -1, 0 ); AddComponent( new AddonComponent( 0x3081 ), 1, -1, 0 ); @@ -18,7 +19,6 @@ namespace Server.Items AddComponent( new AddonComponent( 0x307E ), 1, 0, 0 ); AddComponent( new AddonComponent( 0x307C ), 0, 1, 0 ); AddComponent( new AddonComponent( 0x307B ), 1, 1, 0 ); - AddComponent( new AddonComponent( 0x3083 ), 1, 1, 0 ); } public ArcaneCircleAddon( Serial serial ) : base( serial ) diff --git a/Scripts/Items/Special/11th Year promo/EarringosfProtection.cs b/Scripts/Items/Special/11th Year promo/EarringosfProtection.cs new file mode 100644 index 000000000..3868c76e5 --- /dev/null +++ b/Scripts/Items/Special/11th Year promo/EarringosfProtection.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Server.Items +{ + public class EarringosfProtection : BaseJewel + { + [CommandProperty( AccessLevel.GameMaster )] + public virtual AosElementAttribute Attribute + { + get + { + return m_Attribute; + } + } + + public override int LabelNumber + { + get + { + return GetItemData( m_Attribute, true ); + } + } + + public override int Hue + { + get + { + return GetItemData( m_Attribute, false ); + } + } + + private AosElementAttribute m_Attribute; + private LootType m_LootType; + + [Constructable] + public EarringosfProtection() + : this( RandomType() ) + { + } + + [Constructable] + public EarringosfProtection( AosElementAttribute element ) + : base( 0x1087, Layer.Earrings ) + { + Resistances[ ( (AosElementAttribute)element ) ] = 2; + + m_Attribute = element; + LootType = LootType.Blessed; + } + + public EarringosfProtection( Serial serial ) + : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.Write( (int)0 ); // version + writer.Write( (int)m_Attribute ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadInt(); + m_Attribute = (AosElementAttribute)reader.ReadInt(); + } + + public static AosElementAttribute RandomType() + { + return GetTypes( Utility.Random( 5 ) ); + } + + public static AosElementAttribute GetTypes( int value ) + { + switch( value ) + { + case 0: return AosElementAttribute.Physical; + case 1: return AosElementAttribute.Fire; + case 2: return AosElementAttribute.Cold; + case 3: return AosElementAttribute.Poison; + default: return AosElementAttribute.Energy; + } + } + + public static int GetItemData( AosElementAttribute element, bool label ) + { + switch( element ) + { + case AosElementAttribute.Physical: return ( label ) ? 1071091 : 0; // Earring of Protection (Physical) 1071091 + case AosElementAttribute.Fire: return ( label ) ? 1071092 : 0x4ec; // Earring of Protection (Fire) 1071092 + case AosElementAttribute.Cold: return ( label ) ? 1071093 : 0x4f2; // Earring of Protection (Cold) 1071093 + case AosElementAttribute.Poison: return ( label ) ? 1071094 : 0x4f8; // Earring of Protection (Poison) 1071094 + case AosElementAttribute.Energy: return ( label ) ? 1071095 : 0x4fe; // Earring of Protection (Energy) 1071095 + + default: return -1; + } + } + } + + public class EarringBoxSet : RedVelvetGiftBox + { + [Constructable] + public EarringBoxSet() + : base() + { + DropItem( new EarringosfProtection( AosElementAttribute.Physical ) ); + DropItem( new EarringosfProtection( AosElementAttribute.Fire ) ); + DropItem( new EarringosfProtection( AosElementAttribute.Cold ) ); + DropItem( new EarringosfProtection( AosElementAttribute.Poison ) ); + DropItem( new EarringosfProtection( AosElementAttribute.Energy ) ); + } + + public EarringBoxSet( Serial serial ) : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.Write( (int)0 ); // version + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadInt(); + } + } +} \ No newline at end of file diff --git a/Scripts/Items/Special/Community Collection/JesterHatofChuckles.cs b/Scripts/Items/Special/Community Collection/JesterHatofChuckles.cs new file mode 100644 index 000000000..6070d5b56 --- /dev/null +++ b/Scripts/Items/Special/Community Collection/JesterHatofChuckles.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Server.Items +{ + public class JesterHatofChuckles : BaseHat, ITokunoDyable + { + public override int LabelNumber { get { return 1073256; } } //Jester Hat of Chuckles - Museum of Vesper Replica 1073256 + + public override int BasePhysicalResistance { get { return 12; } } + public override int BaseFireResistance { get { return 12; } } + public override int BaseColdResistance { get { return 12; } } + public override int BasePoisonResistance { get { return 12; } } + public override int BaseEnergyResistance { get { return 12; } } + + public override int InitMinHits{ get{ return 100; } } + public override int InitMaxHits{ get{ return 100; } } + + [Constructable] + public JesterHatofChuckles() : this( Utility.RandomList( 0x13e, 0x03, 0x172, 0x3f ) ) + { + } + + [Constructable] + public JesterHatofChuckles( int hue ) : base( 0x171C, hue ) + { + Attributes.Luck = 150; + Weight = 1.0; + } + + public JesterHatofChuckles( Serial serial ) : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.Write( (int) 0 ); // version + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadInt(); + } + } +} diff --git a/Scripts/Items/TeleporterTile.cs b/Scripts/Items/TeleporterTile.cs new file mode 100644 index 000000000..58afb7c8f --- /dev/null +++ b/Scripts/Items/TeleporterTile.cs @@ -0,0 +1,326 @@ +using System; +using System.Collections.Generic; +using Server.Gumps; +using Server.Mobiles; +using Server.Multis; +using Server.Regions; +using Server.Spells; +using Server.Targeting; + +namespace Server.Items +{ + public class TeleporterTile : Item, ISecurable + { + [CommandProperty( AccessLevel.GameMaster )] + public SecureLevel Level { get { return m_Level; } set { m_Level = value; } } + + [CommandProperty( AccessLevel.GameMaster )] + public TeleporterTile Dest { get { return m_Dest; } set { m_Dest = value; } } + + public virtual BaseHouse House + { + get + { + if( m_House == null || m_House.Deleted ) + { + m_House = FindHouse( this ); + } + + return m_House; + } + } + + public override int LabelNumber { get { return ( Dest == null || Dest.Deleted ) ? 1114916 : 1113857; } } + + public override bool HandlesOnMovement { get { return true; } } + + private SecureLevel m_Level; + private TeleporterTile m_Dest; + private BaseHouse m_House; + + private Dictionary m_InSequence; + + public enum TelMes + { + None = -1, + UnlinkedName = 1114916, // house teleporter (unlinked) 1114916 + LinkedName = 1113857, // house teleporter 1113857 + SelectTele = 1114918, // Select a House Teleporter to link to. 1114918 + MustBeInPack = 1114917, // This must be in your backpack to link it. 1114917 + TelesNowLinked = 1114919, // The two House Teleporters are now linked. 1114919 + MustBeSecured = 502692, // This must be in a house and be locked down to work. 502692 + NotAllowed = 1019004, // You are not allowed to travel there. 1019004 + InvalidDest = 1113858, // This teleporter does not have a valid destination. 1113858 + Criminal = 1005270, // Thou'rt a criminal and cannot escape so easily... 1005270 + InCombat = 1005564, // Wouldst thou flee during the heat of battle?? 100556 + NoAccess = 1061637 // You are not allowed to access this. 1061637 + } + + [Constructable] + public TeleporterTile() + : base( 0x40bb ) + { + } + + public override void OnAdded( object parent ) + { + Movable = true; + m_InSequence = new Dictionary(); + base.OnAdded( parent ); + } + + public TeleporterTile( Serial serial ) + : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int)0 ); + + writer.Write( (Item)m_Dest ); + writer.Write( (int)m_Level ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + + m_Dest = (TeleporterTile)reader.ReadItem(); + m_Level = (SecureLevel)reader.ReadInt(); + + if( m_InSequence == null ) + { + m_InSequence = new Dictionary(); + } + } + + public override void OnLocationChange( Point3D oldLocation ) + { + base.OnLocationChange( oldLocation ); + + bool tmp = ( ( m_House = null ) == House ); + } + + public override void OnMapChange() + { + base.OnMapChange(); + + bool tmp = ( ( m_House = null ) == House ); + } + + public override void OnDoubleClick( Mobile from ) + { + if( RootParent == from ) + { + from.SendLocalizedMessage( 1114918 ); + + from.Target = new InternalTarget( this ); + } + else + { + from.SendLocalizedMessage( 1114917 ); + } + + base.OnDoubleClick( from ); + } + + public virtual bool IsValidObject( object obj, TelMes message, ref TelMes error ) + { + if( obj != null ) + { + if( obj is Item ) + { + Item tmp = obj as Item; + + return ( ( ( tmp != null && !tmp.Deleted ) ? TelMes.None : message ) == TelMes.None ); + } + + if( obj is PlayerMobile ) + { + PlayerMobile tmp = obj as PlayerMobile; + + return ( ( ( tmp != null && !tmp.Deleted ) ? TelMes.None : message ) == TelMes.None ); + } + } + return false; + } + + private static PlayerMobile ExtractPlayerMobile( Mobile m, ref PlayerMobile player ) + { + return player = ( m != null && !m.Deleted && m is PlayerMobile ) ? m as PlayerMobile : null; + } + + public override bool OnMoveOver( Mobile m ) + { + TelMes error = TelMes.None; PlayerMobile player = null; + + if( IsValidObject( ExtractPlayerMobile( m, ref player ), TelMes.None, ref error ) ) + { + if( IsValidObject( m_Dest, TelMes.InvalidDest, ref error ) ) + { + if( IsValidObject( House, TelMes.MustBeSecured, ref error ) ) + { + if( IsValidPlacement( this, ref error ) ) + { + m_InSequence[ player ] = TryReadAndCreateKey( player, null ); + + if( m_InSequence[ player ] == null ) + { + m_InSequence[ player ] = StartSequence( SequenceStart_Callback, player, 0 ); + } + } + } + } + } + + if( error == TelMes.None ) + { + m.SendLocalizedMessage( ( (int)error ) ); + } + + return base.OnMoveOver( m ); + } + + private static bool IsValidPlacement( TeleporterTile tile, ref TelMes error ) + { + return ( error = ( CheckSecure( tile ) || CheckSecure( tile.Dest ) ) ? TelMes.MustBeSecured : TelMes.None ) == TelMes.MustBeSecured; + } + + private static bool CheckSecure( TeleporterTile tile ) + { + return ( tile.IsLockedDown || tile.IsSecure ); + } + + private static BaseHouse FindHouse( TeleporterTile teleporter ) + { + return BaseHouse.FindHouseAt( teleporter ); + } + + private static bool IsPlayerAllowed( TeleporterTile tile, PlayerMobile player, ref TelMes error ) + { + if( CheckAccess( tile, player ) && ( CheckAccess( tile.Dest, player ) ) ) + { + if( player.Kills < 5 || tile.Dest.Map == Map.Felucca ) + { + if( !SpellHelper.CheckCombat( player ) ) + { + if( player.Criminal ) + { + error = TelMes.Criminal; + } + } + else + { + error = TelMes.InCombat; + } + } + error = TelMes.NotAllowed; + } + error = TelMes.NoAccess; + + return ( error == 0 ); + } + + private static bool CheckAccess( TeleporterTile teleporter, PlayerMobile player ) + { + return ( BaseHouse.CheckAccessible( player, teleporter ) && ( teleporter.House.HasAccess( player ) ) ); + } + + public virtual Timer TryReadAndCreateKey( PlayerMobile player, Timer timer ) + { + if( m_InSequence == null ) + { + m_InSequence = new Dictionary(); + } + + if( m_InSequence.Count < 1 || !m_InSequence.ContainsKey( player ) ) + { + m_InSequence.Add( player, null ); + } + + return ( m_InSequence[ player ] != null ) ? m_InSequence[ player ] : null; + } + + public delegate void Sequence_Callback( PlayerMobile player ); + + public virtual Timer StartSequence( Sequence_Callback callback, PlayerMobile player, double delay ) + { + return m_InSequence[ player ] = Timer.DelayCall( TimeSpan.FromSeconds( delay ), new TimerStateCallback( callback ), player ); + } + + public virtual void SequenceStart_Callback( PlayerMobile player ) + { + if( IsStillValid( player ) ) + { + Effects.PlaySound( player.Location, player.Map, 0x1F0 ); + + StartSequence( SourceEffect_Callback, player, 0 ); + } + } + + public virtual void SourceEffect_Callback( PlayerMobile player ) + { + if( IsStillValid( player ) ) + { + if( !player.Hidden || player.AccessLevel == AccessLevel.Player ) + { + Effects.SendLocationEffect( player.Location, player.Map, 0x3728, 10, 10 ); + } + + StartSequence( Teleport_Callback, player, .5 ); + } + } + + public virtual void Teleport_Callback( PlayerMobile player ) + { + StartSequence( SequenceEnd_Callback, player, .5 ); + } + + public virtual void SequenceEnd_Callback( PlayerMobile player ) + { + if( IsStillValid( player ) ) + { + Effects.PlaySound( player.Location, player.Map, 0x1F0 ); + + StartSequence( SourceEffect_Callback, player, .25 ); + } + } + + public virtual bool IsStillValid( PlayerMobile player ) + { + return ( ( player != null && !player.Deleted ) && player.X == X && player.Y == Y ); + } + } + + public class InternalTarget : Target + { + private TeleporterTile m_Clicked; + + public InternalTarget( TeleporterTile usedtele ) + : base( 4, false, TargetFlags.None ) + { + m_Clicked = usedtele; + } + + protected override void OnTarget( Mobile from, object targeted ) + { + TeleporterTile teleporter = ( targeted is TeleporterTile ) ? targeted as TeleporterTile : null; + + if( teleporter != null ) + { + if( teleporter.RootParent != from ) + { + from.SendLocalizedMessage( 1114917 ); + } + } + + m_Clicked.Dest = teleporter; + teleporter.Dest = m_Clicked; + + from.SendLocalizedMessage( 1114919 ); + } + } +} \ No newline at end of file diff --git a/Scripts/Mobiles/Monsters/ML/Animal/CuSidhe.cs b/Scripts/Mobiles/Monsters/ML/Animal/CuSidhe.cs index b33da3782..125a374b4 100644 --- a/Scripts/Mobiles/Monsters/ML/Animal/CuSidhe.cs +++ b/Scripts/Mobiles/Monsters/ML/Animal/CuSidhe.cs @@ -25,9 +25,11 @@ namespace Server.Mobiles else if ( chance < 500 ) Hue = Utility.RandomList( 0x97A, 0x978, 0x901, 0x8AC, 0x5A7, 0x527 ); - SetStr( 1201, 1225 ); - SetDex( 151, 170 ); - SetInt( 251, 282 ); + SetStr( 1200, 1225 ); + SetDex( 150, 170 ); + SetInt( 250, 285 ); + + SetHits( 1010, 1275 ); SetDamage( 21, 28 ); @@ -35,8 +37,8 @@ namespace Server.Mobiles SetDamageType( ResistanceType.Cold, 50 ); SetDamageType( ResistanceType.Energy, 50 ); - SetResistance( ResistanceType.Physical, 55, 65 ); - SetResistance( ResistanceType.Fire, 30, 45 ); + SetResistance( ResistanceType.Physical, 50, 65 ); + SetResistance( ResistanceType.Fire, 25, 45 ); SetResistance( ResistanceType.Cold, 70, 85 ); SetResistance( ResistanceType.Poison, 30, 50 ); SetResistance( ResistanceType.Energy, 70, 85 ); diff --git a/Scripts/Spells/Spellweaving/ArcaneCircle.cs b/Scripts/Spells/Spellweaving/ArcaneCircle.cs index 9b61e1934..91ea51357 100644 --- a/Scripts/Spells/Spellweaving/ArcaneCircle.cs +++ b/Scripts/Spells/Spellweaving/ArcaneCircle.cs @@ -61,7 +61,7 @@ namespace Server.Spells.Spellweaving private static bool IsSanctuary( Point3D p, Map m ) { - return (m == Map.Trammel || m == Map.Felucca) && p.X == 6267 && p.Y == 131 && p.Z == 5; + return (m == Map.Trammel || m == Map.Felucca) && p.X == 6267 && p.Y == 131; } private static bool IsValidLocation( Point3D location, Map map ) @@ -76,10 +76,11 @@ namespace Server.Spells.Spellweaving for( int i = 0; i < tiles.Length; ++i ) { StaticTile t = tiles[i]; + ItemData id = TileData.ItemTable[t.ID & TileData.MaxItemValue]; int tand = t.ID; - if( t.Z != location.Z ) + if( t.Z + id.CalcHeight != location.Z ) continue; else if( IsValidTile( tand ) ) return true; @@ -89,7 +90,9 @@ namespace Server.Spells.Spellweaving foreach( Item item in eable ) { - if( item == null || item.Z != location.Z ) + ItemData id = item.ItemData; + + if( item == null || item.Z + id.CalcHeight != location.Z ) continue; else if( IsValidTile( item.ItemID ) ) {