From 2ad37d54aa8b696a6243fe2ac38169deb97e8889 Mon Sep 17 00:00:00 2001 From: asayre Date: Sat, 26 May 2007 03:12:41 +0000 Subject: [PATCH] Lots of fixes, changes, rewrites of various things, including but not limited to: Logging of staff crafting items, Fixes for the OSI client changes The potion stacking stuff BaseWeapon fix, so that damage increase things don't multiply themselves. admin gump fixes for Firewall Various display tweaks for weight SoS no longer spawn in Tokuno Hiryu hues happified to OSI standards staff now see alliance chat correctly Play barkeeper text increased per OSI Various other OSI skill requirement changes Various unimplemented features of the SE moves EventSink for when the client version is received from client. Client validation moved out of the core. Client version validation now has options to ignore/kick/warn/annoy. Automagically tries to detect current client. Reverted the delayeddamagecontext back to OSI standards. Can no longer use bags of sending in jail. MagerySpell implemented. Now only Magery spells have a circle, and various other properties of 'em. TransformationSpellHelper now implemented. Things moved around for this. Spells now need a Timespan for the cast delay, instead of arbitrarily based on Circle. Circle doesn't make sense for non-Magery spells! Alot of the spellweaving spells added to OSI standards. --- Scripts/Accounting/AccountHandler.cs | 3 +- Scripts/Accounting/Firewall.cs | 12 +- Scripts/Accounting/IPLimiter.cs | 2 +- Scripts/Commands/Handlers.cs | 4 +- Scripts/Engines/AI/AI/BaseAI.cs | 10 +- Scripts/Engines/AI/Creature/BaseCreature.cs | 14 +- Scripts/Engines/CannedEvil/ChampionSpawn.cs | 2 +- Scripts/Engines/Craft/Core/CraftItem.cs | 10 +- Scripts/Engines/Craft/DefBlacksmithy.cs | 217 ++++++- Scripts/Engines/Craft/DefCarpentry.cs | 20 +- Scripts/Engines/Harvest/Fishing.cs | 15 +- Scripts/Engines/Help/HelpGump.cs | 2 +- Scripts/Engines/Help/SpeechLog.cs | 4 +- Scripts/Engines/Plants/PlantItem.cs | 2 +- Scripts/Engines/Plants/PlantSystem.cs | 5 +- .../Quests/Core/Items/EnchantedSextant.cs | 1 + Scripts/Engines/Reports/Reports.cs | 2 +- Scripts/Engines/Virtues/Honor.cs | 10 +- Scripts/Gumps/AdminGump.cs | 30 +- .../New Guild System/GuildRosterGump.cs | 2 +- Scripts/Gumps/PetResurrectGump.cs | 17 +- Scripts/Gumps/Properties/SetBodyGump.cs | 6 +- Scripts/Gumps/ResurrectGump.cs | 85 ++- Scripts/Gumps/WarningGump.cs | 14 +- Scripts/Items/Armor/BaseArmor.cs | 24 +- Scripts/Items/Maps/TreasureMap.cs | 2 +- Scripts/Items/Misc/Corpses/Corpse.cs | 2 + Scripts/Items/Misc/PublicMoongate.cs | 2 +- Scripts/Items/Misc/TribalPaint.cs | 3 +- .../Fishing/Misc/MessageInABottle.cs | 6 +- Scripts/Items/Skill Items/Fishing/Misc/SOS.cs | 6 +- .../Skill Items/Magical/Misc/PotionKeg.cs | 39 +- .../Skill Items/Magical/Potions/BasePotion.cs | 26 +- .../Potions/Cure Potions/BaseCurePotion.cs | 3 +- .../Explosion Potions/BaseExplosionPotion.cs | 7 +- .../Magical/Scrolls/SpellweavingScrolls.cs | 550 ++++++++++++++++++ .../Items/Skill Items/Magical/Spellbook.cs | 2 + Scripts/Items/Skill Items/Misc/Bandage.cs | 4 +- .../Items/Skill Items/Thief/DisguiseKit.cs | 2 +- .../Items/Special/Solen Items/BagOfSending.cs | 14 +- .../Special/Special Scrolls/PowerScroll.cs | 37 +- .../Items/Weapons/Abilities/BleedAttack.cs | 3 +- Scripts/Items/Weapons/BaseMeleeWeapon.cs | 5 +- Scripts/Items/Weapons/BaseWeapon.cs | 109 +++- .../Items/Weapons/ML Weapons/AssassinSpike.cs | 1 + Scripts/Misc/BuffIcons.cs | 37 +- Scripts/Misc/CharacterCreation.cs | 18 +- Scripts/Misc/Cleanup.cs | 3 +- Scripts/Misc/ClientVerification.cs | 183 +++++- Scripts/Misc/Gifts/GiftGiving.cs | 2 +- Scripts/Misc/LootPack.cs | 4 +- Scripts/Misc/MapDefinitions.cs | 4 +- Scripts/Misc/Notoriety.cs | 3 +- Scripts/Misc/Poison.cs | 2 +- Scripts/Misc/RegenRates.cs | 2 +- Scripts/Misc/SkillCheck.cs | 2 +- Scripts/Mobiles/Animals/Mounts/BaseMount.cs | 2 + Scripts/Mobiles/Animals/Mounts/Ethereals.cs | 228 ++++---- Scripts/Mobiles/Animals/Mounts/Hiryu.cs | 96 ++- Scripts/Mobiles/Animals/Mounts/LesserHiryu.cs | 72 ++- .../Monsters/Humanoid/Magic/SavageShaman.cs | 2 +- .../Mobiles/Monsters/LBR/Meers/MeerCaptain.cs | 2 +- .../Monsters/Misc/Melee/BladeSpirits.cs | 2 +- .../Monsters/Misc/Melee/EnergyVortex.cs | 8 +- Scripts/Mobiles/PlayerMobile.cs | 16 +- Scripts/Mobiles/Special/BaseChampion.cs | 90 +-- Scripts/Mobiles/Vendors/PlayerBarkeeper.cs | 12 +- Scripts/Regions/GuardedRegion.cs | 5 + Scripts/Skills/SpiritSpeak.cs | 8 +- Scripts/Skills/Stealing.cs | 6 +- Scripts/Skills/Stealth.cs | 11 +- Scripts/Skills/Tracking.cs | 6 +- Scripts/Spells/Base/MagerySpell.cs | 116 ++++ Scripts/Spells/Base/Spell.cs | 250 +++----- Scripts/Spells/Base/SpellHelper.cs | 320 +++++++++- Scripts/Spells/Base/SpellInfo.cs | 17 +- Scripts/Spells/Base/SpellRegistry.cs | 5 +- Scripts/Spells/Bushido/Confidence.cs | 3 +- Scripts/Spells/Bushido/CounterAttack.cs | 3 +- Scripts/Spells/Bushido/Evasion.cs | 3 +- Scripts/Spells/Bushido/SamuraiMove.cs | 5 + Scripts/Spells/Bushido/SamuraiSpell.cs | 9 +- Scripts/Spells/Chivalry/CleanseByFire.cs | 3 +- Scripts/Spells/Chivalry/CloseWounds.cs | 7 +- Scripts/Spells/Chivalry/ConsecrateWeapon.cs | 3 +- Scripts/Spells/Chivalry/DispelEvil.cs | 6 +- Scripts/Spells/Chivalry/DivineFury.cs | 3 +- Scripts/Spells/Chivalry/EnemyOfOne.cs | 3 +- Scripts/Spells/Chivalry/HolyLight.cs | 3 +- Scripts/Spells/Chivalry/NobleSacrifice.cs | 5 +- Scripts/Spells/Chivalry/PaladinSpell.cs | 2 +- Scripts/Spells/Chivalry/RemoveCurse.cs | 3 +- Scripts/Spells/Chivalry/SacredJourney.cs | 3 +- Scripts/Spells/Eighth/AirElemental.cs | 5 +- Scripts/Spells/Eighth/EarthElemental.cs | 5 +- Scripts/Spells/Eighth/Earthquake.cs | 5 +- Scripts/Spells/Eighth/EnergyVortex.cs | 5 +- Scripts/Spells/Eighth/FireElemental.cs | 5 +- Scripts/Spells/Eighth/Resurrection.cs | 5 +- Scripts/Spells/Eighth/SummonDaemon.cs | 5 +- Scripts/Spells/Eighth/WaterElemental.cs | 5 +- Scripts/Spells/Fifth/BladeSpirits.cs | 5 +- Scripts/Spells/Fifth/DispelField.cs | 5 +- Scripts/Spells/Fifth/Incognito.cs | 5 +- Scripts/Spells/Fifth/MagicReflect.cs | 5 +- Scripts/Spells/Fifth/MindBlast.cs | 5 +- Scripts/Spells/Fifth/Paralyze.cs | 7 +- Scripts/Spells/Fifth/PoisonField.cs | 5 +- Scripts/Spells/Fifth/SummonCreature.cs | 5 +- Scripts/Spells/First/Clumsy.cs | 5 +- Scripts/Spells/First/CreateFood.cs | 5 +- Scripts/Spells/First/Feeblemind.cs | 5 +- Scripts/Spells/First/Heal.cs | 8 +- Scripts/Spells/First/MagicArrow.cs | 5 +- Scripts/Spells/First/NightSight.cs | 5 +- Scripts/Spells/First/ReactiveArmor.cs | 5 +- Scripts/Spells/First/Weaken.cs | 5 +- Scripts/Spells/Fourth/ArchCure.cs | 7 +- Scripts/Spells/Fourth/ArchProtection.cs | 5 +- Scripts/Spells/Fourth/Curse.cs | 5 +- Scripts/Spells/Fourth/FireField.cs | 40 +- Scripts/Spells/Fourth/GreaterHeal.cs | 8 +- Scripts/Spells/Fourth/Lightning.cs | 5 +- Scripts/Spells/Fourth/ManaDrain.cs | 5 +- Scripts/Spells/Fourth/Recall.cs | 7 +- Scripts/Spells/Initializer.cs | 20 + Scripts/Spells/Necromancy/AnimateDeadSpell.cs | 3 +- Scripts/Spells/Necromancy/BloodOathSpell.cs | 4 +- Scripts/Spells/Necromancy/CorpseSkin.cs | 4 +- Scripts/Spells/Necromancy/CurseWeapon.cs | 3 +- Scripts/Spells/Necromancy/EvilOmen.cs | 3 +- Scripts/Spells/Necromancy/Exorcism.cs | 21 +- Scripts/Spells/Necromancy/HorrificBeast.cs | 12 +- Scripts/Spells/Necromancy/LichForm.cs | 5 +- Scripts/Spells/Necromancy/MindRot.cs | 4 +- Scripts/Spells/Necromancy/NecromancerSpell.cs | 10 +- Scripts/Spells/Necromancy/PainSpike.cs | 6 +- Scripts/Spells/Necromancy/PoisonStrike.cs | 36 +- Scripts/Spells/Necromancy/Strangle.cs | 5 +- Scripts/Spells/Necromancy/SummonFamiliar.cs | 3 +- .../Spells/Necromancy/TransformationSpell.cs | 208 +------ Scripts/Spells/Necromancy/VampiricEmbrace.cs | 5 +- Scripts/Spells/Necromancy/VengefulSpirit.cs | 3 +- Scripts/Spells/Necromancy/Wither.cs | 3 +- Scripts/Spells/Necromancy/WraithForm.cs | 5 +- Scripts/Spells/Ninjitsu/AnimalForm.cs | 20 +- Scripts/Spells/Ninjitsu/Backstab.cs | 15 +- Scripts/Spells/Ninjitsu/FocusAttack.cs | 6 +- Scripts/Spells/Ninjitsu/MirrorImage.cs | 11 +- Scripts/Spells/Ninjitsu/NinjaMove.cs | 5 + Scripts/Spells/Ninjitsu/NinjaSpell.cs | 8 +- Scripts/Spells/Ninjitsu/ShadowJump.cs | 3 +- Scripts/Spells/Ninjitsu/SurpriseAttack.cs | 15 +- Scripts/Spells/Second/Agility.cs | 5 +- Scripts/Spells/Second/Cunning.cs | 5 +- Scripts/Spells/Second/Cure.cs | 5 +- Scripts/Spells/Second/Harm.cs | 5 +- Scripts/Spells/Second/MagicTrap.cs | 5 +- Scripts/Spells/Second/Protection.cs | 5 +- Scripts/Spells/Second/RemoveTrap.cs | 5 +- Scripts/Spells/Second/Strength.cs | 5 +- Scripts/Spells/Seventh/ChainLightning.cs | 5 +- Scripts/Spells/Seventh/EnergyField.cs | 5 +- Scripts/Spells/Seventh/FlameStrike.cs | 5 +- Scripts/Spells/Seventh/GateTravel.cs | 5 +- Scripts/Spells/Seventh/ManaVampire.cs | 5 +- Scripts/Spells/Seventh/MassDispel.cs | 5 +- Scripts/Spells/Seventh/MeteorSwarm.cs | 5 +- Scripts/Spells/Seventh/Polymorph.cs | 9 +- Scripts/Spells/Sixth/Dispel.cs | 5 +- Scripts/Spells/Sixth/EnergyBolt.cs | 5 +- Scripts/Spells/Sixth/Explosion.cs | 9 +- Scripts/Spells/Sixth/Invisibility.cs | 5 +- Scripts/Spells/Sixth/Mark.cs | 5 +- Scripts/Spells/Sixth/MassCurse.cs | 5 +- Scripts/Spells/Sixth/ParalyzeField.cs | 5 +- Scripts/Spells/Sixth/Reveal.cs | 5 +- Scripts/Spells/Spellweaving/ArcaneCircle.cs | 156 +++++ Scripts/Spells/Spellweaving/ArcaneForm.cs | 60 ++ Scripts/Spells/Spellweaving/ArcaneSummon.cs | 51 ++ Scripts/Spells/Spellweaving/ArcanistSpell.cs | 144 +++++ Scripts/Spells/Spellweaving/AttuneWeapon.cs | 134 +++++ Scripts/Spells/Spellweaving/EssenceOfWind.cs | 153 +++++ Scripts/Spells/Spellweaving/EtherealVoyage.cs | 88 +++ Scripts/Spells/Spellweaving/GiftOfLife.cs | 218 +++++++ Scripts/Spells/Spellweaving/GiftOfRenewal.cs | 187 ++++++ .../Spells/Spellweaving/Items/ArcaneFocus.cs | 55 ++ .../Spellweaving/Items/TransientItem.cs | 117 ++++ .../Spells/Spellweaving/Mobiles/ArcaneFey.cs | 66 +++ .../Spellweaving/Mobiles/ArcaneFiend.cs | 67 +++ .../Spells/Spellweaving/Mobiles/NatureFury.cs | 106 ++++ Scripts/Spells/Spellweaving/NatureFury.cs | 122 ++++ Scripts/Spells/Spellweaving/ReaperForm.cs | 58 ++ Scripts/Spells/Spellweaving/SummonFey.cs | 25 + Scripts/Spells/Spellweaving/SummonFiend.cs | 25 + Scripts/Spells/Spellweaving/Thunderstorm.cs | 87 +++ Scripts/Spells/Spellweaving/WordOfDeath.cs | 89 +++ Scripts/Spells/Third/Bless.cs | 5 +- Scripts/Spells/Third/Fireball.cs | 5 +- Scripts/Spells/Third/MagicLock.cs | 5 +- Scripts/Spells/Third/Poison.cs | 5 +- Scripts/Spells/Third/Telekinesis.cs | 5 +- Scripts/Spells/Third/Teleport.cs | 5 +- Scripts/Spells/Third/Unlock.cs | 5 +- Scripts/Spells/Third/WallOfStone.cs | 5 +- Server/ClientVersion.cs | 64 -- Server/EventSink.cs | 23 + Server/ExpansionInfo.cs | 2 + Server/Item.cs | 155 +++-- Server/Items/Container.cs | 18 +- Server/Mobile.cs | 15 +- Server/Network/PacketHandlers.cs | 60 +- Server/Network/Packets.cs | 16 +- Server/Timer.cs | 8 +- 214 files changed, 4881 insertions(+), 1243 deletions(-) create mode 100644 Scripts/Items/Skill Items/Magical/Scrolls/SpellweavingScrolls.cs create mode 100644 Scripts/Spells/Base/MagerySpell.cs create mode 100644 Scripts/Spells/Spellweaving/ArcaneCircle.cs create mode 100644 Scripts/Spells/Spellweaving/ArcaneForm.cs create mode 100644 Scripts/Spells/Spellweaving/ArcaneSummon.cs create mode 100644 Scripts/Spells/Spellweaving/ArcanistSpell.cs create mode 100644 Scripts/Spells/Spellweaving/AttuneWeapon.cs create mode 100644 Scripts/Spells/Spellweaving/EssenceOfWind.cs create mode 100644 Scripts/Spells/Spellweaving/EtherealVoyage.cs create mode 100644 Scripts/Spells/Spellweaving/GiftOfLife.cs create mode 100644 Scripts/Spells/Spellweaving/GiftOfRenewal.cs create mode 100644 Scripts/Spells/Spellweaving/Items/ArcaneFocus.cs create mode 100644 Scripts/Spells/Spellweaving/Items/TransientItem.cs create mode 100644 Scripts/Spells/Spellweaving/Mobiles/ArcaneFey.cs create mode 100644 Scripts/Spells/Spellweaving/Mobiles/ArcaneFiend.cs create mode 100644 Scripts/Spells/Spellweaving/Mobiles/NatureFury.cs create mode 100644 Scripts/Spells/Spellweaving/NatureFury.cs create mode 100644 Scripts/Spells/Spellweaving/ReaperForm.cs create mode 100644 Scripts/Spells/Spellweaving/SummonFey.cs create mode 100644 Scripts/Spells/Spellweaving/SummonFiend.cs create mode 100644 Scripts/Spells/Spellweaving/Thunderstorm.cs create mode 100644 Scripts/Spells/Spellweaving/WordOfDeath.cs 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() {