diff --git a/Scripts/Accounting/AccountHandler.cs b/Scripts/Accounting/AccountHandler.cs index bd267f5d9..f9b3fbf60 100644 --- a/Scripts/Accounting/AccountHandler.cs +++ b/Scripts/Accounting/AccountHandler.cs @@ -61,7 +61,8 @@ namespace Server.Misc if ( Core.AOS ) { - CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3618, 2591, 0 ); + //CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3618, 2591, 0 ); + CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3503, 2574, 14 ); StartingCities[StartingCities.Length - 1] = haven; } } diff --git a/Scripts/Accounting/Firewall.cs b/Scripts/Accounting/Firewall.cs index 30e97e546..6f37a0f6c 100644 --- a/Scripts/Accounting/Firewall.cs +++ b/Scripts/Accounting/Firewall.cs @@ -225,8 +225,6 @@ namespace Server if( IPAddress.TryParse( entry, out addr ) ) return new IPFirewallEntry( addr ); - - //Try CIDR parse string[] str = entry.Split( '/' ); @@ -269,6 +267,16 @@ namespace Server Add( (IPAddress)obj ); else if( obj is string ) Add( (string)obj ); + else if( obj is IFirewallEntry ) + Add( (IFirewallEntry)obj ); + } + + public static void Add( IFirewallEntry entry ) + { + if( !m_Blocked.Contains( entry ) ) + m_Blocked.Add( entry ); + + Save(); } public static void Add( string pattern ) diff --git a/Scripts/Accounting/IPLimiter.cs b/Scripts/Accounting/IPLimiter.cs index f13b247f4..47558763d 100644 --- a/Scripts/Accounting/IPLimiter.cs +++ b/Scripts/Accounting/IPLimiter.cs @@ -48,7 +48,7 @@ namespace Server.Misc { ++count; - if ( count > MaxAddresses ) + if ( count >= MaxAddresses ) return false; } } diff --git a/Scripts/Commands/Handlers.cs b/Scripts/Commands/Handlers.cs index cd7caff07..3e4cab2a5 100644 --- a/Scripts/Commands/Handlers.cs +++ b/Scripts/Commands/Handlers.cs @@ -102,12 +102,12 @@ namespace Server.Commands { if ( e.Length == 1 && !e.GetBoolean( 0 ) ) { - from.Send( SpeedBoost.Disabled ); + from.Send( SpeedControl.Disable ); from.SendMessage( "Speed boost has been disabled." ); } else { - from.Send( SpeedBoost.Enabled ); + from.Send( SpeedControl.MountSpeed ); from.SendMessage( "Speed boost has been enabled." ); } } diff --git a/Scripts/Engines/AI/AI/BaseAI.cs b/Scripts/Engines/AI/AI/BaseAI.cs index 2e9f91257..97adff4d2 100644 --- a/Scripts/Engines/AI/AI/BaseAI.cs +++ b/Scripts/Engines/AI/AI/BaseAI.cs @@ -11,6 +11,8 @@ using Server.ContextMenus; using Server.Engines.Quests; using Server.Engines.Quests.Necro; using MoveImpl=Server.Movement.MovementImpl; +using Server.Spells; +using Server.Spells.Spellweaving; namespace Server.Mobiles { @@ -1486,7 +1488,7 @@ namespace Server.Mobiles if( aggr.IsDeadBondedPet || !aggr.Alive ) continue; - double aggrScore = m_Mobile.GetValueFrom( aggr, FightMode.Closest, false ); + double aggrScore = m_Mobile.GetFightModeRanking( aggr, FightMode.Closest, false ); if( (newCombatant == null || aggrScore > newScore) && m_Mobile.InLOS( aggr ) ) { @@ -2484,6 +2486,10 @@ namespace Server.Mobiles if ( bFacFoe && !m_Mobile.IsEnemy( m ) ) continue; + //Ignore anyone under EtherealVoyage + if( TransformationSpellHelper.UnderTransformation( m, typeof( EtherealVoyageSpell ) ) ) + continue; + if( acqType == FightMode.Aggressor || acqType == FightMode.Evil ) { // Only acquire this mobile if it attacked us, or if it's evil. @@ -2516,7 +2522,7 @@ namespace Server.Mobiles if ( bFacFoe && !bFacFriend && !m_Mobile.CanBeHarmful( m, false ) ) continue; - theirVal = m_Mobile.GetValueFrom( m, acqType, bPlayerOnly ); + theirVal = m_Mobile.GetFightModeRanking( m, acqType, bPlayerOnly ); if( theirVal > val && m_Mobile.InLOS( m ) ) { diff --git a/Scripts/Engines/AI/Creature/BaseCreature.cs b/Scripts/Engines/AI/Creature/BaseCreature.cs index fc926ae03..cf4fef1ba 100644 --- a/Scripts/Engines/AI/Creature/BaseCreature.cs +++ b/Scripts/Engines/AI/Creature/BaseCreature.cs @@ -13,6 +13,7 @@ using Server.ContextMenus; using Server.Engines.Quests; using Server.Factions; using Server.Spells.Bushido; +using Server.Spells.Spellweaving; namespace Server.Mobiles { @@ -758,6 +759,9 @@ namespace Server.Mobiles if ( !(m is BaseCreature) || m is Server.Engines.Quests.Haven.MilitiaFighter ) return true; + if( TransformationSpellHelper.UnderTransformation( m, typeof( EtherealVoyageSpell ) ) ) + return false; + BaseCreature c = (BaseCreature)m; return ( m_iTeam != c.m_iTeam || ( (m_bSummoned || m_bControlled) != (c.m_bSummoned || c.m_bControlled) )/* || c.Combatant == this*/ ); @@ -2519,15 +2523,13 @@ namespace Server.Mobiles this.PublicOverheadMessage( MessageType.Regular, 41, false, String.Format( format, args ) ); } - /* - * Will need to be givent a better name - * + /* * This function can be overriden.. so a "Strongest" mobile, can have a different definition depending * on who check for value * -Could add a FightMode.Prefered * */ - public virtual double GetValueFrom( Mobile m, FightMode acqType, bool bPlayerOnly ) + public virtual double GetFightModeRanking( Mobile m, FightMode acqType, bool bPlayerOnly ) { if ( ( bPlayerOnly && m.Player ) || !bPlayerOnly ) { @@ -2549,7 +2551,7 @@ namespace Server.Mobiles } } - // Turn, - for let, + for right + // Turn, - for left, + for right // Basic for now, needs work public virtual void Turn(int iTurnSteps) { @@ -4159,6 +4161,8 @@ namespace Server.Mobiles this.OwnerAbandonTime = DateTime.MinValue; } + GiftOfLifeSpell.HandleDeath( this ); + CheckStatTimers(); } else diff --git a/Scripts/Engines/CannedEvil/ChampionSpawn.cs b/Scripts/Engines/CannedEvil/ChampionSpawn.cs index 68d09b447..5bc4ab014 100644 --- a/Scripts/Engines/CannedEvil/ChampionSpawn.cs +++ b/Scripts/Engines/CannedEvil/ChampionSpawn.cs @@ -1011,7 +1011,7 @@ namespace Server.Engines.CannedEvil public override void AlterLightLevel( Mobile m, ref int global, ref int personal ) { base.AlterLightLevel( m, ref global, ref personal ); - global = Math.Max( global, 1 + m_Spawn.Level ); //This is a gusstimate. TODO: Verify & get exact values // OSI testing: at 2 red skulls, light = 0x3 ; 1 red = 0x3.; 3 = 8; 9 = 0xD 8 = 0xD 12 = 0x12 10 = 0xD + global = Math.Max( global, 1 + m_Spawn.Level ); //This is a guesstimate. TODO: Verify & get exact values // OSI testing: at 2 red skulls, light = 0x3 ; 1 red = 0x3.; 3 = 8; 9 = 0xD 8 = 0xD 12 = 0x12 10 = 0xD } } diff --git a/Scripts/Engines/Craft/Core/CraftItem.cs b/Scripts/Engines/Craft/Core/CraftItem.cs index c8905b76a..acd07a661 100644 --- a/Scripts/Engines/Craft/Core/CraftItem.cs +++ b/Scripts/Engines/Craft/Core/CraftItem.cs @@ -5,6 +5,7 @@ using Server; using Server.Items; using Server.Factions; using Server.Mobiles; +using Server.Commands; namespace Server.Engines.Craft { @@ -679,11 +680,11 @@ namespace Server.Engines.Craft { // Runebooks are a special case, they need a blank recall rune - Item[] runes = ourPack.FindItemsByType( typeof( RecallRune ) ); + List runes = ourPack.FindItemsByType(); - for ( int i = 0; i < runes.Length; ++i ) + for ( int i = 0; i < runes.Count; ++i ) { - RecallRune rune = runes[i] as RecallRune; + RecallRune rune = runes[i]; if ( rune != null && !rune.Marked ) { @@ -1115,6 +1116,9 @@ namespace Server.Engines.Craft from.AddToBackpack( item ); + if( from.AccessLevel > AccessLevel.Player ) + CommandLogging.WriteLine( from, "Crafting {0} with craft system {1}", CommandLogging.Format( item ), craftSystem.GetType().Name ); + //from.PlaySound( 0x57 ); } diff --git a/Scripts/Engines/Craft/DefBlacksmithy.cs b/Scripts/Engines/Craft/DefBlacksmithy.cs index bed2a2f67..bd694f3df 100644 --- a/Scripts/Engines/Craft/DefBlacksmithy.cs +++ b/Scripts/Engines/Craft/DefBlacksmithy.cs @@ -282,7 +282,7 @@ namespace Server.Engines.Craft index = AddCraft( typeof( StandardPlateKabuto ), 1011079, 1030196, 90.0, 140.0, typeof( IronIngot ), 1044036, 25, 1044037 ); SetNeededExpansion( index, Expansion.SE ); - + /* if( Core.ML ) { index = AddCraft( typeof( Circlet ), 1011079, 1032645, 62.1, 112.1, typeof( IronIngot ), 1044036, 6, 1044037 ); @@ -296,8 +296,8 @@ namespace Server.Engines.Craft AddRes( index, typeof( Amethyst ), 1044236, 1, 1044240 ); AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 ); SetNeededExpansion( index, Expansion.ML ); - } + * */ } #endregion @@ -336,7 +336,6 @@ namespace Server.Engines.Craft if( Core.SE ) { - index = AddCraft( typeof( NoDachi ), 1011081, 1030221, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 ); SetNeededExpansion( index, Expansion.SE ); index = AddCraft( typeof( Wakizashi ), 1011081, 1030223, 50.0, 100.0, typeof( IronIngot ), 1044036, 8, 1044037 ); @@ -353,7 +352,7 @@ namespace Server.Engines.Craft SetNeededExpansion( index, Expansion.SE ); index = AddCraft( typeof( Sai ), 1011081, 1030234, 50.0, 100.0, typeof( IronIngot ), 1044036, 12, 1044037 ); SetNeededExpansion( index, Expansion.SE ); - + /* if( Core.ML ) { index = AddCraft( typeof( RadiantScimitar ), 1011081, 1031571, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); @@ -409,17 +408,152 @@ namespace Server.Engines.Craft ForceNonExceptional( index ); SetNeededExpansion( index, Expansion.ML ); - /* //TODO: true spellblade; - index = AddCraft( typeof( ), 1011081, 1072920, 70.0, 120.0, typeof( IronIngot ), 1044036, 15, 1044037 ); - AddRes( index, typeof( GrizzledBones ), 1032684, 1, 1053098 ); - AddRes( index, typeof( Blight ), 1032675, 10, 1053098 ); - AddRes( index, typeof( Scourge ), 1032677, 10, 1053098 ); + index = AddCraft( typeof( TrueSpellblade ), 1011081, 1073513, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 ); + AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 ); AddRecipe( index, 4 ); - ForceNonExceptional( index ); SetNeededExpansion( index, Expansion.ML ); - * */ + index = AddCraft( typeof( IcySpellblade ), 1011081, 1073514, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 ); + AddRes( index, typeof( Turquoise ), 1032691, 1, 1044240 ); + AddRecipe( index, 5 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( FierySpellblade ), 1011081, 1073515, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 ); + AddRes( index, typeof( FireRuby ), 1032695, 1, 1044240 ); + AddRecipe( index, 6 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( SpellbladeOfDefense ), 1011081, 1073516, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 ); + AddRes( index, typeof( WhitePearl ), 1032694, 1, 1044240 ); + AddRecipe( index, 7 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( TrueAssassinSpike ), 1011081, 1073517, 75.0, 125.0, typeof( IronIngot ), 1044036, 9, 1044037 ); + AddRes( index, typeof( DarkSapphire ), 1032690, 1, 1044240 ); + AddRecipe( index, 8 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( ChargedAssassinSpike ), 1011081, 1073518, 75.0, 125.0, typeof( IronIngot ), 1044036, 9, 1044037 ); + AddRes( index, typeof( EcruCitrine ), 1032693, 1, 1044240 ); + AddRecipe( index, 9 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( MagekillerAssassinSpike ), 1011081, 1073519, 75.0, 125.0, typeof( IronIngot ), 1044036, 9, 1044037 ); + AddRes( index, typeof( BrilliantAmber ), 1032697, 1, 1044240 ); + AddRecipe( index, 10 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( WoundingAssassinSpike ), 1011081, 1073520, 75.0, 125.0, typeof( IronIngot ), 1044036, 9, 1044037 ); + AddRes( index, typeof( PerfectEmerald ), 1032692, 1, 1044240 ); + AddRecipe( index, 11 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( TrueLeafblade ), 1011081, 1073521, 75.0, 125.0, typeof( IronIngot ), 1044036, 12, 1044037 ); + AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 ); + AddRecipe( index, 12 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( Luckblade ), 1011081, 1073522, 75.0, 125.0, typeof( IronIngot ), 1044036, 12, 1044037 ); + AddRes( index, typeof( WhitePearl ), 1032694, 1, 1044240 ); + AddRecipe( index, 13 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( MagekillerLeafblade ), 1011081, 1073523, 75.0, 125.0, typeof( IronIngot ), 1044036, 12, 1044037 ); + AddRes( index, typeof( FireRuby ), 1032695, 1, 1044240 ); + AddRecipe( index, 14 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( LeafbladeOfEase ), 1011081, 1073524, 75.0, 125.0, typeof( IronIngot ), 1044036, 12, 1044037 ); + AddRes( index, typeof( PerfectEmerald ), 1032692, 1, 1044240 ); + AddRecipe( index, 15 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( KnightsWarCleaver ), 1011081, 1073525, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 ); + AddRes( index, typeof( PerfectEmerald ), 1032692, 1, 1044240 ); + AddRecipe( index, 16 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( ButchersWarCleaver ), 1011081, 1073526, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 ); + AddRes( index, typeof( Turquoise ), 1032691, 1, 1044240 ); + AddRecipe( index, 17 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( SerratedWarCleaver ), 1011081, 1073527, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 ); + AddRes( index, typeof( EcruCitrine ), 1032693, 1, 1044240 ); + AddRecipe( index, 18 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( TrueWarCleaver ), 1011081, 1073528, 75.0, 125.0, typeof( IronIngot ), 1044036, 18, 1044037 ); + AddRes( index, typeof( BrilliantAmber ), 1032697, 1, 1044240 ); + AddRecipe( index, 19 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( AdventurersMachete ), 1011081, 1073533, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 ); + AddRes( index, typeof( WhitePearl ), 1032694, 1, 1044240 ); + AddRecipe( index, 20 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( OrcishMachete ), 1011081, 1073534, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 ); + AddRes( index, typeof( Scourge ), 1072136, 1, 1042081 ); + AddRecipe( index, 21 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( MacheteOfDefense ), 1011081, 1073535, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 ); + AddRes( index, typeof( BrilliantAmber ), 1032697, 1, 1044240 ); + AddRecipe( index, 22 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( DiseasedMachete ), 1011081, 1073536, 75.0, 125.0, typeof( IronIngot ), 1044036, 14, 1044037 ); + AddRes( index, typeof( Blight ), 1072134, 1, 1042081 ); + AddRecipe( index, 23 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( RuneSabre ), 1011081, 1073537, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( Turquoise ), 1032691, 1, 1044240 ); + AddRecipe( index, 24 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( MagesRuneBlade ), 1011081, 1073538, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 ); + AddRecipe( index, 25 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( RuneBladeOfKnowledge ), 1011081, 1073539, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( EcruCitrine ), 1032693, 1, 1044240 ); + AddRecipe( index, 26 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( CorruptedRuneBlade ), 1011081, 1073540, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( Corruption ), 1072135, 1, 1042081 ); + AddRecipe( index, 27 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( TrueRadiantScimitar ), 1011081, 1073541, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( BrilliantAmber ), 1032697, 1, 1044240 ); + AddRecipe( index, 28 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( DarkglowScimitar ), 1011081, 1073542, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( DarkSapphire ), 1032690, 1, 1044240 ); + AddRecipe( index, 29 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( IcyScimitar ), 1011081, 1073543, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( DarkSapphire ), 1032690, 1, 1044240 ); + AddRecipe( index, 30 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( TwinklingScimitar ), 1011081, 1073544, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( DarkSapphire ), 1032690, 1, 1044240 ); + AddRecipe( index, 31 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( BoneMachete ), 1011081, 1020526, 75.0, 125.0, typeof( IronIngot ), 1044036, 20, 1044037 ); + AddRes( index, typeof( Bone ), 1049064, 6, 1049063 ); + AddRecipe( index, 32 ); + SetNeededExpansion( index, Expansion.ML ); } + */ } #endregion @@ -431,6 +565,33 @@ namespace Server.Engines.Craft AddCraft( typeof( LargeBattleAxe ), 1011082, 1025115, 28.0, 78.0, typeof( IronIngot ), 1044036, 12, 1044037 ); AddCraft( typeof( TwoHandedAxe ), 1011082, 1025187, 33.0, 83.0, typeof( IronIngot ), 1044036, 16, 1044037 ); AddCraft( typeof( WarAxe ), 1011082, 1025040, 39.1, 89.1, typeof( IronIngot ), 1044036, 16, 1044037 ); + /* + if( Core.ML ) + { + index = AddCraft( typeof( OrnateAxe ), 1011082, 1031572, 70.0, 120.0, typeof( IronIngot ), 1044036, 18, 1044037 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( GuardianAxe ), 1011082, 1073545, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 ); + AddRecipe( index, 33 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( SingingAxe ), 1011082, 1073546, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( BrilliantAmber ), 1032697, 1, 1044240 ); + AddRecipe( index, 34 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( ThunderingAxe ), 1011082, 1073547, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( EcruCitrine ), 1032693, 1, 1044240 ); + AddRecipe( index, 35 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( HeavyOrnateAxe ), 1011082, 1073548, 75.0, 125.0, typeof( IronIngot ), 1044036, 15, 1044037 ); + AddRes( index, typeof( Turquoise ), 1032691, 1, 1044240 ); + AddRecipe( index, 36 ); + SetNeededExpansion( index, Expansion.ML ); + + }*/ #endregion #region Pole Arms @@ -481,6 +642,40 @@ namespace Server.Engines.Craft AddRes( index, typeof( Cloth ), 1044286, 10, 1044287 ); SetNeededExpansion( index, Expansion.SE ); } + /* + if( Core.ML ) + { + index = AddCraft( typeof( DiamondMace ), 1011084, 1073568, 70.0, 120.0, typeof( IronIngot ), 1044036, 20, 1044037 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( ShardThrasher ), 1011084, 1072918, 70.0, 120.0, typeof( IronIngot ), 1044036, 20, 1044037 ); + AddRes( index, typeof( EyeOfTheTravesty ), 1073126, 1, 1042081 ); + AddRes( index, typeof( Muculent ), 1072139, 10, 1042081 ); + AddRes( index, typeof( Corruption ), 1072135, 10, 1042081 ); + AddRecipe( index, 37 ); + ForceNonExceptional( index ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( RubyMace ), 1011084, 1073529, 75.0, 125.0, typeof( IronIngot ), 1044036, 20, 1044037 ); + AddRes( index, typeof( FireRuby ), 1032695, 1, 1044240 ); + AddRecipe( index, 38 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( EmeraldMace ), 1011084, 1073530, 75.0, 125.0, typeof( IronIngot ), 1044036, 20, 1044037 ); + AddRes( index, typeof( PerfectEmerald ), 1032692, 1, 1044240 ); + AddRecipe( index, 39 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( SapphireMace ), 1011084, 1073531, 75.0, 125.0, typeof( IronIngot ), 1044036, 20, 1044037 ); + AddRes( index, typeof( DarkSapphire ), 1032690, 1, 1044240 ); + AddRecipe( index, 40 ); + SetNeededExpansion( index, Expansion.ML ); + + index = AddCraft( typeof( SilverEtchedMace ), 1011084, 1073532, 75.0, 125.0, typeof( IronIngot ), 1044036, 20, 1044037 ); + AddRes( index, typeof( BlueDiamond ), 1032696, 1, 1044240 ); + AddRecipe( index, 41 ); + SetNeededExpansion( index, Expansion.ML ); + }*/ #endregion #region Dragon Scale Armor diff --git a/Scripts/Engines/Craft/DefCarpentry.cs b/Scripts/Engines/Craft/DefCarpentry.cs index e8df13675..c9546f969 100644 --- a/Scripts/Engines/Craft/DefCarpentry.cs +++ b/Scripts/Engines/Craft/DefCarpentry.cs @@ -115,6 +115,15 @@ namespace Server.Engines.Craft SetNeededExpansion( index, Expansion.SE ); } + if( Core.AOS ) //Duplicate Entries to preserve ordering depending on era + { + index = AddCraft( typeof( FishingPole ), 1044294, 1023519, 68.4, 93.4, typeof( Log ), 1044041, 5, 1044351 ); //This is in the categor of Other during AoS + AddSkill( index, SkillName.Tailoring, 40.0, 45.0 ); + AddRes( index, typeof( Cloth ), 1044286, 5, 1044287 ); + } + + + // Furniture AddCraft( typeof( FootStool ), 1044291, 1022910, 11.0, 36.0, typeof( Log ), 1044041, 9, 1044351 ); AddCraft( typeof( Stool ), 1044291, 1022602, 11.0, 36.0, typeof( Log ), 1044041, 9, 1044351 ); @@ -194,10 +203,13 @@ namespace Server.Engines.Craft AddCraft( typeof( QuarterStaff ), 1044295, 1023721, 73.6, 98.6, typeof( Log ), 1044041, 6, 1044351 ); AddCraft( typeof( GnarledStaff ), 1044295, 1025112, 78.9, 103.9, typeof( Log ), 1044041, 7, 1044351 ); AddCraft( typeof( WoodenShield ), 1044295, 1027034, 52.6, 77.6, typeof( Log ), 1044041, 9, 1044351 ); - - index = AddCraft( typeof( FishingPole ), Core.AOS ? 1044294 : 1044295, 1023519, 68.4, 93.4, typeof( Log ), 1044041, 5, 1044351 ); //This is in the categor of Other during AoS - AddSkill( index, SkillName.Tailoring, 40.0, 45.0 ); - AddRes( index, typeof( Cloth ), 1044286, 5, 1044287 ); + + if( !Core.AOS ) //Duplicate Entries to preserve ordering depending on era + { + index = AddCraft( typeof( FishingPole ), 1044295, 1023519, 68.4, 93.4, typeof( Log ), 1044041, 5, 1044351 ); //This is in the categor of Other during AoS + AddSkill( index, SkillName.Tailoring, 40.0, 45.0 ); + AddRes( index, typeof( Cloth ), 1044286, 5, 1044287 ); + } if( Core.SE ) { diff --git a/Scripts/Engines/Harvest/Fishing.cs b/Scripts/Engines/Harvest/Fishing.cs index 7db60f7d5..73ae65308 100644 --- a/Scripts/Engines/Harvest/Fishing.cs +++ b/Scripts/Engines/Harvest/Fishing.cs @@ -4,6 +4,7 @@ using Server.Items; using Server.Mobiles; using Server.Engines.Quests; using Server.Engines.Quests.Collector; +using System.Collections.Generic; namespace Server.Engines.Harvest { @@ -200,11 +201,11 @@ namespace Server.Engines.Harvest if ( pack != null ) { - Item[] messages = pack.FindItemsByType( typeof( SOS ) ); + List messages = pack.FindItemsByType(); - for ( int i = 0; i < messages.Length; ++i ) + for ( int i = 0; i < messages.Count; ++i ) { - SOS sos = (SOS)messages[i]; + SOS sos = messages[i]; if ( from.Map == sos.TargetMap && from.InRange( sos.TargetLocation, 60 ) ) return true; @@ -228,18 +229,18 @@ namespace Server.Engines.Harvest } else if ( type == typeof( MessageInABottle ) ) { - return new MessageInABottle( SafeMap( from.Map ) ); + return new MessageInABottle( from.Map == Map.Felucca ? Map.Felucca : Map.Trammel ); } Container pack = from.Backpack; if ( pack != null ) { - Item[] messages = pack.FindItemsByType( typeof( SOS ) ); + List messages = pack.FindItemsByType(); - for ( int i = 0; i < messages.Length; ++i ) + for ( int i = 0; i < messages.Count; ++i ) { - SOS sos = (SOS)messages[i]; + SOS sos = messages[i]; if ( from.Map == sos.TargetMap && from.InRange( sos.TargetLocation, 60 ) ) { diff --git a/Scripts/Engines/Help/HelpGump.cs b/Scripts/Engines/Help/HelpGump.cs index 6ec040f29..5dfa08833 100644 --- a/Scripts/Engines/Help/HelpGump.cs +++ b/Scripts/Engines/Help/HelpGump.cs @@ -298,7 +298,7 @@ namespace Server.Engines.Help } else { - from.MoveToWorld( new Point3D( 3618, 2587, 0 ), Map.Trammel ); + from.MoveToWorld( new Point3D( 3503, 2574, 14 ), Map.Trammel ); } } diff --git a/Scripts/Engines/Help/SpeechLog.cs b/Scripts/Engines/Help/SpeechLog.cs index 2c8913701..70b8183e5 100644 --- a/Scripts/Engines/Help/SpeechLog.cs +++ b/Scripts/Engines/Help/SpeechLog.cs @@ -15,7 +15,7 @@ namespace Server.Engines.Help public static readonly bool Enabled = true; // How long should we maintain each speech entry? - public static readonly TimeSpan EntryDuration = TimeSpan.FromMinutes( 10.0 ); + public static readonly TimeSpan EntryDuration = TimeSpan.FromMinutes( 20.0 ); // What is the maximum number of entries a log can contain? (0 -> no limit) public static readonly int MaxLength = 0; @@ -49,7 +49,7 @@ namespace Server.Engines.Help { from.SendMessage( "Speech logs aren't supported on that target." ); } - else if ( from != targeted && from.AccessLevel <= pm.AccessLevel ) + else if ( from != targeted && from.AccessLevel <= pm.AccessLevel && from.AccessLevel != AccessLevel.Owner ) { from.SendMessage( "You don't have the required access level to view {0} speech log.", pm.Female ? "her" : "his" ); } diff --git a/Scripts/Engines/Plants/PlantItem.cs b/Scripts/Engines/Plants/PlantItem.cs index 599eba375..e5ef1fed3 100644 --- a/Scripts/Engines/Plants/PlantItem.cs +++ b/Scripts/Engines/Plants/PlantItem.cs @@ -431,7 +431,7 @@ namespace Server.Engines.Plants int message; if ( ApplyPotion( potion.PotionEffect, false, out message ) ) { - potion.Delete(); + potion.Consume(); from.PlaySound( 0x240 ); from.AddToBackpack( new Bottle() ); } diff --git a/Scripts/Engines/Plants/PlantSystem.cs b/Scripts/Engines/Plants/PlantSystem.cs index 08b4585fc..27da22781 100644 --- a/Scripts/Engines/Plants/PlantSystem.cs +++ b/Scripts/Engines/Plants/PlantSystem.cs @@ -2,6 +2,7 @@ using System; using System.Collections; using Server; using Server.Items; +using System.Collections.Generic; namespace Server.Engines.Plants { @@ -391,7 +392,7 @@ namespace Server.Engines.Plants if ( from.Backpack != null ) { - Item[] plants = from.Backpack.FindItemsByType( typeof( PlantItem ) ); + List plants = from.Backpack.FindItemsByType(); foreach ( PlantItem plant in plants ) { @@ -404,7 +405,7 @@ namespace Server.Engines.Plants if ( bank != null ) { - Item[] plants = bank.FindItemsByType( typeof( PlantItem ) ); + List plants = bank.FindItemsByType(); foreach ( PlantItem plant in plants ) { diff --git a/Scripts/Engines/Quests/Core/Items/EnchantedSextant.cs b/Scripts/Engines/Quests/Core/Items/EnchantedSextant.cs index a22a80ca9..a00087cb0 100644 --- a/Scripts/Engines/Quests/Core/Items/EnchantedSextant.cs +++ b/Scripts/Engines/Quests/Core/Items/EnchantedSextant.cs @@ -6,6 +6,7 @@ namespace Server.Items { public class EnchantedSextant : Item { + //TODO: Trammel/Haven private static readonly Point2D[] m_TrammelBanks = new Point2D[] { new Point2D( 652, 820 ), diff --git a/Scripts/Engines/Reports/Reports.cs b/Scripts/Engines/Reports/Reports.cs index 69fe66f79..cdc456b17 100644 --- a/Scripts/Engines/Reports/Reports.cs +++ b/Scripts/Engines/Reports/Reports.cs @@ -160,7 +160,7 @@ namespace Server.Engines.Reports public static SkillDistribution[] GetSkillDistribution() { - int skip = ( Core.ML ? 0 : Core.SE ? 1 : Core.AOS ? 3 : 6 ); //TODO: Change for ML + int skip = ( Core.ML ? 0 : Core.SE ? 1 : Core.AOS ? 3 : 6 ); SkillDistribution[] distribs = new SkillDistribution[SkillInfo.Table.Length - skip]; diff --git a/Scripts/Engines/Virtues/Honor.cs b/Scripts/Engines/Virtues/Honor.cs index 65bc9c7be..0b83e7010 100644 --- a/Scripts/Engines/Virtues/Honor.cs +++ b/Scripts/Engines/Virtues/Honor.cs @@ -369,16 +369,14 @@ namespace Server } } - public void ApplyPerfectionDamageBonus( ref double factor ) + public int PerfectionDamageBonus { - if ( m_Perfection > 0 ) - factor *= 1.0 + (m_Perfection / 100.0); + get { return m_Perfection; } } - public void ApplyPerfectionLuckBonus( ref int luck ) + public int PerfectionLuckBonus { - if ( m_Perfection > 0 ) - luck += (m_Perfection * m_Perfection) / 10; + get{ return (m_Perfection * m_Perfection) / 10; } } public bool CheckDistance() diff --git a/Scripts/Gumps/AdminGump.cs b/Scripts/Gumps/AdminGump.cs index 490af849c..9e141e9f3 100644 --- a/Scripts/Gumps/AdminGump.cs +++ b/Scripts/Gumps/AdminGump.cs @@ -1182,7 +1182,7 @@ namespace Server.Gumps { object obj = m_List[index]; - if ( !(obj is IPAddress) && !(obj is String) ) + if ( !(obj is Firewall.IFirewallEntry ) ) break; int offset = 140 + (i * 20); @@ -1197,7 +1197,7 @@ namespace Server.Gumps { AddFirewallHeader(); - if ( !(state is IPAddress) && !(state is String) ) + if ( !(state is Firewall.IFirewallEntry) ) break; AddHtml( 10, 125, 400, 20, Color( Center( state.ToString() ), LabelColor32 ), false, false ); @@ -1210,9 +1210,6 @@ namespace Server.Gumps { m_List = new ArrayList(); - string pattern = state as String; - IPAddress addr = ( state is IPAddress ? (IPAddress)state : IPAddress.Any ); - foreach ( Account acct in Accounts.GetAccounts() ) { IPAddress[] loginList = acct.LoginIPs; @@ -1221,22 +1218,12 @@ namespace Server.Gumps for( int i = 0; !contains && i < loginList.Length; ++i ) { - if( pattern == null ) //if is IP Address + if( ((Firewall.IFirewallEntry)state).IsBlocked( loginList[i] ) ) { - contains = loginList[i].Equals( addr ); - continue; + m_List.Add( acct ); + break; } - - contains = Utility.IPMatchCIDR( pattern, loginList[i] ); - - if( !contains ) - contains = Utility.IPMatch( pattern, loginList[i] ); } - - - - if ( contains ) - m_List.Add( acct ); } m_List.Sort( AccountComparer.Instance ); @@ -2481,10 +2468,7 @@ namespace Server.Gumps } else { - object toAdd; - - try{ toAdd = IPAddress.Parse( text ); } - catch{ toAdd = text; } + object toAdd = Firewall.ToFirewallEntry( text ); CommandLogging.WriteLine( from, "{0} {1} firewalling {2}", from.AccessLevel, CommandLogging.Format( from ), toAdd ); @@ -2502,7 +2486,7 @@ namespace Server.Gumps } case 3: { - if ( m_State is IPAddress || m_State is String ) + if ( m_State is Firewall.IFirewallEntry ) { CommandLogging.WriteLine( from, "{0} {1} removing {2} from firewall list", from.AccessLevel, CommandLogging.Format( from ), m_State ); diff --git a/Scripts/Gumps/Guilds/New Guild System/GuildRosterGump.cs b/Scripts/Gumps/Guilds/New Guild System/GuildRosterGump.cs index 53a80f340..3ce7e6fdb 100644 --- a/Scripts/Gumps/Guilds/New Guild System/GuildRosterGump.cs +++ b/Scripts/Gumps/Guilds/New Guild System/GuildRosterGump.cs @@ -10,7 +10,7 @@ using System.Collections.Generic; namespace Server.Guilds { - public class GuildRosterGump : BaseGuildListGump //TODO: Convert to + public class GuildRosterGump : BaseGuildListGump { #region Comparers private class NameComparer : IComparer diff --git a/Scripts/Gumps/PetResurrectGump.cs b/Scripts/Gumps/PetResurrectGump.cs index bede19155..0c874cf9c 100644 --- a/Scripts/Gumps/PetResurrectGump.cs +++ b/Scripts/Gumps/PetResurrectGump.cs @@ -9,12 +9,19 @@ namespace Server.Gumps public class PetResurrectGump : Gump { private BaseCreature m_Pet; + private double m_HitsScalar; - public PetResurrectGump( Mobile from, BaseCreature pet ) : base( 50, 50 ) + public PetResurrectGump( Mobile from, BaseCreature pet ) + : this( from, pet, 0.0 ) + { + } + + public PetResurrectGump( Mobile from, BaseCreature pet, double hitsScalar ) : base( 50, 50 ) { from.CloseGump( typeof( PetResurrectGump ) ); m_Pet = pet; + m_HitsScalar = hitsScalar; AddPage( 0 ); @@ -48,6 +55,11 @@ namespace Server.Gumps from.SendLocalizedMessage( 503256 ); // You fail to resurrect the creature. return; } + else if( m_Pet.Region != null && m_Pet.Region.IsPartOf( "Khaldun" ) ) //TODO: Confirm for pets, as per Bandage's script. + { + from.SendLocalizedMessage( 1010395 ); // The veil of death in this area is too strong and resists thy efforts to restore life. + return; + } m_Pet.PlaySound( 0x214 ); m_Pet.FixedEffect( 0x376A, 10, 16 ); @@ -62,6 +74,9 @@ namespace Server.Gumps for ( int i = 0; i < m_Pet.Skills.Length; ++i ) //Decrease all skills on pet. m_Pet.Skills[i].Base -= decreaseAmount; + + if( !m_Pet.IsDeadPet && m_HitsScalar > 0 ) + m_Pet.Hits = (int)(m_Pet.HitsMax * m_HitsScalar); } } diff --git a/Scripts/Gumps/Properties/SetBodyGump.cs b/Scripts/Gumps/Properties/SetBodyGump.cs index 78ec9754e..96749e8cb 100644 --- a/Scripts/Gumps/Properties/SetBodyGump.cs +++ b/Scripts/Gumps/Properties/SetBodyGump.cs @@ -25,7 +25,8 @@ namespace Server.Gumps private const int SelectedColor32 = 0x8080FF; private const int TextColor32 = 0xFFFFFF; - public SetBodyGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list ) : this( prop, mobile, o, stack, page, list, 0, null, ModelBodyType.Invalid ) + public SetBodyGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list ) + : this( prop, mobile, o, stack, page, list, 0, null, ModelBodyType.Invalid ) { } @@ -47,7 +48,8 @@ namespace Server.Gumps AddHtml( x + 35, y, 200, 20, Color( text, isSelection ? SelectedColor32 : LabelColor32 ), false, false ); } - public SetBodyGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list, int ourPage, ArrayList ourList, ModelBodyType ourType ) : base( 20, 30 ) + public SetBodyGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list, int ourPage, ArrayList ourList, ModelBodyType ourType ) + : base( 20, 30 ) { m_Property = prop; m_Mobile = mobile; diff --git a/Scripts/Gumps/ResurrectGump.cs b/Scripts/Gumps/ResurrectGump.cs index 4e10c7a7c..3d4182340 100644 --- a/Scripts/Gumps/ResurrectGump.cs +++ b/Scripts/Gumps/ResurrectGump.cs @@ -11,10 +11,10 @@ namespace Server.Gumps { public enum ResurrectMessage { - ChaosShrine = 0, - VirtueShrine = 1, - Healer = 2, - Generic = 3, + ChaosShrine=0, + VirtueShrine=1, + Healer=2, + Generic=3, } public class ResurrectGump : Gump @@ -22,28 +22,44 @@ namespace Server.Gumps private Mobile m_Healer; private int m_Price; private bool m_FromSacrifice; + private double m_HitsScalar; - public ResurrectGump( Mobile owner ) : this( owner, owner, ResurrectMessage.Generic, false ) + public ResurrectGump( Mobile owner ) + : this( owner, owner, ResurrectMessage.Generic, false ) { } - public ResurrectGump( Mobile owner, bool fromSacrifice ) : this( owner, owner, ResurrectMessage.Generic, fromSacrifice ) + public ResurrectGump( Mobile owner, double hitsScalar ) + : this( owner, owner, ResurrectMessage.Generic, false, hitsScalar ) { } - public ResurrectGump( Mobile owner, Mobile healer ) : this( owner, healer, ResurrectMessage.Generic, false ) + public ResurrectGump( Mobile owner, bool fromSacrifice ) + : this( owner, owner, ResurrectMessage.Generic, fromSacrifice ) { } - public ResurrectGump( Mobile owner, ResurrectMessage msg ) : this( owner, owner, msg, false ) + public ResurrectGump( Mobile owner, Mobile healer ) + : this( owner, healer, ResurrectMessage.Generic, false ) { } - public ResurrectGump( Mobile owner, Mobile healer, ResurrectMessage msg, bool fromSacrifice ) : base( 100, 0 ) + public ResurrectGump( Mobile owner, ResurrectMessage msg ) + : this( owner, owner, msg, false ) + { + } + + public ResurrectGump( Mobile owner, Mobile healer, ResurrectMessage msg, bool fromSacrifice ) + : this( owner, healer, msg, fromSacrifice, 0.0 ) + { + } + + public ResurrectGump( Mobile owner, Mobile healer, ResurrectMessage msg, bool fromSacrifice, double hitsScalar ) + : base( 100, 0 ) { m_Healer = healer; - m_FromSacrifice = fromSacrifice; + m_HitsScalar = hitsScalar; AddPage( 0 ); @@ -63,7 +79,8 @@ namespace Server.Gumps AddHtmlLocalized( 100, 230, 110, 35, 1011011, false, false ); // CONTINUE } - public ResurrectGump( Mobile owner, Mobile healer, int price ) : base( 150, 50 ) + public ResurrectGump( Mobile owner, Mobile healer, int price ) + : base( 150, 50 ) { m_Healer = healer; m_Price = price; @@ -122,19 +139,19 @@ namespace Server.Gumps { Mobile from = state.Mobile; - if ( info.ButtonID == 1 || info.ButtonID == 2 ) + if( info.ButtonID == 1 || info.ButtonID == 2 ) { - if ( from.Map == null || !from.Map.CanFit( from.Location, 16, false, false ) ) + if( from.Map == null || !from.Map.CanFit( from.Location, 16, false, false ) ) { from.SendLocalizedMessage( 502391 ); // Thou can not be resurrected there! return; } - if ( m_Price > 0 ) + if( m_Price > 0 ) { - if ( info.IsSwitched( 1 ) ) + if( info.IsSwitched( 1 ) ) { - if ( Banker.Withdraw( from, m_Price ) ) + if( Banker.Withdraw( from, m_Price ) ) { from.SendLocalizedMessage( 1060398, m_Price.ToString() ); // ~1_AMOUNT~ gold has been withdrawn from your bank box. from.SendLocalizedMessage( 1060022, Banker.GetBalance( from ).ToString() ); // You have ~1_AMOUNT~ gold in cash remaining in your bank box. @@ -157,11 +174,11 @@ namespace Server.Gumps from.Resurrect(); - if ( m_Healer != null && from != m_Healer ) + if( m_Healer != null && from != m_Healer ) { VirtueLevel level = VirtueHelper.GetLevel( m_Healer, VirtueName.Compassion ); - switch ( level ) + switch( level ) { case VirtueLevel.Seeker: from.Hits = AOS.Scale( from.HitsMax, 20 ); break; case VirtueLevel.Follower: from.Hits = AOS.Scale( from.HitsMax, 40 ); break; @@ -169,56 +186,60 @@ namespace Server.Gumps } } - if ( m_FromSacrifice && !from.Criminal && from is PlayerMobile ) + if( m_FromSacrifice && !from.Criminal && from is PlayerMobile ) { ((PlayerMobile)from).AvailableResurrects -= 1; Container pack = from.Backpack; Container corpse = from.Corpse; - if ( pack != null && corpse != null ) + if( pack != null && corpse != null ) { List items = new List( corpse.Items ); - for ( int i = 0; i < items.Count; ++i ) + for( int i = 0; i < items.Count; ++i ) { Item item = items[i]; - if ( item.Layer != Layer.Hair && item.Layer != Layer.FacialHair && item.Movable ) + if( item.Layer != Layer.Hair && item.Layer != Layer.FacialHair && item.Movable ) pack.DropItem( item ); } } } - if ( from.Fame > 0 ) + if( from.Fame > 0 ) { int amount = from.Fame / 10; Misc.Titles.AwardFame( from, -amount, true ); } - if ( !Core.AOS && from.ShortTermMurders >= 5 ) + if( !Core.AOS && from.ShortTermMurders >= 5 ) { - double loss = (100.0 - ( 4.0 + (from.ShortTermMurders / 5.0))) / 100.0; // 5 to 15% loss + double loss = (100.0 - (4.0 + (from.ShortTermMurders / 5.0))) / 100.0; // 5 to 15% loss - if ( loss < 0.85 ) + if( loss < 0.85 ) loss = 0.85; - else if ( loss > 0.95 ) + else if( loss > 0.95 ) loss = 0.95; - if ( from.RawStr * loss > 10 ) + if( from.RawStr * loss > 10 ) from.RawStr = (int)(from.RawStr * loss); - if ( from.RawInt * loss > 10 ) + if( from.RawInt * loss > 10 ) from.RawInt = (int)(from.RawInt * loss); - if ( from.RawDex * loss > 10 ) + if( from.RawDex * loss > 10 ) from.RawDex = (int)(from.RawDex * loss); - for ( int s = 0; s < from.Skills.Length; s++ ) + for( int s = 0; s < from.Skills.Length; s++ ) { - if ( from.Skills[s].Base * loss > 35 ) + if( from.Skills[s].Base * loss > 35 ) from.Skills[s].Base *= loss; } } + + + if( from.Alive && m_HitsScalar > 0 ) + from.Hits = (int)(from.HitsMax * m_HitsScalar); } } } diff --git a/Scripts/Gumps/WarningGump.cs b/Scripts/Gumps/WarningGump.cs index bba00a492..49e610741 100644 --- a/Scripts/Gumps/WarningGump.cs +++ b/Scripts/Gumps/WarningGump.cs @@ -9,6 +9,13 @@ namespace Server.Gumps { private WarningGumpCallback m_Callback; private object m_State; + private bool m_CancelButton; + + public WarningGump( int header, int headerColor, object content, int contentColor, int width, int height, WarningGumpCallback callback, object state, bool cancelButton ) + : this( header, headerColor, content, contentColor, width, height, callback, state ) + { + m_CancelButton = cancelButton; + } public WarningGump( int header, int headerColor, object content, int contentColor, int width, int height, WarningGumpCallback callback, object state ) : base( (640 - width) / 2, (480 - height) / 2 ) { @@ -39,8 +46,11 @@ namespace Server.Gumps AddButton( 10, height - 30, 4005, 4007, 1, GumpButtonType.Reply, 0 ); AddHtmlLocalized( 40, height - 30, 170, 20, 1011036, 32767, false, false ); // OKAY - AddButton( 10 + ((width - 20) / 2), height - 30, 4005, 4007, 0, GumpButtonType.Reply, 0 ); - AddHtmlLocalized( 40 + ((width - 20) / 2), height - 30, 170, 20, 1011012, 32767, false, false ); // CANCEL + if( m_CancelButton ) + { + AddButton( 10 + ((width - 20) / 2), height - 30, 4005, 4007, 0, GumpButtonType.Reply, 0 ); + AddHtmlLocalized( 40 + ((width - 20) / 2), height - 30, 170, 20, 1011012, 32767, false, false ); // CANCEL + } } public override void OnResponse( Server.Network.NetState sender, RelayInfo info ) diff --git a/Scripts/Items/Armor/BaseArmor.cs b/Scripts/Items/Armor/BaseArmor.cs index 09854bbbf..bd6503ebc 100644 --- a/Scripts/Items/Armor/BaseArmor.cs +++ b/Scripts/Items/Armor/BaseArmor.cs @@ -1569,6 +1569,7 @@ namespace Server.Items from.Send( new DisplayEquipmentInfo( this, eqInfo ) ); } + #region ICraftable Members public int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue ) @@ -1591,9 +1592,30 @@ namespace Server.Items if ( context != null && context.DoNotColor ) Hue = 0; - if ( quality == 2 ) + if( Quality == ArmorQuality.Exceptional ) + { DistributeBonuses( (tool is BaseRunicTool ? 6 : Core.SE ? 15 : 14) ); // Not sure since when, but right now 15 points are added, not 14. + if( Core.ML && !(this is BaseShield) ) + { + int bonus = (int)(from.Skills.ArmsLore.Value / 20); + + for( int i = 0; i < bonus; i++ ) + { + switch( Utility.Random( 5 ) ) + { + case 0: m_PhysicalBonus++; break; + case 1: m_FireBonus++; break; + case 2: m_ColdBonus++; break; + case 3: m_EnergyBonus++; break; + case 4: m_PoisonBonus++; break; + } + } + + from.CheckSkill( SkillName.ArmsLore, 0, 100 ); + } + } + if ( Core.AOS && tool is BaseRunicTool ) ((BaseRunicTool)tool).ApplyAttributesTo( this ); diff --git a/Scripts/Items/Maps/TreasureMap.cs b/Scripts/Items/Maps/TreasureMap.cs index c047d238b..99667a90c 100644 --- a/Scripts/Items/Maps/TreasureMap.cs +++ b/Scripts/Items/Maps/TreasureMap.cs @@ -249,7 +249,7 @@ namespace Server.Items if ( m.Backpack == null ) return false; - Item[] items = m.Backpack.FindItemsByType( typeof( BaseHarvestTool ) ); + List items = m.Backpack.FindItemsByType(); foreach ( BaseHarvestTool tool in items ) { diff --git a/Scripts/Items/Misc/Corpses/Corpse.cs b/Scripts/Items/Misc/Corpses/Corpse.cs index fa53a8711..15d67c65f 100644 --- a/Scripts/Items/Misc/Corpses/Corpse.cs +++ b/Scripts/Items/Misc/Corpses/Corpse.cs @@ -55,6 +55,8 @@ namespace Server.Items set{ m_TimeOfDeath = value; } } + public override bool DisplayWeight { get { return false; } } + public HairInfo Hair { get { return m_Hair; } } public FacialHairInfo FacialHair { get { return m_FacialHair; } } diff --git a/Scripts/Items/Misc/PublicMoongate.cs b/Scripts/Items/Misc/PublicMoongate.cs index 7d8641d16..ee8d41428 100644 --- a/Scripts/Items/Misc/PublicMoongate.cs +++ b/Scripts/Items/Misc/PublicMoongate.cs @@ -237,7 +237,7 @@ namespace Server.Items new PMEntry( new Point3D( 1828, 2948,-20), 1012008 ), // Trinsic new PMEntry( new Point3D( 643, 2067, 5 ), 1012009 ), // Skara Brae new PMEntry( new Point3D( 3563, 2139, 34), 1012010 ), // Magincia - new PMEntry( new Point3D( 3763, 2771, 50), 1046259 ) // Haven + new PMEntry( new Point3D( 3763, 2771, 50), 1078098 ) // New Haven } ); public static readonly PMList Felucca = diff --git a/Scripts/Items/Misc/TribalPaint.cs b/Scripts/Items/Misc/TribalPaint.cs index 4fd51df4d..3f3275bbe 100644 --- a/Scripts/Items/Misc/TribalPaint.cs +++ b/Scripts/Items/Misc/TribalPaint.cs @@ -1,6 +1,7 @@ using System; using Server; using Server.Mobiles; +using Server.Spells; namespace Server.Items { @@ -35,7 +36,7 @@ namespace Server.Items { from.SendLocalizedMessage( 501699 ); // You cannot disguise yourself while polymorphed. } - else if ( Spells.Necromancy.TransformationSpell.UnderTransformation( from ) ) + else if( TransformationSpellHelper.UnderTransformation( from ) ) { from.SendLocalizedMessage( 501699 ); // You cannot disguise yourself while polymorphed. } diff --git a/Scripts/Items/Skill Items/Fishing/Misc/MessageInABottle.cs b/Scripts/Items/Skill Items/Fishing/Misc/MessageInABottle.cs index 3785a4e91..b7feacfe7 100644 --- a/Scripts/Items/Skill Items/Fishing/Misc/MessageInABottle.cs +++ b/Scripts/Items/Skill Items/Fishing/Misc/MessageInABottle.cs @@ -58,7 +58,7 @@ namespace Server.Items { base.Serialize( writer ); - writer.Write( (int) 2 ); // version + writer.Write( (int) 3 ); // version writer.Write( (int) m_Level ); @@ -73,6 +73,7 @@ namespace Server.Items switch ( version ) { + case 3: case 2: { m_Level = reader.ReadInt(); @@ -92,6 +93,9 @@ namespace Server.Items if ( version < 2 ) m_Level = GetRandomLevel(); + + if( version < 3 && m_TargetMap == Map.Tokuno ) + m_TargetMap = Map.Trammel; } public override void OnDoubleClick( Mobile from ) diff --git a/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs b/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs index 65dfca95e..b73e5206f 100644 --- a/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs +++ b/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs @@ -100,7 +100,7 @@ namespace Server.Items { base.Serialize( writer ); - writer.Write( (int) 3 ); // version + writer.Write( (int) 4 ); // version writer.Write( m_Level ); @@ -117,6 +117,7 @@ namespace Server.Items switch ( version ) { + case 4: case 3: case 2: { @@ -150,6 +151,9 @@ namespace Server.Items if ( version < 3 ) UpdateHue(); + + if( version < 4 && m_TargetMap == Map.Tokuno ) + m_TargetMap = Map.Trammel; } public override void OnDoubleClick( Mobile from ) diff --git a/Scripts/Items/Skill Items/Magical/Misc/PotionKeg.cs b/Scripts/Items/Skill Items/Magical/Misc/PotionKeg.cs index 018cba3e8..a01efef1b 100644 --- a/Scripts/Items/Skill Items/Magical/Misc/PotionKeg.cs +++ b/Scripts/Items/Skill Items/Magical/Misc/PotionKeg.cs @@ -209,19 +209,30 @@ namespace Server.Items if ( item is BasePotion ) { BasePotion pot = (BasePotion)item; + int toHold = Math.Min( 100 - m_Held, pot.Amount ); - if ( m_Held == 0 ) + + if ( toHold <= 0 ) { - if ( GiveBottle( from ) ) + from.SendLocalizedMessage( 502233 ); // The keg will not hold any more! + return false; + } + else if ( m_Held == 0 ) + { + if ( GiveBottle( from, toHold ) ) { m_Type = pot.PotionEffect; - Held = 1; + Held = toHold; from.PlaySound( 0x240 ); from.SendLocalizedMessage( 502237 ); // You place the empty bottle in your backpack. - item.Delete(); + item.Consume( toHold ); + + if( !item.Deleted ) + item.Bounce( from ); + return true; } else @@ -235,23 +246,21 @@ namespace Server.Items from.SendLocalizedMessage( 502236 ); // You decide that it would be a bad idea to mix different types of potions. return false; } - else if ( m_Held >= 100 ) - { - from.SendLocalizedMessage( 502233 ); // The keg will not hold any more! - return false; - } else { - if ( GiveBottle( from ) ) + if ( GiveBottle( from, toHold ) ) { - ++Held; - item.Delete(); + Held += toHold; from.PlaySound( 0x240 ); from.SendLocalizedMessage( 502237 ); // You place the empty bottle in your backpack. - item.Delete(); + item.Consume( toHold ); + + if( !item.Deleted ) + item.Bounce( from ); + return true; } else @@ -268,11 +277,11 @@ namespace Server.Items } } - public bool GiveBottle( Mobile m ) + public bool GiveBottle( Mobile m, int amount ) { Container pack = m.Backpack; - Bottle bottle = new Bottle(); + Bottle bottle = new Bottle( amount ); if ( pack == null || !pack.TryDropItem( m, bottle, false ) ) { diff --git a/Scripts/Items/Skill Items/Magical/Potions/BasePotion.cs b/Scripts/Items/Skill Items/Magical/Potions/BasePotion.cs index 80899491a..b6fdf469d 100644 --- a/Scripts/Items/Skill Items/Magical/Potions/BasePotion.cs +++ b/Scripts/Items/Skill Items/Magical/Potions/BasePotion.cs @@ -1,6 +1,7 @@ using System; using Server; using Server.Engines.Craft; +using System.Collections.Generic; namespace Server.Items { @@ -51,7 +52,7 @@ namespace Server.Items { m_PotionEffect = effect; - Stackable = false; + Stackable = Core.ML; Weight = 1.0; } @@ -94,7 +95,7 @@ namespace Server.Items { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int) 1 ); // version writer.Write( (int) m_PotionEffect ); } @@ -107,12 +108,16 @@ namespace Server.Items switch ( version ) { + case 1: case 0: { m_PotionEffect = (PotionEffect)reader.ReadInt(); break; } } + + if( version == 0 ) + Stackable = Core.ML; } public abstract void Drink( Mobile from ); @@ -156,6 +161,15 @@ namespace Server.Items return AOS.Scale( v, 100 + AosAttributes.GetValue( m, AosAttribute.EnhancePotions ) ); } + + public override bool StackWith( Mobile from, Item dropped, bool playSound ) + { + if( dropped is BasePotion && ((BasePotion)dropped).m_PotionEffect == m_PotionEffect ) + return base.StackWith( from, dropped, playSound ); + + return false; + } + #region ICraftable Members public int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue ) @@ -166,11 +180,11 @@ namespace Server.Items if ( pack != null ) { - Item[] kegs = pack.FindItemsByType( typeof( PotionKeg ), true ); + List kegs = pack.FindItemsByType(); - for ( int i = 0; i < kegs.Length; ++i ) + for ( int i = 0; i < kegs.Count; ++i ) { - PotionKeg keg = kegs[i] as PotionKeg; + PotionKeg keg = kegs[i]; if ( keg == null ) continue; @@ -183,7 +197,7 @@ namespace Server.Items ++keg.Held; - Delete(); + Consume(); from.AddToBackpack( new Bottle() ); return -1; // signal placed in keg diff --git a/Scripts/Items/Skill Items/Magical/Potions/Cure Potions/BaseCurePotion.cs b/Scripts/Items/Skill Items/Magical/Potions/Cure Potions/BaseCurePotion.cs index 6673aaf27..24ff57728 100644 --- a/Scripts/Items/Skill Items/Magical/Potions/Cure Potions/BaseCurePotion.cs +++ b/Scripts/Items/Skill Items/Magical/Potions/Cure Potions/BaseCurePotion.cs @@ -1,5 +1,6 @@ using System; using Server; +using Server.Spells; namespace Server.Items { @@ -83,7 +84,7 @@ namespace Server.Items public override void Drink( Mobile from ) { - if ( Spells.Necromancy.TransformationSpell.UnderTransformation( from, typeof( Spells.Necromancy.VampiricEmbraceSpell ) ) ) + if ( TransformationSpellHelper.UnderTransformation( from, typeof( Spells.Necromancy.VampiricEmbraceSpell ) ) ) { from.SendLocalizedMessage( 1061652 ); // The garlic in the potion would surely kill you. } diff --git a/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs b/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs index 1e2b0fa80..235eb0beb 100644 --- a/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs +++ b/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs @@ -200,6 +200,11 @@ namespace Server.Items Effects.SendMovingEffect( from, to, m_Potion.ItemID & 0x3FFF, 7, 0, false, false, m_Potion.Hue, 0 ); + if( m_Potion.Amount > 1 ) + { + Mobile.LiftItemDupe( m_Potion, 1 ); + } + m_Potion.Internalize(); Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), new TimerStateCallback( m_Potion.Reposition_OnTick ), new object[]{ from, p, map } ); } @@ -210,7 +215,7 @@ namespace Server.Items if ( Deleted ) return; - Delete(); + Consume(); for ( int i = 0; m_Users != null && i < m_Users.Count; ++i ) { diff --git a/Scripts/Items/Skill Items/Magical/Scrolls/SpellweavingScrolls.cs b/Scripts/Items/Skill Items/Magical/Scrolls/SpellweavingScrolls.cs new file mode 100644 index 000000000..10cde2c50 --- /dev/null +++ b/Scripts/Items/Skill Items/Magical/Scrolls/SpellweavingScrolls.cs @@ -0,0 +1,550 @@ +using System; +using Server; +using Server.Items; + +namespace Server.Items +{ + public class ArcaneCircleScroll : SpellScroll + { + [Constructable] + public ArcaneCircleScroll() + : this( 1 ) + { + } + + [Constructable] + public ArcaneCircleScroll( int amount ) + : base( 600, 0x2D51, amount ) + { + } + + public ArcaneCircleScroll( 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(); + } + } + + public class GiftOfRenewalScroll : SpellScroll + { + [Constructable] + public GiftOfRenewalScroll() + : this( 1 ) + { + } + + [Constructable] + public GiftOfRenewalScroll( int amount ) + : base( 601, 0x2D52, amount ) + { + } + + public GiftOfRenewalScroll( 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(); + } + } + + public class ImmolatingWeaponScroll : SpellScroll + { + [Constructable] + public ImmolatingWeaponScroll() + : this( 1 ) + { + } + + [Constructable] + public ImmolatingWeaponScroll( int amount ) + : base( 602, 0x2D53, amount ) + { + } + + public ImmolatingWeaponScroll( 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(); + } + } + + public class AttuneWeaponScroll : SpellScroll + { + [Constructable] + public AttuneWeaponScroll() + : this( 1 ) + { + } + + [Constructable] + public AttuneWeaponScroll( int amount ) + : base( 603, 0x2D54, amount ) + { + } + + public AttuneWeaponScroll( 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(); + } + } + + public class ThunderstormScroll : SpellScroll + { + [Constructable] + public ThunderstormScroll() + : this( 1 ) + { + } + + [Constructable] + public ThunderstormScroll( int amount ) + : base( 604, 0x2D55, amount ) + { + } + + public ThunderstormScroll( 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(); + } + } + + public class NatureFuryScroll : SpellScroll + { + [Constructable] + public NatureFuryScroll() + : this( 1 ) + { + } + + [Constructable] + public NatureFuryScroll( int amount ) + : base( 605, 0x2D56, amount ) + { + } + + public NatureFuryScroll( 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(); + } + } + + public class SummonFeyScroll : SpellScroll + { + [Constructable] + public SummonFeyScroll() + : this( 1 ) + { + } + + [Constructable] + public SummonFeyScroll( int amount ) + : base( 606, 0x2D57, amount ) + { + } + + public SummonFeyScroll( 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(); + } + } + + public class SummonFiendScroll : SpellScroll + { + [Constructable] + public SummonFiendScroll() + : this( 1 ) + { + } + + [Constructable] + public SummonFiendScroll( int amount ) + : base( 606, 0x2D57, amount ) + { + } + + public SummonFiendScroll( 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(); + } + } + + public class ReaperFormScroll : SpellScroll + { + [Constructable] + public ReaperFormScroll() + : this( 1 ) + { + } + + [Constructable] + public ReaperFormScroll( int amount ) + : base( 608, 0x2D59, amount ) + { + } + + public ReaperFormScroll( 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(); + } + } + + public class WildfireScroll : SpellScroll + { + [Constructable] + public WildfireScroll() + : this( 1 ) + { + } + + [Constructable] + public WildfireScroll( int amount ) + : base( 609, 0x2D5A, amount ) + { + } + + public WildfireScroll( 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(); + } + } + + public class EssenceOfWindScroll : SpellScroll + { + [Constructable] + public EssenceOfWindScroll() + : this( 1 ) + { + } + + [Constructable] + public EssenceOfWindScroll( int amount ) + : base( 610, 0x2D5B, amount ) + { + } + + public EssenceOfWindScroll( 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(); + } + } + + public class DryadAllureScroll : SpellScroll + { + [Constructable] + public DryadAllureScroll() + : this( 1 ) + { + } + + [Constructable] + public DryadAllureScroll( int amount ) + : base( 611, 0x2D5C, amount ) + { + } + + public DryadAllureScroll( 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(); + } + } + + public class EtherealVoyageScroll : SpellScroll + { + [Constructable] + public EtherealVoyageScroll() + : this( 1 ) + { + } + + [Constructable] + public EtherealVoyageScroll( int amount ) + : base( 612, 0x2D5D, amount ) + { + } + + public EtherealVoyageScroll( 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(); + } + } + + public class WordOfDeathScroll : SpellScroll + { + [Constructable] + public WordOfDeathScroll() + : this( 1 ) + { + } + + [Constructable] + public WordOfDeathScroll( int amount ) + : base( 613, 0x2D5E, amount ) + { + } + + public WordOfDeathScroll( 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(); + } + } + + public class GiftOfLifeScroll : SpellScroll + { + [Constructable] + public GiftOfLifeScroll() + : this( 1 ) + { + } + + [Constructable] + public GiftOfLifeScroll( int amount ) + : base( 614, 0x2D5F, amount ) + { + } + + public GiftOfLifeScroll( 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(); + } + } + + public class ArcaneEmpowermentScroll : SpellScroll + { + [Constructable] + public ArcaneEmpowermentScroll() + : this( 1 ) + { + } + + [Constructable] + public ArcaneEmpowermentScroll( int amount ) + : base( 615, 0x2D60, amount ) + { + } + + public ArcaneEmpowermentScroll( 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/Skill Items/Magical/Spellbook.cs b/Scripts/Items/Skill Items/Magical/Spellbook.cs index 2e8fa6089..03d97459f 100644 --- a/Scripts/Items/Skill Items/Magical/Spellbook.cs +++ b/Scripts/Items/Skill Items/Magical/Spellbook.cs @@ -265,6 +265,8 @@ namespace Server.Items return ( book.SpellbookType == type && ( spellID == -1 || book.HasSpell( spellID ) ) ); } + public override bool DisplayWeight { get { return false; } } + private AosAttributes m_AosAttributes; private AosSkillBonuses m_AosSkillBonuses; diff --git a/Scripts/Items/Skill Items/Misc/Bandage.cs b/Scripts/Items/Skill Items/Misc/Bandage.cs index 9e282e8af..7272aa8b0 100644 --- a/Scripts/Items/Skill Items/Misc/Bandage.cs +++ b/Scripts/Items/Skill Items/Misc/Bandage.cs @@ -310,7 +310,7 @@ namespace Server.Items healerNumber = 1060088; // You bind the wound and stop the bleeding patientNumber = 1060167; // The bleeding wounds have healed, you are no longer bleeding! - BleedAttack.EndBleed( m_Patient, true ); + BleedAttack.EndBleed( m_Patient, false ); } else if ( MortalStrike.IsWounded( m_Patient ) ) { @@ -365,7 +365,7 @@ namespace Server.Items healerNumber = 500968; // You apply the bandages, but they barely help. } - m_Patient.Heal( (int) toHeal, false ); + m_Patient.Heal( (int) toHeal, m_Healer, false ); } else { diff --git a/Scripts/Items/Skill Items/Thief/DisguiseKit.cs b/Scripts/Items/Skill Items/Thief/DisguiseKit.cs index 310d671f8..3a763c0af 100644 --- a/Scripts/Items/Skill Items/Thief/DisguiseKit.cs +++ b/Scripts/Items/Skill Items/Thief/DisguiseKit.cs @@ -68,7 +68,7 @@ namespace Server.Items { from.SendLocalizedMessage( 1010465 ); // You cannot disguise yourself while holding a sigil } - else if ( TransformationSpell.UnderTransformation( from ) ) + else if ( TransformationSpellHelper.UnderTransformation( from ) ) { // You cannot disguise yourself while in that form. from.SendLocalizedMessage( 1061634 ); diff --git a/Scripts/Items/Special/Solen Items/BagOfSending.cs b/Scripts/Items/Special/Solen Items/BagOfSending.cs index 6964d0cee..893cda8d0 100644 --- a/Scripts/Items/Special/Solen Items/BagOfSending.cs +++ b/Scripts/Items/Special/Solen Items/BagOfSending.cs @@ -155,11 +155,15 @@ namespace Server.Items public override void OnDoubleClick( Mobile from ) { - if ( !this.IsChildOf( from.Backpack ) ) + if( from.Region.IsPartOf( typeof( Regions.Jail ) ) ) + { + from.SendMessage( "You may not do that in jail." ); + } + else if( !this.IsChildOf( from.Backpack ) ) { MessageHelper.SendLocalizedMessageTo( this, from, 1054107, 0x59 ); // The bag of sending must be in your backpack. } - else if ( this.Charges == 0 ) + else if( this.Charges == 0 ) { MessageHelper.SendLocalizedMessageTo( this, from, 1042544, 0x59 ); // This item is out of charges. } @@ -183,7 +187,11 @@ namespace Server.Items if ( m_Bag.Deleted ) return; - if ( !m_Bag.IsChildOf( from.Backpack ) ) + if( from.Region.IsPartOf( typeof( Regions.Jail ) ) ) + { + from.SendMessage( "You may not do that in jail." ); + } + else if( !m_Bag.IsChildOf( from.Backpack ) ) { MessageHelper.SendLocalizedMessageTo( m_Bag, from, 1054107, 0x59 ); // The bag of sending must be in your backpack. } diff --git a/Scripts/Items/Special/Special Scrolls/PowerScroll.cs b/Scripts/Items/Special/Special Scrolls/PowerScroll.cs index f35c22cca..074543f49 100644 --- a/Scripts/Items/Special/Special Scrolls/PowerScroll.cs +++ b/Scripts/Items/Special/Special Scrolls/PowerScroll.cs @@ -102,7 +102,42 @@ namespace Server.Items SkillName.Bushido }; - public static SkillName[] Skills{ get{ return ( Core.SE ? m_SESkills : Core.AOS ? m_AOSSkills : m_Skills ); } } + private static SkillName[] m_MLSkills = new SkillName[] + { + SkillName.Blacksmith, + SkillName.Tailoring, + SkillName.Swords, + SkillName.Fencing, + SkillName.Macing, + SkillName.Archery, + SkillName.Wrestling, + SkillName.Parry, + SkillName.Tactics, + SkillName.Anatomy, + SkillName.Healing, + SkillName.Magery, + SkillName.Meditation, + SkillName.EvalInt, + SkillName.MagicResist, + SkillName.AnimalTaming, + SkillName.AnimalLore, + SkillName.Veterinary, + SkillName.Musicianship, + SkillName.Provocation, + SkillName.Discordance, + SkillName.Peacemaking, + SkillName.Chivalry, + SkillName.Focus, + SkillName.Necromancy, + SkillName.Stealing, + SkillName.Stealth, + SkillName.SpiritSpeak, + SkillName.Ninjitsu, + SkillName.Bushido, + SkillName.Spellweaving + }; + + public static SkillName[] Skills{ get{ return ( Core.ML ? m_MLSkills : Core.SE ? m_SESkills : Core.AOS ? m_AOSSkills : m_Skills ); } } public static PowerScroll CreateRandom( int min, int max ) { diff --git a/Scripts/Items/Weapons/Abilities/BleedAttack.cs b/Scripts/Items/Weapons/Abilities/BleedAttack.cs index 33ab70081..293c92d2e 100644 --- a/Scripts/Items/Weapons/Abilities/BleedAttack.cs +++ b/Scripts/Items/Weapons/Abilities/BleedAttack.cs @@ -3,6 +3,7 @@ using System.Collections; using Server.Mobiles; using Server.Spells.Necromancy; using Server.Network; +using Server.Spells; namespace Server.Items { @@ -27,7 +28,7 @@ namespace Server.Items ClearCurrentAbility( attacker ); // Necromancers under Lich or Wraith Form are immune to Bleed Attacks. - TransformContext context = TransformationSpell.GetContext( defender ); + TransformContext context = TransformationSpellHelper.GetContext( defender ); if ( (context != null && ( context.Type == typeof( LichFormSpell ) || context.Type == typeof( WraithFormSpell ))) || (defender is BaseCreature && ((BaseCreature)defender).BleedImmune) ) diff --git a/Scripts/Items/Weapons/BaseMeleeWeapon.cs b/Scripts/Items/Weapons/BaseMeleeWeapon.cs index 75faa64ca..a5e527f2e 100644 --- a/Scripts/Items/Weapons/BaseMeleeWeapon.cs +++ b/Scripts/Items/Weapons/BaseMeleeWeapon.cs @@ -1,5 +1,6 @@ using System; using Server; +using Server.Spells.Spellweaving; namespace Server.Items { @@ -17,9 +18,11 @@ namespace Server.Items { damage = base.AbsorbDamage( attacker, defender, damage ); + AttuneWeaponSpell.TryAbsorb( defender, ref damage ); + if ( Core.AOS ) return damage; - + int absorb = defender.MeleeDamageAbsorb; if ( absorb > 0 ) diff --git a/Scripts/Items/Weapons/BaseWeapon.cs b/Scripts/Items/Weapons/BaseWeapon.cs index 22a556c80..30f0286a1 100644 --- a/Scripts/Items/Weapons/BaseWeapon.cs +++ b/Scripts/Items/Weapons/BaseWeapon.cs @@ -11,6 +11,7 @@ using Server.Spells.Ninjitsu; using Server.Factions; using Server.Engines.Craft; using System.Collections.Generic; +using Server.Spells.Spellweaving; namespace Server.Items { @@ -865,12 +866,20 @@ namespace Server.Items if( Feint.Registry.Contains( m ) ) bonus -= ((Feint.FeintTimer)Feint.Registry[m]).SwingSpeedReduction; + TransformContext context = TransformationSpellHelper.GetContext( m ); + + if( context != null && context.Spell is ReaperFormSpell ) + bonus += ((ReaperFormSpell)context.Spell).SwingSpeedBonus; + int discordanceEffect = 0; // Discordance gives a malus of -0/-28% to swing speed. if ( SkillHandlers.Discordance.GetEffect( m, ref discordanceEffect ) ) bonus -= discordanceEffect; + if( EssenceOfWindSpell.IsDebuffed( m ) ) + bonus -= EssenceOfWindSpell.GetSSIMalus( m ); + if ( bonus > 60 ) bonus = 60; @@ -1323,18 +1332,26 @@ namespace Server.Items * The following damage bonuses multiply damage by a factor. * Capped at x3 (300%). */ - double factor = 1.0; + //double factor = 1.0; + int percentageBonus = 0; WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker ); SpecialMove move = SpecialMove.GetCurrentMove( attacker ); - if ( a != null ) - factor *= a.DamageScalar; + if( a != null ) + { + //factor *= a.DamageScalar; + percentageBonus += (int)(a.DamageScalar * 100) - 100; + } - if ( move != null ) - factor *= move.GetDamageScalar( attacker, defender ); + if( move != null ) + { + //factor *= move.GetDamageScalar( attacker, defender ); + percentageBonus += (int)(move.GetDamageScalar( attacker, defender ) * 100) - 100; + } - factor *= damageBonus; + //factor *= damageBonus; + percentageBonus += (int)(damageBonus * 100) - 100; CheckSlayerResult cs = CheckSlayers( attacker, defender ); @@ -1343,7 +1360,8 @@ namespace Server.Items if ( cs == CheckSlayerResult.Slayer ) defender.FixedEffect( 0x37B9, 10, 5 ); - factor *= 2.0; + //factor *= 2.0; + percentageBonus += 100; } if ( !attacker.Player ) @@ -1352,8 +1370,11 @@ namespace Server.Items { PlayerMobile pm = (PlayerMobile)defender; - if ( pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType() ) - factor *= 2.0; + if( pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType() ) + { + //factor *= 2.0; + percentageBonus += 100; + } } } else if ( !defender.Player ) @@ -1371,39 +1392,58 @@ namespace Server.Items if ( pm.EnemyOfOneType == defender.GetType() ) { defender.FixedEffect( 0x37B9, 10, 5, 1160, 0 ); - factor *= 1.5; + //factor *= 1.5; + percentageBonus += 50; } } } int packInstinctBonus = GetPackInstinctBonus( attacker, defender ); - if ( packInstinctBonus != 0 ) - factor *= 1.0 + (double)packInstinctBonus / 100.0; + 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 + if( m_InDoubleStrike ) + { + //factor *= 0.9; // 10% loss when attacking with double-strike + percentageBonus -= 10; + } - TransformContext context = TransformationSpell.GetContext( defender ); + TransformContext context = TransformationSpellHelper.GetContext( defender ); - if ( (m_Slayer == SlayerName.Silver || m_Slayer2 == SlayerName.Silver) && context != null && context.Type != typeof( HorrificBeastSpell ) ) - factor *= 1.25; // Every necromancer transformation other than horrific beast takes an additional 25% damage + 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 + percentageBonus += 25; + } if ( attacker is PlayerMobile && !(Core.ML && defender is PlayerMobile )) { - PlayerMobile pmAttacker = (PlayerMobile) attacker; + PlayerMobile pmAttacker = (PlayerMobile) attacker; - if ( pmAttacker.HonorActive && pmAttacker.InRange( defender, 1 ) ) - factor *= 1.25; + 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 ); + if( pmAttacker.SentHonorContext != null && pmAttacker.SentHonorContext.Target == defender ) + { + //pmAttacker.SentHonorContext.ApplyPerfectionDamageBonus( ref factor ); + percentageBonus += pmAttacker.SentHonorContext.PerfectionDamageBonus; + } } - if ( factor > 3.0 ) - factor = 3.0; + //if ( factor > 3.0 ) + // factor = 3.0; - damage = (int)(damage * factor); + percentageBonus = Math.Min( percentageBonus, 300 ); + + //damage = (int)(damage * factor); + damage = AOS.Scale( damage, 100 + percentageBonus ); #endregion if ( attacker is BaseCreature ) @@ -1496,7 +1536,7 @@ namespace Server.Items if ( m_Cursed ) lifeLeech += 50; // Additional 50% life leech for cursed weapons (necro spell) - context = TransformationSpell.GetContext( attacker ); + context = TransformationSpellHelper.GetContext( attacker ); if ( context != null && context.Type == typeof( VampiricEmbraceSpell ) ) lifeLeech += 20; // Vampiric embrace gives an additional 20% life leech @@ -1666,6 +1706,11 @@ namespace Server.Items // SDI bonus damageBonus += AosAttributes.GetValue( attacker, AosAttribute.SpellDamage ); + + TransformContext context = TransformationSpellHelper.GetContext( attacker ); + + if( context != null && context.Spell is ReaperFormSpell ) + damageBonus += ((ReaperFormSpell)context.Spell).SpellDamageBonus; } damage = AOS.Scale( damage, 100 + damageBonus ); @@ -1753,7 +1798,7 @@ namespace Server.Items attacker.DoHarmful( defender ); - Spells.Spell sp = new Spells.Sixth.DispelSpell( attacker, null ); + Spells.MagerySpell sp = new Spells.Sixth.DispelSpell( attacker, null ); if ( sp.CheckResisted( defender ) ) { @@ -2092,7 +2137,7 @@ namespace Server.Items int damageBonus = AosAttributes.GetValue( attacker, AosAttribute.WeaponDamage ); // Horrific Beast transformation gives a +25% bonus to damage. - if ( TransformationSpell.UnderTransformation( attacker, typeof( HorrificBeastSpell ) ) ) + if( TransformationSpellHelper.UnderTransformation( attacker, typeof( HorrificBeastSpell ) ) ) damageBonus += 25; // Divine Fury gives a +10% bonus to damage. @@ -3296,12 +3341,18 @@ namespace Server.Items if ( tool is BaseRunicTool ) ((BaseRunicTool)tool).ApplyAttributesTo( this ); - if ( quality == 2 ) + if ( Quality == WeaponQuality.Exceptional ) { if ( Attributes.WeaponDamage > 35 ) Attributes.WeaponDamage -= 20; else Attributes.WeaponDamage = 15; + + if( Core.ML ) + { + Attributes.WeaponDamage += (int)(from.Skills.ArmsLore.Value / 20); + from.CheckSkill( SkillName.ArmsLore, 0, 100 ); + } } } else if ( tool is BaseRunicTool ) diff --git a/Scripts/Items/Weapons/ML Weapons/AssassinSpike.cs b/Scripts/Items/Weapons/ML Weapons/AssassinSpike.cs index 561f36b07..cc5f3a799 100644 --- a/Scripts/Items/Weapons/ML Weapons/AssassinSpike.cs +++ b/Scripts/Items/Weapons/ML Weapons/AssassinSpike.cs @@ -21,6 +21,7 @@ namespace Server.Items public override int OldSpeed{ get{ return 50; } } public override int DefMissSound{ get{ return 0x239; } } + public override SkillName DefSkill { get { return SkillName.Fencing; } } public override int InitMinHits{ get{ return 30; } } // TODO public override int InitMaxHits{ get{ return 60; } } // TODO diff --git a/Scripts/Misc/BuffIcons.cs b/Scripts/Misc/BuffIcons.cs index 2a7853cdc..a594641ff 100644 --- a/Scripts/Misc/BuffIcons.cs +++ b/Scripts/Misc/BuffIcons.cs @@ -12,23 +12,15 @@ namespace Server public static void Initialize() { - //To Ensure that it's sent only AFTER we get the client's version, and right after. if( Enabled ) { - PacketHandlers.Register( 0xBD, 0, true, new OnPacketReceive - ( - delegate( NetState state, PacketReader pvSrc ) - { - PacketHandlers.ClientVersion( state, pvSrc ); - - PlayerMobile pm = state.Mobile as PlayerMobile; - - if( pm != null ) - { - Timer.DelayCall( TimeSpan.Zero, new TimerCallback( pm.ResendBuffs ) ); - } - } - ) ); + EventSink.ClientVersionRecieved += new ClientVersionRecievedHandler( delegate( ClientVersionRecievedArgs args ) + { + PlayerMobile pm = args.State.Mobile as PlayerMobile; + + if( pm != null ) + Timer.DelayCall( TimeSpan.Zero, pm.ResendBuffs ); + } ); } } @@ -143,6 +135,19 @@ namespace Server { m_Args = args; } + + public BuffInfo( BuffIcon iconID, int titleCliloc, TimeSpan length, Mobile m, TextDefinition args, bool retainThroughDeath ) + : this( iconID, titleCliloc, titleCliloc + 1, length, m, args, retainThroughDeath ) + { + } + + public BuffInfo( BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m, TextDefinition args, bool retainThroughDeath ) + : this( iconID, titleCliloc, secondaryCliloc, length, m ) + { + m_Args = args; + m_RetainThroughDeath = retainThroughDeath; + } + #endregion #region Convience Methods @@ -192,7 +197,7 @@ namespace Server Mindrot, //* PainSpike, //* Strangle, - GiftOfRenewal, + GiftOfRenewal, //* AttuneWeapon, Thunderstorm, EssenceOfWind, diff --git a/Scripts/Misc/CharacterCreation.cs b/Scripts/Misc/CharacterCreation.cs index c7f2c0bf5..7e329fa49 100644 --- a/Scripts/Misc/CharacterCreation.cs +++ b/Scripts/Misc/CharacterCreation.cs @@ -733,8 +733,20 @@ namespace Server.Misc m_Mobile.SendLocalizedMessage( m_Message ); } } + + private static readonly ClientVersion m_NewHavenClient = new ClientVersion( "6.0.0.0" ); + private static readonly CityInfo m_NewHavenInfo = new CityInfo( "New Haven", "The Bountiful Harvest Inn", 3503, 2574, 14, Map.Trammel ); + private static CityInfo GetStartLocation( CharacterCreatedEventArgs args, bool isYoung ) { + if( Core.ML ) + { + //if( args.State != null && args.State.Version >= m_NewHavenClient ) + return m_NewHavenInfo; //We don't get the client Version until AFTER Character creation + + //return args.City; TODO: Uncomment when the old quest system is actually phased out + } + bool useHaven = isYoung; int flags = args.State == null ? 0 : args.State.Flags; @@ -766,7 +778,7 @@ namespace Server.Misc } case 5: //Paladin { - return new CityInfo( "Haven", "Uzeraan's Mansion", 3578, 2589, 0, Map.Trammel ); + return m_NewHavenInfo; } case 6: //Samurai { @@ -815,7 +827,7 @@ namespace Server.Misc } if( useHaven ) - return new CityInfo( "Haven", "Uzeraan's Mansion", 3582, 2587, 0, Map.Trammel ); + return m_NewHavenInfo; else return args.City; } @@ -1102,6 +1114,8 @@ namespace Server.Misc book.LootType = LootType.Blessed; + addSkillItems = false; + break; } diff --git a/Scripts/Misc/Cleanup.cs b/Scripts/Misc/Cleanup.cs index 966a07655..62a93af1a 100644 --- a/Scripts/Misc/Cleanup.cs +++ b/Scripts/Misc/Cleanup.cs @@ -141,7 +141,8 @@ namespace Server.Misc || item is TreasureMap || item is MessageInABottle || item is BaseArmor || item is BaseWeapon || item is BaseClothing - || (item is BaseJewel && Core.AOS) ) + || (item is BaseJewel && Core.AOS) + || (item is BasePotion && Core.ML)) return true; return false; diff --git a/Scripts/Misc/ClientVerification.cs b/Scripts/Misc/ClientVerification.cs index ba4add798..2e3d4bd2d 100644 --- a/Scripts/Misc/ClientVerification.cs +++ b/Scripts/Misc/ClientVerification.cs @@ -2,16 +2,95 @@ using System; using Server; using System.Diagnostics; using System.IO; +using Server.Network; +using Server.Gumps; namespace Server.Misc { public class ClientVerification { - private static bool m_DetectClientRequirement = false; + private enum OldClientResponse + { + Ignore, + Warn, + Annoy, + Kick + } + + private static bool m_DetectClientRequirement = true; + private static OldClientResponse m_OldClientResponse = OldClientResponse.Annoy; + + private static ClientVersion m_Required; + private static bool m_AllowRegular = true, m_AllowUOTD = true, m_AllowGod = true; + + private static TimeSpan m_KickDelay = TimeSpan.FromSeconds( 10.0 ); + + public static ClientVersion Required + { + get + { + return m_Required; + } + set + { + m_Required = value; + } + } + + public static bool AllowRegular + { + get + { + return m_AllowRegular; + } + set + { + m_AllowRegular = value; + } + } + + public static bool AllowUOTD + { + get + { + return m_AllowUOTD; + } + set + { + m_AllowUOTD = value; + } + } + + public static bool AllowGod + { + get + { + return m_AllowGod; + } + set + { + m_AllowGod = value; + } + } + + public static TimeSpan KickDelay + { + get + { + return m_KickDelay; + } + set + { + m_KickDelay = value; + } + } + public static void Initialize() { + EventSink.ClientVersionRecieved += new ClientVersionRecievedHandler( EventSink_ClientVersionRecieved ); + //ClientVersion.Required = null; - //ClientVersion.Required = new ClientVersion( "3.0.8q" ); + //Required = new ClientVersion( "6.0.0.0" ); if( m_DetectClientRequirement ) { @@ -23,17 +102,105 @@ namespace Server.Misc if ( info.FileMajorPart != 0 || info.FileMinorPart != 0 || info.FileBuildPart != 0 || info.FilePrivatePart != 0 ) { - ClientVersion.Required = new ClientVersion( info.FileMajorPart, info.FileMinorPart, info.FileBuildPart, info.FilePrivatePart ); - Console.WriteLine( "Restricting client version to {0}", ClientVersion.Required ); + Required = new ClientVersion( info.FileMajorPart, info.FileMinorPart, info.FileBuildPart, info.FilePrivatePart ); } } } - ClientVersion.AllowGod = true; - ClientVersion.AllowUOTD = true; - ClientVersion.AllowRegular = true; + if( Required != null ) + { + Utility.PushColor( ConsoleColor.White ); + Console.WriteLine( "Restricting client version to {0}. Action to be taken: {1}", Required, m_OldClientResponse ); + Utility.PopColor(); + } + } - ClientVersion.KickDelay = TimeSpan.FromSeconds( 10.0 ); + private static void EventSink_ClientVersionRecieved( ClientVersionRecievedArgs e ) + { + string kickMessage = null; + NetState state = e.State; + ClientVersion version = e.Version; + + if( Required != null && m_OldClientResponse == OldClientResponse.Kick && version < Required ) + { + kickMessage = String.Format( "This server requires your client version be at least {0}.", Required ); + } + else if( !AllowGod || !AllowRegular || !AllowUOTD ) + { + if( !AllowGod && version.Type == ClientType.God ) + kickMessage = "This server does not allow god clients to connect."; + else if( !AllowRegular && version.Type == ClientType.Regular ) + kickMessage = "This server does not allow regular clients to connect."; + else if( !AllowUOTD && state.IsUOTDClient ) + kickMessage = "This server does not allow UO:TD clients to connect."; + + if( !AllowGod && !AllowRegular && !AllowUOTD ) + { + kickMessage = "This server does not allow any clients to connect."; + } + else if( AllowGod && !AllowRegular && !AllowUOTD && version.Type != ClientType.God ) + { + kickMessage = "This server requires you to use the god client."; + } + else if( kickMessage != null ) + { + if( AllowRegular && AllowUOTD ) + kickMessage += " You can use regular or UO:TD clients."; + else if( AllowRegular ) + kickMessage += " You can use regular clients."; + else if( AllowUOTD ) + kickMessage += " You can use UO:TD clients."; + } + } + + if( kickMessage != null ) + { + state.Mobile.SendMessage( 0x22, kickMessage ); + state.Mobile.SendMessage( 0x22, "You will be disconnected in {0} seconds.", KickDelay.TotalSeconds ); + + Timer.DelayCall( KickDelay, delegate + { + if( state.Socket != null ) + { + Console.WriteLine( "Client: {0}: Disconnecting, bad version", state ); + state.Dispose(); + } + } ); + } + else if( Required != null && version < Required ) + { + switch( m_OldClientResponse ) + { + case OldClientResponse.Warn: + { + state.Mobile.SendMessage( 0x22, "Your client is out of date. Please update your client.", Required ); + state.Mobile.SendMessage( 0x22, "This server reccomends that your client version be at least {0}.", Required ); + break; + } + case OldClientResponse.Annoy: + { + SendAnnoyGump( state.Mobile ); + break; + } + } + } + } + + private static void SendAnnoyGump( Mobile m ) + { + if( m.NetState != null && m.NetState.Version < Required ) + { + Gump g = new WarningGump( 1060637, 30720, String.Format( "Your client is out of date. Please update your client.
This server reccomends that your client version be at least {0}.

You are currently using version {1}.

To patch, run UOPatch.exe inside your Ultima Online folder.", Required, m.NetState.Version ), 0xFFC000, 480, 360, + delegate( Mobile mob, bool selection, object o ) + { + m.SendMessage( "You will be reminded of this again." ); + Timer.DelayCall( TimeSpan.FromMinutes( 20 ), delegate { SendAnnoyGump( m ); } ); + }, null, false ); + + g.Dragable = false; + + m.SendGump( g ); + } } } } \ No newline at end of file diff --git a/Scripts/Misc/Gifts/GiftGiving.cs b/Scripts/Misc/Gifts/GiftGiving.cs index ae9a5ddca..94cbbd2a6 100644 --- a/Scripts/Misc/Gifts/GiftGiving.cs +++ b/Scripts/Misc/Gifts/GiftGiving.cs @@ -21,7 +21,7 @@ namespace Server.Misc m_Givers.Add( giver ); } - public static void Configure() + public static void Initialize() { EventSink.Login += new LoginEventHandler( EventSink_Login ); } diff --git a/Scripts/Misc/LootPack.cs b/Scripts/Misc/LootPack.cs index 9046f5cd6..33c04227a 100644 --- a/Scripts/Misc/LootPack.cs +++ b/Scripts/Misc/LootPack.cs @@ -17,8 +17,8 @@ namespace Server int luck = killer.Luck; PlayerMobile pmKiller = killer as PlayerMobile; - if ( pmKiller != null && pmKiller.SentHonorContext != null && pmKiller.SentHonorContext.Target == victim ) - pmKiller.SentHonorContext.ApplyPerfectionLuckBonus( ref luck ); + if( pmKiller != null && pmKiller.SentHonorContext != null && pmKiller.SentHonorContext.Target == victim ) + luck += pmKiller.SentHonorContext.PerfectionLuckBonus; if ( luck < 0 ) return 0; diff --git a/Scripts/Misc/MapDefinitions.cs b/Scripts/Misc/MapDefinitions.cs index 20bb27550..745f453b4 100644 --- a/Scripts/Misc/MapDefinitions.cs +++ b/Scripts/Misc/MapDefinitions.cs @@ -16,7 +16,7 @@ namespace Server.Misc */ RegisterMap( 0, 0, 0, 7168, 4096, 4, "Felucca", MapRules.FeluccaRules ); - RegisterMap( 1, 1, 0, 7168, 4096, 0, "Trammel", MapRules.TrammelRules ); + RegisterMap( 1, 1, 1, 7168, 4096, 0, "Trammel", MapRules.TrammelRules ); RegisterMap( 2, 2, 2, 2304, 1600, 1, "Ilshenar", MapRules.TrammelRules ); RegisterMap( 3, 3, 3, 2560, 2048, 1, "Malas", MapRules.TrammelRules ); RegisterMap( 4, 4, 4, 1448, 1448, 1, "Tokuno", MapRules.TrammelRules ); @@ -35,6 +35,8 @@ namespace Server.Misc * - : Reference name for the map, used in props gump, get/set commands, region loading, etc * - : Rules and restrictions associated with the map. See documentation for details */ + + TileMatrixPatch.Enabled = false; //OSI client patch 6.0.0.0 } public static void RegisterMap( int mapIndex, int mapID, int fileIndex, int width, int height, int season, string name, MapRules rules ) diff --git a/Scripts/Misc/Notoriety.cs b/Scripts/Misc/Notoriety.cs index 8c9e7b6bc..a60ab2105 100644 --- a/Scripts/Misc/Notoriety.cs +++ b/Scripts/Misc/Notoriety.cs @@ -10,6 +10,7 @@ using Server.Engines.PartySystem; using Server.Factions; using Server.Spells.Necromancy; using Server.Spells.Ninjitsu; +using Server.Spells; namespace Server.Misc { @@ -310,7 +311,7 @@ namespace Server.Misc if( !(target is BaseCreature && ((BaseCreature)target).InitialInnocent) ) { - if( !target.Body.IsHuman && !target.Body.IsGhost && !IsPet( target as BaseCreature ) && !TransformationSpell.UnderTransformation( target ) && !AnimalForm.UnderTransformation( target ) ) + if( !target.Body.IsHuman && !target.Body.IsGhost && !IsPet( target as BaseCreature ) && !TransformationSpellHelper.UnderTransformation( target ) && !AnimalForm.UnderTransformation( target ) ) return Notoriety.CanBeAttacked; } diff --git a/Scripts/Misc/Poison.cs b/Scripts/Misc/Poison.cs index f961b1552..0aabbc675 100644 --- a/Scripts/Misc/Poison.cs +++ b/Scripts/Misc/Poison.cs @@ -87,7 +87,7 @@ namespace Server protected override void OnTick() { - if ( (Core.AOS && m_Poison.Level < 4 && TransformationSpell.UnderTransformation( m_Mobile, typeof( VampiricEmbraceSpell ) )) || + if ( (Core.AOS && m_Poison.Level < 4 && TransformationSpellHelper.UnderTransformation( m_Mobile, typeof( VampiricEmbraceSpell ) )) || (m_Poison.Level < 3 && OrangePetals.UnderEffect( m_Mobile )) || AnimalForm.UnderTransformation( m_Mobile, typeof( Unicorn ) ) ) { diff --git a/Scripts/Misc/RegenRates.cs b/Scripts/Misc/RegenRates.cs index 74eae28eb..26025b7d6 100644 --- a/Scripts/Misc/RegenRates.cs +++ b/Scripts/Misc/RegenRates.cs @@ -42,7 +42,7 @@ namespace Server.Misc private static bool CheckTransform( Mobile m, Type type ) { - return TransformationSpell.UnderTransformation( m, type ); + return TransformationSpellHelper.UnderTransformation( m, type ); } private static bool CheckAnimal( Mobile m, Type type ) diff --git a/Scripts/Misc/SkillCheck.cs b/Scripts/Misc/SkillCheck.cs index b883d1f76..24098e984 100644 --- a/Scripts/Misc/SkillCheck.cs +++ b/Scripts/Misc/SkillCheck.cs @@ -6,7 +6,7 @@ namespace Server.Misc { public class SkillCheck { - private static readonly bool AntiMacroCode = true; //Change this to false to disable anti-macro code + private static readonly bool AntiMacroCode = !Core.ML; //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 diff --git a/Scripts/Mobiles/Animals/Mounts/BaseMount.cs b/Scripts/Mobiles/Animals/Mounts/BaseMount.cs index f72667f41..36ed6d040 100644 --- a/Scripts/Mobiles/Animals/Mounts/BaseMount.cs +++ b/Scripts/Mobiles/Animals/Mounts/BaseMount.cs @@ -19,6 +19,8 @@ namespace Server.Mobiles set { m_NextMountAbility = value; } } + protected Item InternalItem { get { return m_InternalItem; } } + public virtual bool AllowMaleRider{ get{ return true; } } public virtual bool AllowFemaleRider{ get{ return true; } } diff --git a/Scripts/Mobiles/Animals/Mounts/Ethereals.cs b/Scripts/Mobiles/Animals/Mounts/Ethereals.cs index f77b1a793..a29f08b24 100644 --- a/Scripts/Mobiles/Animals/Mounts/Ethereals.cs +++ b/Scripts/Mobiles/Animals/Mounts/Ethereals.cs @@ -17,8 +17,8 @@ namespace Server.Mobiles [CommandProperty( AccessLevel.GameMaster )] public bool IsRewardItem { - get{ return m_IsRewardItem; } - set{ m_IsRewardItem = value; } + get { return m_IsRewardItem; } + set { m_IsRewardItem = value; } } public override double DefaultWeight @@ -34,7 +34,8 @@ namespace Server.Mobiles } [Constructable] - public EtherealMount( int itemID, int mountID ) : base( itemID ) + public EtherealMount( int itemID, int mountID ) + : base( itemID ) { m_MountedID = mountID; m_RegularID = itemID; @@ -65,11 +66,11 @@ namespace Server.Mobiles } set { - if ( m_MountedID != value ) + if( m_MountedID != value ) { m_MountedID = value; - if ( m_Rider != null ) + if( m_Rider != null ) ItemID = value; } } @@ -84,77 +85,78 @@ namespace Server.Mobiles } set { - if ( m_RegularID != value ) + if( m_RegularID != value ) { m_RegularID = value; - if ( m_Rider == null ) + if( m_Rider == null ) ItemID = value; } } } - public EtherealMount( Serial serial ) : base( serial ) + public EtherealMount( Serial serial ) + : base( serial ) { } - public override bool DisplayLootType{ get{ return false; } } + public override bool DisplayLootType { get { return false; } } - public virtual int FollowerSlots{ get{ return 1; } } + public virtual int FollowerSlots { get { return 1; } } public void RemoveFollowers() { - if ( m_Rider != null ) + if( m_Rider != null ) m_Rider.Followers -= FollowerSlots; - if ( m_Rider != null && m_Rider.Followers < 0 ) + if( m_Rider != null && m_Rider.Followers < 0 ) m_Rider.Followers = 0; } public void AddFollowers() { - if ( m_Rider != null ) + if( m_Rider != null ) m_Rider.Followers += FollowerSlots; } public virtual bool Validate( Mobile from ) { - if ( !IsChildOf( from.Backpack ) ) + if( !IsChildOf( from.Backpack ) ) { from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it. return false; } - else if ( m_IsRewardItem && !Engines.VeteranRewards.RewardSystem.CheckIsUsableBy( from, this, null ) ) + else if( m_IsRewardItem && !Engines.VeteranRewards.RewardSystem.CheckIsUsableBy( from, this, null ) ) { // CheckIsUsableBy sends the message return false; } - else if ( !BaseMount.CheckMountAllowed( from, true ) ) + else if( !BaseMount.CheckMountAllowed( from, true ) ) { // CheckMountAllowed sends the message return false; } - else if ( from.Mounted ) + else if( from.Mounted ) { from.SendLocalizedMessage( 1005583 ); // Please dismount first. return false; } - else if ( from.IsBodyMod && !from.Body.IsHuman ) + else if( from.IsBodyMod && !from.Body.IsHuman ) { from.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed. return false; } - else if ( from.HasTrade ) + else if( from.HasTrade ) { from.SendLocalizedMessage( 1042317, "", 0x41 ); // You may not ride at this time return false; } - else if ( (from.Followers + FollowerSlots) > from.FollowersMax ) + else if( (from.Followers + FollowerSlots) > from.FollowersMax ) { from.SendLocalizedMessage( 1049679 ); // You have too many followers to summon your mount. return false; } - else if ( !Multis.DesignContext.Check( from ) ) + else if( !Multis.DesignContext.Check( from ) ) { // Check sends the message return false; @@ -165,7 +167,7 @@ namespace Server.Mobiles public override void OnDoubleClick( Mobile from ) { - if ( Validate( from ) ) + if( Validate( from ) ) new EtherealSpell( this, from ).Cast(); } @@ -173,10 +175,10 @@ namespace Server.Mobiles { base.Serialize( writer ); - writer.Write( (int) 3 ); // version + writer.Write( (int)3 ); // version writer.Write( m_IsDonationItem ); - writer.Write( (bool) m_IsRewardItem ); + writer.Write( (bool)m_IsRewardItem ); writer.Write( (int)m_MountedID ); writer.Write( (int)m_RegularID ); @@ -190,35 +192,35 @@ namespace Server.Mobiles int version = reader.ReadInt(); - switch ( version ) + switch( version ) { case 3: - { - m_IsDonationItem = reader.ReadBool(); - goto case 2; - } + { + m_IsDonationItem = reader.ReadBool(); + goto case 2; + } case 2: - { - m_IsRewardItem = reader.ReadBool(); - goto case 0; - } + { + m_IsRewardItem = reader.ReadBool(); + goto case 0; + } case 1: reader.ReadInt(); goto case 0; case 0: - { - m_MountedID = reader.ReadInt(); - m_RegularID = reader.ReadInt(); - m_Rider = reader.ReadMobile(); + { + m_MountedID = reader.ReadInt(); + m_RegularID = reader.ReadInt(); + m_Rider = reader.ReadMobile(); - if ( m_MountedID == 0x3EA2 ) - m_MountedID = 0x3EAA; + if( m_MountedID == 0x3EA2 ) + m_MountedID = 0x3EAA; - break; - } + break; + } } AddFollowers(); - if ( version < 3 && Weight == 0 ) + if( version < 3 && Weight == 0 ) Weight = -1; } @@ -233,7 +235,7 @@ namespace Server.Mobiles { IMount mount = m.Mount; - if ( mount != null ) + if( mount != null ) mount.Rider = null; } @@ -246,9 +248,9 @@ namespace Server.Mobiles } set { - if ( value != m_Rider ) + if( value != m_Rider ) { - if ( value == null ) + if( value == null ) { Internalize(); UnmountMe(); @@ -258,7 +260,7 @@ namespace Server.Mobiles } else { - if ( m_Rider != null ) + if( m_Rider != null ) Dismount( m_Rider ); Dismount( value ); @@ -286,7 +288,7 @@ namespace Server.Mobiles if( Hue == EtherealHue ) Hue = 0; - if ( bp != null ) + if( bp != null ) { bp.DropItem( this ); } @@ -295,7 +297,7 @@ namespace Server.Mobiles Point3D loc = m_Rider.Location; Map map = m_Rider.Map; - if ( map == null || map == Map.Internal ) + if( map == null || map == Map.Internal ) { loc = m_Rider.LogoutLocation; map = m_Rider.LogoutMap; @@ -311,7 +313,7 @@ namespace Server.Mobiles Layer = Layer.Mount; Movable = false; - if ( Hue == 0 ) + if( Hue == 0 ) Hue = EtherealHue; ProcessDelta(); @@ -331,7 +333,7 @@ namespace Server.Mobiles public static void StopMounting( Mobile mob ) { - if ( mob.Spell is EtherealSpell ) + if( mob.Spell is EtherealSpell ) ((EtherealSpell)mob.Spell).Stop(); } @@ -341,28 +343,34 @@ namespace Server.Mobiles private class EtherealSpell : Spell { - private static SpellInfo m_Info = new SpellInfo( "Ethereal Mount", "", SpellCircle.Second, 230 ); + private static SpellInfo m_Info = new SpellInfo( "Ethereal Mount", "", 230 ); private EtherealMount m_Mount; private Mobile m_Rider; - public EtherealSpell( EtherealMount mount, Mobile rider ) : base( rider, null, m_Info ) + public EtherealSpell( EtherealMount mount, Mobile rider ) + : base( rider, null, m_Info ) { m_Rider = rider; m_Mount = mount; } - public override bool ClearHandsOnCast{ get{ return false; } } - public override bool RevealOnCast{ get{ return false; } } + public override bool ClearHandsOnCast { get { return false; } } + public override bool RevealOnCast { get { return false; } } public override TimeSpan GetCastRecovery() { return TimeSpan.Zero; } - public override TimeSpan GetCastDelay() + public override double CastDelayFastScalar { get { return 0; } } + + public override TimeSpan CastDelayBase { - return TimeSpan.FromSeconds( ( (m_Mount.IsDonationItem && RewardSystem.GetRewardLevel( m_Rider ) < 3 )? 12.5 : 5.0 ) ); + get + { + return TimeSpan.FromSeconds( ((m_Mount.IsDonationItem && RewardSystem.GetRewardLevel( m_Rider ) < 3)? 12.5 : 5.0) ); + } } public override int GetMana() @@ -390,7 +398,7 @@ namespace Server.Mobiles public override bool CheckDisturb( DisturbType type, bool checkFirst, bool resistable ) { - if ( type == DisturbType.EquipRequest || type == DisturbType.UseRequest/* || type == DisturbType.Hurt*/ ) + if( type == DisturbType.EquipRequest || type == DisturbType.UseRequest/* || type == DisturbType.Hurt*/ ) return false; return true; @@ -398,19 +406,19 @@ namespace Server.Mobiles public override void DoHurtFizzle() { - if ( !m_Stop ) + if( !m_Stop ) base.DoHurtFizzle(); } public override void DoFizzle() { - if ( !m_Stop ) + if( !m_Stop ) base.DoFizzle(); } public override void OnDisturb( DisturbType type, bool message ) { - if ( message && !m_Stop ) + if( message && !m_Stop ) Caster.SendLocalizedMessage( 1049455 ); // You have been disrupted while attempting to summon your ethereal mount! //m_Mount.UnmountMe(); @@ -418,7 +426,7 @@ namespace Server.Mobiles public override void OnCast() { - if ( !m_Mount.Deleted && m_Mount.Rider == null && m_Mount.Validate( m_Rider ) ) + if( !m_Mount.Deleted && m_Mount.Rider == null && m_Mount.Validate( m_Rider ) ) m_Mount.Rider = m_Rider; FinishSequence(); @@ -428,14 +436,16 @@ namespace Server.Mobiles public class EtherealHorse : EtherealMount { - public override int LabelNumber{ get{ return 1041298; } } // Ethereal Horse Statuette + public override int LabelNumber { get { return 1041298; } } // Ethereal Horse Statuette [Constructable] - public EtherealHorse() : base( 0x20DD, 0x3EAA ) + public EtherealHorse() + : base( 0x20DD, 0x3EAA ) { } - public EtherealHorse( Serial serial ) : base( serial ) + public EtherealHorse( Serial serial ) + : base( serial ) { } @@ -443,7 +453,7 @@ namespace Server.Mobiles { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int)0 ); // version } public override void Deserialize( GenericReader reader ) @@ -452,24 +462,26 @@ namespace Server.Mobiles int version = reader.ReadInt(); - if ( Name == "an ethereal horse" ) + if( Name == "an ethereal horse" ) Name = null; - if ( ItemID == 0x2124 ) + if( ItemID == 0x2124 ) ItemID = 0x20DD; } } public class EtherealLlama : EtherealMount { - public override int LabelNumber{ get{ return 1041300; } } // Ethereal Llama Statuette + public override int LabelNumber { get { return 1041300; } } // Ethereal Llama Statuette [Constructable] - public EtherealLlama() : base( 0x20F6, 0x3EAB ) + public EtherealLlama() + : base( 0x20F6, 0x3EAB ) { } - public EtherealLlama( Serial serial ) : base( serial ) + public EtherealLlama( Serial serial ) + : base( serial ) { } @@ -477,7 +489,7 @@ namespace Server.Mobiles { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int)0 ); // version } public override void Deserialize( GenericReader reader ) @@ -486,21 +498,23 @@ namespace Server.Mobiles int version = reader.ReadInt(); - if ( Name == "an ethereal llama" ) + if( Name == "an ethereal llama" ) Name = null; } } public class EtherealOstard : EtherealMount { - public override int LabelNumber{ get{ return 1041299; } } // Ethereal Ostard Statuette + public override int LabelNumber { get { return 1041299; } } // Ethereal Ostard Statuette [Constructable] - public EtherealOstard() : base( 0x2135, 0x3EAC ) + public EtherealOstard() + : base( 0x2135, 0x3EAC ) { } - public EtherealOstard( Serial serial ) : base( serial ) + public EtherealOstard( Serial serial ) + : base( serial ) { } @@ -508,7 +522,7 @@ namespace Server.Mobiles { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int)0 ); // version } public override void Deserialize( GenericReader reader ) @@ -517,21 +531,23 @@ namespace Server.Mobiles int version = reader.ReadInt(); - if ( Name == "an ethereal ostard" ) + if( Name == "an ethereal ostard" ) Name = null; } } public class EtherealRidgeback : EtherealMount { - public override int LabelNumber{ get{ return 1049747; } } // Ethereal Ridgeback Statuette + public override int LabelNumber { get { return 1049747; } } // Ethereal Ridgeback Statuette [Constructable] - public EtherealRidgeback() : base( 0x2615, 0x3E9A ) + public EtherealRidgeback() + : base( 0x2615, 0x3E9A ) { } - public EtherealRidgeback( Serial serial ) : base( serial ) + public EtherealRidgeback( Serial serial ) + : base( serial ) { } @@ -539,7 +555,7 @@ namespace Server.Mobiles { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int)0 ); // version } public override void Deserialize( GenericReader reader ) @@ -548,21 +564,23 @@ namespace Server.Mobiles int version = reader.ReadInt(); - if ( Name == "an ethereal ridgeback" ) + if( Name == "an ethereal ridgeback" ) Name = null; } } public class EtherealUnicorn : EtherealMount { - public override int LabelNumber{ get{ return 1049745; } } // Ethereal Unicorn Statuette + public override int LabelNumber { get { return 1049745; } } // Ethereal Unicorn Statuette [Constructable] - public EtherealUnicorn() : base( 0x25CE, 0x3E9B ) + public EtherealUnicorn() + : base( 0x25CE, 0x3E9B ) { } - public EtherealUnicorn( Serial serial ) : base( serial ) + public EtherealUnicorn( Serial serial ) + : base( serial ) { } @@ -570,7 +588,7 @@ namespace Server.Mobiles { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int)0 ); // version } public override void Deserialize( GenericReader reader ) @@ -579,21 +597,23 @@ namespace Server.Mobiles int version = reader.ReadInt(); - if ( Name == "an ethereal unicorn" ) + if( Name == "an ethereal unicorn" ) Name = null; } } public class EtherealBeetle : EtherealMount { - public override int LabelNumber{ get{ return 1049748; } } // Ethereal Beetle Statuette + public override int LabelNumber { get { return 1049748; } } // Ethereal Beetle Statuette [Constructable] - public EtherealBeetle() : base( 0x260F, 0x3E97 ) + public EtherealBeetle() + : base( 0x260F, 0x3E97 ) { } - public EtherealBeetle( Serial serial ) : base( serial ) + public EtherealBeetle( Serial serial ) + : base( serial ) { } @@ -601,7 +621,7 @@ namespace Server.Mobiles { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int)0 ); // version } public override void Deserialize( GenericReader reader ) @@ -610,21 +630,23 @@ namespace Server.Mobiles int version = reader.ReadInt(); - if ( Name == "an ethereal beetle" ) + if( Name == "an ethereal beetle" ) Name = null; } } public class EtherealKirin : EtherealMount { - public override int LabelNumber{ get{ return 1049746; } } // Ethereal Ki-Rin Statuette + public override int LabelNumber { get { return 1049746; } } // Ethereal Ki-Rin Statuette [Constructable] - public EtherealKirin() : base( 0x25A0, 0x3E9C ) + public EtherealKirin() + : base( 0x25A0, 0x3E9C ) { } - public EtherealKirin( Serial serial ) : base( serial ) + public EtherealKirin( Serial serial ) + : base( serial ) { } @@ -632,7 +654,7 @@ namespace Server.Mobiles { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int)0 ); // version } public override void Deserialize( GenericReader reader ) @@ -641,21 +663,23 @@ namespace Server.Mobiles int version = reader.ReadInt(); - if ( Name == "an ethereal kirin" ) + if( Name == "an ethereal kirin" ) Name = null; } } public class EtherealSwampDragon : EtherealMount { - public override int LabelNumber{ get{ return 1049749; } } // Ethereal Swamp Dragon Statuette + public override int LabelNumber { get { return 1049749; } } // Ethereal Swamp Dragon Statuette [Constructable] - public EtherealSwampDragon() : base( 0x2619, 0x3E98 ) + public EtherealSwampDragon() + : base( 0x2619, 0x3E98 ) { } - public EtherealSwampDragon( Serial serial ) : base( serial ) + public EtherealSwampDragon( Serial serial ) + : base( serial ) { } @@ -663,7 +687,7 @@ namespace Server.Mobiles { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int)0 ); // version } public override void Deserialize( GenericReader reader ) @@ -672,7 +696,7 @@ namespace Server.Mobiles int version = reader.ReadInt(); - if ( Name == "an ethereal swamp dragon" ) + if( Name == "an ethereal swamp dragon" ) Name = null; } } diff --git a/Scripts/Mobiles/Animals/Mounts/Hiryu.cs b/Scripts/Mobiles/Animals/Mounts/Hiryu.cs index dbfa17306..a84ea3ae4 100644 --- a/Scripts/Mobiles/Animals/Mounts/Hiryu.cs +++ b/Scripts/Mobiles/Animals/Mounts/Hiryu.cs @@ -13,13 +13,71 @@ namespace Server.Mobiles return WeaponAbility.Dismount; } - public override bool StatLossAfterTame{ get{ return true; } } + public override bool StatLossAfterTame { get { return true; } } + + private static int GetHue() + { + int rand = Utility.Random( 1075 ); + + /* + 1000 1075 No Hue Color 93.02% 0x0 + * + 10 1075 Ice Green 0.93% 0x847F + 10 1075 Light Blue 0.93% 0x848D + 10 1075 Strong Cyan 0.93% 0x8495 + 10 1075 Agapite 0.93% 0x8899 + 10 1075 Gold 0.93% 0x8032 + * + 8 1075 Blue and Yellow 0.74% 0x8487 + * + 5 1075 Ice Blue 0.47% 0x8482 + * + 3 1075 Cyan 0.28% 0x8123 + 3 1075 Light Green 0.28% 0x8295 + * + 2 1075 Strong Yellow 0.19% 0x8037 + 2 1075 Green 0.19% 0x8030 //this one is an approximation + * + 1 1075 Strong Purple 0.09% 0x8490 + 1 1075 Strong Green 0.09% 0x855C + * */ + + if( rand <= 0 ) + return 0x855C; + else if( rand <= 1 ) + return 0x8490; + else if( rand <= 3 ) + return 0x8030; + else if( rand <= 5 ) + return 0x8037; + else if( rand <= 8 ) + return 0x8295; + else if( rand <= 11 ) + return 0x8123; + else if( rand <= 16 ) + return 0x8482; + else if( rand <= 24 ) + return 0x8487; + else if( rand <= 34 ) + return 0x8032; + else if( rand <= 44 ) + return 0x8899; + else if( rand <= 54 ) + return 0x8495; + else if( rand <= 64 ) + return 0x848D; + else if( rand <= 74 ) + return 0x847F; + + + return 0; + } [Constructable] - public Hiryu() : base( "a hiryu", 243, 0x3E94, AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 ) + public Hiryu() + : base( "a hiryu", 243, 0x3E94, AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 ) { - if ( 0.05 > Utility.RandomDouble() ) - Hue = Utility.RandomList( 0x32, 0x37, 0x3C, 0x3D, 0x123, 0x294, 0x295, 0x47F, 0x482, 0x487, 0x48D, 0x490, 0x495, 0x55C, 0x8A0, 0x899, 0x89F ) | 0x8000; + Hue = GetHue(); SetStr( 1201, 1410 ); SetDex( 171, 270 ); @@ -50,7 +108,7 @@ namespace Server.Mobiles ControlSlots = 4; MinTameSkill = 98.7; - if ( Utility.RandomDouble() < .33 ) + if( Utility.RandomDouble() < .33 ) PackItem( Engines.Plants.Seed.RandomBonsaiSeed() ); } @@ -85,18 +143,18 @@ namespace Server.Mobiles AddLoot( LootPack.FilthyRich, 3 ); AddLoot( LootPack.Gems, 4 ); } - - public override int TreasureMapLevel{ get{ return 5; } } - public override int Meat{ get{ return 16; } } - public override int Hides{ get{ return 60; } } - public override FoodType FavoriteFood{ get{ return FoodType.Meat; } } + + public override int TreasureMapLevel { get { return 5; } } + public override int Meat { get { return 16; } } + public override int Hides { get { return 60; } } + public override FoodType FavoriteFood { get { return FoodType.Meat; } } public override bool CanAngerOnTame { get { return true; } } public override void OnGaveMeleeAttack( Mobile defender ) { base.OnGaveMeleeAttack( defender ); - if ( 0.1 > Utility.RandomDouble() ) + if( 0.1 > Utility.RandomDouble() ) { /* Grasping Claw * Start cliloc: 1070836 @@ -107,7 +165,7 @@ namespace Server.Mobiles ExpireTimer timer = (ExpireTimer)m_Table[defender]; - if ( timer != null ) + if( timer != null ) { timer.DoExpire(); defender.SendLocalizedMessage( 1070837 ); // The creature lands another blow in your weakened state. @@ -135,7 +193,8 @@ namespace Server.Mobiles private Mobile m_Mobile; private ResistanceMod m_Mod; - public ExpireTimer( Mobile m, ResistanceMod mod, TimeSpan delay ) : base( delay ) + public ExpireTimer( Mobile m, ResistanceMod mod, TimeSpan delay ) + : base( delay ) { m_Mobile = m; m_Mod = mod; @@ -156,20 +215,27 @@ namespace Server.Mobiles } } - public Hiryu( Serial serial ) : base( serial ) + public Hiryu( Serial serial ) + : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); - writer.Write( (int) 0 ); + writer.Write( (int)1 ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); + + if( version == 0 ) + Timer.DelayCall( TimeSpan.Zero, delegate { Hue = GetHue(); } ); + + if( version <= 1 ) + Timer.DelayCall( TimeSpan.Zero, delegate { InternalItem.Hue = this.Hue; } ); } } } diff --git a/Scripts/Mobiles/Animals/Mounts/LesserHiryu.cs b/Scripts/Mobiles/Animals/Mounts/LesserHiryu.cs index c725e7fc3..4c3be4f16 100644 --- a/Scripts/Mobiles/Animals/Mounts/LesserHiryu.cs +++ b/Scripts/Mobiles/Animals/Mounts/LesserHiryu.cs @@ -13,13 +13,43 @@ namespace Server.Mobiles return WeaponAbility.Dismount; } - public override bool StatLossAfterTame{ get{ return true; } } + public override bool StatLossAfterTame { get { return true; } } + + private static int GetHue() + { + int rand = Utility.Random( 527 ); + + /* + + 500 527 No Hue Color 94.88% 0 + 10 527 Green 1.90% 0x8295 + 10 527 Green 1.90% 0x8163 (Very Close to Above Green) //this one is an approximation + 5 527 Dark Green 0.95% 0x87D4 + 1 527 Valorite 0.19% 0x88AB + 1 527 Midnight Blue 0.19% 0x8258 + + * */ + + if( rand <= 0 ) + return 0x8258; + else if( rand <= 1 ) + return 0x88AB; + else if( rand <= 6 ) + return 0x87D4; + else if( rand <= 16 ) + return 0x8163; + else if( rand <= 26 ) + return 0x8295; + + + return 0; + } [Constructable] - public LesserHiryu() : base( "a lesser hiryu", 243, 0x3E94, AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 ) - { - if ( 0.05 > Utility.RandomDouble() ) - Hue = Utility.RandomList( 0x32, 0x37, 0x3C, 0x3D, 0x123, 0x294, 0x295, 0x47F, 0x482, 0x487, 0x48D, 0x490, 0x495, 0x55C, 0x8A0, 0x899, 0x89F ) | 0x8000; + public LesserHiryu() + : base( "a lesser hiryu", 243, 0x3E94, AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 ) + { + Hue = GetHue(); SetStr( 301, 410 ); SetDex( 171, 270 ); @@ -50,7 +80,7 @@ namespace Server.Mobiles ControlSlots = 3; MinTameSkill = 98.7; - if ( Utility.RandomDouble() < .33 ) + if( Utility.RandomDouble() < .33 ) PackItem( Engines.Plants.Seed.RandomBonsaiSeed() ); } @@ -89,24 +119,24 @@ namespace Server.Mobiles public override double GetControlChance( Mobile m, bool useBaseSkill ) { double skill = (useBaseSkill? m.Skills.Bushido.Base : m.Skills.Bushido.Value); - - if ( skill >= 90.0 ) + + if( skill >= 90.0 ) return 1.0; return base.GetControlChance( m, useBaseSkill ); } - public override int TreasureMapLevel{ get{ return 3; } } - public override int Meat{ get{ return 16; } } - public override int Hides{ get{ return 60; } } - public override FoodType FavoriteFood{ get{ return FoodType.Meat; } } + public override int TreasureMapLevel { get { return 3; } } + public override int Meat { get { return 16; } } + public override int Hides { get { return 60; } } + public override FoodType FavoriteFood { get { return FoodType.Meat; } } public override bool CanAngerOnTame { get { return true; } } public override void OnGaveMeleeAttack( Mobile defender ) { base.OnGaveMeleeAttack( defender ); - if ( 0.1 > Utility.RandomDouble() ) + if( 0.1 > Utility.RandomDouble() ) { /* Grasping Claw * Start cliloc: 1070836 @@ -117,7 +147,7 @@ namespace Server.Mobiles ExpireTimer timer = (ExpireTimer)m_Table[defender]; - if ( timer != null ) + if( timer != null ) { timer.DoExpire(); defender.SendLocalizedMessage( 1070837 ); // The creature lands another blow in your weakened state. @@ -145,7 +175,8 @@ namespace Server.Mobiles private Mobile m_Mobile; private ResistanceMod m_Mod; - public ExpireTimer( Mobile m, ResistanceMod mod, TimeSpan delay ) : base( delay ) + public ExpireTimer( Mobile m, ResistanceMod mod, TimeSpan delay ) + : base( delay ) { m_Mobile = m; m_Mod = mod; @@ -166,20 +197,27 @@ namespace Server.Mobiles } } - public LesserHiryu( Serial serial ) : base( serial ) + public LesserHiryu( Serial serial ) + : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); - writer.Write( (int) 0 ); + writer.Write( (int)1 ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); + + if( version == 0 ) + Timer.DelayCall( TimeSpan.Zero, delegate { Hue = GetHue(); } ); + + if( version <= 1 ) + Timer.DelayCall( TimeSpan.Zero, delegate { InternalItem.Hue = this.Hue; } ); } } } diff --git a/Scripts/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs b/Scripts/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs index d98eb473c..ba59d540b 100644 --- a/Scripts/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs +++ b/Scripts/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs @@ -180,7 +180,7 @@ namespace Server.Mobiles int toHeal = (int)(Skills[SkillName.Magery].Value * 0.4); toHeal += Utility.Random( 1, 10 ); - m.Heal( toHeal ); + m.Heal( toHeal, this ); m.FixedParticles( 0x376A, 9, 32, 5030, EffectLayer.Waist ); m.PlaySound( 0x202 ); diff --git a/Scripts/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs b/Scripts/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs index da4d3e63f..3b50d048a 100644 --- a/Scripts/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs +++ b/Scripts/Mobiles/Monsters/LBR/Meers/MeerCaptain.cs @@ -139,7 +139,7 @@ namespace Server.Mobiles SpellHelper.Turn( this, m ); - m.Heal( toHeal ); + m.Heal( toHeal, this ); m.FixedParticles( 0x376A, 9, 32, 5030, EffectLayer.Waist ); m.PlaySound( 0x202 ); diff --git a/Scripts/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs b/Scripts/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs index a158ed690..d043152c6 100644 --- a/Scripts/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs +++ b/Scripts/Mobiles/Monsters/Misc/Melee/BladeSpirits.cs @@ -14,7 +14,7 @@ namespace Server.Mobiles public override double DispelDifficulty { get { return 0.0; } } public override double DispelFocus { get { return 20.0; } } - public override double GetValueFrom( Mobile m, FightMode acqType, bool bPlayerOnly ) + public override double GetFightModeRanking( Mobile m, FightMode acqType, bool bPlayerOnly ) { return ( m.Str + m.Skills[SkillName.Tactics].Value ) / Math.Max( GetDistanceToSqrt( m ), 1.0 ); } diff --git a/Scripts/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs b/Scripts/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs index 4ae771d2b..df49c0525 100644 --- a/Scripts/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs +++ b/Scripts/Mobiles/Monsters/Misc/Melee/EnergyVortex.cs @@ -14,7 +14,7 @@ namespace Server.Mobiles public override double DispelDifficulty { get { return 80.0; } } public override double DispelFocus { get { return 20.0; } } - public override double GetValueFrom( Mobile m, FightMode acqType, bool bPlayerOnly ) + public override double GetFightModeRanking( Mobile m, FightMode acqType, bool bPlayerOnly ) { return ( m.Int + m.Skills[SkillName.Magery].Value ) / Math.Max( GetDistanceToSqrt( m ), 1.0 ); } @@ -25,14 +25,16 @@ namespace Server.Mobiles { Name = "an energy vortex"; - if ( Core.SE && 0.02 > Utility.RandomDouble() ) // Tested on OSI, but is this right? Who knows. + if( Core.SE && 0.02 > Utility.RandomDouble() ) // Tested on OSI, but is this right? Who knows. { // Llama vortex! Body = 0xDC; Hue = 0x76; } else - Body = 164; + { + Body = 164; + } SetStr( 200 ); SetDex( 200 ); diff --git a/Scripts/Mobiles/PlayerMobile.cs b/Scripts/Mobiles/PlayerMobile.cs index c6d446758..e8e32bf88 100644 --- a/Scripts/Mobiles/PlayerMobile.cs +++ b/Scripts/Mobiles/PlayerMobile.cs @@ -23,6 +23,7 @@ using Server.Regions; using Server.Accounting; using Server.Engines.CannedEvil; using Server.Engines.Craft; +using Server.Spells.Spellweaving; namespace Server.Mobiles { @@ -1691,7 +1692,7 @@ namespace Server.Mobiles public override bool CheckShove( Mobile shoved ) { - if( TransformationSpell.UnderTransformation( this, typeof( WraithFormSpell ) ) ) + if( TransformationSpellHelper.UnderTransformation( this, typeof( WraithFormSpell ) ) ) return true; else return base.CheckShove( shoved ); @@ -2133,7 +2134,7 @@ namespace Server.Mobiles { //g.Alliance.AllianceTextMessage( hue, "[Alliance][{0}]: {1}", this.Name, text ); g.Alliance.AllianceChat( this, text ); - SendToStaffMessage( this, "[Alliance]: {0}", this.Name, text ); + SendToStaffMessage( this, "[Alliance]: {0}", text ); m_AllianceMessageHue = hue; } @@ -3043,13 +3044,18 @@ namespace Server.Mobiles if ( checkTurning && (dir & Direction.Mask) != (this.Direction & Direction.Mask) ) return TimeSpan.FromSeconds( 0.1 ); // We are NOT actually moving (just a direction change) + TransformContext context = TransformationSpellHelper.GetContext( this ); + + if( context != null && context.Type == typeof( ReaperFormSpell ) ) + return Mobile.WalkFoot; + bool running = ( (dir & Direction.Running) != 0 ); bool onHorse = ( this.Mount != null ); - AnimalFormContext context = AnimalForm.GetContext( this ); + AnimalFormContext animalContext = AnimalForm.GetContext( this ); - if ( onHorse || (context != null && context.SpeedBoost) ) + if( onHorse || (animalContext != null && animalContext.SpeedBoost) ) return ( running ? Mobile.RunMount : Mobile.WalkMount ); return ( running ? Mobile.RunFoot : Mobile.WalkFoot ); @@ -3188,6 +3194,8 @@ namespace Server.Mobiles public DateTime LastSacrificeGain{ get{ return m_LastSacrificeGain; } set{ m_LastSacrificeGain = value; } } public DateTime LastSacrificeLoss{ get{ return m_LastSacrificeLoss; } set{ m_LastSacrificeLoss = value; } } + + [CommandProperty( AccessLevel.GameMaster )] public int AvailableResurrects{ get{ return m_AvailableResurrects; } set{ m_AvailableResurrects = value; } } private DateTime m_NextJustAward; diff --git a/Scripts/Mobiles/Special/BaseChampion.cs b/Scripts/Mobiles/Special/BaseChampion.cs index 3182a6512..2344627fd 100644 --- a/Scripts/Mobiles/Special/BaseChampion.cs +++ b/Scripts/Mobiles/Special/BaseChampion.cs @@ -57,7 +57,7 @@ namespace Server.Mobiles if ( Map != Map.Felucca ) return; - ArrayList toGive = new ArrayList(); + List toGive = new List(); List rights = BaseCreature.GetLootingRights( this.DamageEntries, this.HitsMax ); for ( int i = rights.Count - 1; i >= 0; --i ) @@ -73,7 +73,7 @@ namespace Server.Mobiles for( int i = 0; i < toGive.Count; i++ ) { - Mobile m = (Mobile)toGive[i]; + Mobile m = toGive[i]; if( !(m is PlayerMobile) ) continue; @@ -97,64 +97,72 @@ namespace Server.Mobiles for ( int i = 0; i < toGive.Count; ++i ) { int rand = Utility.Random( toGive.Count ); - object hold = toGive[i]; + Mobile hold = toGive[i]; toGive[i] = toGive[rand]; toGive[rand] = hold; } for ( int i = 0; i < 6; ++i ) { - Mobile m = (Mobile)toGive[i % toGive.Count]; + Mobile m = toGive[i % toGive.Count]; PowerScroll ps = CreateRandomPowerScroll(); - m.SendLocalizedMessage( 1049524 ); // You have received a scroll of power! + GivePowerScrollTo( m, ps ); + } + } - if ( !Core.SE || m.Alive ) - m.AddToBackpack( ps ); + public static void GivePowerScrollTo( Mobile m, PowerScroll ps ) + { + if( ps == null || m == null ) //sanity + return; + + m.SendLocalizedMessage( 1049524 ); // You have received a scroll of power! + + if( !Core.SE || m.Alive ) + m.AddToBackpack( ps ); + else + { + if( m.Corpse != null && !m.Corpse.Deleted ) + m.Corpse.DropItem( ps ); else - { - if ( m.Corpse != null && !m.Corpse.Deleted ) - ((Container)m.Corpse).DropItem( ps ); - else - m.AddToBackpack( ps ); - } + m.AddToBackpack( ps ); + } - if ( m is PlayerMobile ) - { - PlayerMobile pm = (PlayerMobile)m; + if( m is PlayerMobile ) + { + PlayerMobile pm = (PlayerMobile)m; - for ( int j = 0; j < pm.JusticeProtectors.Count; ++j ) + for( int j = 0; j < pm.JusticeProtectors.Count; ++j ) + { + Mobile prot = pm.JusticeProtectors[j]; + + if( prot.Map != m.Map || prot.Kills >= 5 || prot.Criminal || !JusticeVirtue.CheckMapRegion( m, prot ) ) + continue; + + int chance = 0; + + switch( VirtueHelper.GetLevel( prot, VirtueName.Justice ) ) { - Mobile prot = (Mobile)pm.JusticeProtectors[j]; + case VirtueLevel.Seeker: chance = 60; break; + case VirtueLevel.Follower: chance = 80; break; + case VirtueLevel.Knight: chance = 100; break; + } - if ( prot.Map != m.Map || prot.Kills >= 5 || prot.Criminal || !JusticeVirtue.CheckMapRegion( m, prot ) ) - continue; + if( chance > Utility.Random( 100 ) ) + { + PowerScroll powerScroll = new PowerScroll( ps.Skill, ps.Value ); - int chance = 0; + prot.SendLocalizedMessage( 1049368 ); // You have been rewarded for your dedication to Justice! - switch ( VirtueHelper.GetLevel( prot, VirtueName.Justice ) ) + if( !Core.SE || prot.Alive ) + prot.AddToBackpack( powerScroll ); + else { - case VirtueLevel.Seeker: chance = 60; break; - case VirtueLevel.Follower: chance = 80; break; - case VirtueLevel.Knight: chance = 100; break; - } - - if ( chance > Utility.Random( 100 ) ) - { - ps = CreateRandomPowerScroll(); - - prot.SendLocalizedMessage( 1049368 ); // You have been rewarded for your dedication to Justice! - - if ( !Core.SE || prot.Alive ) - prot.AddToBackpack( ps ); + if( prot.Corpse != null && !prot.Corpse.Deleted ) + prot.Corpse.DropItem( powerScroll ); else - { - if ( prot.Corpse != null && !prot.Corpse.Deleted ) - ((Container)prot.Corpse).DropItem( ps ); - else - prot.AddToBackpack( ps ); - } + prot.AddToBackpack( powerScroll ); } } } diff --git a/Scripts/Mobiles/Vendors/PlayerBarkeeper.cs b/Scripts/Mobiles/Vendors/PlayerBarkeeper.cs index 671f6dd37..26d6ccae9 100644 --- a/Scripts/Mobiles/Vendors/PlayerBarkeeper.cs +++ b/Scripts/Mobiles/Vendors/PlayerBarkeeper.cs @@ -29,8 +29,8 @@ namespace Server.Mobiles public override void OnResponse( Mobile from, string text ) { - if ( text.Length > 50 ) - text = text.Substring( 0, 50 ); + if( text.Length > 130 ) + text = text.Substring( 0, 130 ); m_Barkeeper.EndChangeRumor( from, m_RumorIndex, text ); } @@ -54,8 +54,8 @@ namespace Server.Mobiles public override void OnResponse( Mobile from, string text ) { - if ( text.Length > 50 ) - text = text.Substring( 0, 50 ); + if( text.Length > 130 ) + text = text.Substring( 0, 130 ); m_Barkeeper.EndChangeKeyword( from, m_RumorIndex, text ); } @@ -77,8 +77,8 @@ namespace Server.Mobiles public override void OnResponse( Mobile from, string text ) { - if ( text.Length > 50 ) - text = text.Substring( 0, 50 ); + if ( text.Length > 130 ) + text = text.Substring( 0, 130 ); m_Barkeeper.EndChangeTip( from, text ); } diff --git a/Scripts/Regions/GuardedRegion.cs b/Scripts/Regions/GuardedRegion.cs index 7d2241937..dd44f07f2 100644 --- a/Scripts/Regions/GuardedRegion.cs +++ b/Scripts/Regions/GuardedRegion.cs @@ -128,6 +128,11 @@ namespace Server.Regions m_GuardType = DefaultGuardType; } + public GuardedRegion( string name, Map map, int priority, params Rectangle2D[] area ) + : base( name, map, priority, area ) + { + m_GuardType = DefaultGuardType; + } public GuardedRegion( XmlElement xml, Map map, Region parent ) : base( xml, map, parent ) { XmlElement el = xml["guards"]; diff --git a/Scripts/Skills/SpiritSpeak.cs b/Scripts/Skills/SpiritSpeak.cs index ac83bf71a..9356cf22a 100644 --- a/Scripts/Skills/SpiritSpeak.cs +++ b/Scripts/Skills/SpiritSpeak.cs @@ -74,7 +74,7 @@ namespace Server.SkillHandlers private class SpiritSpeakSpell : Spell { - private static SpellInfo m_Info = new SpellInfo( "Spirit Speak", "", SpellCircle.Second, 269 ); + private static SpellInfo m_Info = new SpellInfo( "Spirit Speak", "", 269 ); public override bool BlockedByHorrificBeast{ get{ return false; } } @@ -84,10 +84,8 @@ namespace Server.SkillHandlers public override bool ClearHandsOnCast{ get{ return false; } } - public override TimeSpan GetCastDelay() - { - return TimeSpan.FromSeconds( 1.0 ); - } + public override double CastDelayFastScalar { get { return 0; } } + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } } public override int GetMana() { diff --git a/Scripts/Skills/Stealing.cs b/Scripts/Skills/Stealing.cs index 2e4e48008..5d34bd5dc 100644 --- a/Scripts/Skills/Stealing.cs +++ b/Scripts/Skills/Stealing.cs @@ -9,6 +9,8 @@ using Server.Factions; using Server.Spells.Seventh; using Server.Spells.Fifth; using Server.Spells.Necromancy; +using Server.Spells; +using Server.Spells.Ninjitsu; namespace Server.SkillHandlers { @@ -111,11 +113,11 @@ namespace Server.SkillHandlers { m_Thief.SendLocalizedMessage( 1010582 ); // You cannot steal the sigil while polymorphed } - else if ( TransformationSpell.UnderTransformation( m_Thief ) ) + else if( TransformationSpellHelper.UnderTransformation( m_Thief ) ) { m_Thief.SendLocalizedMessage( 1061622 ); // You cannot steal the sigil while in that form. } - else if ( Spells.Ninjitsu.AnimalForm.UnderTransformation( m_Thief ) ) + else if ( AnimalForm.UnderTransformation( m_Thief ) ) { m_Thief.SendLocalizedMessage( 1063222 ); // You cannot steal the sigil while mimicking an animal. } diff --git a/Scripts/Skills/Stealth.cs b/Scripts/Skills/Stealth.cs index a91d1341c..e6d29f044 100644 --- a/Scripts/Skills/Stealth.cs +++ b/Scripts/Skills/Stealth.cs @@ -65,20 +65,25 @@ namespace Server.SkillHandlers m.SendLocalizedMessage( 502726 ); // You are not hidden well enough. Become better at hiding. m.RevealingAction(); } + else if( !m.CanBeginAction( typeof( Stealth ) ) ) + { + m.SendLocalizedMessage( 1063086 ); // You cannot use this skill right now. + m.RevealingAction(); + } else { int armorRating = GetArmorRating( m ); - if ( armorRating >= (Core.AOS ? 42 : 26) ) //I have a hunch '42' was chosen cause someone's a fan of DNA + if( armorRating >= (Core.AOS ? 42 : 26) ) //I have a hunch '42' was chosen cause someone's a fan of DNA { m.SendLocalizedMessage( 502727 ); // You could not hope to move quietly wearing this much armor. m.RevealingAction(); } - else if ( m.CheckSkill( SkillName.Stealth, -20.0 + (armorRating * 2), (Core.AOS ? 60.0 : 80.0) + (armorRating * 2) ) ) + else if( m.CheckSkill( SkillName.Stealth, -20.0 + (armorRating * 2), (Core.AOS ? 60.0 : 80.0) + (armorRating * 2) ) ) { int steps = (int)(m.Skills[SkillName.Stealth].Value / (Core.AOS ? 5.0 : 10.0)); - if ( steps < 1 ) + if( steps < 1 ) steps = 1; m.AllowedStealthSteps = steps; diff --git a/Scripts/Skills/Tracking.cs b/Scripts/Skills/Tracking.cs index b5e2d58f0..9e7c87974 100644 --- a/Scripts/Skills/Tracking.cs +++ b/Scripts/Skills/Tracking.cs @@ -221,11 +221,11 @@ namespace Server.SkillHandlers int divisor = hiding + stealth; // Necromancy forms affect tracking difficulty - if ( TransformationSpell.UnderTransformation( m, typeof( HorrificBeastSpell ) ) ) + if ( TransformationSpellHelper.UnderTransformation( m, typeof( HorrificBeastSpell ) ) ) divisor -= 200; - else if ( TransformationSpell.UnderTransformation( m, typeof( VampiricEmbraceSpell ) ) && divisor < 500 ) + else if ( TransformationSpellHelper.UnderTransformation( m, typeof( VampiricEmbraceSpell ) ) && divisor < 500 ) divisor = 500; - else if ( TransformationSpell.UnderTransformation( m, typeof( WraithFormSpell ) ) && divisor <= 2000 ) + else if ( TransformationSpellHelper.UnderTransformation( m, typeof( WraithFormSpell ) ) && divisor <= 2000 ) divisor += 200; int chance; diff --git a/Scripts/Spells/Base/MagerySpell.cs b/Scripts/Spells/Base/MagerySpell.cs new file mode 100644 index 000000000..a850ca42d --- /dev/null +++ b/Scripts/Spells/Base/MagerySpell.cs @@ -0,0 +1,116 @@ +using System; +using Server; +using Server.Items; + +namespace Server.Spells +{ + public abstract class MagerySpell : Spell + { + public MagerySpell( Mobile caster, Item scroll, SpellInfo info ) + : base( caster, scroll, info ) + { + } + + public abstract SpellCircle Circle { get; } + + public override bool ConsumeReagents() + { + if( base.ConsumeReagents() ) + return true; + + if( ArcaneGem.ConsumeCharges( Caster, (Core.SE ? 1 : 1 + (int)Circle) ) ) + return true; + + return false; + } + + private const double ChanceOffset = 20.0, ChanceLength = 100.0 / 7.0; + + public override void GetCastSkills( out double min, out double max ) + { + int circle = (int)Circle; + + if( Scroll != null ) + circle -= 2; + + double avg = ChanceLength * circle; + + min = avg - ChanceOffset; + max = avg + ChanceOffset; + } + + private static int[] m_ManaTable = new int[] { 4, 6, 9, 11, 14, 20, 40, 50 }; + + public override int GetMana() + { + if( Scroll is BaseWand ) + return 0; + + return m_ManaTable[(int)Circle]; + } + + public override double GetResistSkill( Mobile m ) + { + int maxSkill = (1 + (int)Circle) * 10; + maxSkill += (1 + ((int)Circle / 6)) * 25; + + if( m.Skills[SkillName.MagicResist].Value < maxSkill ) + m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); + + return m.Skills[SkillName.MagicResist].Value; + } + + public virtual bool CheckResisted( Mobile target ) + { + double n = GetResistPercent( target ); + + n /= 100.0; + + if( n <= 0.0 ) + return false; + + if( n >= 1.0 ) + return true; + + int maxSkill = (1 + (int)Circle) * 10; + maxSkill += (1 + ((int)Circle / 6)) * 25; + + if( target.Skills[SkillName.MagicResist].Value < maxSkill ) + target.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); + + return (n >= Utility.RandomDouble()); + } + + public virtual double GetResistPercentForCircle( Mobile target, SpellCircle circle ) + { + double firstPercent = target.Skills[SkillName.MagicResist].Value / 5.0; + double secondPercent = target.Skills[SkillName.MagicResist].Value - (((Caster.Skills[CastSkill].Value - 20.0) / 5.0) + (1 + (int)circle) * 5.0); + + return (firstPercent > secondPercent ? firstPercent : secondPercent) / 2.0; // Seems should be about half of what stratics says. + } + + public virtual double GetResistPercent( Mobile target ) + { + return GetResistPercentForCircle( target, Circle ); + } + + public override TimeSpan GetCastDelay() + { + if( Scroll is BaseWand ) + return TimeSpan.Zero; + + if( !Core.AOS ) + return TimeSpan.FromSeconds( 0.5 + (0.25 * (int)Circle) ); + + return base.GetCastDelay(); + } + + public override TimeSpan CastDelayBase + { + get + { + return TimeSpan.FromSeconds( (3 + (int)Circle) * CastDelaySecondsPerTick ); + } + } + } +} diff --git a/Scripts/Spells/Base/Spell.cs b/Scripts/Spells/Base/Spell.cs index aac607215..a866eaf3e 100644 --- a/Scripts/Spells/Base/Spell.cs +++ b/Scripts/Spells/Base/Spell.cs @@ -7,6 +7,8 @@ using Server.Spells.Second; using Server.Spells.Necromancy; using Server.Spells.Ninjitsu; using System.Collections.Generic; +using Server.Spells.Spellweaving; +using Server.Spells.Bushido; namespace Server.Spells { @@ -23,7 +25,6 @@ namespace Server.Spells public SpellInfo Info{ get{ return m_Info; } } public string Name{ get{ return m_Info.Name; } } public string Mantra{ get{ return m_Info.Mantra; } } - public SpellCircle Circle{ get{ return m_Info.Circle; } } public Type[] Reagents{ get{ return m_Info.Reagents; } } public Item Scroll{ get{ return m_Scroll; } } public DateTime StartCastTime { get { return m_StartCastTime; } } @@ -46,65 +47,55 @@ namespace Server.Spells //the possibility of stacking 'em. Note that a MA & an Explosion will stack, but //of course, two MA's won't. - private static Dictionary> m_ContextTable = new Dictionary>(); + private static Dictionary m_ContextTable = new Dictionary(); - private class DelayedDamageContext { - public Mobile Target; - public Type Type; - public Timer Timer; + private class DelayedDamageContextWrapper + { + private Dictionary m_Contexts = new Dictionary(); - public DelayedDamageContext( Mobile target, Type type, Timer timer ) { - Target = target; - Type = type; - Timer = timer; - } - } - - public void StartDelayedDamageContext( Mobile target, Timer timer ) - { - if( DelayedDamageStacking ) - return; //Sanity - - List contexts; - Type type = this.GetType(); - - if( !m_ContextTable.TryGetValue( m_Caster, out contexts ) ) - contexts = new List(); - else { - for ( int i = 0; i < contexts.Count; i++ ) { - DelayedDamageContext ddc = contexts[i]; - - if ( ddc.Target == target && ddc.Type == type ) { - ddc.Timer.Stop(); - contexts.RemoveAt( i ); - break; - } + public void Add( Mobile m, Timer t ) + { + Timer oldTimer; + if( m_Contexts.TryGetValue( m, out oldTimer ) ) + { + oldTimer.Stop(); + m_Contexts.Remove( m ); } + + m_Contexts.Add( m, t ); } - contexts.Add( new DelayedDamageContext( target, type, timer ) ); + public void Remove( Mobile m ) + { + m_Contexts.Remove( m ); + } } - public void RemoveDelayedDamageContext( Mobile target ) - { - List contexts; - Type type = this.GetType(); + public void StartDelayedDamageContext( Mobile m, Timer t ) + { + if( DelayedDamageStacking ) + return; //Sanity - if( !m_ContextTable.TryGetValue( m_Caster, out contexts ) ) + DelayedDamageContextWrapper contexts; + + if( !m_ContextTable.TryGetValue( GetType(), out contexts ) ) + { + contexts = new DelayedDamageContextWrapper(); + m_ContextTable.Add( GetType(), contexts ); + } + + contexts.Add( m, t ); + } + + public void RemoveDelayedDamageContext( Mobile m ) + { + DelayedDamageContextWrapper contexts; + + if( !m_ContextTable.TryGetValue( GetType(), out contexts ) ) return; - for ( int i = 0; i < contexts.Count; i++ ) { - DelayedDamageContext ddc = contexts[i]; - - if ( ddc.Target == target && ddc.Type == type ) { - contexts.RemoveAt( i ); - break; - } - } - - if ( contexts.Count == 0 ) - m_ContextTable.Remove( m_Caster ); - } + contexts.Remove( m ); + } public Spell( Mobile caster, Item scroll, SpellInfo info ) { @@ -146,8 +137,14 @@ namespace Server.Spells // PvP spell damage increase cap of 15% from an item’s magic property if ( playerVsPlayer && sdiBonus > 15 ) sdiBonus = 15; + damageBonus += sdiBonus; + TransformContext context = TransformationSpellHelper.GetContext( Caster ); + + if( context != null && context.Spell is ReaperFormSpell ) + damageBonus += ((ReaperFormSpell)context.Spell).SpellDamageBonus; + damage = AOS.Scale( damage, 100 + damageBonus ); int evalSkill = GetDamageFixed( m_Caster ); @@ -160,27 +157,6 @@ namespace Server.Spells return damage / 100; } - /* - public virtual double GetAosDamage( int min, int random, double div ) - { - double scale = 1.0; - - scale += GetInscribeSkill( m_Caster ) * 0.001; - - if ( Caster.Player ) - { - scale += Caster.Int * 0.001; - scale += AosAttributes.GetValue( m_Caster, AosAttribute.SpellDamage ) * 0.01; - } - - int baseDamage = min + (int)(GetDamageSkill( m_Caster ) / div); - - double damage = Utility.RandomMinMax( baseDamage, baseDamage + random ); - - return damage * scale; - } - */ - public virtual bool IsCasting{ get{ return m_State == SpellState.Casting; } } public virtual void OnCasterHurt() @@ -263,36 +239,9 @@ namespace Server.Spells if ( pack.ConsumeTotal( m_Info.Reagents, m_Info.Amounts ) == -1 ) return true; - if ( GetType().BaseType == typeof( Spell ) ) - { - if ( ArcaneGem.ConsumeCharges( m_Caster, ( Core.SE ? 1 : 1 + (int)Circle ) ) ) - return true; - } - return false; } - public virtual bool CheckResisted( Mobile target ) - { - double n = GetResistPercent( target ); - - n /= 100.0; - - if ( n <= 0.0 ) - return false; - - if ( n >= 1.0 ) - return true; - - int maxSkill = (1 + (int)Circle) * 10; - maxSkill += (1 + ((int)Circle / 6)) * 25; - - if ( target.Skills[SkillName.MagicResist].Value < maxSkill ) - target.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); - - return ( n >= Utility.RandomDouble() ); - } - public virtual double GetInscribeSkill( Mobile m ) { // There is no chance to gain @@ -323,41 +272,11 @@ namespace Server.Spells return m.Skills[DamageSkill].Value; } - public virtual int GetResistFixed( Mobile m ) - { - int maxSkill = (1 + (int)Circle) * 10; - maxSkill += (1 + ((int)Circle / 6)) * 25; - - if ( m.Skills[SkillName.MagicResist].Value < maxSkill ) - m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); - - return m.Skills[SkillName.MagicResist].Fixed; - } - public virtual double GetResistSkill( Mobile m ) { - int maxSkill = (1 + (int)Circle) * 10; - maxSkill += (1 + ((int)Circle / 6)) * 25; - - if ( m.Skills[SkillName.MagicResist].Value < maxSkill ) - m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); - return m.Skills[SkillName.MagicResist].Value; } - public virtual double GetResistPercentForCircle( Mobile target, SpellCircle circle ) - { - double firstPercent = target.Skills[SkillName.MagicResist].Value / 5.0; - double secondPercent = target.Skills[SkillName.MagicResist].Value - (((m_Caster.Skills[CastSkill].Value - 20.0) / 5.0) + (1 + (int)circle) * 5.0); - - return ( firstPercent > secondPercent ? firstPercent : secondPercent ) / 2.0; // Seems should be about half of what stratics says. - } - - public virtual double GetResistPercent( Mobile target ) - { - return GetResistPercentForCircle( target, m_Info.Circle ); - } - public virtual double GetDamageScalar( Mobile target ) { double scalar = 1.0; @@ -397,6 +316,9 @@ namespace Server.Spells target.Region.SpellDamageScalar( m_Caster, target, ref scalar ); + if( Evasion.CheckSpellEvasion( target ) ) //Only single target spells an be evaded + scalar = 0; + return scalar; } @@ -417,7 +339,7 @@ namespace Server.Spells } - TransformContext context = TransformationSpell.GetContext( defender ); + TransformContext context = TransformationSpellHelper.GetContext( defender ); if( (atkBook.Slayer == SlayerName.Silver || atkBook.Slayer2 == SlayerName.Silver) && context != null && context.Type != typeof( HorrificBeastSpell ) ) scalar +=.25; // Every necromancer transformation other than horrific beast take an additional 25% damage @@ -481,7 +403,7 @@ namespace Server.Spells if ( m_State == SpellState.Casting ) { - if ( !firstCircle && Circle == SpellCircle.First && !Core.AOS ) + if( !firstCircle && !Core.AOS && this is MagerySpell && ((MagerySpell)this).Circle == SpellCircle.First ) return; m_State = SpellState.None; @@ -502,7 +424,7 @@ namespace Server.Spells } else if ( m_State == SpellState.Sequencing ) { - if ( !firstCircle && Circle == SpellCircle.First && !Core.AOS ) + if( !firstCircle && !Core.AOS && this is MagerySpell && ((MagerySpell)this).Circle == SpellCircle.First ) return; m_State = SpellState.None; @@ -564,7 +486,7 @@ namespace Server.Spells { m_Caster.SendLocalizedMessage( 502642 ); // You are already casting a spell. } - else if ( BlockedByHorrificBeast && TransformationSpell.UnderTransformation( m_Caster, typeof( HorrificBeastSpell ) ) || ( BlockedByAnimalForm && AnimalForm.UnderTransformation( m_Caster ) )) + else if ( BlockedByHorrificBeast && TransformationSpellHelper.UnderTransformation( m_Caster, typeof( HorrificBeastSpell ) ) || ( BlockedByAnimalForm && AnimalForm.UnderTransformation( m_Caster ) )) { m_Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form. } @@ -636,19 +558,9 @@ namespace Server.Spells { } - private const double ChanceOffset = 20.0, ChanceLength = 100.0 / 7.0; - public virtual void GetCastSkills( out double min, out double max ) { - int circle = (int)m_Info.Circle; - - if ( m_Scroll != null ) - circle -= 2; - - double avg = ChanceLength * circle; - - min = avg - ChanceOffset; - max = avg + ChanceOffset; + min = max = 0; //Intended but not required for overriding. } public virtual bool CheckFizzle() @@ -663,15 +575,7 @@ namespace Server.Spells return Caster.CheckSkill( CastSkill, minSkill, maxSkill ); } - private static int[] m_ManaTable = new int[]{ 4, 6, 9, 11, 14, 20, 40, 50 }; - - public virtual int GetMana() - { - if ( m_Scroll is BaseWand ) - return 0; - - return m_ManaTable[(int)Circle]; - } + public abstract int GetMana(); public virtual int ScaleMana( int mana ) { @@ -704,7 +608,6 @@ namespace Server.Spells } public virtual int CastRecoveryBase{ get{ return 6; } } - public virtual int CastRecoveryCircleScalar{ get{ return 0; } } public virtual int CastRecoveryFastScalar{ get{ return 1; } } public virtual int CastRecoveryPerSecond{ get{ return 4; } } public virtual int CastRecoveryMinimum{ get{ return 0; } } @@ -716,10 +619,11 @@ namespace Server.Spells int fcr = AosAttributes.GetValue( m_Caster, AosAttribute.CastRecovery ); - int circleDelay = CastRecoveryCircleScalar * (1 + (int)Circle); // Note: Circle is 0-based so we must offset + fcr -= ThunderstormSpell.GetCastRecoveryMalus( m_Caster ); + int fcrDelay = -(CastRecoveryFastScalar * fcr); - int delay = CastRecoveryBase + circleDelay + fcrDelay; + int delay = CastRecoveryBase + fcrDelay; if ( delay < CastRecoveryMinimum ) delay = CastRecoveryMinimum; @@ -727,20 +631,24 @@ namespace Server.Spells return TimeSpan.FromSeconds( (double)delay / CastRecoveryPerSecond ); } - public virtual int CastDelayBase{ get{ return 3; } } - public virtual int CastDelayCircleScalar{ get{ return 1; } } - public virtual int CastDelayFastScalar{ get{ return 1; } } - public virtual int CastDelayPerSecond{ get{ return 4; } } - public virtual int CastDelayMinimum{ get{ return 1; } } + + + public abstract TimeSpan CastDelayBase { get; } + + public virtual double CastDelayFastScalar { get { return 1; } } + public virtual double CastDelaySecondsPerTick { get { return 0.25; } } + public virtual TimeSpan CastDelayMinimum { get { return TimeSpan.FromSeconds( 0.25 ); } } + + //public virtual int CastDelayBase{ get{ return 3; } } + //public virtual int CastDelayFastScalar{ get{ return 1; } } + //public virtual int CastDelayPerSecond{ get{ return 4; } } + //public virtual int CastDelayMinimum{ get{ return 1; } } public virtual TimeSpan GetCastDelay() { if ( m_Scroll is BaseWand ) return TimeSpan.Zero; - if ( !Core.AOS ) - return TimeSpan.FromSeconds( 0.5 + (0.25 * (int)Circle) ); - // Faster casting cap of 2 (if not using the protection spell) // Faster casting cap of 0 (if using the protection spell) // Paladin spells are subject to a faster casting cap of 4 @@ -758,17 +666,21 @@ namespace Server.Spells if ( ProtectionSpell.Registry.Contains( m_Caster ) ) fc -= 2; - // Circle is 0-based but we must not offset, first circle spells are cast at base delay. - int circleDelay = CastDelayCircleScalar * (int)Circle; + if( EssenceOfWindSpell.IsDebuffed( m_Caster ) ) + fc -= EssenceOfWindSpell.GetFCMalus( m_Caster ); - int fcDelay = -(CastDelayFastScalar * fc); + TimeSpan baseDelay = CastDelayBase; - int delay = CastDelayBase + circleDelay + fcDelay; + TimeSpan fcDelay = TimeSpan.FromSeconds( -(CastDelayFastScalar * fc * CastDelaySecondsPerTick) ); + + //int delay = CastDelayBase + circleDelay + fcDelay; + TimeSpan delay = baseDelay + fcDelay; if ( delay < CastDelayMinimum ) delay = CastDelayMinimum; - return TimeSpan.FromSeconds( (double)delay / CastDelayPerSecond ); + //return TimeSpan.FromSeconds( (double)delay / CastDelayPerSecond ); + return delay; } public virtual void FinishSequence() @@ -840,7 +752,7 @@ namespace Server.Spells if ( karma != 0 ) Misc.Titles.AwardKarma( Caster, karma, true ); - if ( TransformationSpell.UnderTransformation( m_Caster, typeof( VampiricEmbraceSpell ) ) ) + if( TransformationSpellHelper.UnderTransformation( m_Caster, typeof( VampiricEmbraceSpell ) ) ) { bool garlic = false; diff --git a/Scripts/Spells/Base/SpellHelper.cs b/Scripts/Spells/Base/SpellHelper.cs index feec5276a..36207c98d 100644 --- a/Scripts/Spells/Base/SpellHelper.cs +++ b/Scripts/Spells/Base/SpellHelper.cs @@ -9,6 +9,10 @@ using Server.Targeting; using Server.Engines.PartySystem; using Server.Misc; using Server.Spells.Bushido; +using Server.Spells.Ninjitsu; +using System.Collections.Generic; +using Server.Spells.Seventh; +using Server.Spells.Fifth; namespace Server { @@ -423,6 +427,16 @@ namespace Server.Spells creature.Mana = creature.ManaMax; } + Point3D p = new Point3D( caster ); + + if( SpellHelper.FindValidSpawnLocation( map, ref p, true ) ) + { + BaseCreature.Summon( creature, caster, p, sound, duration ); + return; + } + + + /* int offset = Utility.Random( 8 ) * 2; for( int i = 0; i < m_Offsets.Length; i += 2 ) @@ -446,11 +460,61 @@ namespace Server.Spells } } } + * */ creature.Delete(); caster.SendLocalizedMessage( 501942 ); // That location is blocked. } + public static bool FindValidSpawnLocation( Map map, ref Point3D p, bool surroundingsOnly ) + { + if( map == null ) //sanity + return false; + + if( !surroundingsOnly ) + { + if( map.CanSpawnMobile( p ) ) //p's fine. + { + p = new Point3D( p ); + return true; + } + + int z = map.GetAverageZ( p.X, p.Y ); + + if( map.CanSpawnMobile( p.X, p.Y, z ) ) + { + p = new Point3D( p.X, p.Y, z ); + return true; + } + } + + int offset = Utility.Random( 8 ) * 2; + + for( int i = 0; i < m_Offsets.Length; i += 2 ) + { + int x = p.X + m_Offsets[(offset + i) % m_Offsets.Length]; + int y = p.Y + m_Offsets[(offset + i + 1) % m_Offsets.Length]; + + if( map.CanSpawnMobile( x, y, p.Z ) ) + { + p = new Point3D( x, y, p.Z ); + return true; + } + else + { + int z = map.GetAverageZ( x, y ); + + if( map.CanSpawnMobile( x, y, z ) ) + { + p = new Point3D( x, y, z ); + return true; + } + } + } + + return false; + } + private delegate bool TravelValidator( Map map, Point3D loc ); private static TravelValidator[] m_Validators = new TravelValidator[] @@ -789,9 +853,6 @@ namespace Server.Spells { int iDamage = (int)damage; - if( Evasion.CheckSpellEvasion( target ) ) - iDamage = 0; - if( delay == TimeSpan.Zero ) { if( from is BaseCreature ) @@ -844,9 +905,6 @@ namespace Server.Spells { int iDamage = (int)damage; - if( Evasion.CheckSpellEvasion( target ) ) - iDamage = 0; - if( delay == TimeSpan.Zero ) { if( from is BaseCreature ) @@ -868,6 +926,16 @@ namespace Server.Spells ((BaseCreature)target).OnDamagedBySpell( from ); } + public static void Heal( int amount, Mobile target, Mobile from ) + { + Heal( amount, target, from, true ); + } + public static void Heal( int amount, Mobile target, Mobile from, bool message ) + { + //TODO: All Healing *spells* go through ArcaneEmpowerment + target.Heal( amount, from, message ); + } + private class SpellDamageTimer : Timer { private Mobile m_Target, m_From; @@ -950,4 +1018,244 @@ namespace Server.Spells } } } + + public class TransformationSpellHelper + { + #region Context Stuff + private static Dictionary m_Table = new Dictionary(); + + public static void AddContext( Mobile m, TransformContext context ) + { + m_Table[m] = context; + } + + public static void RemoveContext( Mobile m, bool resetGraphics ) + { + TransformContext context = GetContext( m ); + + if( context != null ) + RemoveContext( m, context, resetGraphics ); + } + + public static void RemoveContext( Mobile m, TransformContext context, bool resetGraphics ) + { + if( m_Table.ContainsKey( m ) ) + { + m_Table.Remove( m ); + + List mods = context.Mods; + + for( int i = 0; i < mods.Count; ++i ) + m.RemoveResistanceMod( mods[i] ); + + if( resetGraphics ) + { + m.HueMod = -1; + m.BodyMod = 0; + } + + context.Timer.Stop(); + context.Spell.RemoveEffect( m ); + } + } + + public static TransformContext GetContext( Mobile m ) + { + TransformContext context = null; + + m_Table.TryGetValue( m, out context ); + + return context; + } + + public static bool UnderTransformation( Mobile m ) + { + return (GetContext( m ) != null); + } + + public static bool UnderTransformation( Mobile m, Type type ) + { + TransformContext context = GetContext( m ); + + return (context != null && context.Type == type); + } + #endregion + + public static bool CheckCast( Mobile caster, Spell spell ) + { + if( Factions.Sigil.ExistsOn( caster ) ) + { + caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil. + return false; + } + else if( !caster.CanBeginAction( typeof( PolymorphSpell ) ) ) + { + caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed. + return false; + } + else if( AnimalForm.UnderTransformation( caster ) ) + { + caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form. + return false; + } + + return true; + } + + public static bool OnCast( Mobile caster, Spell spell ) + { + ITransformationSpell transformSpell = spell as ITransformationSpell; + + if( transformSpell == null ) + return false; + + if( Factions.Sigil.ExistsOn( caster ) ) + { + caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil. + } + else if( !caster.CanBeginAction( typeof( PolymorphSpell ) ) ) + { + caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed. + } + else if( AnimalForm.UnderTransformation( caster ) ) + { + caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form. + } + else if( !caster.CanBeginAction( typeof( IncognitoSpell ) ) || (caster.IsBodyMod && GetContext( caster ) == null) ) + { + spell.DoFizzle(); + } + else if( spell.CheckSequence() ) + { + TransformContext context = GetContext( caster ); + Type ourType = spell.GetType(); + + bool wasTransformed = (context != null); + bool ourTransform = (wasTransformed && context.Type == ourType); + + if( wasTransformed ) + { + RemoveContext( caster, context, ourTransform ); + + if( ourTransform ) + { + caster.PlaySound( 0xFA ); + caster.FixedParticles( 0x3728, 1, 13, 5042, EffectLayer.Waist ); + } + } + + if( !ourTransform ) + { + List mods = new List(); + + if( transformSpell.PhysResistOffset != 0 ) + mods.Add( new ResistanceMod( ResistanceType.Physical, transformSpell.PhysResistOffset ) ); + + if( transformSpell.FireResistOffset != 0 ) + mods.Add( new ResistanceMod( ResistanceType.Fire, transformSpell.FireResistOffset ) ); + + if( transformSpell.ColdResistOffset != 0 ) + mods.Add( new ResistanceMod( ResistanceType.Cold, transformSpell.ColdResistOffset ) ); + + if( transformSpell.PoisResistOffset != 0 ) + mods.Add( new ResistanceMod( ResistanceType.Poison, transformSpell.PoisResistOffset ) ); + + if( transformSpell.NrgyResistOffset != 0 ) + mods.Add( new ResistanceMod( ResistanceType.Energy, transformSpell.NrgyResistOffset ) ); + + if( !((Body)transformSpell.Body).IsHuman ) + { + Mobiles.IMount mt = caster.Mount; + + if( mt != null ) + mt.Rider = null; + } + + caster.BodyMod = transformSpell.Body; + caster.HueMod = transformSpell.Hue; + + for( int i = 0; i < mods.Count; ++i ) + caster.AddResistanceMod( mods[i] ); + + transformSpell.DoEffect( caster ); + + Timer timer = new TransformTimer( caster, transformSpell ); + timer.Start(); + + AddContext( caster, new TransformContext( timer, mods, ourType, transformSpell ) ); + return true; + } + } + + return false; + } + } + + public interface ITransformationSpell + { + int Body { get; } + int Hue { get; } + + int PhysResistOffset { get; } + int FireResistOffset { get; } + int ColdResistOffset { get; } + int PoisResistOffset { get; } + int NrgyResistOffset { get; } + + double TickRate { get; } + void OnTick( Mobile m ); + + void DoEffect( Mobile m ); + void RemoveEffect( Mobile m ); + } + + + public class TransformContext + { + private Timer m_Timer; + private List m_Mods; + private Type m_Type; + private ITransformationSpell m_Spell; + + public Timer Timer { get { return m_Timer; } } + public List Mods { get { return m_Mods; } } + public Type Type { get { return m_Type; } } + public ITransformationSpell Spell { get { return m_Spell; } } + + public TransformContext( Timer timer, List mods, Type type, ITransformationSpell spell ) + { + m_Timer = timer; + m_Mods = mods; + m_Type = type; + m_Spell = spell; + } + } + + public class TransformTimer : Timer + { + private Mobile m_Mobile; + private ITransformationSpell m_Spell; + + public TransformTimer( Mobile from, ITransformationSpell spell ) + : base( TimeSpan.FromSeconds( spell.TickRate ), TimeSpan.FromSeconds( spell.TickRate ) ) + { + m_Mobile = from; + m_Spell = spell; + + Priority = TimerPriority.TwoFiftyMS; + } + + protected override void OnTick() + { + if( m_Mobile.Deleted || !m_Mobile.Alive || m_Mobile.Body != m_Spell.Body || m_Mobile.Hue != m_Spell.Hue ) + { + TransformationSpellHelper.RemoveContext( m_Mobile, true ); + Stop(); + } + else + { + m_Spell.OnTick( m_Mobile ); + } + } + } } diff --git a/Scripts/Spells/Base/SpellInfo.cs b/Scripts/Spells/Base/SpellInfo.cs index 7e4d6bf28..47b2491e8 100644 --- a/Scripts/Spells/Base/SpellInfo.cs +++ b/Scripts/Spells/Base/SpellInfo.cs @@ -7,42 +7,40 @@ namespace Server.Spells { private string m_Name; private string m_Mantra; - private SpellCircle m_Circle; private Type[] m_Reagents; private int[] m_Amounts; private int m_Action; private bool m_AllowTown; private int m_LeftHandEffect, m_RightHandEffect; - public SpellInfo( string name, string mantra, SpellCircle circle, params Type[] regs ) : this( name, mantra, circle, 16, 0, 0, true, regs ) + public SpellInfo( string name, string mantra, params Type[] regs ) : this( name, mantra, 16, 0, 0, true, regs ) { } - public SpellInfo( string name, string mantra, SpellCircle circle, bool allowTown, params Type[] regs ) : this( name, mantra, circle, 16, 0, 0, allowTown, regs ) + public SpellInfo( string name, string mantra, bool allowTown, params Type[] regs ) : this( name, mantra, 16, 0, 0, allowTown, regs ) { } - public SpellInfo( string name, string mantra, SpellCircle circle, int action, params Type[] regs ) : this( name, mantra, circle, action, 0, 0, true, regs ) + public SpellInfo( string name, string mantra, int action, params Type[] regs ) : this( name, mantra, action, 0, 0, true, regs ) { } - public SpellInfo( string name, string mantra, SpellCircle circle, int action, bool allowTown, params Type[] regs ) : this( name, mantra, circle, action, 0, 0, allowTown, regs ) + public SpellInfo( string name, string mantra, int action, bool allowTown, params Type[] regs ) : this( name, mantra, action, 0, 0, allowTown, regs ) { } - public SpellInfo( string name, string mantra, SpellCircle circle, int action, int handEffect, params Type[] regs ) : this( name, mantra, circle, action, handEffect, handEffect, true, regs ) + public SpellInfo( string name, string mantra, int action, int handEffect, params Type[] regs ) : this( name, mantra, action, handEffect, handEffect, true, regs ) { } - public SpellInfo( string name, string mantra, SpellCircle circle, int action, int handEffect, bool allowTown, params Type[] regs ) : this( name, mantra, circle, action, handEffect, handEffect, allowTown, regs ) + public SpellInfo( string name, string mantra, int action, int handEffect, bool allowTown, params Type[] regs ) : this( name, mantra, action, handEffect, handEffect, allowTown, regs ) { } - public SpellInfo( string name, string mantra, SpellCircle circle, int action, int leftHandEffect, int rightHandEffect, bool allowTown, params Type[] regs ) + public SpellInfo( string name, string mantra, int action, int leftHandEffect, int rightHandEffect, bool allowTown, params Type[] regs ) { m_Name = name; m_Mantra = mantra; - m_Circle = circle; m_Action = action; m_Reagents = regs; m_AllowTown = allowTown; @@ -59,7 +57,6 @@ namespace Server.Spells public int Action{ get{ return m_Action; } set{ m_Action = value; } } public bool AllowTown{ get{ return m_AllowTown; } set{ m_AllowTown = value; } } public int[] Amounts{ get{ return m_Amounts; } set{ m_Amounts = value; } } - public SpellCircle Circle{ get{ return m_Circle; } set{ m_Circle = value; } } public string Mantra{ get{ return m_Mantra; } set{ m_Mantra = value; } } public string Name{ get{ return m_Name; } set{ m_Name = value; } } public Type[] Reagents{ get{ return m_Reagents; } set{ m_Reagents = value; } } diff --git a/Scripts/Spells/Base/SpellRegistry.cs b/Scripts/Spells/Base/SpellRegistry.cs index bd66d354c..80fa2c532 100644 --- a/Scripts/Spells/Base/SpellRegistry.cs +++ b/Scripts/Spells/Base/SpellRegistry.cs @@ -11,7 +11,7 @@ namespace Server.Spells { public class SpellRegistry { - private static Type[] m_Types = new Type[600]; + private static Type[] m_Types = new Type[700]; private static int m_Count; public static Type[] Types @@ -146,7 +146,8 @@ namespace Server.Spells "Necromancy", "Chivalry", "Bushido", - "Ninjitsu" + "Ninjitsu", + "SpellWeaving" }; public static Spell NewSpell( string name, Mobile caster, Item scroll ) diff --git a/Scripts/Spells/Bushido/Confidence.cs b/Scripts/Spells/Bushido/Confidence.cs index 8d5cbcb30..48b7e0241 100644 --- a/Scripts/Spells/Bushido/Confidence.cs +++ b/Scripts/Spells/Bushido/Confidence.cs @@ -10,11 +10,12 @@ namespace Server.Spells.Bushido { private static SpellInfo m_Info = new SpellInfo( "Confidence", null, - SpellCircle.First, // 0 + 0.25 = 0.25s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.25 ); } } + public override double RequiredSkill{ get{ return 25.0; } } public override int RequiredMana{ get{ return 10; } } diff --git a/Scripts/Spells/Bushido/CounterAttack.cs b/Scripts/Spells/Bushido/CounterAttack.cs index e0cdcf453..f0ce431ed 100644 --- a/Scripts/Spells/Bushido/CounterAttack.cs +++ b/Scripts/Spells/Bushido/CounterAttack.cs @@ -11,11 +11,12 @@ namespace Server.Spells.Bushido { private static SpellInfo m_Info = new SpellInfo( "CounterAttack", null, - SpellCircle.First, // 0 + 0.25 = 0.25s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.25 ); } } + public override double RequiredSkill{ get{ return 40.0; } } public override int RequiredMana{ get{ return 5; } } diff --git a/Scripts/Spells/Bushido/Evasion.cs b/Scripts/Spells/Bushido/Evasion.cs index 1e45c1769..2a06fa25d 100644 --- a/Scripts/Spells/Bushido/Evasion.cs +++ b/Scripts/Spells/Bushido/Evasion.cs @@ -11,11 +11,12 @@ namespace Server.Spells.Bushido { private static SpellInfo m_Info = new SpellInfo( "Evasion", null, - SpellCircle.First, // 0 + 0.25 = 0.25s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.25 ); } } + public override double RequiredSkill { get { return 60.0; } } public override int RequiredMana { get { return 10; } } diff --git a/Scripts/Spells/Bushido/SamuraiMove.cs b/Scripts/Spells/Bushido/SamuraiMove.cs index b165d17a5..69215379f 100644 --- a/Scripts/Spells/Bushido/SamuraiMove.cs +++ b/Scripts/Spells/Bushido/SamuraiMove.cs @@ -6,5 +6,10 @@ namespace Server.Spells public class SamuraiMove : SpecialMove { public override SkillName MoveSkill{ get{ return SkillName.Bushido; } } + + public override void CheckGain( Mobile m ) + { + m.CheckSkill( MoveSkill, RequiredSkill - 12.5, RequiredSkill + 37.5 ); //Per five on friday 02/16/07 + } } } \ No newline at end of file diff --git a/Scripts/Spells/Bushido/SamuraiSpell.cs b/Scripts/Spells/Bushido/SamuraiSpell.cs index 830f40811..a11fb54bb 100644 --- a/Scripts/Spells/Bushido/SamuraiSpell.cs +++ b/Scripts/Spells/Bushido/SamuraiSpell.cs @@ -18,8 +18,8 @@ namespace Server.Spells.Bushido public override bool BlocksMovement{ get{ return false; } } public override bool ShowHandMovement{ get{ return false; } } - public override int CastDelayBase{ get{ return 1; } } - public override int CastDelayFastScalar{ get{ return 0; } } + //public override int CastDelayBase{ get{ return 1; } } + public override double CastDelayFastScalar{ get{ return 0; } } public override int CastRecoveryBase{ get{ return 7; } } @@ -35,7 +35,8 @@ namespace Server.Spells.Bushido if ( from.NetState == null ) return false; - return ( (from.NetState.Flags & 0x10) != 0 ); + //return ( (from.NetState.Flags & 0x10) != 0 ); + return from.NetState.SupportsExpansion( Expansion.SE ); } public override bool CheckCast() @@ -89,7 +90,7 @@ namespace Server.Spells.Bushido public override void GetCastSkills( out double min, out double max ) { - min = RequiredSkill; + min = RequiredSkill - 12.5; //per 5 on friday, 2/16/07 max = RequiredSkill + 37.5; } diff --git a/Scripts/Spells/Chivalry/CleanseByFire.cs b/Scripts/Spells/Chivalry/CleanseByFire.cs index 4ea0bff8d..1e9831558 100644 --- a/Scripts/Spells/Chivalry/CleanseByFire.cs +++ b/Scripts/Spells/Chivalry/CleanseByFire.cs @@ -10,11 +10,12 @@ namespace Server.Spells.Chivalry { private static SpellInfo m_Info = new SpellInfo( "Cleanse By Fire", "Expor Flamus", - SpellCircle.Fourth, // 0 + 1.0 = 1s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } } + public override double RequiredSkill{ get{ return 5.0; } } public override int RequiredMana{ get{ return 10; } } public override int RequiredTithing{ get{ return 10; } } diff --git a/Scripts/Spells/Chivalry/CloseWounds.cs b/Scripts/Spells/Chivalry/CloseWounds.cs index 0d0cb811b..6b2eb6a3a 100644 --- a/Scripts/Spells/Chivalry/CloseWounds.cs +++ b/Scripts/Spells/Chivalry/CloseWounds.cs @@ -11,11 +11,12 @@ namespace Server.Spells.Chivalry { private static SpellInfo m_Info = new SpellInfo( "Close Wounds", "Obsu Vulni", - SpellCircle.Sixth, // 0 + 1.5 = 1.5s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + public override double RequiredSkill{ get{ return 0.0; } } public override int RequiredMana{ get{ return 10; } } public override int RequiredTithing{ get{ return 10; } } @@ -71,7 +72,9 @@ namespace Server.Spells.Chivalry if ( (m.Hits + toHeal) > m.HitsMax ) toHeal = m.HitsMax - m.Hits; - m.Hits += toHeal; + //m.Hits += toHeal; //Was previosuly due to the message + //m.Heal( toHeal, Caster, false ); + SpellHelper.Heal( toHeal, m, Caster, false ); m.SendLocalizedMessage( 1060203, toHeal.ToString() ); // You have had ~1_HEALED_AMOUNT~ hit points of damage healed. diff --git a/Scripts/Spells/Chivalry/ConsecrateWeapon.cs b/Scripts/Spells/Chivalry/ConsecrateWeapon.cs index f26bef5b0..db592fc1b 100644 --- a/Scripts/Spells/Chivalry/ConsecrateWeapon.cs +++ b/Scripts/Spells/Chivalry/ConsecrateWeapon.cs @@ -10,11 +10,12 @@ namespace Server.Spells.Chivalry { private static SpellInfo m_Info = new SpellInfo( "Consecrate Weapon", "Consecrus Arma", - SpellCircle.Second, // 0 + 0.5 = 0.5s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.5 ); } } + public override double RequiredSkill{ get{ return 15.0; } } public override int RequiredMana{ get{ return 10; } } public override int RequiredTithing{ get{ return 10; } } diff --git a/Scripts/Spells/Chivalry/DispelEvil.cs b/Scripts/Spells/Chivalry/DispelEvil.cs index 8b7920cef..f2e01a2a5 100644 --- a/Scripts/Spells/Chivalry/DispelEvil.cs +++ b/Scripts/Spells/Chivalry/DispelEvil.cs @@ -12,11 +12,12 @@ namespace Server.Spells.Chivalry { private static SpellInfo m_Info = new SpellInfo( "Dispel Evil", "Dispiro Malas", - SpellCircle.First, // 0 + 0.25 = 0.25s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.25 ); } } + public override double RequiredSkill{ get{ return 35.0; } } public override int RequiredMana{ get{ return 10; } } public override int RequiredTithing{ get{ return 10; } } @@ -93,7 +94,8 @@ namespace Server.Spells.Chivalry } } - if ( TransformationSpell.GetContext( m ) != null ) + TransformContext context = TransformationSpellHelper.GetContext( m ); + if( context != null && context.Spell is NecromancerSpell ) //Trees are not evil! TODO: OSI confirm? { // transformed .. diff --git a/Scripts/Spells/Chivalry/DivineFury.cs b/Scripts/Spells/Chivalry/DivineFury.cs index ca9728d94..530badb09 100644 --- a/Scripts/Spells/Chivalry/DivineFury.cs +++ b/Scripts/Spells/Chivalry/DivineFury.cs @@ -10,11 +10,12 @@ namespace Server.Spells.Chivalry { private static SpellInfo m_Info = new SpellInfo( "Divine Fury", "Divinum Furis", - SpellCircle.Fourth, // 0 + 1.0 = 1s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } } + public override double RequiredSkill{ get{ return 25.0; } } public override int RequiredMana{ get{ return 15; } } public override int RequiredTithing{ get{ return 10; } } diff --git a/Scripts/Spells/Chivalry/EnemyOfOne.cs b/Scripts/Spells/Chivalry/EnemyOfOne.cs index dc1456652..d1490c47e 100644 --- a/Scripts/Spells/Chivalry/EnemyOfOne.cs +++ b/Scripts/Spells/Chivalry/EnemyOfOne.cs @@ -12,11 +12,12 @@ namespace Server.Spells.Chivalry { private static SpellInfo m_Info = new SpellInfo( "Enemy of One", "Forul Solum", - SpellCircle.Second, // 0 + 0.5 = 0.5s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.5 ); } } + public override double RequiredSkill{ get{ return 45.0; } } public override int RequiredMana{ get{ return 20; } } public override int RequiredTithing{ get{ return 10; } } diff --git a/Scripts/Spells/Chivalry/HolyLight.cs b/Scripts/Spells/Chivalry/HolyLight.cs index e2200e075..070c67132 100644 --- a/Scripts/Spells/Chivalry/HolyLight.cs +++ b/Scripts/Spells/Chivalry/HolyLight.cs @@ -10,11 +10,12 @@ namespace Server.Spells.Chivalry { private static SpellInfo m_Info = new SpellInfo( "Holy Light", "Augus Luminos", - SpellCircle.Seventh, // 0 + 1.75 = 1.75s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.75 ); } } + public override double RequiredSkill{ get{ return 55.0; } } public override int RequiredMana{ get{ return 10; } } public override int RequiredTithing{ get{ return 10; } } diff --git a/Scripts/Spells/Chivalry/NobleSacrifice.cs b/Scripts/Spells/Chivalry/NobleSacrifice.cs index 13f3ce143..0ca3dc1df 100644 --- a/Scripts/Spells/Chivalry/NobleSacrifice.cs +++ b/Scripts/Spells/Chivalry/NobleSacrifice.cs @@ -16,11 +16,12 @@ namespace Server.Spells.Chivalry { private static SpellInfo m_Info = new SpellInfo( "Noble Sacrifice", "Dium Prostra", - SpellCircle.Sixth, // 0 + 1.5 = 1.5s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + public override double RequiredSkill{ get{ return 65.0; } } public override int RequiredMana{ get{ return 20; } } public override int RequiredTithing{ get{ return 30; } } @@ -109,7 +110,7 @@ namespace Server.Spells.Chivalry toHeal = 24; Caster.DoBeneficial( m ); - m.Heal( toHeal ); + m.Heal( toHeal, Caster ); sendEffect = true; } diff --git a/Scripts/Spells/Chivalry/PaladinSpell.cs b/Scripts/Spells/Chivalry/PaladinSpell.cs index fbc9abd7c..0d9d436fc 100644 --- a/Scripts/Spells/Chivalry/PaladinSpell.cs +++ b/Scripts/Spells/Chivalry/PaladinSpell.cs @@ -16,7 +16,7 @@ namespace Server.Spells.Chivalry public override bool ClearHandsOnCast{ get{ return false; } } - public override int CastDelayBase{ get{ return 1; } } + //public override int CastDelayBase{ get{ return 1; } } public override int CastRecoveryBase{ get{ return 7; } } diff --git a/Scripts/Spells/Chivalry/RemoveCurse.cs b/Scripts/Spells/Chivalry/RemoveCurse.cs index 86b1d0310..eac0f7d61 100644 --- a/Scripts/Spells/Chivalry/RemoveCurse.cs +++ b/Scripts/Spells/Chivalry/RemoveCurse.cs @@ -12,11 +12,12 @@ namespace Server.Spells.Chivalry { private static SpellInfo m_Info = new SpellInfo( "Remove Curse", "Extermo Vomica", - SpellCircle.Sixth, // 0 + 1.5 = 1.5s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + public override double RequiredSkill{ get{ return 5.0; } } public override int RequiredMana{ get{ return 20; } } public override int RequiredTithing{ get{ return 10; } } diff --git a/Scripts/Spells/Chivalry/SacredJourney.cs b/Scripts/Spells/Chivalry/SacredJourney.cs index 0784cf90f..66e3d0406 100644 --- a/Scripts/Spells/Chivalry/SacredJourney.cs +++ b/Scripts/Spells/Chivalry/SacredJourney.cs @@ -12,11 +12,12 @@ namespace Server.Spells.Chivalry { private static SpellInfo m_Info = new SpellInfo( "Sacred Journey", "Sanctum Viatas", - SpellCircle.Sixth, // 0 + 1.5 = 1.5s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + public override double RequiredSkill{ get{ return 15.0; } } public override int RequiredMana{ get{ return 10; } } public override int RequiredTithing{ get{ return 15; } } diff --git a/Scripts/Spells/Eighth/AirElemental.cs b/Scripts/Spells/Eighth/AirElemental.cs index 0bb79eed3..97c07f78c 100644 --- a/Scripts/Spells/Eighth/AirElemental.cs +++ b/Scripts/Spells/Eighth/AirElemental.cs @@ -5,11 +5,10 @@ using Server.Targeting; namespace Server.Spells.Eighth { - public class AirElementalSpell : Spell + public class AirElementalSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Air Elemental", "Kal Vas Xen Hur", - SpellCircle.Eighth, 269, 9010, false, @@ -18,6 +17,8 @@ namespace Server.Spells.Eighth Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Eighth; } } + public AirElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Eighth/EarthElemental.cs b/Scripts/Spells/Eighth/EarthElemental.cs index 4eb2ff30f..de871a020 100644 --- a/Scripts/Spells/Eighth/EarthElemental.cs +++ b/Scripts/Spells/Eighth/EarthElemental.cs @@ -5,11 +5,10 @@ using Server.Targeting; namespace Server.Spells.Eighth { - public class EarthElementalSpell : Spell + public class EarthElementalSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Earth Elemental", "Kal Vas Xen Ylem", - SpellCircle.Eighth, 269, 9020, false, @@ -18,6 +17,8 @@ namespace Server.Spells.Eighth Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Eighth; } } + public EarthElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Eighth/Earthquake.cs b/Scripts/Spells/Eighth/Earthquake.cs index e6d80f764..d00a7c930 100644 --- a/Scripts/Spells/Eighth/Earthquake.cs +++ b/Scripts/Spells/Eighth/Earthquake.cs @@ -6,11 +6,10 @@ using Server.Targeting; namespace Server.Spells.Eighth { - public class EarthquakeSpell : Spell + public class EarthquakeSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Earthquake", "In Vas Por", - SpellCircle.Eighth, 233, 9012, false, @@ -20,6 +19,8 @@ namespace Server.Spells.Eighth Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Eighth; } } + public EarthquakeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Eighth/EnergyVortex.cs b/Scripts/Spells/Eighth/EnergyVortex.cs index 119c72275..69b3d0060 100644 --- a/Scripts/Spells/Eighth/EnergyVortex.cs +++ b/Scripts/Spells/Eighth/EnergyVortex.cs @@ -5,11 +5,10 @@ using Server.Targeting; namespace Server.Spells.Eighth { - public class EnergyVortexSpell : Spell + public class EnergyVortexSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Energy Vortex", "Vas Corp Por", - SpellCircle.Eighth, 260, 9032, false, @@ -19,6 +18,8 @@ namespace Server.Spells.Eighth Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.Eighth; } } + public EnergyVortexSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Eighth/FireElemental.cs b/Scripts/Spells/Eighth/FireElemental.cs index 7f4136f7e..bfee23191 100644 --- a/Scripts/Spells/Eighth/FireElemental.cs +++ b/Scripts/Spells/Eighth/FireElemental.cs @@ -5,11 +5,10 @@ using Server.Targeting; namespace Server.Spells.Eighth { - public class FireElementalSpell : Spell + public class FireElementalSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Fire Elemental", "Kal Vas Xen Flam", - SpellCircle.Eighth, 269, 9050, false, @@ -19,6 +18,8 @@ namespace Server.Spells.Eighth Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Eighth; } } + public FireElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Eighth/Resurrection.cs b/Scripts/Spells/Eighth/Resurrection.cs index 1b938fdd5..20e427bb3 100644 --- a/Scripts/Spells/Eighth/Resurrection.cs +++ b/Scripts/Spells/Eighth/Resurrection.cs @@ -5,11 +5,10 @@ using Server.Gumps; namespace Server.Spells.Eighth { - public class ResurrectionSpell : Spell + public class ResurrectionSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Resurrection", "An Corp", - SpellCircle.Eighth, 245, 9062, Reagent.Bloodmoss, @@ -17,6 +16,8 @@ namespace Server.Spells.Eighth Reagent.Ginseng ); + public override SpellCircle Circle { get { return SpellCircle.Eighth; } } + public ResurrectionSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Eighth/SummonDaemon.cs b/Scripts/Spells/Eighth/SummonDaemon.cs index 3646909e6..558bbcfb2 100644 --- a/Scripts/Spells/Eighth/SummonDaemon.cs +++ b/Scripts/Spells/Eighth/SummonDaemon.cs @@ -5,11 +5,10 @@ using Server.Targeting; namespace Server.Spells.Eighth { - public class SummonDaemonSpell : Spell + public class SummonDaemonSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Summon Daemon", "Kal Vas Xen Corp", - SpellCircle.Eighth, 269, 9050, false, @@ -19,6 +18,8 @@ namespace Server.Spells.Eighth Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Eighth; } } + public SummonDaemonSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Eighth/WaterElemental.cs b/Scripts/Spells/Eighth/WaterElemental.cs index 786bb8656..34a018226 100644 --- a/Scripts/Spells/Eighth/WaterElemental.cs +++ b/Scripts/Spells/Eighth/WaterElemental.cs @@ -5,11 +5,10 @@ using Server.Targeting; namespace Server.Spells.Eighth { - public class WaterElementalSpell : Spell + public class WaterElementalSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Water Elemental", "Kal Vas Xen An Flam", - SpellCircle.Eighth, 269, 9070, false, @@ -18,6 +17,8 @@ namespace Server.Spells.Eighth Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Eighth; } } + public WaterElementalSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fifth/BladeSpirits.cs b/Scripts/Spells/Fifth/BladeSpirits.cs index c72c7b56b..92b17236c 100644 --- a/Scripts/Spells/Fifth/BladeSpirits.cs +++ b/Scripts/Spells/Fifth/BladeSpirits.cs @@ -5,11 +5,10 @@ using Server.Targeting; namespace Server.Spells.Fifth { - public class BladeSpiritsSpell : Spell + public class BladeSpiritsSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Blade Spirits", "In Jux Hur Ylem", - SpellCircle.Fifth, 266, 9040, false, @@ -18,6 +17,8 @@ namespace Server.Spells.Fifth Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.Fifth; } } + public BladeSpiritsSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fifth/DispelField.cs b/Scripts/Spells/Fifth/DispelField.cs index ffc162ed4..361f3db4c 100644 --- a/Scripts/Spells/Fifth/DispelField.cs +++ b/Scripts/Spells/Fifth/DispelField.cs @@ -6,11 +6,10 @@ using Server.Misc; namespace Server.Spells.Fifth { - public class DispelFieldSpell : Spell + public class DispelFieldSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Dispel Field", "An Grav", - SpellCircle.Fifth, 206, 9002, Reagent.BlackPearl, @@ -19,6 +18,8 @@ namespace Server.Spells.Fifth Reagent.Garlic ); + public override SpellCircle Circle { get { return SpellCircle.Fifth; } } + public DispelFieldSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fifth/Incognito.cs b/Scripts/Spells/Fifth/Incognito.cs index b00ee4be2..0905f3888 100644 --- a/Scripts/Spells/Fifth/Incognito.cs +++ b/Scripts/Spells/Fifth/Incognito.cs @@ -10,11 +10,10 @@ using Server.Spells.Seventh; namespace Server.Spells.Fifth { - public class IncognitoSpell : Spell + public class IncognitoSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Incognito", "Kal In Ex", - SpellCircle.Fifth, 206, 9002, Reagent.Bloodmoss, @@ -22,6 +21,8 @@ namespace Server.Spells.Fifth Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.Fifth; } } + public IncognitoSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fifth/MagicReflect.cs b/Scripts/Spells/Fifth/MagicReflect.cs index de1369d7b..8f5c75bd0 100644 --- a/Scripts/Spells/Fifth/MagicReflect.cs +++ b/Scripts/Spells/Fifth/MagicReflect.cs @@ -6,11 +6,10 @@ using Server.Network; namespace Server.Spells.Fifth { - public class MagicReflectSpell : Spell + public class MagicReflectSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Magic Reflection", "In Jux Sanct", - SpellCircle.Fifth, 242, 9012, Reagent.Garlic, @@ -18,6 +17,8 @@ namespace Server.Spells.Fifth Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Fifth; } } + public MagicReflectSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fifth/MindBlast.cs b/Scripts/Spells/Fifth/MindBlast.cs index 52068cc8b..f7ab401ad 100644 --- a/Scripts/Spells/Fifth/MindBlast.cs +++ b/Scripts/Spells/Fifth/MindBlast.cs @@ -4,11 +4,10 @@ using Server.Network; namespace Server.Spells.Fifth { - public class MindBlastSpell : Spell + public class MindBlastSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Mind Blast", "Por Corp Wis", - SpellCircle.Fifth, 218, Core.AOS ? 9002 : 9032, Reagent.BlackPearl, @@ -17,6 +16,8 @@ namespace Server.Spells.Fifth Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Fifth; } } + public MindBlastSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { if ( Core.AOS ) diff --git a/Scripts/Spells/Fifth/Paralyze.cs b/Scripts/Spells/Fifth/Paralyze.cs index 882d496bd..0498b1bf4 100644 --- a/Scripts/Spells/Fifth/Paralyze.cs +++ b/Scripts/Spells/Fifth/Paralyze.cs @@ -4,11 +4,10 @@ using Server.Network; namespace Server.Spells.Fifth { - public class ParalyzeSpell : Spell + public class ParalyzeSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Paralyze", "An Ex Por", - SpellCircle.Fifth, 218, 9012, Reagent.Garlic, @@ -16,6 +15,8 @@ namespace Server.Spells.Fifth Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Fifth; } } + public ParalyzeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } @@ -45,7 +46,7 @@ namespace Server.Spells.Fifth if ( Core.AOS ) { - int secs = (GetDamageFixed( Caster ) / 100) - (GetResistFixed( m ) / 100); + int secs = (int)((GetDamageSkill( Caster ) / 10) - (GetResistSkill( m ) / 10)); if( !Core.SE ) secs += 2; diff --git a/Scripts/Spells/Fifth/PoisonField.cs b/Scripts/Spells/Fifth/PoisonField.cs index e8100d8f8..d7f1f8ad9 100644 --- a/Scripts/Spells/Fifth/PoisonField.cs +++ b/Scripts/Spells/Fifth/PoisonField.cs @@ -7,11 +7,10 @@ using Server.Items; namespace Server.Spells.Fifth { - public class PoisonFieldSpell : Spell + public class PoisonFieldSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Poison Field", "In Nox Grav", - SpellCircle.Fifth, 230, 9052, false, @@ -20,6 +19,8 @@ namespace Server.Spells.Fifth Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Fifth; } } + public PoisonFieldSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fifth/SummonCreature.cs b/Scripts/Spells/Fifth/SummonCreature.cs index d4acf8ea0..fdd042c66 100644 --- a/Scripts/Spells/Fifth/SummonCreature.cs +++ b/Scripts/Spells/Fifth/SummonCreature.cs @@ -5,11 +5,10 @@ using Server.Targeting; namespace Server.Spells.Fifth { - public class SummonCreatureSpell : Spell + public class SummonCreatureSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Summon Creature", "Kal Xen", - SpellCircle.Fifth, 266, 9040, Reagent.Bloodmoss, @@ -17,6 +16,8 @@ namespace Server.Spells.Fifth Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Fifth; } } + public SummonCreatureSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/First/Clumsy.cs b/Scripts/Spells/First/Clumsy.cs index 66d31ef99..5230efed8 100644 --- a/Scripts/Spells/First/Clumsy.cs +++ b/Scripts/Spells/First/Clumsy.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.First { - public class ClumsySpell : Spell + public class ClumsySpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Clumsy", "Uus Jux", - SpellCircle.First, 212, 9031, Reagent.Bloodmoss, Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.First; } } + public ClumsySpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/First/CreateFood.cs b/Scripts/Spells/First/CreateFood.cs index e184ee251..81049a2f4 100644 --- a/Scripts/Spells/First/CreateFood.cs +++ b/Scripts/Spells/First/CreateFood.cs @@ -3,11 +3,10 @@ using Server.Items; namespace Server.Spells.First { - public class CreateFoodSpell : Spell + public class CreateFoodSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Create Food", "In Mani Ylem", - SpellCircle.First, 224, 9011, Reagent.Garlic, @@ -15,6 +14,8 @@ namespace Server.Spells.First Reagent.MandrakeRoot ); + public override SpellCircle Circle { get { return SpellCircle.First; } } + public CreateFoodSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/First/Feeblemind.cs b/Scripts/Spells/First/Feeblemind.cs index c8b7fac5c..309cef4a4 100644 --- a/Scripts/Spells/First/Feeblemind.cs +++ b/Scripts/Spells/First/Feeblemind.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.First { - public class FeeblemindSpell : Spell + public class FeeblemindSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Feeblemind", "Rel Wis", - SpellCircle.First, 212, 9031, Reagent.Ginseng, Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.First; } } + public FeeblemindSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/First/Heal.cs b/Scripts/Spells/First/Heal.cs index a630bcb1b..161fdd927 100644 --- a/Scripts/Spells/First/Heal.cs +++ b/Scripts/Spells/First/Heal.cs @@ -6,11 +6,10 @@ using Server.Mobiles; namespace Server.Spells.First { - public class HealSpell : Spell + public class HealSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Heal", "In Mani", - SpellCircle.First, 224, 9061, Reagent.Garlic, @@ -18,6 +17,8 @@ namespace Server.Spells.First Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.First; } } + public HealSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } @@ -69,7 +70,8 @@ namespace Server.Spells.First toHeal += Utility.Random( 1, 5 ); } - m.Heal( toHeal ); + //m.Heal( toHeal, Caster ); + SpellHelper.Heal( toHeal, m, Caster ); m.FixedParticles( 0x376A, 9, 32, 5005, EffectLayer.Waist ); m.PlaySound( 0x1F2 ); diff --git a/Scripts/Spells/First/MagicArrow.cs b/Scripts/Spells/First/MagicArrow.cs index 0e811db1d..036194e68 100644 --- a/Scripts/Spells/First/MagicArrow.cs +++ b/Scripts/Spells/First/MagicArrow.cs @@ -4,16 +4,17 @@ using Server.Network; namespace Server.Spells.First { - public class MagicArrowSpell : Spell + public class MagicArrowSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Magic Arrow", "In Por Ylem", - SpellCircle.First, 212, 9041, Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.First; } } + public MagicArrowSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/First/NightSight.cs b/Scripts/Spells/First/NightSight.cs index 9def601be..7ec4a37e4 100644 --- a/Scripts/Spells/First/NightSight.cs +++ b/Scripts/Spells/First/NightSight.cs @@ -5,17 +5,18 @@ using Server; namespace Server.Spells.First { - public class NightSightSpell : Spell + public class NightSightSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Night Sight", "In Lor", - SpellCircle.First, 236, 9031, Reagent.SulfurousAsh, Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.First; } } + public NightSightSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/First/ReactiveArmor.cs b/Scripts/Spells/First/ReactiveArmor.cs index 0412cf5e9..de2ec6a08 100644 --- a/Scripts/Spells/First/ReactiveArmor.cs +++ b/Scripts/Spells/First/ReactiveArmor.cs @@ -5,11 +5,10 @@ using Server.Network; namespace Server.Spells.First { - public class ReactiveArmorSpell : Spell + public class ReactiveArmorSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Reactive Armor", "Flam Sanct", - SpellCircle.First, 236, 9011, Reagent.Garlic, @@ -17,6 +16,8 @@ namespace Server.Spells.First Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.First; } } + public ReactiveArmorSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/First/Weaken.cs b/Scripts/Spells/First/Weaken.cs index 0481bf225..c1ced57ec 100644 --- a/Scripts/Spells/First/Weaken.cs +++ b/Scripts/Spells/First/Weaken.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.First { - public class WeakenSpell : Spell + public class WeakenSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Weaken", "Des Mani", - SpellCircle.First, 212, 9031, Reagent.Garlic, Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.First; } } + public WeakenSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fourth/ArchCure.cs b/Scripts/Spells/Fourth/ArchCure.cs index e7bbeb4fc..16214ba87 100644 --- a/Scripts/Spells/Fourth/ArchCure.cs +++ b/Scripts/Spells/Fourth/ArchCure.cs @@ -6,11 +6,10 @@ using Server.Targeting; namespace Server.Spells.Fourth { - public class ArchCureSpell : Spell + public class ArchCureSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Arch Cure", "Vas An Nox", - SpellCircle.Fourth, 215, 9061, Reagent.Garlic, @@ -18,6 +17,8 @@ namespace Server.Spells.Fourth Reagent.MandrakeRoot ); + public override SpellCircle Circle { get { return SpellCircle.Fourth; } } + public ArchCureSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } @@ -28,7 +29,7 @@ namespace Server.Spells.Fourth } // Archcure is now 1/4th of a second faster - public override int CastDelayBase{ get{ return base.CastDelayBase - 1; } } + public override TimeSpan CastDelayBase{ get{ return base.CastDelayBase - TimeSpan.FromSeconds( 0.25 ); } } public void Target( IPoint3D p ) { diff --git a/Scripts/Spells/Fourth/ArchProtection.cs b/Scripts/Spells/Fourth/ArchProtection.cs index 94d8958cb..0547142c0 100644 --- a/Scripts/Spells/Fourth/ArchProtection.cs +++ b/Scripts/Spells/Fourth/ArchProtection.cs @@ -7,11 +7,10 @@ using Server.Engines.PartySystem; namespace Server.Spells.Fourth { - public class ArchProtectionSpell : Spell + public class ArchProtectionSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Arch Protection", "Vas Uus Sanct", - SpellCircle.Fourth, Core.AOS ? 239 : 215, 9011, Reagent.Garlic, @@ -20,6 +19,8 @@ namespace Server.Spells.Fourth Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Fourth; } } + public ArchProtectionSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fourth/Curse.cs b/Scripts/Spells/Fourth/Curse.cs index 7366a8c54..4153a9e08 100644 --- a/Scripts/Spells/Fourth/Curse.cs +++ b/Scripts/Spells/Fourth/Curse.cs @@ -5,11 +5,10 @@ using Server.Network; namespace Server.Spells.Fourth { - public class CurseSpell : Spell + public class CurseSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Curse", "Des Sanct", - SpellCircle.Fourth, 227, 9031, Reagent.Nightshade, @@ -17,6 +16,8 @@ namespace Server.Spells.Fourth Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Fourth; } } + public CurseSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fourth/FireField.cs b/Scripts/Spells/Fourth/FireField.cs index 89ad623ea..ab95cdfbc 100644 --- a/Scripts/Spells/Fourth/FireField.cs +++ b/Scripts/Spells/Fourth/FireField.cs @@ -7,11 +7,10 @@ using Server.Items; namespace Server.Spells.Fourth { - public class FireFieldSpell : Spell + public class FireFieldSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Fire Field", "In Flam Grav", - SpellCircle.Fourth, 215, 9041, false, @@ -20,6 +19,8 @@ namespace Server.Spells.Fourth Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Fourth; } } + public FireFieldSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } @@ -80,7 +81,7 @@ namespace Server.Spells.Fourth { Point3D loc = new Point3D( eastToWest ? p.X + i : p.X, eastToWest ? p.Y : p.Y + i, p.Z ); - new InternalItem( itemID, loc, Caster, Caster.Map, duration, i ); + new FireFieldItem( itemID, loc, Caster, Caster.Map, duration, i ); } } @@ -88,15 +89,21 @@ namespace Server.Spells.Fourth } [DispellableField] - private class InternalItem : Item + public class FireFieldItem : Item { private Timer m_Timer; private DateTime m_End; private Mobile m_Caster; + private int m_Damage; public override bool BlocksFit{ get{ return true; } } - public InternalItem( int itemID, Point3D loc, Mobile caster, Map map, TimeSpan duration, int val ) : base( itemID ) + public FireFieldItem( int itemID, Point3D loc, Mobile caster, Map map, TimeSpan duration, int val ) + : this( itemID, loc, caster, map, duration, val, 2 ) + { + } + + public FireFieldItem( int itemID, Point3D loc, Mobile caster, Map map, TimeSpan duration, int val, int damage ) : base( itemID ) { bool canFit = SpellHelper.AdjustField( ref loc, map, 12, false ); @@ -108,6 +115,8 @@ namespace Server.Spells.Fourth m_Caster = caster; + m_Damage = damage; + m_End = DateTime.Now + duration; m_Timer = new InternalTimer( this, TimeSpan.FromSeconds( Math.Abs( val ) * 0.2 ), caster.InLOS( this ), canFit ); @@ -122,7 +131,7 @@ namespace Server.Spells.Fourth m_Timer.Stop(); } - public InternalItem( Serial serial ) : base( serial ) + public FireFieldItem( Serial serial ) : base( serial ) { } @@ -130,8 +139,9 @@ namespace Server.Spells.Fourth { base.Serialize( writer ); - writer.Write( (int) 1 ); // version + writer.Write( (int) 2 ); // version + writer.Write( m_Damage ); writer.Write( m_Caster ); writer.WriteDeltaTime( m_End ); } @@ -144,6 +154,11 @@ namespace Server.Spells.Fourth switch ( version ) { + case 2: + { + m_Damage = reader.ReadInt(); + goto case 1; + } case 1: { m_Caster = reader.ReadMobile(); @@ -160,6 +175,9 @@ namespace Server.Spells.Fourth break; } } + + if( version < 2 ) + m_Damage = 2; } public override bool OnMoveOver( Mobile m ) @@ -168,7 +186,7 @@ namespace Server.Spells.Fourth { m_Caster.DoHarmful( m ); - int damage = 2; + int damage = m_Damage; if ( !Core.AOS && m.CheckSkill( SkillName.MagicResist, 0.0, 30.0 ) ) { @@ -186,12 +204,12 @@ namespace Server.Spells.Fourth private class InternalTimer : Timer { - private InternalItem m_Item; + private FireFieldItem m_Item; private bool m_InLOS, m_CanFit; private static Queue m_Queue = new Queue(); - public InternalTimer( InternalItem item, TimeSpan delay, bool inLOS, bool canFit ) : base( delay, TimeSpan.FromSeconds( 1.0 ) ) + public InternalTimer( FireFieldItem item, TimeSpan delay, bool inLOS, bool canFit ) : base( delay, TimeSpan.FromSeconds( 1.0 ) ) { m_Item = item; m_InLOS = inLOS; @@ -242,7 +260,7 @@ namespace Server.Spells.Fourth caster.DoHarmful( m ); - int damage = 2; + int damage = m_Item.m_Damage; if ( !Core.AOS && m.CheckSkill( SkillName.MagicResist, 0.0, 30.0 ) ) { diff --git a/Scripts/Spells/Fourth/GreaterHeal.cs b/Scripts/Spells/Fourth/GreaterHeal.cs index 4b5dc939a..9ccd7480c 100644 --- a/Scripts/Spells/Fourth/GreaterHeal.cs +++ b/Scripts/Spells/Fourth/GreaterHeal.cs @@ -6,11 +6,10 @@ using Server.Mobiles; namespace Server.Spells.Fourth { - public class GreaterHealSpell : Spell + public class GreaterHealSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Greater Heal", "In Vas Mani", - SpellCircle.Fourth, 204, 9061, Reagent.Garlic, @@ -19,6 +18,8 @@ namespace Server.Spells.Fourth Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Fourth; } } + public GreaterHealSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } @@ -59,7 +60,8 @@ namespace Server.Spells.Fourth int toHeal = (int)(Caster.Skills[SkillName.Magery].Value * 0.4); toHeal += Utility.Random( 1, 10 ); - m.Heal( toHeal ); + //m.Heal( toHeal, Caster ); + SpellHelper.Heal( toHeal, m, Caster ); m.FixedParticles( 0x376A, 9, 32, 5030, EffectLayer.Waist ); m.PlaySound( 0x202 ); diff --git a/Scripts/Spells/Fourth/Lightning.cs b/Scripts/Spells/Fourth/Lightning.cs index c4899551b..1eeb113d1 100644 --- a/Scripts/Spells/Fourth/Lightning.cs +++ b/Scripts/Spells/Fourth/Lightning.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.Fourth { - public class LightningSpell : Spell + public class LightningSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Lightning", "Por Ort Grav", - SpellCircle.Fourth, 239, 9021, Reagent.MandrakeRoot, Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Fourth; } } + public LightningSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fourth/ManaDrain.cs b/Scripts/Spells/Fourth/ManaDrain.cs index 5e0b45ee8..bb18fdb26 100644 --- a/Scripts/Spells/Fourth/ManaDrain.cs +++ b/Scripts/Spells/Fourth/ManaDrain.cs @@ -5,11 +5,10 @@ using Server.Targeting; namespace Server.Spells.Fourth { - public class ManaDrainSpell : Spell + public class ManaDrainSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Mana Drain", "Ort Rel", - SpellCircle.Fourth, 215, 9031, Reagent.BlackPearl, @@ -17,6 +16,8 @@ namespace Server.Spells.Fourth Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Fourth; } } + public ManaDrainSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Fourth/Recall.cs b/Scripts/Spells/Fourth/Recall.cs index 3ea79bd34..ec48954ed 100644 --- a/Scripts/Spells/Fourth/Recall.cs +++ b/Scripts/Spells/Fourth/Recall.cs @@ -9,11 +9,10 @@ using Server.Spells.Necromancy; namespace Server.Spells.Fourth { - public class RecallSpell : Spell + public class RecallSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Recall", "Kal Ort Por", - SpellCircle.Fourth, 239, 9031, Reagent.BlackPearl, @@ -21,6 +20,8 @@ namespace Server.Spells.Fourth Reagent.MandrakeRoot ); + public override SpellCircle Circle { get { return SpellCircle.Fourth; } } + private RunebookEntry m_Entry; private Runebook m_Book; @@ -36,7 +37,7 @@ namespace Server.Spells.Fourth public override void GetCastSkills( out double min, out double max ) { - if ( TransformationSpell.UnderTransformation( Caster, typeof( WraithFormSpell ) ) ) + if ( TransformationSpellHelper.UnderTransformation( Caster, typeof( WraithFormSpell ) ) ) min = max = 0; else if( Core.SE && m_Book != null ) //recall using Runebook charge min = max = 0; diff --git a/Scripts/Spells/Initializer.cs b/Scripts/Spells/Initializer.cs index 333f83adb..25cefded4 100644 --- a/Scripts/Spells/Initializer.cs +++ b/Scripts/Spells/Initializer.cs @@ -142,6 +142,26 @@ namespace Server.Spells Register( 506, typeof( Ninjitsu.Shadowjump ) ); Register( 507, typeof( Ninjitsu.MirrorImage ) ); } + + if( Core.ML ) + { + Register( 600, typeof( Spellweaving.ArcaneCircleSpell ) ); + Register( 601, typeof( Spellweaving.GiftOfRenewalSpell ) ); + //Register( 602, typeof( Spellweaving.ImmolatingWeaponSpell ) ); + Register( 603, typeof( Spellweaving.AttuneWeaponSpell ) ); + Register( 604, typeof( Spellweaving.ThunderstormSpell ) ); + Register( 605, typeof( Spellweaving.NatureFurySpell ) ); + Register( 606, typeof( Spellweaving.SummonFeySpell ) ); + Register( 607, typeof( Spellweaving.SummonFiendSpell ) ); + Register( 608, typeof( Spellweaving.ReaperFormSpell ) ); + //Register( 609, typeof( Spellweaving.WildfireSpell ) ); + Register( 610, typeof( Spellweaving.EssenceOfWindSpell ) ); + //Register( 611, typeof( Spellweaving.DryadAllureSpell ) ); + Register( 612, typeof( Spellweaving.EtherealVoyageSpell ) ); + Register( 613, typeof( Spellweaving.WordOfDeathSpell ) ); + Register( 614, typeof( Spellweaving.GiftOfLifeSpell ) ); + //Register( 615, typeof( Spellweaving.ArcaneEmpowermentSpell ) ); + } } } diff --git a/Scripts/Spells/Necromancy/AnimateDeadSpell.cs b/Scripts/Spells/Necromancy/AnimateDeadSpell.cs index 022cfd7c4..a2d12dfcc 100644 --- a/Scripts/Spells/Necromancy/AnimateDeadSpell.cs +++ b/Scripts/Spells/Necromancy/AnimateDeadSpell.cs @@ -13,13 +13,14 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Animate Dead", "Uus Corp", - SpellCircle.Fourth, // 0.5 + 1.0 = 1.5s base cast delay 203, 9031, Reagent.GraveDust, Reagent.DaemonBlood ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + public override double RequiredSkill{ get{ return 40.0; } } public override int RequiredMana{ get{ return 23; } } diff --git a/Scripts/Spells/Necromancy/BloodOathSpell.cs b/Scripts/Spells/Necromancy/BloodOathSpell.cs index 0b47f37bb..e4bc63fe7 100644 --- a/Scripts/Spells/Necromancy/BloodOathSpell.cs +++ b/Scripts/Spells/Necromancy/BloodOathSpell.cs @@ -10,12 +10,13 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Blood Oath", "In Jux Mani Xen", - SpellCircle.Fourth, // 0.5 + 1.0 = 1.5s base cast delay 203, 9031, Reagent.DaemonBlood ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + public override double RequiredSkill{ get{ return 20.0; } } public override int RequiredMana{ get{ return 13; } } @@ -69,6 +70,7 @@ namespace Server.Spells.Necromancy m.FixedParticles( 0x3728, 1, 13, 9502, 33, 7, (EffectLayer)255 ); TimeSpan duration = TimeSpan.FromSeconds( ((GetDamageSkill( Caster ) - GetResistSkill( m )) / 8) + 8 ); + m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); //Skill check for gain new ExpireTimer( Caster, m, duration ).Start(); } diff --git a/Scripts/Spells/Necromancy/CorpseSkin.cs b/Scripts/Spells/Necromancy/CorpseSkin.cs index b8d433f44..0bb568298 100644 --- a/Scripts/Spells/Necromancy/CorpseSkin.cs +++ b/Scripts/Spells/Necromancy/CorpseSkin.cs @@ -10,13 +10,14 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Corpse Skin", "In Agle Corp Ylem", - SpellCircle.Fourth, // 0.5 + 1.0 = 1.5s base cast delay 203, 9051, Reagent.BatWing, Reagent.GraveDust ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + public override double RequiredSkill{ get{ return 20.0; } } public override int RequiredMana{ get{ return 11; } } @@ -59,6 +60,7 @@ namespace Server.Spells.Necromancy double ss = GetDamageSkill( Caster ); double mr = ( Caster == m ? 0.0 : GetResistSkill( m ) ); + m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); //Skill check for gain TimeSpan duration = TimeSpan.FromSeconds( ((ss - mr) / 2.5) + 40.0 ); diff --git a/Scripts/Spells/Necromancy/CurseWeapon.cs b/Scripts/Spells/Necromancy/CurseWeapon.cs index 8a30477cd..81b9092a4 100644 --- a/Scripts/Spells/Necromancy/CurseWeapon.cs +++ b/Scripts/Spells/Necromancy/CurseWeapon.cs @@ -10,12 +10,13 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Curse Weapon", "An Sanct Gra Char", - SpellCircle.First, // 0.5 + 0.25 = 0.75s base cast delay 203, 9031, Reagent.PigIron ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.75 ); } } + public override double RequiredSkill{ get{ return 0.0; } } public override int RequiredMana{ get{ return 7; } } diff --git a/Scripts/Spells/Necromancy/EvilOmen.cs b/Scripts/Spells/Necromancy/EvilOmen.cs index da71ce40a..a28831ee7 100644 --- a/Scripts/Spells/Necromancy/EvilOmen.cs +++ b/Scripts/Spells/Necromancy/EvilOmen.cs @@ -11,13 +11,14 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Evil Omen", "Pas Tym An Sanct", - SpellCircle.First, // 0.5 + 0.25 = 0.75s base cast delay 203, 9031, Reagent.BatWing, Reagent.NoxCrystal ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.75 ); } } + public override double RequiredSkill{ get{ return 20.0; } } public override int RequiredMana{ get{ return 11; } } diff --git a/Scripts/Spells/Necromancy/Exorcism.cs b/Scripts/Spells/Necromancy/Exorcism.cs index 2ef6bb152..7041da8ca 100644 --- a/Scripts/Spells/Necromancy/Exorcism.cs +++ b/Scripts/Spells/Necromancy/Exorcism.cs @@ -14,13 +14,14 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Exorcism", "Ort Corp Grav", - SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay 203, 9031, Reagent.NoxCrystal, Reagent.GraveDust ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } } + public override double RequiredSkill { get { return 80.0; } } public override int RequiredMana { get { return 40; } } @@ -42,7 +43,7 @@ namespace Server.Spells.Necromancy public override bool DelayedDamage { get { return false; } } - private const int Range = 18; + private static readonly int Range = (Core.ML ? 48 : 18); public override int ComputeKarmaAward() { @@ -59,10 +60,6 @@ namespace Server.Spells.Necromancy } else if( CheckSequence() ) { - /* Creates a withering frost around the Caster, - * which deals Cold Damage to all valid targets in a radius of 5 tiles. - */ - Map map = Caster.Map; if( map != null ) @@ -73,17 +70,11 @@ namespace Server.Spells.Necromancy if( IsValidTarget( m ) ) targets.Add( m ); - //Effects.PlaySound( Caster.Location, map, 0x1FB ); - //Effects.PlaySound( Caster.Location, map, 0x10B ); - //Effects.SendLocationParticles( EffectItem.Create( Caster.Location, map, EffectItem.DefaultDuration ), 0x37CC, 1, 40, 97, 3, 9917, 0 ); - for( int i = 0; i < targets.Count; ++i ) { Mobile m = targets[i]; - //m.FixedParticles( 0x374A, 1, 15, 9502, 97, 3, (EffectLayer)255 ); - - //Suprisingly, no effects + //Suprisingly, no sparkle type effects m.Location = GetNearestShrine( m ); } @@ -97,10 +88,6 @@ namespace Server.Spells.Necromancy { if( !m.Player || m.Alive ) return false; - /* - if( m.Corpse != null && m.Corpse.Map == m.Map ) - return false; - * */ Corpse c = m.Corpse as Corpse; Map map = m.Map; diff --git a/Scripts/Spells/Necromancy/HorrificBeast.cs b/Scripts/Spells/Necromancy/HorrificBeast.cs index 3ecf7572a..3e6705b14 100644 --- a/Scripts/Spells/Necromancy/HorrificBeast.cs +++ b/Scripts/Spells/Necromancy/HorrificBeast.cs @@ -10,13 +10,14 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Horrific Beast", "Rel Xen Vas Bal", - SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay 203, 9031, Reagent.BatWing, Reagent.DaemonBlood ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } } + public override double RequiredSkill{ get{ return 40.0; } } public override int RequiredMana{ get{ return 11; } } @@ -26,10 +27,17 @@ namespace Server.Spells.Necromancy { } - public override void PlayEffect( Mobile m ) + public override void DoEffect( Mobile m ) { m.PlaySound( 0x165 ); m.FixedParticles( 0x3728, 1, 13, 9918, 92, 3, EffectLayer.Head ); + + m.Delta( MobileDelta.WeaponDamage ); + } + + public override void RemoveEffect( Mobile m ) + { + m.Delta( MobileDelta.WeaponDamage ); } } } \ No newline at end of file diff --git a/Scripts/Spells/Necromancy/LichForm.cs b/Scripts/Spells/Necromancy/LichForm.cs index 5914f438b..96aaa0101 100644 --- a/Scripts/Spells/Necromancy/LichForm.cs +++ b/Scripts/Spells/Necromancy/LichForm.cs @@ -10,7 +10,6 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Lich Form", "Rel Xen Corp Ort", - SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay 203, 9031, Reagent.GraveDust, @@ -18,6 +17,8 @@ namespace Server.Spells.Necromancy Reagent.NoxCrystal ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } } + public override double RequiredSkill{ get{ return 70.0; } } public override int RequiredMana{ get{ return 23; } } @@ -33,7 +34,7 @@ namespace Server.Spells.Necromancy { } - public override void PlayEffect( Mobile m ) + public override void DoEffect( Mobile m ) { m.PlaySound( 0x19C ); m.FixedParticles( 0x3709, 1, 30, 9904, 1108, 6, EffectLayer.RightFoot ); diff --git a/Scripts/Spells/Necromancy/MindRot.cs b/Scripts/Spells/Necromancy/MindRot.cs index a12429855..38c981862 100644 --- a/Scripts/Spells/Necromancy/MindRot.cs +++ b/Scripts/Spells/Necromancy/MindRot.cs @@ -10,7 +10,6 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Mind Rot", "Wis An Ben", - SpellCircle.Fourth, // 0.5 + 1.0 = 1.5s base cast delay 203, 9031, Reagent.BatWing, @@ -18,6 +17,8 @@ namespace Server.Spells.Necromancy Reagent.DaemonBlood ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + public override double RequiredSkill{ get{ return 30.0; } } public override int RequiredMana{ get{ return 17; } } @@ -50,6 +51,7 @@ namespace Server.Spells.Necromancy m.FixedParticles( 0x373A, 1, 17, 9903, 15, 4, EffectLayer.Head ); TimeSpan duration = TimeSpan.FromSeconds( (((GetDamageSkill( Caster ) - GetResistSkill( m )) / 5.0) + 20.0) * (m.Player ? 1.0 : 2.0 ) ); + m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); //Skill check for gain if ( m.Player ) SetMindRotScalar( Caster, m, 1.25, duration ); diff --git a/Scripts/Spells/Necromancy/NecromancerSpell.cs b/Scripts/Spells/Necromancy/NecromancerSpell.cs index 1f47a0a67..721b11fc6 100644 --- a/Scripts/Spells/Necromancy/NecromancerSpell.cs +++ b/Scripts/Spells/Necromancy/NecromancerSpell.cs @@ -11,9 +11,11 @@ namespace Server.Spells.Necromancy public override SkillName CastSkill{ get{ return SkillName.Necromancy; } } public override SkillName DamageSkill{ get{ return SkillName.SpiritSpeak; } } + //public override int CastDelayBase{ get{ return base.CastDelayBase; } } // Reference, 3 + public override bool ClearHandsOnCast{ get{ return false; } } - public override int CastDelayFastScalar{ get{ return (Core.SE? base.CastDelayFastScalar : 0); } } // Necromancer spells are not effected by fast cast items, though they are by fast cast recovery + public override double CastDelayFastScalar{ get{ return (Core.SE? base.CastDelayFastScalar : 0); } } // Necromancer spells are not affected by fast cast items, though they are by fast cast recovery public NecromancerSpell( Mobile caster, Item scroll, SpellInfo info ) : base( caster, scroll, info ) { @@ -21,7 +23,11 @@ namespace Server.Spells.Necromancy public override int ComputeKarmaAward() { - return -(70 + (10 * (int)Circle)); + //TODO: Verify this formula being that Necro spells don't HAVE a circle. + + //return -(70 + (10 * (int)Circle)); + + return -(40 + (int)(10 * (CastDelayBase.TotalSeconds / CastDelaySecondsPerTick))); } public override void GetCastSkills( out double min, out double max ) diff --git a/Scripts/Spells/Necromancy/PainSpike.cs b/Scripts/Spells/Necromancy/PainSpike.cs index fc05a8a3f..7e3ee87d2 100644 --- a/Scripts/Spells/Necromancy/PainSpike.cs +++ b/Scripts/Spells/Necromancy/PainSpike.cs @@ -10,13 +10,14 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Pain Spike", "In Sar", - SpellCircle.Second, // 0.5 + 0.5 = 1s base cast delay 203, 9031, Reagent.GraveDust, Reagent.PigIron ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } } + public override double RequiredSkill{ get{ return 20.0; } } public override int RequiredMana{ get{ return 5; } } @@ -37,7 +38,7 @@ namespace Server.Spells.Necromancy { SpellHelper.Turn( Caster, m ); - SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m ); + //SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m ); //Irrelevent asfter AoS /* Temporarily causes intense physical pain to the target, dealing direct damage. * After 10 seconds the spell wears off, and if the target is still alive, @@ -49,6 +50,7 @@ namespace Server.Spells.Necromancy m.PlaySound( 0x210 ); double damage = ((GetDamageSkill( Caster ) - GetResistSkill( m )) / 10) + (m.Player ? 18 : 30); + m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); //Skill check for gain if ( damage < 1 ) damage = 1; diff --git a/Scripts/Spells/Necromancy/PoisonStrike.cs b/Scripts/Spells/Necromancy/PoisonStrike.cs index 6a591e47a..c34b61746 100644 --- a/Scripts/Spells/Necromancy/PoisonStrike.cs +++ b/Scripts/Spells/Necromancy/PoisonStrike.cs @@ -10,17 +10,18 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Poison Strike", "In Vas Nox", - (Core.ML ? SpellCircle.Fifth : // 0.5 + 1.25 = 1.75s base cast delay - SpellCircle.Fourth), // 0.5 + 1.0 = 1.5s base cast delay 203, 9031, Reagent.NoxCrystal ); - public override double RequiredSkill{ get{ return 50.0; } } - public override int RequiredMana{ get{ return 17; } } + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( (Core.ML ? 1.75 : 1.5) ); } } - public PoisonStrikeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) + public override double RequiredSkill { get { return 50.0; } } + public override int RequiredMana { get { return 17; } } + + public PoisonStrikeSpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) { } @@ -29,11 +30,11 @@ namespace Server.Spells.Necromancy Caster.Target = new InternalTarget( this ); } - public override bool DelayedDamage{ get{ return false; } } + public override bool DelayedDamage { get { return false; } } public void Target( Mobile m ) { - if ( CheckHSequence( m ) ) + if( CheckHSequence( m ) ) { SpellHelper.Turn( Caster, m ); @@ -42,7 +43,7 @@ namespace Server.Spells.Necromancy * One tile from main target receives 50% damage, two tiles from target receives 33% damage. */ - CheckResisted( m ); // Check magic resist for skill, but do not use return value + //CheckResisted( m ); // Check magic resist for skill, but do not use return value //reports from OSI: Necro spells don't give Resist gain Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 63, 7, 9915, 0 ); Effects.PlaySound( m.Location, m.Map, 0x229 ); @@ -51,23 +52,23 @@ namespace Server.Spells.Necromancy Map map = m.Map; - if ( map != null ) + if( map != null ) { List targets = new List(); - foreach ( Mobile targ in m.GetMobilesInRange( 2 ) ) - if ( (Caster == targ || SpellHelper.ValidIndirectTarget( Caster, targ )) && Caster.CanBeHarmful( targ, false ) ) + foreach( Mobile targ in m.GetMobilesInRange( 2 ) ) + if( (Caster == targ || SpellHelper.ValidIndirectTarget( Caster, targ )) && Caster.CanBeHarmful( targ, false ) ) targets.Add( targ ); - for ( int i = 0; i < targets.Count; ++i ) + for( int i = 0; i < targets.Count; ++i ) { Mobile targ = targets[i]; int num; - if ( targ.InRange( m.Location, 0 ) ) + if( targ.InRange( m.Location, 0 ) ) num = 1; - else if ( targ.InRange( m.Location, 1 ) ) + else if( targ.InRange( m.Location, 1 ) ) num = 2; else num = 3; @@ -85,15 +86,16 @@ namespace Server.Spells.Necromancy { private PoisonStrikeSpell m_Owner; - public InternalTarget( PoisonStrikeSpell owner ) : base( 12, false, TargetFlags.Harmful ) + public InternalTarget( PoisonStrikeSpell owner ) + : base( 12, false, TargetFlags.Harmful ) { m_Owner = owner; } protected override void OnTarget( Mobile from, object o ) { - if ( o is Mobile ) - m_Owner.Target( (Mobile) o ); + if( o is Mobile ) + m_Owner.Target( (Mobile)o ); } protected override void OnTargetFinish( Mobile from ) diff --git a/Scripts/Spells/Necromancy/Strangle.cs b/Scripts/Spells/Necromancy/Strangle.cs index 411d31f11..9a8a7b00f 100644 --- a/Scripts/Spells/Necromancy/Strangle.cs +++ b/Scripts/Spells/Necromancy/Strangle.cs @@ -10,13 +10,14 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Strangle", "In Bal Nox", - SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay 209, 9031, Reagent.DaemonBlood, Reagent.NoxCrystal ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } } + public override double RequiredSkill{ get{ return 65.0; } } public override int RequiredMana{ get{ return 29; } } @@ -35,7 +36,7 @@ namespace Server.Spells.Necromancy { SpellHelper.Turn( Caster, m ); - SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m ); + //SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m ); //Irrelevent after AoS /* Temporarily chokes off the air suply of the target with poisonous fumes. * The target is inflicted with poison damage over time. diff --git a/Scripts/Spells/Necromancy/SummonFamiliar.cs b/Scripts/Spells/Necromancy/SummonFamiliar.cs index d4e10058c..d89e67767 100644 --- a/Scripts/Spells/Necromancy/SummonFamiliar.cs +++ b/Scripts/Spells/Necromancy/SummonFamiliar.cs @@ -12,7 +12,6 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Summon Familiar", "Kal Xen Bal", - SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay 203, 9031, Reagent.BatWing, @@ -20,6 +19,8 @@ namespace Server.Spells.Necromancy Reagent.DaemonBlood ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } } + public override double RequiredSkill{ get{ return 30.0; } } public override int RequiredMana{ get{ return 17; } } diff --git a/Scripts/Spells/Necromancy/TransformationSpell.cs b/Scripts/Spells/Necromancy/TransformationSpell.cs index c1ba6b535..7dd9679ea 100644 --- a/Scripts/Spells/Necromancy/TransformationSpell.cs +++ b/Scripts/Spells/Necromancy/TransformationSpell.cs @@ -7,7 +7,7 @@ using Server.Spells.Seventh; namespace Server.Spells.Necromancy { - public abstract class TransformationSpell : NecromancerSpell + public abstract class TransformationSpell : NecromancerSpell, ITransformationSpell { public abstract int Body{ get; } public virtual int Hue{ get{ return 0; } } @@ -26,116 +26,15 @@ namespace Server.Spells.Necromancy public override bool CheckCast() { - /*if ( Caster.Mounted ) - { - Caster.SendLocalizedMessage( 1042561 ); // Please dismount first. + if( !TransformationSpellHelper.CheckCast( Caster, this ) ) return false; - } - else */ - if ( Factions.Sigil.ExistsOn( Caster ) ) - { - Caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil. - return false; - } - else if ( !Caster.CanBeginAction( typeof( PolymorphSpell ) ) ) - { - Caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed. - return false; - } - else if ( Spells.Ninjitsu.AnimalForm.UnderTransformation( Caster ) ) - { - Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form. - return false; - } return base.CheckCast(); } public override void OnCast() { - Mobile caster = this.Caster; - - /*if ( caster.Mounted ) - { - caster.SendLocalizedMessage( 1042561 ); // Please dismount first. - } - else */ - if ( Factions.Sigil.ExistsOn( Caster ) ) - { - Caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil. - } - else if ( !caster.CanBeginAction( typeof( PolymorphSpell ) ) ) - { - Caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed. - } - else if ( Spells.Ninjitsu.AnimalForm.UnderTransformation( Caster ) ) - { - Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form. - } - else if ( !caster.CanBeginAction( typeof( IncognitoSpell ) ) || (caster.IsBodyMod && GetContext( caster ) == null) ) - { - DoFizzle(); - } - else if ( CheckSequence() ) - { - TransformContext context = GetContext( caster ); - Type ourType = this.GetType(); - - bool wasTransformed = ( context != null ); - bool ourTransform = ( wasTransformed && context.Type == ourType ); - - if ( wasTransformed ) - { - RemoveContext( caster, context, ourTransform ); - - if ( ourTransform ) - { - caster.PlaySound( 0xFA ); - caster.FixedParticles( 0x3728, 1, 13, 5042, EffectLayer.Waist ); - } - } - - if ( !ourTransform ) - { - List mods = new List(); - - if ( PhysResistOffset != 0 ) - mods.Add( new ResistanceMod( ResistanceType.Physical, PhysResistOffset ) ); - - if ( FireResistOffset != 0 ) - mods.Add( new ResistanceMod( ResistanceType.Fire, FireResistOffset ) ); - - if ( ColdResistOffset != 0 ) - mods.Add( new ResistanceMod( ResistanceType.Cold, ColdResistOffset ) ); - - if ( PoisResistOffset != 0 ) - mods.Add( new ResistanceMod( ResistanceType.Poison, PoisResistOffset ) ); - - if ( NrgyResistOffset != 0 ) - mods.Add( new ResistanceMod( ResistanceType.Energy, NrgyResistOffset ) ); - - if ( !((Body)this.Body).IsHuman ) - { - Mobiles.IMount mt = Caster.Mount; - - if ( mt != null ) - mt.Rider = null; - } - - caster.BodyMod = this.Body; - caster.HueMod = this.Hue; - - for ( int i = 0; i < mods.Count; ++i ) - caster.AddResistanceMod( mods[i] ); - - PlayEffect( caster ); - - Timer timer = new TransformTimer( caster, this ); - timer.Start(); - - AddContext( caster, new TransformContext( timer, mods, ourType ) ); - } - } + TransformationSpellHelper.OnCast( Caster, this ); FinishSequence(); } @@ -146,109 +45,12 @@ namespace Server.Spells.Necromancy { } - public virtual void PlayEffect( Mobile m ) + public virtual void DoEffect( Mobile m ) { } - private static Hashtable m_Table = new Hashtable(); - - public static void AddContext( Mobile m, TransformContext context ) + public virtual void RemoveEffect( Mobile m ) { - m_Table[m] = context; - - if ( context.Type == typeof( HorrificBeastSpell ) ) - m.Delta( MobileDelta.WeaponDamage ); - } - - public static void RemoveContext( Mobile m, bool resetGraphics ) - { - TransformContext context = GetContext( m ); - - if ( context != null ) - RemoveContext( m, context, resetGraphics ); - } - - public static void RemoveContext( Mobile m, TransformContext context, bool resetGraphics ) - { - m_Table.Remove( m ); - - List mods = context.Mods; - - for ( int i = 0; i < mods.Count; ++i ) - m.RemoveResistanceMod( mods[i] ); - - if ( resetGraphics ) - { - m.HueMod = -1; - m.BodyMod = 0; - } - - context.Timer.Stop(); - - if ( context.Type == typeof( HorrificBeastSpell ) ) - m.Delta( MobileDelta.WeaponDamage ); - } - - public static TransformContext GetContext( Mobile m ) - { - return ( m_Table[m] as TransformContext ); - } - - public static bool UnderTransformation( Mobile m ) - { - return ( GetContext( m ) != null ); - } - - public static bool UnderTransformation( Mobile m, Type type ) - { - TransformContext context = GetContext( m ); - - return ( context != null && context.Type == type ); - } - } - - public class TransformContext - { - private Timer m_Timer; - private List m_Mods; - private Type m_Type; - - public Timer Timer{ get{ return m_Timer; } } - public List Mods{ get{ return m_Mods; } } - public Type Type{ get{ return m_Type; } } - - public TransformContext( Timer timer, List mods, Type type ) - { - m_Timer = timer; - m_Mods = mods; - m_Type = type; - } - } - - public class TransformTimer : Timer - { - private Mobile m_Mobile; - private TransformationSpell m_Spell; - - public TransformTimer( Mobile from, TransformationSpell spell ) : base( TimeSpan.FromSeconds( spell.TickRate ), TimeSpan.FromSeconds( spell.TickRate ) ) - { - m_Mobile = from; - m_Spell = spell; - - Priority = TimerPriority.TwoFiftyMS; - } - - protected override void OnTick() - { - if ( m_Mobile.Deleted || !m_Mobile.Alive || m_Mobile.Body != m_Spell.Body || m_Mobile.Hue != m_Spell.Hue ) - { - TransformationSpell.RemoveContext( m_Mobile, true ); - Stop(); - } - else - { - m_Spell.OnTick( m_Mobile ); - } } } } \ No newline at end of file diff --git a/Scripts/Spells/Necromancy/VampiricEmbrace.cs b/Scripts/Spells/Necromancy/VampiricEmbrace.cs index 2554731ce..e1aace8ee 100644 --- a/Scripts/Spells/Necromancy/VampiricEmbrace.cs +++ b/Scripts/Spells/Necromancy/VampiricEmbrace.cs @@ -10,7 +10,6 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Vampiric Embrace", "Rel Xen An Sanct", - SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay 203, 9031, Reagent.BatWing, @@ -18,6 +17,8 @@ namespace Server.Spells.Necromancy Reagent.PigIron ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } } + public override double RequiredSkill{ get{ return 99.0; } } public override int RequiredMana{ get{ return 23; } } @@ -43,7 +44,7 @@ namespace Server.Spells.Necromancy } } - public override void PlayEffect( Mobile m ) + public override void DoEffect( Mobile m ) { Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x373A, 1, 17, 1108, 7, 9914, 0 ); Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x376A, 1, 22, 67, 7, 9502, 0 ); diff --git a/Scripts/Spells/Necromancy/VengefulSpirit.cs b/Scripts/Spells/Necromancy/VengefulSpirit.cs index d6d08c534..93477ac56 100644 --- a/Scripts/Spells/Necromancy/VengefulSpirit.cs +++ b/Scripts/Spells/Necromancy/VengefulSpirit.cs @@ -11,7 +11,6 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Vengeful Spirit", "Kal Xen Bal Beh", - SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay 203, 9031, Reagent.BatWing, @@ -19,6 +18,8 @@ namespace Server.Spells.Necromancy Reagent.PigIron ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } } + public override double RequiredSkill{ get{ return 80.0; } } public override int RequiredMana{ get{ return 41; } } diff --git a/Scripts/Spells/Necromancy/Wither.cs b/Scripts/Spells/Necromancy/Wither.cs index e62acefe5..a57677a5a 100644 --- a/Scripts/Spells/Necromancy/Wither.cs +++ b/Scripts/Spells/Necromancy/Wither.cs @@ -10,7 +10,6 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Wither", "Kal Vas An Flam", - SpellCircle.Third, // 0.5 + 0.75 = 1.25s base cast delay 203, 9031, Reagent.NoxCrystal, @@ -18,6 +17,8 @@ namespace Server.Spells.Necromancy Reagent.PigIron ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.25 ); } } + public override double RequiredSkill{ get{ return 60.0; } } public override int RequiredMana{ get{ return 23; } } diff --git a/Scripts/Spells/Necromancy/WraithForm.cs b/Scripts/Spells/Necromancy/WraithForm.cs index 71eb4baf6..d13e09a13 100644 --- a/Scripts/Spells/Necromancy/WraithForm.cs +++ b/Scripts/Spells/Necromancy/WraithForm.cs @@ -10,13 +10,14 @@ namespace Server.Spells.Necromancy { private static SpellInfo m_Info = new SpellInfo( "Wraith Form", "Rel Xen Um", - SpellCircle.Sixth, // 0.5 + 1.5 = 2s base cast delay 203, 9031, Reagent.NoxCrystal, Reagent.PigIron ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } } + public override double RequiredSkill{ get{ return 20.0; } } public override int RequiredMana{ get{ return 17; } } @@ -33,7 +34,7 @@ namespace Server.Spells.Necromancy { } - public override void PlayEffect( Mobile m ) + public override void DoEffect( Mobile m ) { m.PlaySound( 0x17F ); m.FixedParticles( 0x374A, 1, 15, 9902, 1108, 4, EffectLayer.Waist ); diff --git a/Scripts/Spells/Ninjitsu/AnimalForm.cs b/Scripts/Spells/Ninjitsu/AnimalForm.cs index 806f9005c..79e7ca5cb 100644 --- a/Scripts/Spells/Ninjitsu/AnimalForm.cs +++ b/Scripts/Spells/Ninjitsu/AnimalForm.cs @@ -22,16 +22,17 @@ namespace Server.Spells.Ninjitsu AnimalFormContext context = AnimalForm.GetContext( e.Mobile ); if( context != null && context.SpeedBoost ) - e.Mobile.Send( SpeedBoost.Enabled ); + e.Mobile.Send( SpeedControl.MountSpeed ); } private static SpellInfo m_Info = new SpellInfo( "Animal Form", null, - SpellCircle.Fourth, // 1.0s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } } + public override double RequiredSkill{ get{ return 0.0; } } public override int RequiredMana{ get{ return (Core.ML ? 10 : 0); } } public override int CastRecoveryBase{ get { return (Core.ML ? 10 : base.CastRecoveryBase); } } @@ -49,7 +50,7 @@ namespace Server.Spells.Ninjitsu Caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed. return false; } - else if ( Necromancy.TransformationSpell.UnderTransformation( Caster ) ) + else if ( TransformationSpellHelper.UnderTransformation( Caster ) ) { Caster.SendLocalizedMessage( 1063219 ); // You cannot mimic an animal while in that form. return false; @@ -82,7 +83,7 @@ namespace Server.Spells.Ninjitsu { Caster.SendLocalizedMessage( 1061628 ); // You can't do that while polymorphed. } - else if ( Necromancy.TransformationSpell.UnderTransformation( Caster ) ) + else if( TransformationSpellHelper.UnderTransformation( Caster ) ) { Caster.SendLocalizedMessage( 1063219 ); // You cannot mimic an animal while in that form. } @@ -154,6 +155,13 @@ namespace Server.Spells.Ninjitsu return MorphResult.NoSkill; } + /* + if( !m.CheckSkill( SkillName.Ninjitsu, entry.ReqSkill, entry.ReqSkill + 37.5 ) ) + return MorphResult.Fail; + * + * On OSI,it seems you can only gain starting at '0' using Animal form. + */ + double ninjitsu = m.Skills.Ninjitsu.Value; if ( ninjitsu < entry.ReqSkill + 37.5 ) @@ -174,7 +182,7 @@ namespace Server.Spells.Ninjitsu m.HueMod = entry.HueMod; if ( entry.SpeedBoost ) - m.Send( SpeedBoost.Instantiate( true ) ); + m.Send( SpeedControl.MountSpeed ); SkillMod mod = null; @@ -216,7 +224,7 @@ namespace Server.Spells.Ninjitsu m_Table.Remove( m ); if ( context.SpeedBoost ) - m.Send( SpeedBoost.Instantiate( false ) ); + m.Send( SpeedControl.Disable ); SkillMod mod = context.Mod; diff --git a/Scripts/Spells/Ninjitsu/Backstab.cs b/Scripts/Spells/Ninjitsu/Backstab.cs index 5a8e9edac..66576eddb 100644 --- a/Scripts/Spells/Ninjitsu/Backstab.cs +++ b/Scripts/Spells/Ninjitsu/Backstab.cs @@ -10,14 +10,12 @@ namespace Server.Spells.Ninjitsu { public class Backstab : NinjaMove { - // TODO: Cannot hide for 5s - public Backstab() { } public override int BaseMana{ get{ return 30; } } - public override double RequiredSkill{ get{ return 20.0; } } + public override double RequiredSkill{ get{ return Core.ML ? 40.0 : 20.0; } } public override TextDefinition AbilityMessage{ get{ return new TextDefinition( 1063089 ); } } // You prepare to Backstab your opponent. @@ -41,7 +39,16 @@ namespace Server.Spells.Ninjitsu public override bool OnBeforeSwing( Mobile attacker, Mobile defender ) { - return Validate( attacker ) && CheckMana( attacker, true ); + bool valid = Validate( attacker ) && CheckMana( attacker, true ); + + if( valid ) + { + attacker.BeginAction( typeof( Stealth ) ); + Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), delegate { attacker.EndAction( typeof( Stealth ) ); } ); + } + + return valid; + } public override bool ValidatesDuringHit { get { return false; } } diff --git a/Scripts/Spells/Ninjitsu/FocusAttack.cs b/Scripts/Spells/Ninjitsu/FocusAttack.cs index 54808b7e8..6a5fce8be 100644 --- a/Scripts/Spells/Ninjitsu/FocusAttack.cs +++ b/Scripts/Spells/Ninjitsu/FocusAttack.cs @@ -9,14 +9,12 @@ namespace Server.Spells.Ninjitsu { public class FocusAttack : NinjaMove { - // TODO: Display property bonus on equipped weapons. - public FocusAttack() { } - public override int BaseMana{ get{ return 20; } } - public override double RequiredSkill{ get{ return 60.0; } } + public override int BaseMana{ get{ return Core.ML ? 10 : 20; } } + public override double RequiredSkill{ get{ return Core.ML? 30.0 : 60 ; } } public override TextDefinition AbilityMessage{ get{ return new TextDefinition( 1063095 ); } } // You prepare to focus all of your abilities into your next strike. diff --git a/Scripts/Spells/Ninjitsu/MirrorImage.cs b/Scripts/Spells/Ninjitsu/MirrorImage.cs index 472871acd..34d48e635 100644 --- a/Scripts/Spells/Ninjitsu/MirrorImage.cs +++ b/Scripts/Spells/Ninjitsu/MirrorImage.cs @@ -11,7 +11,7 @@ namespace Server.Spells.Ninjitsu { public class MirrorImage : NinjaSpell { - private static Dictionary m_CloneCount = new Dictionary(); + private static Dictionary m_CloneCount = new Dictionary(); public static bool HasClone( Mobile m ) { @@ -45,12 +45,13 @@ namespace Server.Spells.Ninjitsu private static SpellInfo m_Info = new SpellInfo( "Mirror Image", null, - SpellCircle.Sixth, // 1.5s base cast delay -1, 9002 ); - public override double RequiredSkill{ get{ return 40.0; } } + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + + public override double RequiredSkill{ get{ return Core.ML ? 20.0 : 40.0; } } public override int RequiredMana{ get{ return 10; } } public override bool BlockedByAnimalForm{ get{ return false; } } @@ -71,7 +72,7 @@ namespace Server.Spells.Ninjitsu Caster.SendLocalizedMessage( 1063133 ); // You cannot summon a mirror image because you have too many followers. return false; } - else if ( Necromancy.TransformationSpell.UnderTransformation( Caster, typeof( HorrificBeastSpell ) ) ) + else if( TransformationSpellHelper.UnderTransformation( Caster, typeof( HorrificBeastSpell ) ) ) { Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form. return false; @@ -102,7 +103,7 @@ namespace Server.Spells.Ninjitsu { Caster.SendLocalizedMessage( 1063133 ); // You cannot summon a mirror image because you have too many followers. } - else if ( Necromancy.TransformationSpell.UnderTransformation( Caster, typeof( HorrificBeastSpell ) ) ) + else if( TransformationSpellHelper.UnderTransformation( Caster, typeof( HorrificBeastSpell ) ) ) { Caster.SendLocalizedMessage( 1061091 ); // You cannot cast that spell in this form. } diff --git a/Scripts/Spells/Ninjitsu/NinjaMove.cs b/Scripts/Spells/Ninjitsu/NinjaMove.cs index d4ea196f7..3e610cc0e 100644 --- a/Scripts/Spells/Ninjitsu/NinjaMove.cs +++ b/Scripts/Spells/Ninjitsu/NinjaMove.cs @@ -10,5 +10,10 @@ namespace Server.Spells public class NinjaMove : SpecialMove { public override SkillName MoveSkill{ get{ return SkillName.Ninjitsu; } } + + public override void CheckGain( Mobile m ) + { + m.CheckSkill( MoveSkill, RequiredSkill - 12.5, RequiredSkill + 37.5 ); //Per five on friday 02/16/07 + } } } \ No newline at end of file diff --git a/Scripts/Spells/Ninjitsu/NinjaSpell.cs b/Scripts/Spells/Ninjitsu/NinjaSpell.cs index da39d58fd..6a985e254 100644 --- a/Scripts/Spells/Ninjitsu/NinjaSpell.cs +++ b/Scripts/Spells/Ninjitsu/NinjaSpell.cs @@ -20,7 +20,8 @@ namespace Server.Spells.Ninjitsu public override bool BlocksMovement{ get{ return false; } } - public override int CastDelayBase{ get{ return 1; } } + //public override int CastDelayBase{ get{ return 1; } } + public override double CastDelayFastScalar { get { return 0; } } public override int CastRecoveryBase{ get{ return 7; } } @@ -36,7 +37,8 @@ namespace Server.Spells.Ninjitsu if ( from.NetState == null ) return false; - return ( (from.NetState.Flags & 0x10) != 0 ); + //return ( (from.NetState.Flags & 0x10) != 0 ); + return from.NetState.SupportsExpansion( Expansion.SE ); } public override bool CheckCast() @@ -90,7 +92,7 @@ namespace Server.Spells.Ninjitsu public override void GetCastSkills( out double min, out double max ) { - min = RequiredSkill; + min = RequiredSkill - 12.5; //Per 5 on friday 2/16/07 max = RequiredSkill + 37.5; } diff --git a/Scripts/Spells/Ninjitsu/ShadowJump.cs b/Scripts/Spells/Ninjitsu/ShadowJump.cs index 4110db2fd..0e1799ba2 100644 --- a/Scripts/Spells/Ninjitsu/ShadowJump.cs +++ b/Scripts/Spells/Ninjitsu/ShadowJump.cs @@ -11,11 +11,12 @@ namespace Server.Spells.Ninjitsu { private static SpellInfo m_Info = new SpellInfo( "Shadowjump", null, - SpellCircle.Fourth, // 1.0s base cast delay -1, 9002 ); + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } } + public override double RequiredSkill{ get{ return 50.0; } } public override int RequiredMana{ get{ return 15; } } diff --git a/Scripts/Spells/Ninjitsu/SurpriseAttack.cs b/Scripts/Spells/Ninjitsu/SurpriseAttack.cs index f816cea2b..6a03f349c 100644 --- a/Scripts/Spells/Ninjitsu/SurpriseAttack.cs +++ b/Scripts/Spells/Ninjitsu/SurpriseAttack.cs @@ -10,14 +10,12 @@ namespace Server.Spells.Ninjitsu { public class SurpriseAttack : NinjaMove { - // TODO: Cannot hide for 5s - public SurpriseAttack() { } public override int BaseMana{ get{ return 20; } } - public override double RequiredSkill{ get{ return 30.0; } } + public override double RequiredSkill{ get{ return Core.ML ? 60.0 : 30.0; } } public override TextDefinition AbilityMessage{ get{ return new TextDefinition( 1063128 ); } } // You prepare to surprise your prey. @@ -34,7 +32,16 @@ namespace Server.Spells.Ninjitsu public override bool OnBeforeSwing( Mobile attacker, Mobile defender ) { - return Validate( attacker ) && CheckMana( attacker, true ); + bool valid = Validate( attacker ) && CheckMana( attacker, true ); + + if( valid ) + { + attacker.BeginAction( typeof( Stealth ) ); + Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), delegate { attacker.EndAction( typeof( Stealth ) ); } ); + } + + return valid; + } public override bool ValidatesDuringHit { get { return false; } } diff --git a/Scripts/Spells/Second/Agility.cs b/Scripts/Spells/Second/Agility.cs index 65910f94a..3adb13267 100644 --- a/Scripts/Spells/Second/Agility.cs +++ b/Scripts/Spells/Second/Agility.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.Second { - public class AgilitySpell : Spell + public class AgilitySpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Agility", "Ex Uus", - SpellCircle.Second, 212, 9061, Reagent.Bloodmoss, Reagent.MandrakeRoot ); + public override SpellCircle Circle { get { return SpellCircle.Second; } } + public AgilitySpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Second/Cunning.cs b/Scripts/Spells/Second/Cunning.cs index 5fdb73a1f..b9cf4c368 100644 --- a/Scripts/Spells/Second/Cunning.cs +++ b/Scripts/Spells/Second/Cunning.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.Second { - public class CunningSpell : Spell + public class CunningSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Cunning", "Uus Wis", - SpellCircle.Second, 212, 9061, Reagent.MandrakeRoot, Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.Second; } } + public CunningSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Second/Cure.cs b/Scripts/Spells/Second/Cure.cs index 754a97994..0ef4676d5 100644 --- a/Scripts/Spells/Second/Cure.cs +++ b/Scripts/Spells/Second/Cure.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.Second { - public class CureSpell : Spell + public class CureSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Cure", "An Nox", - SpellCircle.Second, 212, 9061, Reagent.Garlic, Reagent.Ginseng ); + public override SpellCircle Circle { get { return SpellCircle.Second; } } + public CureSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Second/Harm.cs b/Scripts/Spells/Second/Harm.cs index 1f57dbfb2..dab4027fa 100644 --- a/Scripts/Spells/Second/Harm.cs +++ b/Scripts/Spells/Second/Harm.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.Second { - public class HarmSpell : Spell + public class HarmSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Harm", "An Mani", - SpellCircle.Second, 212, Core.AOS ? 9001 : 9041, Reagent.Nightshade, Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Second; } } + public HarmSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Second/MagicTrap.cs b/Scripts/Spells/Second/MagicTrap.cs index 890d70631..e76ccab00 100644 --- a/Scripts/Spells/Second/MagicTrap.cs +++ b/Scripts/Spells/Second/MagicTrap.cs @@ -5,11 +5,10 @@ using Server.Items; namespace Server.Spells.Second { - public class MagicTrapSpell : Spell + public class MagicTrapSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Magic Trap", "In Jux", - SpellCircle.Second, 212, 9001, Reagent.Garlic, @@ -17,6 +16,8 @@ namespace Server.Spells.Second Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Second; } } + public MagicTrapSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Second/Protection.cs b/Scripts/Spells/Second/Protection.cs index 67407a4fa..efbf204df 100644 --- a/Scripts/Spells/Second/Protection.cs +++ b/Scripts/Spells/Second/Protection.cs @@ -5,14 +5,13 @@ using Server.Network; namespace Server.Spells.Second { - public class ProtectionSpell : Spell + public class ProtectionSpell : MagerySpell { private static Hashtable m_Registry = new Hashtable(); public static Hashtable Registry { get { return m_Registry; } } private static SpellInfo m_Info = new SpellInfo( "Protection", "Uus Sanct", - SpellCircle.Second, 236, 9011, Reagent.Garlic, @@ -20,6 +19,8 @@ namespace Server.Spells.Second Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Second; } } + public ProtectionSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Second/RemoveTrap.cs b/Scripts/Spells/Second/RemoveTrap.cs index 5796d2b4c..d77a8d68d 100644 --- a/Scripts/Spells/Second/RemoveTrap.cs +++ b/Scripts/Spells/Second/RemoveTrap.cs @@ -5,17 +5,18 @@ using Server.Items; namespace Server.Spells.Second { - public class RemoveTrapSpell : Spell + public class RemoveTrapSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Remove Trap", "An Jux", - SpellCircle.Second, 212, 9001, Reagent.Bloodmoss, Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Second; } } + public RemoveTrapSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Second/Strength.cs b/Scripts/Spells/Second/Strength.cs index db7ebb11f..f700df0e6 100644 --- a/Scripts/Spells/Second/Strength.cs +++ b/Scripts/Spells/Second/Strength.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.Second { - public class StrengthSpell : Spell + public class StrengthSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Strength", "Uus Mani", - SpellCircle.Second, 212, 9061, Reagent.MandrakeRoot, Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.Second; } } + public StrengthSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Seventh/ChainLightning.cs b/Scripts/Spells/Seventh/ChainLightning.cs index 3fd4228cc..3ec691d04 100644 --- a/Scripts/Spells/Seventh/ChainLightning.cs +++ b/Scripts/Spells/Seventh/ChainLightning.cs @@ -6,11 +6,10 @@ using Server.Targeting; namespace Server.Spells.Seventh { - public class ChainLightningSpell : Spell + public class ChainLightningSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Chain Lightning", "Vas Ort Grav", - SpellCircle.Seventh, 209, 9022, false, @@ -20,6 +19,8 @@ namespace Server.Spells.Seventh Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Seventh; } } + public ChainLightningSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Seventh/EnergyField.cs b/Scripts/Spells/Seventh/EnergyField.cs index 8f0cab2a0..7d2028c08 100644 --- a/Scripts/Spells/Seventh/EnergyField.cs +++ b/Scripts/Spells/Seventh/EnergyField.cs @@ -6,11 +6,10 @@ using Server.Items; namespace Server.Spells.Seventh { - public class EnergyFieldSpell : Spell + public class EnergyFieldSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Energy Field", "In Sanct Grav", - SpellCircle.Seventh, 221, 9022, false, @@ -20,6 +19,8 @@ namespace Server.Spells.Seventh Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Seventh; } } + public EnergyFieldSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Seventh/FlameStrike.cs b/Scripts/Spells/Seventh/FlameStrike.cs index 5a17e6a68..a3ebd905f 100644 --- a/Scripts/Spells/Seventh/FlameStrike.cs +++ b/Scripts/Spells/Seventh/FlameStrike.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.Seventh { - public class FlameStrikeSpell : Spell + public class FlameStrikeSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Flame Strike", "Kal Vas Flam", - SpellCircle.Seventh, 245, 9042, Reagent.SpidersSilk, Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Seventh; } } + public FlameStrikeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Seventh/GateTravel.cs b/Scripts/Spells/Seventh/GateTravel.cs index 67ae8007f..8746e8a20 100644 --- a/Scripts/Spells/Seventh/GateTravel.cs +++ b/Scripts/Spells/Seventh/GateTravel.cs @@ -9,11 +9,10 @@ using Server.Mobiles; namespace Server.Spells.Seventh { - public class GateTravelSpell : Spell + public class GateTravelSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Gate Travel", "Vas Rel Por", - SpellCircle.Seventh, 263, 9032, Reagent.BlackPearl, @@ -21,6 +20,8 @@ namespace Server.Spells.Seventh Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Seventh; } } + private RunebookEntry m_Entry; public GateTravelSpell( Mobile caster, Item scroll ) : this( caster, scroll, null ) diff --git a/Scripts/Spells/Seventh/ManaVampire.cs b/Scripts/Spells/Seventh/ManaVampire.cs index fdf002ee2..5e13a96b7 100644 --- a/Scripts/Spells/Seventh/ManaVampire.cs +++ b/Scripts/Spells/Seventh/ManaVampire.cs @@ -4,11 +4,10 @@ using Server.Network; namespace Server.Spells.Seventh { - public class ManaVampireSpell : Spell + public class ManaVampireSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Mana Vampire", "Ort Sanct", - SpellCircle.Seventh, 221, 9032, Reagent.BlackPearl, @@ -17,6 +16,8 @@ namespace Server.Spells.Seventh Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Seventh; } } + public ManaVampireSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Seventh/MassDispel.cs b/Scripts/Spells/Seventh/MassDispel.cs index 61451ecac..8d06e60a7 100644 --- a/Scripts/Spells/Seventh/MassDispel.cs +++ b/Scripts/Spells/Seventh/MassDispel.cs @@ -8,11 +8,10 @@ using Server.Mobiles; namespace Server.Spells.Seventh { - public class MassDispelSpell : Spell + public class MassDispelSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Mass Dispel", "Vas An Ort", - SpellCircle.Seventh, 263, 9002, Reagent.Garlic, @@ -21,6 +20,8 @@ namespace Server.Spells.Seventh Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Seventh; } } + public MassDispelSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Seventh/MeteorSwarm.cs b/Scripts/Spells/Seventh/MeteorSwarm.cs index 2b7cffcdb..e8f020b93 100644 --- a/Scripts/Spells/Seventh/MeteorSwarm.cs +++ b/Scripts/Spells/Seventh/MeteorSwarm.cs @@ -6,11 +6,10 @@ using Server.Targeting; namespace Server.Spells.Seventh { - public class MeteorSwarmSpell : Spell + public class MeteorSwarmSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Meteor Swarm", "Flam Kal Des Ylem", - SpellCircle.Seventh, 233, 9042, false, @@ -20,6 +19,8 @@ namespace Server.Spells.Seventh Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Seventh; } } + public MeteorSwarmSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Seventh/Polymorph.cs b/Scripts/Spells/Seventh/Polymorph.cs index 43f7ed283..f829f69d5 100644 --- a/Scripts/Spells/Seventh/Polymorph.cs +++ b/Scripts/Spells/Seventh/Polymorph.cs @@ -8,11 +8,10 @@ using Server.Spells.Fifth; namespace Server.Spells.Seventh { - public class PolymorphSpell : Spell + public class PolymorphSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Polymorph", "Vas Ylem Rel", - SpellCircle.Seventh, 221, 9002, Reagent.Bloodmoss, @@ -20,6 +19,8 @@ namespace Server.Spells.Seventh Reagent.MandrakeRoot ); + public override SpellCircle Circle { get { return SpellCircle.Seventh; } } + private int m_NewBody; public PolymorphSpell( Mobile caster, Item scroll, int body ) : base( caster, scroll, m_Info ) @@ -44,7 +45,7 @@ namespace Server.Spells.Seventh Caster.SendLocalizedMessage( 1010521 ); // You cannot polymorph while you have a Town Sigil return false; } - else if ( Necromancy.TransformationSpell.UnderTransformation( Caster ) ) + else if( TransformationSpellHelper.UnderTransformation( Caster ) ) { Caster.SendLocalizedMessage( 1061633 ); // You cannot polymorph while in that form. return false; @@ -100,7 +101,7 @@ namespace Server.Spells.Seventh else Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect. } - else if ( Necromancy.TransformationSpell.UnderTransformation( Caster ) ) + else if( TransformationSpellHelper.UnderTransformation( Caster ) ) { Caster.SendLocalizedMessage( 1061633 ); // You cannot polymorph while in that form. } diff --git a/Scripts/Spells/Sixth/Dispel.cs b/Scripts/Spells/Sixth/Dispel.cs index b99822006..76fbbb87e 100644 --- a/Scripts/Spells/Sixth/Dispel.cs +++ b/Scripts/Spells/Sixth/Dispel.cs @@ -7,11 +7,10 @@ using Server.Mobiles; namespace Server.Spells.Sixth { - public class DispelSpell : Spell + public class DispelSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Dispel", "An Ort", - SpellCircle.Sixth, 218, 9002, Reagent.Garlic, @@ -19,6 +18,8 @@ namespace Server.Spells.Sixth Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Sixth; } } + public DispelSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Sixth/EnergyBolt.cs b/Scripts/Spells/Sixth/EnergyBolt.cs index b1fb0121c..b12004c12 100644 --- a/Scripts/Spells/Sixth/EnergyBolt.cs +++ b/Scripts/Spells/Sixth/EnergyBolt.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.Sixth { - public class EnergyBoltSpell : Spell + public class EnergyBoltSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Energy Bolt", "Corp Por", - SpellCircle.Sixth, 230, 9022, Reagent.BlackPearl, Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.Sixth; } } + public EnergyBoltSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Sixth/Explosion.cs b/Scripts/Spells/Sixth/Explosion.cs index 80fcf6509..ccdb20dff 100644 --- a/Scripts/Spells/Sixth/Explosion.cs +++ b/Scripts/Spells/Sixth/Explosion.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.Sixth { - public class ExplosionSpell : Spell + public class ExplosionSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Explosion", "Vas Ort Flam", - SpellCircle.Sixth, 230, 9041, Reagent.Bloodmoss, Reagent.MandrakeRoot ); + public override SpellCircle Circle { get { return SpellCircle.Sixth; } } + public ExplosionSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { @@ -52,11 +53,11 @@ namespace Server.Spells.Sixth private class InternalTimer : Timer { - private Spell m_Spell; + private MagerySpell m_Spell; private Mobile m_Target; private Mobile m_Attacker, m_Defender; - public InternalTimer( Spell spell, Mobile attacker, Mobile defender, Mobile target ) + public InternalTimer( MagerySpell spell, Mobile attacker, Mobile defender, Mobile target ) : base( TimeSpan.FromSeconds( Core.AOS ? 3.0 : 2.5 ) ) { m_Spell = spell; diff --git a/Scripts/Spells/Sixth/Invisibility.cs b/Scripts/Spells/Sixth/Invisibility.cs index 74e0d155e..2caebddc3 100644 --- a/Scripts/Spells/Sixth/Invisibility.cs +++ b/Scripts/Spells/Sixth/Invisibility.cs @@ -6,17 +6,18 @@ using Server.Items; namespace Server.Spells.Sixth { - public class InvisibilitySpell : Spell + public class InvisibilitySpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Invisibility", "An Lor Xen", - SpellCircle.Sixth, 206, 9002, Reagent.Bloodmoss, Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.Sixth; } } + public InvisibilitySpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Sixth/Mark.cs b/Scripts/Spells/Sixth/Mark.cs index 8322bc924..5c7741e2c 100644 --- a/Scripts/Spells/Sixth/Mark.cs +++ b/Scripts/Spells/Sixth/Mark.cs @@ -6,11 +6,10 @@ using Server.Regions; namespace Server.Spells.Sixth { - public class MarkSpell : Spell + public class MarkSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Mark", "Kal Por Ylem", - SpellCircle.Sixth, 218, 9002, Reagent.BlackPearl, @@ -18,6 +17,8 @@ namespace Server.Spells.Sixth Reagent.MandrakeRoot ); + public override SpellCircle Circle { get { return SpellCircle.Sixth; } } + public MarkSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Sixth/MassCurse.cs b/Scripts/Spells/Sixth/MassCurse.cs index 4f1909200..0d68aa28a 100644 --- a/Scripts/Spells/Sixth/MassCurse.cs +++ b/Scripts/Spells/Sixth/MassCurse.cs @@ -7,11 +7,10 @@ using Server.Network; namespace Server.Spells.Sixth { - public class MassCurseSpell : Spell + public class MassCurseSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Mass Curse", "Vas Des Sanct", - SpellCircle.Sixth, 218, 9031, false, @@ -21,6 +20,8 @@ namespace Server.Spells.Sixth Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Sixth; } } + public MassCurseSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Sixth/ParalyzeField.cs b/Scripts/Spells/Sixth/ParalyzeField.cs index 048d7cfda..9a055d9d3 100644 --- a/Scripts/Spells/Sixth/ParalyzeField.cs +++ b/Scripts/Spells/Sixth/ParalyzeField.cs @@ -6,11 +6,10 @@ using Server.Misc; namespace Server.Spells.Sixth { - public class ParalyzeFieldSpell : Spell + public class ParalyzeFieldSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Paralyze Field", "In Ex Grav", - SpellCircle.Sixth, 230, 9012, false, @@ -19,6 +18,8 @@ namespace Server.Spells.Sixth Reagent.SpidersSilk ); + public override SpellCircle Circle { get { return SpellCircle.Sixth; } } + public ParalyzeFieldSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Sixth/Reveal.cs b/Scripts/Spells/Sixth/Reveal.cs index ac0b7146b..7e0d6217d 100644 --- a/Scripts/Spells/Sixth/Reveal.cs +++ b/Scripts/Spells/Sixth/Reveal.cs @@ -7,17 +7,18 @@ using Server.Network; namespace Server.Spells.Sixth { - public class RevealSpell : Spell + public class RevealSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Reveal", "Wis Quas", - SpellCircle.Sixth, 206, 9002, Reagent.Bloodmoss, Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Sixth; } } + public RevealSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Spellweaving/ArcaneCircle.cs b/Scripts/Spells/Spellweaving/ArcaneCircle.cs new file mode 100644 index 000000000..3ed2c79ac --- /dev/null +++ b/Scripts/Spells/Spellweaving/ArcaneCircle.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using Server.Items; + +namespace Server.Spells.Spellweaving +{ + public class ArcaneCircleSpell : ArcanistSpell + { + private static SpellInfo m_Info = new SpellInfo( + "Arcane Circle", "Myrshalee", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 0.5 ); } } + + public override double RequiredSkill { get { return 0.0; } } + public override int RequiredMana { get { return 24; } } + + public ArcaneCircleSpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) + { + } + + public override bool CheckCast() + { + if( !IsValidLocation( Caster.Location, Caster.Map ) ) + { + Caster.SendLocalizedMessage( 1072705 ); // You must be standing on an arcane circle, pentagram or abbatoir to use this spell. + return false; + } + + return base.CheckCast(); + } + + public override void OnCast() + { + if( CheckSequence() ) + { + Caster.FixedParticles( 0x3779, 10, 20, 0x0, EffectLayer.Waist ); + Caster.PlaySound( 0x5C0 ); + + List Arcanists = GetArcanists(); + + TimeSpan duration = TimeSpan.FromHours( Math.Max( 1, (int)(Caster.Skills.Spellweaving.Value / 24) ) ); + + int strengthBonus = Math.Min( Arcanists.Count, IsSanctuary( Caster.Location, Caster.Map ) ? 6 : 5 ); //The Sanctuary is a special, single location place + + for( int i = 0; i < Arcanists.Count; i++ ) + GiveArcaneFocus( Arcanists[i], duration, strengthBonus ); + } + + FinishSequence(); + } + + private static bool IsSanctuary( Point3D p, Map m ) + { + return (m == Map.Trammel || m == Map.Felucca) && p.X == 6267 && p.Y == 131 && p.Z == 5; + } + + private static bool IsValidLocation( Point3D location, Map map ) + { + Tile lt = map.Tiles.GetLandTile( location.X, location.Y ); // Land Tiles + + if( IsValidTile( lt.ID ) && lt.Z == location.Z ) + return true; + + Tile[] tiles = map.Tiles.GetStaticTiles( location.X, location.Y ); // Static Tiles + + for( int i = 0; i < tiles.Length; ++i ) + { + Tile t = tiles[i]; + ItemData id = TileData.ItemTable[t.ID & 0x3FFF]; + + int tand = t.ID & 0x3FFF; + + if( t.Z != location.Z ) + continue; + else if( IsValidTile( tand ) ) + return true; + } + + IPooledEnumerable eable = map.GetItemsInRange( location, 0 ); // Added Tiles + + foreach( Item item in eable ) + { + if( item == null || item.Z != location.Z ) + continue; + else if( IsValidTile( item.ItemID ) ) + { + eable.Free(); + return true; + } + } + + eable.Free(); + return false; + } + + public static bool IsValidTile( int itemID ) + { + //Per OSI, Center tile only + return (itemID == 0xFEA || itemID == 0x1216 || itemID == 0x307F); // Pentagram center, Abbatoir center, Arcane Circle Center + } + + private List GetArcanists() + { + List weavers = new List(); + + weavers.Add( Caster ); + + //OSI Verified: Even enemies/combatants count + foreach( Mobile m in Caster.GetMobilesInRange( 1 ) ) //Range verified as 1 + { + if( m != Caster && Caster.CanBeBeneficial( m, false ) && Math.Abs( Caster.Skills.Spellweaving.Value - m.Skills.Spellweaving.Value ) <= 20 ) //TODO: OSI check, aggressor/agressed? Visibility? + { + weavers.Add( m ); + } + // Everyone gets the Arcane Focus, power capped elsewhere + } + + return weavers; + } + + private void GiveArcaneFocus( Mobile to, TimeSpan duration, int strengthBonus ) + { + if( to == null ) //Sanity + return; + + ArcaneFocus focus = FindArcaneFocus( to ); + + if( focus == null ) + { + ArcaneFocus f = new ArcaneFocus( duration, strengthBonus ); + if( to.PlaceInBackpack( f ) ) + { + f.SendTimeRemainingMessage( to ); + to.SendLocalizedMessage( 1072740 ); // An arcane focus appears in your backpack. + } + else + { + f.Delete(); + } + + } + else //OSI renewal rules: the new one will override the old one, always. + { + to.SendLocalizedMessage( 1072828 ); // Your arcane focus is renewed. + focus.LifeSpan = duration; + focus.CreationTime = DateTime.Now; + focus.StrengthBonus = strengthBonus; + focus.InvalidateProperties(); + focus.SendTimeRemainingMessage( to ); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/ArcaneForm.cs b/Scripts/Spells/Spellweaving/ArcaneForm.cs new file mode 100644 index 000000000..288c1d218 --- /dev/null +++ b/Scripts/Spells/Spellweaving/ArcaneForm.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Server.Mobiles; +using Server.Network; +using Server.Spells.Fifth; +using Server.Spells.Seventh; +using Server.Spells.Necromancy; +using Server.Spells.Ninjitsu; + +namespace Server.Spells.Spellweaving +{ + public abstract class ArcaneForm : ArcanistSpell, ITransformationSpell + { + public abstract int Body { get; } + public virtual int Hue { get { return 0; } } + + public virtual int PhysResistOffset { get { return 0; } } + public virtual int FireResistOffset { get { return 0; } } + public virtual int ColdResistOffset { get { return 0; } } + public virtual int PoisResistOffset { get { return 0; } } + public virtual int NrgyResistOffset { get { return 0; } } + + public ArcaneForm( Mobile caster, Item scroll, SpellInfo info ) : base( caster, scroll, info ) + { + } + + public override bool CheckCast() + { + if( !TransformationSpellHelper.CheckCast( Caster, this ) ) + return false; + + return base.CheckCast(); + } + + public override void OnCast() + { + TransformationSpellHelper.OnCast( Caster, this ); + + FinishSequence(); + } + + public virtual double TickRate + { + get { return 1.0; } + } + + public virtual void OnTick( Mobile m ) + { + } + + public virtual void DoEffect( Mobile m ) + { + } + + public virtual void RemoveEffect( Mobile m ) + { + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/ArcaneSummon.cs b/Scripts/Spells/Spellweaving/ArcaneSummon.cs new file mode 100644 index 000000000..9228c925e --- /dev/null +++ b/Scripts/Spells/Spellweaving/ArcaneSummon.cs @@ -0,0 +1,51 @@ +using System; +using Server.Targeting; +using Server.Mobiles; + +namespace Server.Spells.Spellweaving +{ + public abstract class ArcaneSummon : ArcanistSpell where T : BaseCreature + { + public abstract int Sound { get; } + + public ArcaneSummon( Mobile caster, Item scroll, SpellInfo info ) + : base( caster, scroll, info ) + { + } + + public override bool CheckCast() + { + if( !base.CheckCast() ) + return false; + + if( (Caster.Followers + 1) > Caster.FollowersMax ) + { + Caster.SendLocalizedMessage( 1074270 ); // You have too many followers to summon another one. + return false; + } + + return true; + } + + public override void OnCast() + { + if( CheckSequence() ) + { + TimeSpan duration = TimeSpan.FromMinutes( Caster.Skills.Spellweaving.Value /24 + FocusLevel*2 ); + int summons = Math.Min( 1+FocusLevel, Caster.FollowersMax - Caster.Followers ); + + for( int i = 0; i < summons; i++ ) + { + BaseCreature bc; + + try { bc = Activator.CreateInstance(); } + catch { break; } + + SpellHelper.Summon( bc, Caster, Sound, duration, false, false ); + } + + FinishSequence(); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/ArcanistSpell.cs b/Scripts/Spells/Spellweaving/ArcanistSpell.cs new file mode 100644 index 000000000..50504c69b --- /dev/null +++ b/Scripts/Spells/Spellweaving/ArcanistSpell.cs @@ -0,0 +1,144 @@ +using System; +using System.Text; +using Server.Items; +using Server.Mobiles; + +namespace Server.Spells.Spellweaving +{ + public abstract class ArcanistSpell : Spell + { + public abstract double RequiredSkill { get; } + public abstract int RequiredMana { get; } + + public override SkillName CastSkill { get { return SkillName.Spellweaving; } } + public override SkillName DamageSkill { get { return SkillName.Spellweaving; } } + + public override bool ClearHandsOnCast { get { return false; } } + + private int m_CastTimeFocusLevel; + + public ArcanistSpell( Mobile caster, Item scroll, SpellInfo info ) + : base( caster, scroll, info ) + { + } + + public virtual int FocusLevel + { + get { return m_CastTimeFocusLevel; } + } + + public static int GetFocusLevel( Mobile from ) + { + ArcaneFocus focus = FindArcaneFocus( from ); + + if( focus == null || focus.Deleted ) + return 0; + + return focus.StrengthBonus; + } + + public static ArcaneFocus FindArcaneFocus( Mobile from ) + { + if( from == null || from.Backpack == null ) + return null; + + return from.Backpack.FindItemByType(); + } + + public static bool CheckExpansion( Mobile from ) + { + if( !(from is PlayerMobile) ) + return true; + + if( from.NetState == null ) + return false; + + return from.NetState.SupportsExpansion( Expansion.ML ); + } + + public override bool CheckCast() + { + if( !base.CheckCast() ) + return false; + + if( !CheckExpansion( Caster ) ) + { + Caster.SendLocalizedMessage( 1072176 ); // You must upgrade to the Mondain's Legacy Expansion Pack before using that ability + return false; + } + + //TODO: Spellweaving quest completion + + int mana = ScaleMana( RequiredMana ); + + if( Caster.Mana < mana ) + { + Caster.SendLocalizedMessage( 1060174, mana.ToString() ); // You must have at least ~1_MANA_REQUIREMENT~ Mana to use this ability. + return false; + } + else if( Caster.Skills[CastSkill].Value < RequiredSkill ) + { + Caster.SendLocalizedMessage( 1063013, String.Format( "{0}\t{1}", RequiredSkill.ToString( "F1" ), "#1044114" ) ); // You need at least ~1_SKILL_REQUIREMENT~ ~2_SKILL_NAME~ skill to use that ability. + return false; + } + + return true; + } + + public override void GetCastSkills( out double min, out double max ) + { + min = RequiredSkill - 12.5; //per 5 on friday, 2/16/07 + max = RequiredSkill + 37.5; + } + + public override int GetMana() + { + return RequiredMana; + } + + public override void DoFizzle() + { + Caster.PlaySound( 0x1D6 ); + Caster.NextSpellTime = DateTime.Now; + } + + public override void DoHurtFizzle() + { + Caster.PlaySound( 0x1D6 ); + } + + public override void OnDisturb( DisturbType type, bool message ) + { + base.OnDisturb( type, message ); + + if( message ) + Caster.PlaySound( 0x1D6 ); + } + + public override void OnBeginCast() + { + base.OnBeginCast(); + + SendCastEffect(); + m_CastTimeFocusLevel = GetFocusLevel( Caster ); + } + + public virtual void SendCastEffect() + { + Caster.FixedEffect( 0x37C4, 10, (int)(GetCastDelay().TotalSeconds * 28), 4, 3 ); + } + + public virtual bool CheckResisted( Mobile m ) + { + double percent = (50 + 2*(GetResistSkill( m ) - GetDamageSkill( m )))/100; //TODO: According to the guide this is it.. but.. is it correct per OSI? + + if( percent <= 0 ) + return false; + + if( percent >= 1.0 ) + return true; + + return (percent >= Utility.RandomDouble()); + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/AttuneWeapon.cs b/Scripts/Spells/Spellweaving/AttuneWeapon.cs new file mode 100644 index 000000000..2b2cc9eeb --- /dev/null +++ b/Scripts/Spells/Spellweaving/AttuneWeapon.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Server.Spells.Spellweaving +{ + public class AttuneWeaponSpell : ArcanistSpell + { + private static SpellInfo m_Info = new SpellInfo( + "Attune Weapon", "Haeldril", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } } + + public override double RequiredSkill { get { return 0.0; } } + public override int RequiredMana { get { return 24; } } + + public AttuneWeaponSpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) + { + } + + public override bool CheckCast() + { + if( m_Table.ContainsKey( Caster ) ) + { + Caster.SendLocalizedMessage( 501775 ); // This spell is already in effect. + return false; + } + else if( !Caster.CanBeginAction( typeof( AttuneWeaponSpell ) ) ) + { + Caster.SendLocalizedMessage( 1075124 ); // You must wait before casting that spell again. + return false; + } + + return base.CheckCast(); + } + + public override void OnCast() + { + if( CheckSequence() ) + { + Caster.PlaySound( 0x5C3 ); + Caster.FixedParticles( 0x3728, 1, 13, 0x26B8, 0x455, 7, EffectLayer.Waist ); + Caster.FixedParticles( 0x3779, 1, 15, 0x251E, 0x3F, 7, EffectLayer.Waist ); + + double skill = Caster.Skills[SkillName.Spellweaving].Value; + + int damageAbsorb = (int)(18 + ((skill-10)/10)*3 + (FocusLevel * 6)); + Caster.MeleeDamageAbsorb = damageAbsorb; + + TimeSpan duration = TimeSpan.FromSeconds( 60 + (FocusLevel * 12) ); + + ExpireTimer t = new ExpireTimer( Caster, duration ); + t.Start(); + + m_Table[Caster] = t; + + Caster.BeginAction( typeof( AttuneWeaponSpell ) ); + + BuffInfo.AddBuff( Caster, new BuffInfo( BuffIcon.AttuneWeapon, 1075798, duration, Caster, damageAbsorb.ToString() ) ); + } + + FinishSequence(); + } + + private static Dictionary m_Table = new Dictionary(); + + public static void TryAbsorb( Mobile defender, ref int damage ) + { + if( damage == 0 || !IsAbsorbing( defender ) || defender.MeleeDamageAbsorb <= 0 ) + return; + + int absorbed = Math.Min( damage, defender.MeleeDamageAbsorb ); + + damage -= absorbed; + defender.MeleeDamageAbsorb -= absorbed; + + defender.SendLocalizedMessage( 1075127, String.Format( "{0}\t{1}", absorbed, defender.MeleeDamageAbsorb ) ); // ~1_damage~ point(s) of damage have been absorbed. A total of ~2_remaining~ point(s) of shielding remain. + + if( defender.MeleeDamageAbsorb <= 0 ) + StopAbsorbing( defender, true ); + } + + public static bool IsAbsorbing( Mobile m ) + { + return m_Table.ContainsKey( m ); + } + + public static void StopAbsorbing( Mobile m, bool message ) + { + ExpireTimer t; + if( m_Table.TryGetValue( m, out t ) ) + { + t.DoExpire( message ); + } + } + + private class ExpireTimer : Timer + { + private Mobile m_Mobile; + + public ExpireTimer( Mobile m, TimeSpan delay ) + : base( delay ) + { + m_Mobile = m; + } + + protected override void OnTick() + { + DoExpire( true ); + } + + public void DoExpire( bool message ) + { + Stop(); + + m_Mobile.MeleeDamageAbsorb = 0; + + if( message ) + { + m_Mobile.SendLocalizedMessage( 1075126 ); // Your attunement fades. + m_Mobile.PlaySound( 0x1F8 ); + } + + m_Table.Remove( m_Mobile ); + + Timer.DelayCall( TimeSpan.FromSeconds( 120 ), delegate { m_Mobile.EndAction( typeof( AttuneWeaponSpell ) ); } ); + BuffInfo.RemoveBuff( m_Mobile, BuffIcon.AttuneWeapon ); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/EssenceOfWind.cs b/Scripts/Spells/Spellweaving/EssenceOfWind.cs new file mode 100644 index 000000000..64f4640d6 --- /dev/null +++ b/Scripts/Spells/Spellweaving/EssenceOfWind.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Server.Spells.Spellweaving +{ + public class EssenceOfWindSpell : ArcanistSpell + { + private static SpellInfo m_Info = new SpellInfo( + "Essence of Wind", "Anathrae", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 3.0 ); } } + + public override double RequiredSkill { get { return 52.0; } } + public override int RequiredMana { get { return 40; } } + + public EssenceOfWindSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) + { + } + + public override void OnCast() + { + if( CheckSequence() ) + { + Caster.PlaySound( 0x5C6 ); + + int range = 5 + FocusLevel; + int damage = 25 + FocusLevel; + + double skill = Caster.Skills[SkillName.Spellweaving].Value; + + TimeSpan duration = TimeSpan.FromSeconds( (int)(skill / 24) + FocusLevel ); + + int fcMalus = 2 * (FocusLevel + 1); + int ssiMalus = FocusLevel + 1; + + List targets = new List(); + + foreach( Mobile m in Caster.GetMobilesInRange( range ) ) + { + if( Caster != m && Caster.InLOS( m ) && SpellHelper.ValidIndirectTarget( Caster, m ) && Caster.CanBeHarmful( m, false ) ) + targets.Add( m ); + } + + for( int i = 0; i < targets.Count; i++ ) + { + Mobile m = targets[i]; + + Caster.DoHarmful( m ); + + SpellHelper.Damage( this, m, damage, 0, 0, 100, 0, 0 ); + + if( !CheckResisted( m ) ) //No message on resist + { + m_Table[m] = new EssenceOfWindInfo( m, fcMalus, ssiMalus, duration ); + + BuffInfo.AddBuff( m, new BuffInfo( BuffIcon.EssenceOfWind, 1075802, duration, m, String.Format( "{0}\t{1}", fcMalus.ToString(), ssiMalus.ToString() ) ) ); + } + } + } + + FinishSequence(); + } + + private static Dictionary m_Table = new Dictionary(); + + private class EssenceOfWindInfo + { + private Mobile m_Defender; + private int m_FCMalus; + private int m_SSIMalus; + private ExpireTimer m_Timer; + + public Mobile Defender { get { return m_Defender; } } + public int FCMalus { get { return m_FCMalus; } } + public int SSIMalus { get { return m_SSIMalus; } } + public ExpireTimer Timer { get { return m_Timer; } } + + public EssenceOfWindInfo( Mobile defender, int fcMalus, int ssiMalus, TimeSpan duration ) + { + m_Defender = defender; + m_FCMalus = fcMalus; + m_SSIMalus = ssiMalus; + + m_Timer = new ExpireTimer( m_Defender, duration ); + m_Timer.Start(); + } + } + + public static int GetFCMalus( Mobile m ) + { + EssenceOfWindInfo info; + + if( m_Table.TryGetValue( m, out info ) ) + return info.FCMalus; + + return 0; + } + + public static int GetSSIMalus( Mobile m ) + { + EssenceOfWindInfo info; + + if( m_Table.TryGetValue( m, out info ) ) + return info.SSIMalus; + + return 0; + } + + public static bool IsDebuffed( Mobile m ) + { + return m_Table.ContainsKey( m ); + } + + public static void StopDebuffing( Mobile m, bool message ) + { + EssenceOfWindInfo info; + + if( m_Table.TryGetValue( m, out info ) ) + info.Timer.DoExpire( message ); + } + + private class ExpireTimer : Timer + { + private Mobile m_Mobile; + + public ExpireTimer( Mobile m, TimeSpan delay ) : base( delay ) + { + m_Mobile = m; + } + + protected override void OnTick() + { + DoExpire( true ); + } + + public void DoExpire( bool message ) + { + Stop(); + /* + if( message ) + { + } + */ + m_Table.Remove( m_Mobile ); + + BuffInfo.RemoveBuff( m_Mobile, BuffIcon.EssenceOfWind ); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/EtherealVoyage.cs b/Scripts/Spells/Spellweaving/EtherealVoyage.cs new file mode 100644 index 000000000..24821a81b --- /dev/null +++ b/Scripts/Spells/Spellweaving/EtherealVoyage.cs @@ -0,0 +1,88 @@ +using System; + +namespace Server.Spells.Spellweaving +{ + public class EtherealVoyageSpell : ArcaneForm + { + private static SpellInfo m_Info = new SpellInfo( + "Ethereal Voyage", "Orlavdra", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 3.5 ); } } + + public override double RequiredSkill { get { return 24.0; } } + public override int RequiredMana { get { return 32; } } + + public override int Body { get { return 0x302; } } + public override int Hue { get { return 0x48F; } } + + public EtherealVoyageSpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) + { + } + + public static void Initialize() + { + EventSink.AggressiveAction += new AggressiveActionEventHandler( delegate( AggressiveActionEventArgs e ) + { + if( TransformationSpellHelper.UnderTransformation( e.Aggressor, typeof( EtherealVoyageSpell ) ) ) + { + TransformationSpellHelper.RemoveContext( e.Aggressor, true ); + } + } ); + } + + public override bool CheckCast() + { + if( TransformationSpellHelper.UnderTransformation( Caster, typeof( EtherealVoyageSpell ) ) ) + { + Caster.SendLocalizedMessage( 501775 ); // This spell is already in effect. + } + else if( !Caster.CanBeginAction( typeof( EtherealVoyageSpell ) ) ) + { + Caster.SendLocalizedMessage( 1075124 ); // You must wait before casting that spell again. + } + else if( Caster.Combatant != null ) + { + Caster.SendLocalizedMessage( 1072586 ); // You cannot cast Ethereal Voyage while you are in combat. + } + else + { + return base.CheckCast(); + } + + return false; + } + + public override void DoEffect( Mobile m ) + { + m.PlaySound( 0x5C8 ); + m.SendLocalizedMessage( 1074770 ); // You are now under the effects of Ethereal Voyage. + + double skill = Caster.Skills.Spellweaving.Value; + + TimeSpan duration = TimeSpan.FromSeconds( 12 + (int)(skill / 24) + (FocusLevel * 2) ); + + Timer.DelayCall( duration, new TimerStateCallback( RemoveEffect ), Caster ); + + Caster.BeginAction( typeof( EtherealVoyageSpell ) ); //Cannot cast this spell for another 5 minutes(300sec) after effect removed. + + BuffInfo.AddBuff( Caster, new BuffInfo( BuffIcon.EtherealVoyage, 1031613, 1075805, duration, Caster ) ); + } + + public override void RemoveEffect( Mobile m ) + { + m.SendLocalizedMessage( 1074771 ); // You are no longer under the effects of Ethereal Voyage. + + TransformationSpellHelper.RemoveContext( m, true ); + + Timer.DelayCall( TimeSpan.FromMinutes( 5 ), delegate + { + m.EndAction( typeof( EtherealVoyageSpell ) ); + } ); + + BuffInfo.RemoveBuff( m, BuffIcon.EtherealVoyage ); + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/GiftOfLife.cs b/Scripts/Spells/Spellweaving/GiftOfLife.cs new file mode 100644 index 000000000..f4300773d --- /dev/null +++ b/Scripts/Spells/Spellweaving/GiftOfLife.cs @@ -0,0 +1,218 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Server.Mobiles; +using Server.Gumps; +using Server.Targeting; + +namespace Server.Spells.Spellweaving +{ + public class GiftOfLifeSpell : ArcanistSpell + { + private static SpellInfo m_Info = new SpellInfo( + "Gift of Life", "Illorae", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 4.0 ); } } + + public override double RequiredSkill { get { return 38.0; } } + public override int RequiredMana { get { return 70; } } + + public GiftOfLifeSpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) + { + } + + public static void Initialize() + { + EventSink.PlayerDeath += new PlayerDeathEventHandler( delegate( PlayerDeathEventArgs e ) + { + HandleDeath( e.Mobile ); + } ); + } + + public override void OnCast() + { + Caster.Target = new InternalTarget( this ); + } + + public void Target( Mobile m ) + { + BaseCreature bc = m as BaseCreature; + + if( !Caster.CanSee( m ) ) + { + Caster.SendLocalizedMessage( 500237 ); // Target can not be seen. + } + else if( m.IsDeadBondedPet || !m.Alive ) + { + // As per Osi: Nothing happens. + } + else if( m != Caster && (bc == null || !bc.IsBonded || bc.ControlMaster != Caster) ) + { + Caster.SendLocalizedMessage( 1072077 ); // You may only cast this spell on yourself or a bonded pet. + } + else if( m_Table.ContainsKey( m ) ) + { + Caster.SendLocalizedMessage( 501775 ); // This spell is already in effect. + } + else if( CheckBSequence( m ) ) + { + if( Caster == m ) + { + Caster.SendLocalizedMessage( 1074774 ); // You weave powerful magic, protecting yourself from death. + } + else + { + Caster.SendLocalizedMessage( 1074775 ); // You weave powerful magic, protecting your pet from death. + SpellHelper.Turn( Caster, m ); + } + + + m.PlaySound( 0x244 ); + m.FixedParticles( 0x3709, 1, 30, 0x26ED, 5, 2, EffectLayer.Waist ); + m.FixedParticles( 0x376A, 1, 30, 0x251E, 5, 3, EffectLayer.Waist ); + + double skill = Caster.Skills[SkillName.Spellweaving].Value; + + TimeSpan duration = TimeSpan.FromMinutes( ((int)(skill / 24))* 2 + FocusLevel ); + + ExpireTimer t = new ExpireTimer( m, duration, this ); + t.Start(); + + m_Table[m] = t; + + BuffInfo.AddBuff( m, new BuffInfo( BuffIcon.GiftOfLife, 1031615, 1075807, duration, m, null, true ) ); + } + + FinishSequence(); + } + + private static Dictionary m_Table = new Dictionary(); + + public static void HandleDeath( Mobile m ) + { + if( m_Table.ContainsKey( m ) ) + Timer.DelayCall( TimeSpan.FromSeconds( Utility.RandomMinMax( 2, 4 ) ), new TimerStateCallback( HandleDeath_OnCallback ), m ); + } + + private static void HandleDeath_OnCallback( Mobile m ) + { + ExpireTimer timer; + + if( m_Table.TryGetValue( m, out timer ) ) + { + double hitsScalar = timer.Spell.HitsScalar; + + if( m is BaseCreature && m.IsDeadBondedPet ) + { + BaseCreature pet = (BaseCreature)m; + Mobile master = pet.GetMaster(); + + if( master != null && master.NetState != null && Utility.InUpdateRange( pet, master ) ) + { + master.CloseGump( typeof( PetResurrectGump ) ); + master.SendGump( new PetResurrectGump( master, pet, hitsScalar ) ); + } + else + { + List friends = pet.Friends; + + for( int i = 0; friends != null && i < friends.Count; i++ ) + { + Mobile friend = friends[i]; + + if( friend.NetState != null && Utility.InUpdateRange( pet, friend ) ) + { + friend.CloseGump( typeof( PetResurrectGump ) ); + friend.SendGump( new PetResurrectGump( friend, pet ) ); + break; + } + } + } + } + else + { + m.CloseGump( typeof( ResurrectGump ) ); + m.SendGump( new ResurrectGump( m, hitsScalar ) ); + } + + //Per OSI, buff is removed when gump sent, irregardless of online status or acceptence + timer.DoExpire(); + } + + } + + public double HitsScalar { get { return ((Caster.Skills.Spellweaving.Value/2.4) + FocusLevel)/100; } } + + public static void OnLogin( LoginEventArgs e ) + { + Mobile m = e.Mobile; + + if( m == null || m.Alive || m_Table[m] == null ) + return; + + HandleDeath_OnCallback( m ); + } + + private class ExpireTimer : Timer + { + private Mobile m_Mobile; + + private GiftOfLifeSpell m_Spell; + + public GiftOfLifeSpell Spell { get { return m_Spell; } } + + public ExpireTimer( Mobile m, TimeSpan delay, GiftOfLifeSpell spell ) + : base( delay ) + { + m_Mobile = m; + m_Spell = spell; + } + + protected override void OnTick() + { + DoExpire(); + } + + public void DoExpire() + { + Stop(); + + m_Mobile.SendLocalizedMessage( 1074776 ); // You are no longer protected with Gift of Life. + m_Table.Remove( m_Mobile ); + + BuffInfo.RemoveBuff( m_Mobile, BuffIcon.GiftOfLife ); + } + } + + public class InternalTarget : Target + { + private GiftOfLifeSpell m_Owner; + + public InternalTarget( GiftOfLifeSpell owner ) + : base( 12, false, TargetFlags.Beneficial ) + { + m_Owner = owner; + } + + protected override void OnTarget( Mobile m, object o ) + { + if( o is Mobile ) + { + m_Owner.Target( (Mobile)o ); + } + else + { + m.SendLocalizedMessage( 1072077 ); // You may only cast this spell on yourself or a bonded pet. + } + } + + protected override void OnTargetFinish( Mobile m ) + { + m_Owner.FinishSequence(); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/GiftOfRenewal.cs b/Scripts/Spells/Spellweaving/GiftOfRenewal.cs new file mode 100644 index 000000000..543e6998a --- /dev/null +++ b/Scripts/Spells/Spellweaving/GiftOfRenewal.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Server.Targeting; + +namespace Server.Spells.Spellweaving +{ + public class GiftOfRenewalSpell : ArcanistSpell + { + private static SpellInfo m_Info = new SpellInfo( + "Gift of Renewal", "Olorisstra", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 3.0 ); } } + + public override double RequiredSkill { get { return 0.0; } } + public override int RequiredMana { get { return 24; } } + + public GiftOfRenewalSpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) + { + } + + public override void OnCast() + { + Caster.Target = new InternalTarget( this ); + } + + public void Target( Mobile m ) + { + if( !Caster.CanSee( m ) ) + { + Caster.SendLocalizedMessage( 500237 ); // Target can not be seen. + } + if( m_Table.ContainsKey( m ) ) + { + Caster.SendLocalizedMessage( 501775 ); // This spell is already in effect. + } + else if( !Caster.CanBeginAction( typeof( GiftOfRenewalSpell ) ) ) + { + Caster.SendLocalizedMessage( 501789 ); // You must wait before trying again. + } + else if( CheckBSequence( m ) ) + { + SpellHelper.Turn( Caster, m ); + + Caster.FixedEffect( 0x374A, 10, 20 ); + Caster.PlaySound( 0x5C9 ); + + if( m.Poisoned ) + { + m.CurePoison( m ); + } + else + { + double skill = Caster.Skills[SkillName.Spellweaving].Value; + + int hitsPerRound = 5 + (int)(skill / 24) + FocusLevel; + TimeSpan duration = TimeSpan.FromSeconds( 30 + (FocusLevel * 10) ); + + GiftOfRenewalInfo info = new GiftOfRenewalInfo( Caster, m, hitsPerRound ); + + Timer.DelayCall( duration, + delegate + { + if( StopEffect( m ) ) + { + m.PlaySound( 0x455 ); + m.SendLocalizedMessage( 1075071 ); // The Gift of Renewal has faded. + } + } ); + + + + m_Table[m] = info; + + Caster.BeginAction( typeof( GiftOfRenewalSpell ) ); + + BuffInfo.AddBuff( m, new BuffInfo( BuffIcon.GiftOfRenewal, 1031602, 1075797, duration, m, hitsPerRound.ToString() ) ); + } + } + + FinishSequence(); + } + + private static Dictionary m_Table = new Dictionary(); + + private class GiftOfRenewalInfo + { + public Mobile m_Caster; + public Mobile m_Mobile; + public int m_HitsPerRound; + public InternalTimer m_Timer; + + public GiftOfRenewalInfo( Mobile caster, Mobile mobile, int hitsPerRound ) + { + m_Caster = caster; + m_Mobile = mobile; + m_HitsPerRound = hitsPerRound; + + m_Timer = new InternalTimer( this ); + m_Timer.Start(); + } + } + + private class InternalTimer : Timer + { + public GiftOfRenewalInfo m_Info; + + public InternalTimer( GiftOfRenewalInfo info ) + : base( TimeSpan.FromSeconds( 2.0 ), TimeSpan.FromSeconds( 2.0 ) ) + { + m_Info = info; + } + + protected override void OnTick() + { + Mobile m = m_Info.m_Mobile; + + if( !m_Table.ContainsKey( m ) ) + { + Stop(); + return; + } + + if( !m.Alive ) + { + Stop(); + StopEffect( m ); + return; + } + + if( m.Hits >= m.HitsMax ) + return; + + int toHeal = m_Info.m_HitsPerRound; + + SpellHelper.Heal( toHeal, m, m_Info.m_Caster ); + m.FixedParticles( 0x376A, 9, 32, 5005, EffectLayer.Waist ); + } + } + + public static bool StopEffect( Mobile m ) + { + GiftOfRenewalInfo info; + + if( m_Table.TryGetValue( m, out info ) ) + { + m_Table.Remove( m ); + + info.m_Timer.Stop(); + BuffInfo.RemoveBuff( m, BuffIcon.GiftOfRenewal ); + + Timer.DelayCall( TimeSpan.FromSeconds( 60 ), delegate { info.m_Caster.EndAction( typeof( GiftOfRenewalSpell ) ); } ); + + return true; + } + + return false; + } + + public class InternalTarget : Target + { + private GiftOfRenewalSpell m_Owner; + + public InternalTarget( GiftOfRenewalSpell owner ) + : base( 12, false, TargetFlags.Beneficial ) + { + m_Owner = owner; + } + + protected override void OnTarget( Mobile m, object o ) + { + if( o is Mobile ) + { + m_Owner.Target( (Mobile)o ); + } + } + + protected override void OnTargetFinish( Mobile m ) + { + m_Owner.FinishSequence(); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/Items/ArcaneFocus.cs b/Scripts/Spells/Spellweaving/Items/ArcaneFocus.cs new file mode 100644 index 000000000..46fafe4c2 --- /dev/null +++ b/Scripts/Spells/Spellweaving/Items/ArcaneFocus.cs @@ -0,0 +1,55 @@ +using System; +using Server; + +namespace Server.Items +{ + public class ArcaneFocus : TransientItem + { + public override int LabelNumber { get { return 1032629; } } // Arcane Focus + + private int m_StrengthBonus; + + [CommandProperty( AccessLevel.GameMaster )] + public int StrengthBonus + { + get { return m_StrengthBonus; } + set { m_StrengthBonus = value; } + } + + public ArcaneFocus( TimeSpan lifeSpan, int strengthBonus ) : base( 0x3155, lifeSpan ) + { + LootType = LootType.Blessed; + m_StrengthBonus = strengthBonus; + } + + public ArcaneFocus( Serial serial ) : base( serial ) + { + } + + public override void GetProperties( ObjectPropertyList list ) + { + base.GetProperties( list ); + + list.Add( 1060485, m_StrengthBonus.ToString() ); // strength bonus ~1_val~ + } + + public override TextDefinition InvalidTransferMessage{ get { return 1073480; } } // Your arcane focus disappears. + public override bool Nontransferable { get { return true; } } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int)0 ); + + writer.Write( m_StrengthBonus ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + + m_StrengthBonus = reader.ReadInt(); + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/Items/TransientItem.cs b/Scripts/Spells/Spellweaving/Items/TransientItem.cs new file mode 100644 index 000000000..2f2d4c0e8 --- /dev/null +++ b/Scripts/Spells/Spellweaving/Items/TransientItem.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using Server; +using Server.Mobiles; + +namespace Server.Items +{ + public class TransientItem : Item + { + private TimeSpan m_LifeSpan; + + [CommandProperty( AccessLevel.GameMaster )] + public TimeSpan LifeSpan + { + get { return m_LifeSpan; } + set { m_LifeSpan = value; } + } + + private DateTime m_CreationTime; + + [CommandProperty( AccessLevel.GameMaster )] + public DateTime CreationTime + { + get { return m_CreationTime; } + set { m_CreationTime = value; } + } + + private Timer m_Timer; + + public override bool Nontransferable { get { return true; } } + public override void HandleInvalidTransfer( Mobile from ) + { + if( InvalidTransferMessage != null ) + TextDefinition.SendMessageTo( from, InvalidTransferMessage ); + + this.Delete(); + } + + public virtual TextDefinition InvalidTransferMessage { get { return null; } } + + + public virtual void Expire( Mobile parent ) + { + if( parent != null ) + parent.SendLocalizedMessage( 1072515, (this.Name == null ? String.Format( "#{0}", LabelNumber ): this.Name) ); // The ~1_name~ expired... + + Effects.PlaySound( GetWorldLocation(), Map, 0x201 ); + + this.Delete(); + } + + public virtual void SendTimeRemainingMessage( Mobile to ) + { + to.SendLocalizedMessage( 1072516, String.Format( "{0}\t{1}", (this.Name == null ? String.Format( "#{0}", LabelNumber ): this.Name), (int)m_LifeSpan.TotalSeconds ) ); // ~1_name~ will expire in ~2_val~ seconds! + } + + public override void OnDelete() + { + if( m_Timer != null ) + m_Timer.Stop(); + + base.OnDelete(); + } + + public virtual void CheckExpiry() + { + if( (m_CreationTime + m_LifeSpan) < DateTime.Now ) + Expire( RootParent as Mobile ); + else + InvalidateProperties(); + } + + [Constructable] + public TransientItem( int itemID, TimeSpan lifeSpan ) + : base( itemID ) + { + m_CreationTime = DateTime.Now; + m_LifeSpan = lifeSpan; + + m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 5 ), TimeSpan.FromSeconds( 5 ), new TimerCallback( CheckExpiry ) ); + } + + public TransientItem( Serial serial ) + : base( serial ) + { + } + + public override void GetProperties( ObjectPropertyList list ) + { + base.GetProperties( list ); + + TimeSpan remaining = ((m_CreationTime + m_LifeSpan) - DateTime.Now); + + list.Add( 1072517, ((int)remaining.TotalSeconds).ToString() ); // Lifespan: ~1_val~ seconds + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int)0 ); + + writer.Write( m_LifeSpan ); + writer.Write( m_CreationTime ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + + m_LifeSpan = reader.ReadTimeSpan(); + m_CreationTime = reader.ReadDateTime(); + + m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 5 ), TimeSpan.FromSeconds( 5 ), new TimerCallback( CheckExpiry ) ); + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/Mobiles/ArcaneFey.cs b/Scripts/Spells/Spellweaving/Mobiles/ArcaneFey.cs new file mode 100644 index 000000000..0511aa0b9 --- /dev/null +++ b/Scripts/Spells/Spellweaving/Mobiles/ArcaneFey.cs @@ -0,0 +1,66 @@ +using System; +using Server; +using Server.Misc; + +namespace Server.Mobiles +{ + [CorpseName( "a pixie corpse" )] + public class ArcaneFey : BaseCreature + { + public override double DispelDifficulty { get { return 70.0; } } + public override double DispelFocus { get { return 20.0; } } + + public override OppositionGroup OppositionGroup { get { return OppositionGroup.FeyAndUndead; } } + public override bool InitialInnocent { get { return true; } } + + [Constructable] + public ArcaneFey() : base( AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4 ) + { + Name = NameList.RandomName( "pixie" ); + Body = 128; + BaseSoundID = 0x467; + + SetStr( 20 ); + SetDex( 150 ); + SetInt( 125 ); + + SetDamage( 9, 15 ); + + SetDamageType( ResistanceType.Physical, 100 ); + + SetResistance( ResistanceType.Physical, 80, 90 ); + SetResistance( ResistanceType.Fire, 40, 50 ); + SetResistance( ResistanceType.Cold, 40, 50 ); + SetResistance( ResistanceType.Poison, 40, 50 ); + SetResistance( ResistanceType.Energy, 40, 50 ); + + SetSkill( SkillName.EvalInt, 70.1, 80.0 ); + SetSkill( SkillName.Magery, 70.1, 80.0 ); + SetSkill( SkillName.Meditation, 70.1, 80.0 ); + SetSkill( SkillName.MagicResist, 50.5, 100.0 ); + SetSkill( SkillName.Tactics, 10.1, 20.0 ); + SetSkill( SkillName.Wrestling, 10.1, 12.5 ); + + Fame = 0; + Karma = 0; + + ControlSlots = 1; + } + + public ArcaneFey( Serial serial ) : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/Mobiles/ArcaneFiend.cs b/Scripts/Spells/Spellweaving/Mobiles/ArcaneFiend.cs new file mode 100644 index 000000000..a54735857 --- /dev/null +++ b/Scripts/Spells/Spellweaving/Mobiles/ArcaneFiend.cs @@ -0,0 +1,67 @@ +using System; +using Server; +using Server.Items; + +namespace Server.Mobiles +{ + [CorpseName( "an imp corpse" )] + public class ArcaneFiend : BaseCreature + { + public override double DispelDifficulty { get { return 70.0; } } + public override double DispelFocus { get { return 20.0; } } + + public override PackInstinct PackInstinct { get { return PackInstinct.Daemon; } } + public override bool BleedImmune { get { return true; } } //TODO: Verify on OSI. Guide says this. + + [Constructable] + public ArcaneFiend() : base( AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 ) + { + Name = "an imp"; + Body = 74; + BaseSoundID = 422; + + SetStr( 55 ); + SetDex( 40 ); + SetInt( 60 ); + + SetDamage( 10, 14 ); + + SetDamageType( ResistanceType.Physical, 0 ); + SetDamageType( ResistanceType.Fire, 50 ); + SetDamageType( ResistanceType.Poison, 50 ); + + SetResistance( ResistanceType.Physical, 25, 35 ); + SetResistance( ResistanceType.Fire, 40, 50 ); + SetResistance( ResistanceType.Cold, 20, 30 ); + SetResistance( ResistanceType.Poison, 30, 40 ); + SetResistance( ResistanceType.Energy, 30, 40 ); + + SetSkill( SkillName.EvalInt, 20.1, 30.0 ); + SetSkill( SkillName.Magery, 60.1, 70.0 ); + SetSkill( SkillName.MagicResist, 30.1, 50.0 ); + SetSkill( SkillName.Tactics, 42.1, 50.0 ); + SetSkill( SkillName.Wrestling, 40.1, 44.0 ); + + Fame = 0; + Karma = 0; + + ControlSlots = 1; + } + + public ArcaneFiend( Serial serial ) : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/Mobiles/NatureFury.cs b/Scripts/Spells/Spellweaving/Mobiles/NatureFury.cs new file mode 100644 index 000000000..b886208a3 --- /dev/null +++ b/Scripts/Spells/Spellweaving/Mobiles/NatureFury.cs @@ -0,0 +1,106 @@ +using System; +using Server; +using Server.Misc; + +namespace Server.Mobiles +{ + public class NatureFury : BaseCreature + { + public override bool DeleteCorpseOnDeath { get { return Core.AOS; } } + public override bool IsHouseSummonable { get { return true; } } + + public override double DispelDifficulty { get { return 125.0; } } + public override double DispelFocus { get { return 90.0; } } + + public override bool BleedImmune { get { return true; } } + public override Poison PoisonImmune { get { return Poison.Lethal; } } + + public override bool AlwaysMurderer { get { return true; } } + + private Mobile m_Target; + + public override Mobile ConstantFocus { get { return m_Target; } } + + public override void OnThink() + { + if( m_Target != null && (!m_Target.Alive || m_Target.Deleted || !InRange( m_Target, 24 ) || !CanSee( m_Target )) ) + m_Target = null; //Go kill other stuffs + + base.OnThink(); + } + + [Constructable] + public NatureFury( Mobile target ) + : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 ) + { + m_Target = target; + Name = "a nature's fury"; + Body = 0x33; + Hue = 0x4001; + + SetStr( 150 ); + SetDex( 150 ); + SetInt( 100 ); + + SetHits( 80 ); + SetStam( 250 ); + SetMana( 0 ); + + SetDamage( 5, 7 ); + + SetDamageType( ResistanceType.Poison, 100 ); + + SetResistance( ResistanceType.Physical, 90 ); + + SetSkill( SkillName.Wrestling, 90.0 ); + SetSkill( SkillName.MagicResist, 70.0 ); + SetSkill( SkillName.Tactics, 100.0 ); + + Fame = 0; + Karma = 0; + + ControlSlots = 1; + } + + [Constructable] + public NatureFury() + : this( null ) //Null makes it act like any other mob + { + } + + public override void MoveToWorld( Point3D loc, Map map ) + { + base.MoveToWorld( loc, map ); + Timer.DelayCall( TimeSpan.Zero, DoEffects ); + } + + public void DoEffects() + { + FixedParticles( 0x91C, 10, 180, 0x2543, 0, 0, EffectLayer.Waist ); + PlaySound( 0xE ); + PlaySound( 0x1BC ); + + if( Alive && !Deleted ) + Timer.DelayCall( TimeSpan.FromSeconds( 7.0 ), DoEffects ); + } + + public NatureFury( Serial serial ) + : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int)0 ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + + Delete(); + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/NatureFury.cs b/Scripts/Spells/Spellweaving/NatureFury.cs new file mode 100644 index 000000000..189797e97 --- /dev/null +++ b/Scripts/Spells/Spellweaving/NatureFury.cs @@ -0,0 +1,122 @@ +using System; +using Server.Mobiles; +using Server.Targeting; + +namespace Server.Spells.Spellweaving +{ + public class NatureFurySpell : ArcanistSpell + { + private static SpellInfo m_Info = new SpellInfo( + "Nature's Fury", "Rauvvrae", + -1, + false + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + + public override double RequiredSkill { get { return 0.0; } } + public override int RequiredMana { get { return 24; } } + + public NatureFurySpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) + { + } + + private bool m_MobileTarg; + + public override int GetMana() + { + int mana = base.GetMana(); + + if( m_MobileTarg ) + mana *= 2; + + return mana; + } + + + + public override bool CheckCast() + { + if( !base.CheckCast() ) + return false; + + if( (Caster.Followers + 1) > Caster.FollowersMax ) + { + Caster.SendLocalizedMessage( 1049645 ); // You have too many followers to summon that creature. + return false; + } + + return true; + } + + public override void OnCast() + { + Caster.Target = new InternalTarget( this ); + } + + public void Target( IPoint3D point ) + { + //What happens if you cast it on yourself? OSI ANSWER: You're an idiot for wasting the mana, and it'll just look for another target. + Mobile m = point as Mobile; + Point3D p = new Point3D( point ); + Map map = Caster.Map; + + m_MobileTarg = (m != null); + + + + if( !SpellHelper.FindValidSpawnLocation( map, ref p, m_MobileTarg ) ) + { + Caster.SendLocalizedMessage( 501942 ); // That location is blocked. + } + else if( SpellHelper.CheckTown( p, Caster ) && (m_MobileTarg ? CheckHSequence( m ) : CheckSequence()) ) + { + TimeSpan duration = TimeSpan.FromSeconds( Caster.Skills.Spellweaving.Value/24 + 25 + FocusLevel*2 ); + + if( m == Caster ) + m = null; + + NatureFury nf = new NatureFury( m ); + BaseCreature.Summon( nf, false, Caster, p , 0x5CB, duration ); + + Timer t = null; + + t = Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ), delegate + { + if( !nf.Alive || nf.Deleted || nf.DamageMin > 20 ) //sanity + t.Stop(); + + nf.DamageMin++; + nf.DamageMax++; + } ); + } + + FinishSequence(); + } + + private class InternalTarget : Target + { + private NatureFurySpell m_Owner; + + public InternalTarget( NatureFurySpell owner ) + : base( 12, true, TargetFlags.None ) + { + m_Owner = owner; + } + + protected override void OnTarget( Mobile from, object o ) + { + if( o is IPoint3D ) + m_Owner.Target( (IPoint3D)o ); + } + + + protected override void OnTargetFinish( Mobile from ) + { + if( m_Owner != null ) + m_Owner.FinishSequence(); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/ReaperForm.cs b/Scripts/Spells/Spellweaving/ReaperForm.cs new file mode 100644 index 000000000..b8a3719a1 --- /dev/null +++ b/Scripts/Spells/Spellweaving/ReaperForm.cs @@ -0,0 +1,58 @@ +using System; +using Server.Network; + +namespace Server.Spells.Spellweaving +{ + public class ReaperFormSpell : ArcaneForm + { + private static SpellInfo m_Info = new SpellInfo( + "Reaper Form", "Tarisstree", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.5 ); } } + + public static void Initialize() + { + EventSink.Login += new LoginEventHandler( OnLogin ); + } + + public static void OnLogin( LoginEventArgs e ) + { + TransformContext context = TransformationSpellHelper.GetContext( e.Mobile ); + + if( context != null && context.Type == typeof( ReaperFormSpell ) ) + e.Mobile.Send( SpeedControl.WalkSpeed ); + } + + public override double RequiredSkill { get { return 24.0; } } + public override int RequiredMana { get { return 34; } } + + public override int Body { get { return 0x11D; } } + + public override int FireResistOffset { get { return -25; } } + public override int PhysResistOffset { get { return 5 + FocusLevel; } } + public override int ColdResistOffset { get { return 5 + FocusLevel; } } + public override int PoisResistOffset { get { return 5 + FocusLevel; } } + public override int NrgyResistOffset { get { return 5 + FocusLevel; } } + + public virtual int SwingSpeedBonus { get { return 10 + FocusLevel; } } + public virtual int SpellDamageBonus { get { return 10 + FocusLevel; } } + + public ReaperFormSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) + { + } + + public override void DoEffect( Mobile m ) + { + m.PlaySound( 0x1BA ); + + m.Send( SpeedControl.WalkSpeed ); + } + + public override void RemoveEffect( Mobile m ) + { + m.Send( SpeedControl.Disable ); + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/SummonFey.cs b/Scripts/Spells/Spellweaving/SummonFey.cs new file mode 100644 index 000000000..b1e23fa6e --- /dev/null +++ b/Scripts/Spells/Spellweaving/SummonFey.cs @@ -0,0 +1,25 @@ +using System; +using Server.Mobiles; + +namespace Server.Spells.Spellweaving +{ + public class SummonFeySpell : ArcaneSummon + { + private static SpellInfo m_Info = new SpellInfo( + "Summon Fey", "Alalithra", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + + public override double RequiredSkill { get { return 38.0; } } + public override int RequiredMana { get { return 10; } } + + public SummonFeySpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) + { + } + + public override int Sound { get { return 0x217; } } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/SummonFiend.cs b/Scripts/Spells/Spellweaving/SummonFiend.cs new file mode 100644 index 000000000..6285354df --- /dev/null +++ b/Scripts/Spells/Spellweaving/SummonFiend.cs @@ -0,0 +1,25 @@ +using System; +using Server.Mobiles; + +namespace Server.Spells.Spellweaving +{ + public class SummonFiendSpell : ArcaneSummon + { + private static SpellInfo m_Info = new SpellInfo( + "Summon Fiend", "Nylisstra", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } } + + public override double RequiredSkill { get { return 38.0; } } + public override int RequiredMana { get { return 10; } } + + public SummonFiendSpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) + { + } + + public override int Sound { get { return 0x216; } } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/Thunderstorm.cs b/Scripts/Spells/Spellweaving/Thunderstorm.cs new file mode 100644 index 000000000..2eed57bd0 --- /dev/null +++ b/Scripts/Spells/Spellweaving/Thunderstorm.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Server.Spells.Spellweaving +{ + public class ThunderstormSpell : ArcanistSpell + { + private static SpellInfo m_Info = new SpellInfo( + "Thunderstorm", "Erelonia", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.5 ); } } + + public override double RequiredSkill { get { return 10.0; } } + public override int RequiredMana { get { return 32; } } + + public ThunderstormSpell( Mobile caster, Item scroll ) + : base( caster, scroll, m_Info ) + { + } + + public override void OnCast() + { + if( CheckSequence() ) + { + Caster.PlaySound( 0x5CE ); + + int range = 2 + FocusLevel; + int damage = 15 + FocusLevel; + TimeSpan duration = TimeSpan.FromSeconds( 5 + FocusLevel ); + + List targets = new List(); + + foreach( Mobile m in Caster.GetMobilesInRange( range ) ) + { + if( Caster != m && SpellHelper.ValidIndirectTarget( Caster, m ) && Caster.CanBeHarmful( m, false ) && Caster.InLOS( m ) ) + targets.Add( m ); + } + + for( int i = 0; i < targets.Count; i++ ) + { + Mobile m = targets[i]; + + Caster.DoHarmful( m ); + + Spell oldSpell = m.Spell as Spell; + + SpellHelper.Damage( this, m, damage, 0, 0, 0, 0, 100 ); + + if( oldSpell != null && oldSpell != m.Spell ) + { + if( !CheckResisted( m ) ) + { + m_Table[m] = Timer.DelayCall( duration, DoExpire, m ); + + BuffInfo.AddBuff( m, new BuffInfo( BuffIcon.Thunderstorm, 1075800, duration, m, GetCastRecoveryMalus( m ) ) ); + } + } + } + } + + FinishSequence(); + } + + private static Dictionary m_Table = new Dictionary(); + + public static int GetCastRecoveryMalus( Mobile m ) + { + return m_Table.ContainsKey( m ) ? 6 : 0; + } + + public static void DoExpire( Mobile m ) + { + Timer t; + + if( m_Table.TryGetValue( m, out t ) ) + { + t.Stop(); + m_Table.Remove( m ); + + BuffInfo.RemoveBuff( m, BuffIcon.Thunderstorm ); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Spellweaving/WordOfDeath.cs b/Scripts/Spells/Spellweaving/WordOfDeath.cs new file mode 100644 index 000000000..4e416cd62 --- /dev/null +++ b/Scripts/Spells/Spellweaving/WordOfDeath.cs @@ -0,0 +1,89 @@ +using System; +using Server.Targeting; +using Server.Network; + +namespace Server.Spells.Spellweaving +{ + public class WordOfDeathSpell : ArcanistSpell + { + private static SpellInfo m_Info = new SpellInfo( + "Word of Death", "Nyraxle", + -1 + ); + + public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 3.5 ); } } + + public override double RequiredSkill { get { return 80.0; } } + public override int RequiredMana { get { return 50; } } + + public WordOfDeathSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) + { + } + + public override void OnCast() + { + Caster.Target = new InternalTarget( this ); + } + + public void Target( Mobile m ) + { + if( !Caster.CanSee( m ) ) + { + Caster.SendLocalizedMessage( 500237 ); // Target can not be seen. + } + else if( CheckHSequence( m ) ) + { + Point3D loc = m.Location; + loc.Z += 50; + + m.PlaySound( 0x211 ); + m.FixedParticles( 0x3779, 1, 30, 0x26EC, 0x3, 0x3, EffectLayer.Waist ); + + Effects.SendMovingParticles( new Entity( Serial.Zero, loc, m.Map ), new Entity( Serial.Zero, m.Location, m.Map ), 0xF5F, 1, 0, true, false, 0x21, 0x3F, 0x251D, 0, 0, EffectLayer.Head, 0 ); + + int percentage = 5 + (5 * FocusLevel); + + int damage; + + if( !m.Player && ((m.Hits / m.HitsMax)*100) < percentage ) + { + damage = 300; + } + else + { + damage = GetNewAosDamage( (int)Math.Max( Caster.Skills.Spellweaving.Value/24, 1 ) + 4, 1, 4, m ); + } + + int[] types = new int[4]; + types[Utility.Random( types.Length )] = 100; + + SpellHelper.Damage( this, m, damage, 0, types[0], types[1], types[2], types[3] ); //Chaos damage. Random elemental damage + } + + FinishSequence(); + } + + public class InternalTarget : Target + { + private WordOfDeathSpell m_Owner; + + public InternalTarget( WordOfDeathSpell owner ) : base( 12, false, TargetFlags.Harmful ) + { + m_Owner = owner; + } + + protected override void OnTarget( Mobile m, object o ) + { + if( o is Mobile ) + { + m_Owner.Target( (Mobile)o ); + } + } + + protected override void OnTargetFinish( Mobile m ) + { + m_Owner.FinishSequence(); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Spells/Third/Bless.cs b/Scripts/Spells/Third/Bless.cs index 2b410919b..55f57ebf0 100644 --- a/Scripts/Spells/Third/Bless.cs +++ b/Scripts/Spells/Third/Bless.cs @@ -4,17 +4,18 @@ using Server.Network; namespace Server.Spells.Third { - public class BlessSpell : Spell + public class BlessSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Bless", "Rel Sanct", - SpellCircle.Third, 203, 9061, Reagent.Garlic, Reagent.MandrakeRoot ); + public override SpellCircle Circle { get { return SpellCircle.Third; } } + public BlessSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Third/Fireball.cs b/Scripts/Spells/Third/Fireball.cs index 29cd3029e..8f287445a 100644 --- a/Scripts/Spells/Third/Fireball.cs +++ b/Scripts/Spells/Third/Fireball.cs @@ -4,16 +4,17 @@ using Server.Network; namespace Server.Spells.Third { - public class FireballSpell : Spell + public class FireballSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Fireball", "Vas Flam", - SpellCircle.Third, 203, 9041, Reagent.BlackPearl ); + public override SpellCircle Circle { get { return SpellCircle.Third; } } + public FireballSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Third/MagicLock.cs b/Scripts/Spells/Third/MagicLock.cs index 89f4d5561..5edf027b4 100644 --- a/Scripts/Spells/Third/MagicLock.cs +++ b/Scripts/Spells/Third/MagicLock.cs @@ -5,11 +5,10 @@ using Server.Items; namespace Server.Spells.Third { - public class MagicLockSpell : Spell + public class MagicLockSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Magic Lock", "An Por", - SpellCircle.Third, 215, 9001, Reagent.Garlic, @@ -17,6 +16,8 @@ namespace Server.Spells.Third Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Third; } } + public MagicLockSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Third/Poison.cs b/Scripts/Spells/Third/Poison.cs index f43ccf149..974f0da00 100644 --- a/Scripts/Spells/Third/Poison.cs +++ b/Scripts/Spells/Third/Poison.cs @@ -4,16 +4,17 @@ using Server.Network; namespace Server.Spells.Third { - public class PoisonSpell : Spell + public class PoisonSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Poison", "In Nox", - SpellCircle.Third, 203, 9051, Reagent.Nightshade ); + public override SpellCircle Circle { get { return SpellCircle.Third; } } + public PoisonSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Third/Telekinesis.cs b/Scripts/Spells/Third/Telekinesis.cs index b6c40a7a9..07513cc65 100644 --- a/Scripts/Spells/Third/Telekinesis.cs +++ b/Scripts/Spells/Third/Telekinesis.cs @@ -6,17 +6,18 @@ using Server.Items; namespace Server.Spells.Third { - public class TelekinesisSpell : Spell + public class TelekinesisSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Telekinesis", "Ort Por Ylem", - SpellCircle.Third, 203, 9031, Reagent.Bloodmoss, Reagent.MandrakeRoot ); + public override SpellCircle Circle { get { return SpellCircle.Third; } } + public TelekinesisSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Third/Teleport.cs b/Scripts/Spells/Third/Teleport.cs index 5bc593300..bfef29bdc 100644 --- a/Scripts/Spells/Third/Teleport.cs +++ b/Scripts/Spells/Third/Teleport.cs @@ -6,17 +6,18 @@ using Server.Items; namespace Server.Spells.Third { - public class TeleportSpell : Spell + public class TeleportSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Teleport", "Rel Por", - SpellCircle.Third, 215, 9031, Reagent.Bloodmoss, Reagent.MandrakeRoot ); + public override SpellCircle Circle { get { return SpellCircle.Third; } } + public TeleportSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Third/Unlock.cs b/Scripts/Spells/Third/Unlock.cs index 790ac62f7..080d410d9 100644 --- a/Scripts/Spells/Third/Unlock.cs +++ b/Scripts/Spells/Third/Unlock.cs @@ -5,17 +5,18 @@ using Server.Items; namespace Server.Spells.Third { - public class UnlockSpell : Spell + public class UnlockSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Unlock Spell", "Ex Por", - SpellCircle.Third, 215, 9001, Reagent.Bloodmoss, Reagent.SulfurousAsh ); + public override SpellCircle Circle { get { return SpellCircle.Third; } } + public UnlockSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Scripts/Spells/Third/WallOfStone.cs b/Scripts/Spells/Third/WallOfStone.cs index e6fd51359..e89e8a5c7 100644 --- a/Scripts/Spells/Third/WallOfStone.cs +++ b/Scripts/Spells/Third/WallOfStone.cs @@ -6,11 +6,10 @@ using Server.Items; namespace Server.Spells.Third { - public class WallOfStoneSpell : Spell + public class WallOfStoneSpell : MagerySpell { private static SpellInfo m_Info = new SpellInfo( "Wall of Stone", "In Sanct Ylem", - SpellCircle.Third, 227, 9011, false, @@ -18,6 +17,8 @@ namespace Server.Spells.Third Reagent.Garlic ); + public override SpellCircle Circle { get { return SpellCircle.Third; } } + public WallOfStoneSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } diff --git a/Server/ClientVersion.cs b/Server/ClientVersion.cs index 305af72c6..c1fe80e44 100644 --- a/Server/ClientVersion.cs +++ b/Server/ClientVersion.cs @@ -33,70 +33,6 @@ namespace Server public class ClientVersion : IComparable, IComparer { - private static ClientVersion m_Required; - private static bool m_AllowRegular = true, m_AllowUOTD = true, m_AllowGod = true; - private static TimeSpan m_KickDelay = TimeSpan.FromSeconds( 10.0 ); - - public static ClientVersion Required - { - get - { - return m_Required; - } - set - { - m_Required = value; - } - } - - public static bool AllowRegular - { - get - { - return m_AllowRegular; - } - set - { - m_AllowRegular = value; - } - } - - public static bool AllowUOTD - { - get - { - return m_AllowUOTD; - } - set - { - m_AllowUOTD = value; - } - } - - public static bool AllowGod - { - get - { - return m_AllowGod; - } - set - { - m_AllowGod = value; - } - } - - public static TimeSpan KickDelay - { - get - { - return m_KickDelay; - } - set - { - m_KickDelay = value; - } - } - private int m_Major, m_Minor, m_Revision, m_Patch; private ClientType m_Type; private string m_SourceString; diff --git a/Server/EventSink.cs b/Server/EventSink.cs index 85f2f8a67..a40312116 100644 --- a/Server/EventSink.cs +++ b/Server/EventSink.cs @@ -72,6 +72,22 @@ namespace Server public delegate BaseGuild CreateGuildHandler( CreateGuildEventArgs e ); public delegate void GuildGumpRequestHandler( GuildGumpRequestArgs e ); public delegate void QuestGumpRequestHandler( QuestGumpRequestArgs e ); + public delegate void ClientVersionRecievedHandler( ClientVersionRecievedArgs e ); + + public class ClientVersionRecievedArgs : EventArgs + { + private NetState m_State; + private ClientVersion m_Version; + + public NetState State { get { return m_State; } } + public ClientVersion Version { get { return m_Version; } } + + public ClientVersionRecievedArgs( NetState state, ClientVersion cv ) + { + m_State = state; + m_Version = cv; + } + } public class CreateGuildEventArgs : EventArgs { @@ -816,6 +832,13 @@ namespace Server public static event ServerStartedEventHandler ServerStarted; public static event GuildGumpRequestHandler GuildGumpRequest; public static event QuestGumpRequestHandler QuestGumpRequest; + public static event ClientVersionRecievedHandler ClientVersionRecieved; + + public static void InvokeClientVersionRecieved( ClientVersionRecievedArgs e ) + { + if( ClientVersionRecieved != null ) + ClientVersionRecieved( e ); + } public static void InvokeServerStarted() { diff --git a/Server/ExpansionInfo.cs b/Server/ExpansionInfo.cs index c497c02fd..c639cb204 100644 --- a/Server/ExpansionInfo.cs +++ b/Server/ExpansionInfo.cs @@ -77,6 +77,8 @@ namespace Server new ExpansionInfo( 1, "Age of Shadows" , 0x08, 0x801F, 0x028, 0x20 ), new ExpansionInfo( 2, "Samurai Empire" , 0x10, 0x805F, 0x0A8, 0x60 ), //0x40 | 0x20 = 0x60 new ExpansionInfo( 3, "Mondain's Legacy", new ClientVersion( "5.0.0a" ), 0x82DF, 0x1A8, 0x2E0 ) //0x280 | 0x60 = 0x2E0 + + //0x200 + 0x400 for KR? }; public static ExpansionInfo GetInfo( Expansion ex ) diff --git a/Server/Item.cs b/Server/Item.cs index e42d3248b..c934b8570 100644 --- a/Server/Item.cs +++ b/Server/Item.cs @@ -687,7 +687,8 @@ namespace Server Stackable = 0x08, InQueue = 0x10, Insured = 0x20, - PayedInsurance = 0x40 + PayedInsurance = 0x40, + QuestItem = 0x80 } private class CompactInfo @@ -1034,13 +1035,24 @@ namespace Server if ( DisplayLootType ) AddLootTypeProperty( list ); - if ( DisplayWeight ) { + if ( DisplayWeight ) AddWeightProperty( list ); - } + + if( QuestItem ) + AddQuestItemProperty( list ); + AppendChildNameProperties( list ); } + /// + /// Overridable. Adds the "Quest Item" property to the given . + /// + public virtual void AddQuestItemProperty( ObjectPropertyList list ) + { + list.Add( 1072351 ); // Quest Item + } + /// /// Overridable. Adds the "Locked Down & Secure" property to the given . /// @@ -1204,6 +1216,8 @@ namespace Server return DeathMoveResult.MoveToBackpack; else if ( CheckNewbied() && parent.Kills < 5 ) return DeathMoveResult.MoveToBackpack; + else if( parent.Player && Nontransferable ) + return DeathMoveResult.MoveToBackpack; else return DeathMoveResult.MoveToCorpse; } @@ -1218,6 +1232,8 @@ namespace Server return DeathMoveResult.MoveToBackpack; else if ( CheckNewbied() && parent.Kills < 5 ) return DeathMoveResult.MoveToBackpack; + else if( parent.Player && Nontransferable ) + return DeathMoveResult.MoveToBackpack; else return DeathMoveResult.MoveToCorpse; } @@ -1491,7 +1507,7 @@ namespace Server } } - public virtual bool StackWith( Mobile from, Item dropped ) + public bool StackWith( Mobile from, Item dropped ) { return StackWith( from, dropped, true ); } @@ -1969,7 +1985,7 @@ namespace Server } } - ImplFlag implFlags = ( m_Flags & ( ImplFlag.Visible | ImplFlag.Movable | ImplFlag.Stackable | ImplFlag.Insured | ImplFlag.PayedInsurance ) ); + ImplFlag implFlags = ( m_Flags & ( ImplFlag.Visible | ImplFlag.Movable | ImplFlag.Stackable | ImplFlag.Insured | ImplFlag.PayedInsurance | ImplFlag.QuestItem ) ); if ( implFlags != ( ImplFlag.Visible | ImplFlag.Movable ) ) flags |= SaveFlag.ImplFlags; @@ -2738,7 +2754,7 @@ namespace Server { get { - return m_Hue; + return (QuestItem ? QuestItemHue : m_Hue); } set { @@ -2752,6 +2768,22 @@ namespace Server } } + public virtual int QuestItemHue + { + get { return 0x04EA; } //HMMMM... For EA? + } + + public virtual bool Nontransferable + { + get { return QuestItem; } + } + + public virtual void HandleInvalidTransfer( Mobile from ) + { + if( QuestItem ) + from.SendLocalizedMessage( 1074769 ); // An item must be in your backpack (and not in a container within) to be toggled as a quest item. + } + [CommandProperty( AccessLevel.GameMaster )] public virtual Layer Layer { @@ -2807,6 +2839,30 @@ namespace Server } } + public bool ParentsContain() where T : Item + { + object p = m_Parent; + + while( p is Item ) + { + if( p is T ) + return true; + + Item item = (Item)p; + + if( item.m_Parent == null ) + { + break; + } + else + { + p = item.m_Parent; + } + } + + return false; + } + public virtual void AddItem( Item item ) { if ( item == null || item.Deleted || item.m_Parent == this ) @@ -3289,7 +3345,7 @@ namespace Server } } - public virtual void OnAfterDuped( Item newItem ) + public virtual void OnAfterDuped( Item newItem ) { } @@ -3352,6 +3408,8 @@ namespace Server } } + #region Location Location Location! + public virtual void OnLocationChange( Point3D oldLocation ) { } @@ -3463,6 +3521,7 @@ namespace Server get{ return m_Location.m_Z; } set{ Location = new Point3D( m_Location.m_X, m_Location.m_Y, value ); } } + #endregion [CommandProperty( AccessLevel.GameMaster )] public virtual int ItemID @@ -3633,6 +3692,12 @@ namespace Server public virtual bool OnDroppedToMobile( Mobile from, Mobile target ) { + if( Nontransferable && from.Player && from.AccessLevel <= AccessLevel.GameMaster ) + { + HandleInvalidTransfer( from ); + return false; + } + return true; } @@ -3656,8 +3721,15 @@ namespace Server public virtual bool OnDroppedInto( Mobile from, Container target, Point3D p ) { - if ( !from.OnDroppedItemInto( this, target, p ) ) + if( !from.OnDroppedItemInto( this, target, p ) ) + { return false; + } + else if( Nontransferable && from.Player && target != from.Backpack && from.AccessLevel <= AccessLevel.GameMaster ) + { + HandleInvalidTransfer( from ); + return false; + } return target.OnDragDropInto( from, this, p ); } @@ -3674,6 +3746,11 @@ namespace Server return false; else if ( !from.OnDroppedItemOnto( this, target ) ) return false; + else if( Nontransferable && from.Player && from.AccessLevel <= AccessLevel.GameMaster ) + { + HandleInvalidTransfer( from ); + return false; + } else return target.OnDragDrop( from, this ); } @@ -3703,6 +3780,12 @@ namespace Server public virtual bool OnDroppedToWorld( Mobile from, Point3D p ) { + if( Nontransferable && from.Player && from.AccessLevel <= AccessLevel.GameMaster ) + { + HandleInvalidTransfer( from ); + return false; + } + return true; } @@ -4023,6 +4106,8 @@ namespace Server to.Send( new MessageLocalizedAffix( Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", affixType, affix, args ) ); } + #region OnDoubleClick[...] + public virtual void OnDoubleClick( Mobile from ) { } @@ -4049,6 +4134,7 @@ namespace Server { from.SendLocalizedMessage( 500447 ); // That is not accessible. } + #endregion public virtual void OnSnoop( Mobile from ) { @@ -4330,6 +4416,22 @@ namespace Server this.Delete(); } + [CommandProperty( AccessLevel.GameMaster )] + public bool QuestItem + { + get { return GetFlag( ImplFlag.QuestItem ); } + set + { + SetFlag( ImplFlag.QuestItem, value ); + + InvalidateProperties(); + + Packet.Release( ref m_WorldPacket ); + + Delta( ItemDelta.Update ); + } + } + public bool Insured { get{ return GetFlag( ImplFlag.Insured ); } @@ -4454,41 +4556,4 @@ namespace Server { } } - /* public class EmptyArrayList : ArrayList - { - public override bool IsReadOnly{ get{ return true; } } - public override bool IsFixedSize{ get{ return true; } } - - private void OnPopulate() - { - Console.WriteLine( "Warning: Attempted to populate a static empty ArrayList" ); - Console.WriteLine( new System.Diagnostics.StackTrace() ); - } - - public override int Add( object value ) - { - OnPopulate(); - return -1; - } - - public override void AddRange( ICollection c ) - { - OnPopulate(); - } - - public override void InsertRange( int index, ICollection c ) - { - OnPopulate(); - } - - public override void Insert( int index, object value ) - { - OnPopulate(); - } - - public override void SetRange( int index, ICollection c ) - { - OnPopulate(); - } - }*/ } \ No newline at end of file diff --git a/Server/Items/Container.cs b/Server/Items/Container.cs index 57cda5142..483824c78 100644 --- a/Server/Items/Container.cs +++ b/Server/Items/Container.cs @@ -1673,8 +1673,22 @@ namespace Server.Items { base.GetProperties( list ); - if ( DisplaysContent )//CheckContentDisplay( from ) ) - list.Add( 1050044, "{0}\t{1}", TotalItems, TotalWeight ); + if( DisplaysContent )//CheckContentDisplay( from ) ) + { + if( Core.ML ) + { + if( ParentsContain() ) //Root Parent is the Mobile. Parent could be another containter. + list.Add( 1073841, "{0}\t{1}\t{2}", TotalItems, MaxItems, TotalWeight ); // Contents: ~1_COUNT~/~2_MAXCOUNT~ items, ~3_WEIGHT~ stones + else + list.Add( 1072241, "{0}\t{1}\t{2}\t{3}", TotalItems, MaxItems, TotalWeight, MaxWeight ); // Contents: ~1_COUNT~/~2_MAXCOUNT~ items, ~3_WEIGHT~/~4_MAXWEIGHT~ stones + + //TODO: Where do the other clilocs come into play? 1073839 & 1073840? + } + else + { + list.Add( 1050044, "{0}\t{1}", TotalItems, TotalWeight ); // ~1_COUNT~ items, ~2_WEIGHT~ stones + } + } } public override void OnDoubleClick( Mobile from ) diff --git a/Server/Mobile.cs b/Server/Mobile.cs index b4d182459..2ded6f2f7 100644 --- a/Server/Mobile.cs +++ b/Server/Mobile.cs @@ -5187,10 +5187,15 @@ namespace Server public void Heal( int amount ) { - Heal( amount, true ); + Heal( amount, this, true ); } - public void Heal( int amount, bool message ) + public void Heal( int amount, Mobile from ) + { + Heal( amount, from, true ); + } + + public void Heal( int amount, Mobile from, bool message ) { if( !Alive || IsDeadBondedPet ) return; @@ -5198,6 +5203,8 @@ namespace Server if( !Region.OnHeal( this, ref amount ) ) return; + OnHeal( ref amount, from ); + if( (Hits + amount) > HitsMax ) { amount = HitsMax - Hits; @@ -5209,6 +5216,10 @@ namespace Server m_NetState.Send( new MessageLocalizedAffix( Serial.MinusOne, -1, MessageType.Label, 0x3B2, 3, 1008158, "", AffixType.Append | AffixType.System, amount.ToString(), "" ) ); } + public virtual void OnHeal( ref int amount, Mobile from ) + { + } + public void UsedStuckMenu() { if( m_StuckMenuUses == null ) diff --git a/Server/Network/PacketHandlers.cs b/Server/Network/PacketHandlers.cs index 8ae0883d1..116e09bae 100644 --- a/Server/Network/PacketHandlers.cs +++ b/Server/Network/PacketHandlers.cs @@ -1759,66 +1759,8 @@ namespace Server.Network public static void ClientVersion( NetState state, PacketReader pvSrc ) { CV version = state.Version = new CV( pvSrc.ReadString() ); - string kickMessage = null; - if ( CV.Required != null && version < CV.Required ) - { - kickMessage = String.Format( "This server requires your client version be at least {0}.", CV.Required ); - } - else if ( !CV.AllowGod || !CV.AllowRegular || !CV.AllowUOTD ) - { - if ( !CV.AllowGod && version.Type == ClientType.God ) - kickMessage = "This server does not allow god clients to connect."; - else if ( !CV.AllowRegular && version.Type == ClientType.Regular ) - kickMessage = "This server does not allow regular clients to connect."; - else if ( !CV.AllowUOTD && state.IsUOTDClient ) - kickMessage = "This server does not allow UO:TD clients to connect."; - - if ( !CV.AllowGod && !CV.AllowRegular && !CV.AllowUOTD ) - { - kickMessage = "This server does not allow any clients to connect."; - } - else if ( CV.AllowGod && !CV.AllowRegular && !CV.AllowUOTD && version.Type != ClientType.God ) - { - kickMessage = "This server requires you to use the god client."; - } - else if ( kickMessage != null ) - { - if ( CV.AllowRegular && CV.AllowUOTD ) - kickMessage += " You can use regular or UO:TD clients."; - else if ( CV.AllowRegular ) - kickMessage += " You can use regular clients."; - else if ( CV.AllowUOTD ) - kickMessage += " You can use UO:TD clients."; - } - } - - if ( kickMessage != null ) - { - state.Mobile.SendMessage( 0x22, kickMessage ); - state.Mobile.SendMessage( 0x22, "You will be disconnected in {0} seconds.", CV.KickDelay.TotalSeconds ); - - new KickTimer( state, CV.KickDelay ).Start(); - } - } - - private class KickTimer : Timer - { - private NetState m_State; - - public KickTimer( NetState state, TimeSpan delay ) : base( delay ) - { - m_State = state; - } - - protected override void OnTick() - { - if ( m_State.Socket != null ) - { - Console.WriteLine( "Client: {0}: Disconnecting, bad version", m_State ); - m_State.Dispose(); - } - } + EventSink.InvokeClientVersionRecieved( new ClientVersionRecievedArgs( state, version ) ); } public static void MobileQuery( NetState state, PacketReader pvSrc ) diff --git a/Server/Network/Packets.cs b/Server/Network/Packets.cs index 798528fe8..9aa7d558a 100644 --- a/Server/Network/Packets.cs +++ b/Server/Network/Packets.cs @@ -634,23 +634,19 @@ namespace Server.Network } } - public sealed class SpeedBoost : Packet + public sealed class SpeedControl : Packet { - public static readonly Packet Enabled = Packet.SetStatic( new SpeedBoost( true ) ); - public static readonly Packet Disabled = Packet.SetStatic( new SpeedBoost( false ) ); + public static readonly Packet WalkSpeed = Packet.SetStatic( new SpeedControl( 2 ) ); + public static readonly Packet MountSpeed = Packet.SetStatic( new SpeedControl( 1 ) ); + public static readonly Packet Disable = Packet.SetStatic( new SpeedControl( 0 ) ); - public static Packet Instantiate( bool enable ) - { - return (enable ? Enabled : Disabled); - } - - public SpeedBoost( bool enable ) + public SpeedControl( int speedControl ) : base( 0xBF ) { EnsureCapacity( 3 ); m_Stream.Write( (short)0x26 ); - m_Stream.Write( (bool)enable ); + m_Stream.Write( (byte)speedControl ); } } diff --git a/Server/Timer.cs b/Server/Timer.cs index 898b617b5..d96704480 100644 --- a/Server/Timer.cs +++ b/Server/Timer.cs @@ -468,6 +468,8 @@ namespace Server return TimerPriority.EveryTick; } + #region DelayCall(..) + public static Timer DelayCall( TimeSpan delay, TimerCallback callback ) { return DelayCall( delay, TimeSpan.Zero, 1, callback ); @@ -515,8 +517,9 @@ namespace Server return t; } + #endregion - + #region DelayCall(..) public static Timer DelayCall( TimeSpan delay, TimerStateCallback callback, T state ) { return DelayCall( delay, TimeSpan.Zero, 1, callback, state ); @@ -540,7 +543,9 @@ namespace Server return t; } + #endregion + #region DelayCall Timers private class DelayCallTimer : Timer { private TimerCallback m_Callback; @@ -625,6 +630,7 @@ namespace Server return String.Format( "DelayStateCall[{0}]", FormatDelegate( m_Callback ) ); } } + #endregion public void Start() {