From 06e5c8b7320c0e9d975038d51c3153640b492db9 Mon Sep 17 00:00:00 2001 From: mark Date: Sun, 6 Sep 2009 02:06:07 +0000 Subject: [PATCH] --- Data/Locations/malas.xml | 2 + Scripts/Engines/AI/Creature/BaseCreature.cs | 36 +- Scripts/Engines/Craft/Core/CraftGumpItem.cs | 12 +- Scripts/Engines/Craft/Core/CraftItem.cs | 2 +- Scripts/Engines/Craft/Core/Enhance.cs | 2 +- Scripts/Engines/Craft/Core/Repair.cs | 6 +- Scripts/Engines/Craft/Core/Resmelt.cs | 64 +- .../Doom/Guardian Room/DarkGuardian.cs | 87 ++ .../Doom/Guardian Room/GuardianRoom.cs | 599 ++++++++++++++ .../Guardian Room/GuardiansTreasureChest.cs | 179 +++++ .../Engines/Doom/Guardian Room/PoisonRoom.cs | 230 ++++++ .../Engines/Doom/Lamp Room/LampController.cs | 744 ++++++++++++++++++ Scripts/Engines/Doom/Lamp Room/PuzzleBox.cs | 80 ++ Scripts/Engines/Doom/Lamp Room/PuzzleLever.cs | 87 ++ Scripts/Engines/Doom/Lamp Room/PuzzlePad.cs | 124 +++ .../Engines/Doom/Lamp Room/PuzzleStatue.cs | 36 + Scripts/Engines/Plants/MainPlantGump.cs | 6 +- Scripts/Engines/Plants/PlantItem.cs | 33 +- Scripts/Engines/Plants/PlantType.cs | 102 ++- Scripts/Engines/Plants/Seed.cs | 11 + .../Character Statue Maker/CharacterStatue.cs | 5 - Scripts/Items/Addons/BaseAddon.cs | 4 - Scripts/Items/Addons/BaseAddonDeed.cs | 2 - Scripts/Items/Armor/BaseArmor.cs | 6 +- Scripts/Items/Clothing/BaseClothing.cs | 28 +- Scripts/Items/Containers/Container.cs | 15 +- Scripts/Items/Deeds/CommodityDeed.cs | 4 +- Scripts/Items/Deeds/DragonBardingDeed.cs | 2 +- Scripts/Items/Food/Beverage.cs | 11 + Scripts/Items/Jewels/BaseJewel.cs | 6 +- Scripts/Items/Misc/IDurability.cs | 5 +- Scripts/Items/Misc/OilCloth.cs | 9 +- .../Blacksmithy/PowderOfTemperament.cs | 195 +---- Scripts/Misc/AOS.cs | 4 + Scripts/Mobiles/Animals/Cows/Cow.cs | 61 +- Scripts/Mobiles/Animals/Mounts/Ethereals.cs | 4 +- Scripts/Mobiles/Animals/Mounts/Hiryu.cs | 3 + Scripts/Mobiles/Familiars/HordeMinion.cs | 3 + Scripts/Mobiles/Healers/BaseHealer.cs | 1 - Scripts/Mobiles/Healers/EvilHealer.cs | 6 + .../Mobiles/Healers/EvilWanderingHealer.cs | 6 + Scripts/Mobiles/Healers/Healer.cs | 4 + Scripts/Mobiles/Healers/WanderingHealer.cs | 4 + Scripts/Mobiles/Monsters/Ants/AntLion.cs | 3 + .../Arachnid/Melee/TerathanWarrior.cs | 3 + .../Mobiles/Monsters/Humanoid/Magic/Titan.cs | 3 + .../Monsters/Humanoid/Melee/Cyclops.cs | 4 +- .../Mobiles/Monsters/Humanoid/Melee/Mummy.cs | 3 + .../Monsters/Humanoid/Melee/RestlessSoul.cs | 6 +- .../Mobiles/Monsters/LBR/Jukas/JukaMage.cs | 3 + .../Monsters/ML/Humanoid/Magic/MLDryad.cs | 3 + .../Monsters/ML/Misc/Magic/GreaterDragon.cs | 2 +- Scripts/Mobiles/Monsters/Misc/Magic/Wisp.cs | 3 + .../Monsters/Misc/Melee/PlagueBeast.cs | 3 + .../Reptile/Magic/SerpentineDragon.cs | 3 + Scripts/Mobiles/Monsters/SE/BakeKitsune.cs | 92 +++ Scripts/Mobiles/Monsters/SE/Kappa.cs | 14 +- Scripts/Mobiles/Monsters/SE/TsukiWolf.cs | 3 +- Scripts/Mobiles/Vendors/NPC/AnimalTrainer.cs | 2 +- Scripts/Multis/BaseHouse.cs | 8 +- Scripts/Skills/AnimalLore.cs | 32 +- Scripts/Skills/DetectHidden.cs | 2 +- Scripts/Skills/Stealing.cs | 6 +- Scripts/Spells/Fifth/PoisonField.cs | 5 +- Scripts/Spells/Fourth/FireField.cs | 7 + Scripts/Spells/Necromancy/PoisonStrike.cs | 5 +- Scripts/Spells/Ninjitsu/ShadowJump.cs | 3 +- Scripts/Spells/Sixth/ParalyzeField.cs | 4 + Scripts/Spells/Spellweaving/NatureFury.cs | 22 +- Scripts/Spells/Third/Teleport.cs | 10 + 70 files changed, 2798 insertions(+), 286 deletions(-) create mode 100644 Scripts/Engines/Doom/Guardian Room/DarkGuardian.cs create mode 100644 Scripts/Engines/Doom/Guardian Room/GuardianRoom.cs create mode 100644 Scripts/Engines/Doom/Guardian Room/GuardiansTreasureChest.cs create mode 100644 Scripts/Engines/Doom/Guardian Room/PoisonRoom.cs create mode 100644 Scripts/Engines/Doom/Lamp Room/LampController.cs create mode 100644 Scripts/Engines/Doom/Lamp Room/PuzzleBox.cs create mode 100644 Scripts/Engines/Doom/Lamp Room/PuzzleLever.cs create mode 100644 Scripts/Engines/Doom/Lamp Room/PuzzlePad.cs create mode 100644 Scripts/Engines/Doom/Lamp Room/PuzzleStatue.cs diff --git a/Data/Locations/malas.xml b/Data/Locations/malas.xml index feb73db9d..11887223e 100644 --- a/Data/Locations/malas.xml +++ b/Data/Locations/malas.xml @@ -38,6 +38,8 @@ + + diff --git a/Scripts/Engines/AI/Creature/BaseCreature.cs b/Scripts/Engines/AI/Creature/BaseCreature.cs index 49849a23f..fc5eda70c 100644 --- a/Scripts/Engines/AI/Creature/BaseCreature.cs +++ b/Scripts/Engines/AI/Creature/BaseCreature.cs @@ -1069,8 +1069,16 @@ namespace Server.Mobiles { get { - if ( m_HitsMax >= 0 ) - return m_HitsMax + GetStatOffset( StatType.Str ); + if ( m_HitsMax > 0 ) { + int value = m_HitsMax + GetStatOffset( StatType.Str ); + + if( value < 1 ) + value = 1; + else if( value > 65000 ) + value = 65000; + + return value; + } return Str; } @@ -1088,8 +1096,16 @@ namespace Server.Mobiles { get { - if ( m_StamMax >= 0 ) - return m_StamMax + GetStatOffset( StatType.Dex ); + if ( m_StamMax > 0 ) { + int value = m_StamMax + GetStatOffset( StatType.Dex ); + + if( value < 1 ) + value = 1; + else if( value > 65000 ) + value = 65000; + + return value; + } return Dex; } @@ -1107,8 +1123,16 @@ namespace Server.Mobiles { get { - if ( m_ManaMax >= 0 ) - return m_ManaMax + GetStatOffset( StatType.Int ); + if ( m_ManaMax > 0 ) { + int value = m_ManaMax + GetStatOffset( StatType.Int ); + + if( value < 1 ) + value = 1; + else if( value > 65000 ) + value = 65000; + + return value; + } return Int; } diff --git a/Scripts/Engines/Craft/Core/CraftGumpItem.cs b/Scripts/Engines/Craft/Core/CraftGumpItem.cs index 9c32f7512..4bc44a15d 100644 --- a/Scripts/Engines/Craft/Core/CraftGumpItem.cs +++ b/Scripts/Engines/Craft/Core/CraftGumpItem.cs @@ -192,17 +192,17 @@ namespace Server.Engines.Craft if ( context != null ) resIndex = ( m_CraftItem.UseSubRes2 ? context.LastResourceIndex2 : context.LastResourceIndex ); - bool cropScroll = ( m_CraftItem.Ressources.Count > 1 ) - && m_CraftItem.Ressources.GetAt( m_CraftItem.Ressources.Count - 1 ).ItemType == typeofBlankScroll + bool cropScroll = ( m_CraftItem.Resources.Count > 1 ) + && m_CraftItem.Resources.GetAt( m_CraftItem.Resources.Count - 1 ).ItemType == typeofBlankScroll && typeofSpellScroll.IsAssignableFrom( m_CraftItem.ItemType ); - for ( int i = 0; i < m_CraftItem.Ressources.Count - (cropScroll ? 1 : 0) && i < 4; i++ ) + for ( int i = 0; i < m_CraftItem.Resources.Count - (cropScroll ? 1 : 0) && i < 4; i++ ) { Type type; string nameString; int nameNumber; - CraftRes craftResource = m_CraftItem.Ressources.GetAt( i ); + CraftRes craftResource = m_CraftItem.Resources.GetAt( i ); type = craftResource.ItemType; nameString = craftResource.NameString; @@ -240,8 +240,8 @@ namespace Server.Engines.Craft if ( m_CraftItem.NameNumber == 1041267 ) // runebook { - AddHtmlLocalized( 170, 219 + (m_CraftItem.Ressources.Count * 20), 310, 18, 1044447, LabelColor, false, false ); - AddLabel( 430, 219 + (m_CraftItem.Ressources.Count * 20), LabelHue, "1" ); + AddHtmlLocalized( 170, 219 + (m_CraftItem.Resources.Count * 20), 310, 18, 1044447, LabelColor, false, false ); + AddLabel( 430, 219 + (m_CraftItem.Resources.Count * 20), LabelHue, "1" ); } if ( cropScroll ) diff --git a/Scripts/Engines/Craft/Core/CraftItem.cs b/Scripts/Engines/Craft/Core/CraftItem.cs index ec28d0b49..a1e5a239a 100644 --- a/Scripts/Engines/Craft/Core/CraftItem.cs +++ b/Scripts/Engines/Craft/Core/CraftItem.cs @@ -226,7 +226,7 @@ namespace Server.Engines.Craft get { return m_NameNumber; } } - public CraftResCol Ressources + public CraftResCol Resources { get { return m_arCraftRes; } } diff --git a/Scripts/Engines/Craft/Core/Enhance.cs b/Scripts/Engines/Craft/Core/Enhance.cs index 555ab44bc..9e52c9582 100644 --- a/Scripts/Engines/Craft/Core/Enhance.cs +++ b/Scripts/Engines/Craft/Core/Enhance.cs @@ -36,7 +36,7 @@ namespace Server.Engines.Craft CraftItem craftItem = craftSystem.CraftItems.SearchFor( item.GetType() ); - if ( craftItem == null || craftItem.Ressources.Count == 0 ) + if ( craftItem == null || craftItem.Resources.Count == 0 ) return EnhanceResult.BadItem; bool allRequiredSkills = false; diff --git a/Scripts/Engines/Craft/Core/Repair.cs b/Scripts/Engines/Craft/Core/Repair.cs index bec85013c..cbc4d62c6 100644 --- a/Scripts/Engines/Craft/Core/Repair.cs +++ b/Scripts/Engines/Craft/Core/Repair.cs @@ -336,7 +336,7 @@ namespace Server.Engines.Craft toDelete = true; } } - else if ( (targeted is BaseClothing) ) + else if ( targeted is BaseClothing ) { BaseClothing clothing = (BaseClothing)targeted; SkillName skill = m_CraftSystem.MainSkill; @@ -358,8 +358,8 @@ namespace Server.Engines.Craft toWeaken = 3; } - if (m_CraftSystem.CraftItems.SearchForSubclass(clothing.GetType()) == null && !IsSpecialClothing(clothing) && !((targeted is TribalMask) || (targeted is HornedTribalMask) || targeted.GetType().IsSubclassOf(typeof(HornedTribalMask)) || targeted.GetType().IsSubclassOf(typeof(TribalMask)))) - { + if (m_CraftSystem.CraftItems.SearchForSubclass(clothing.GetType()) == null && !IsSpecialClothing(clothing) && !((targeted is TribalMask) || (targeted is HornedTribalMask)) ) + { number = (usingDeed) ? 1061136 : 1044277; // That item cannot be repaired. // You cannot repair that item with this type of repair contract. } else if ( !clothing.IsChildOf( from.Backpack ) ) diff --git a/Scripts/Engines/Craft/Core/Resmelt.cs b/Scripts/Engines/Craft/Core/Resmelt.cs index 82ada6851..4b61604aa 100644 --- a/Scripts/Engines/Craft/Core/Resmelt.cs +++ b/Scripts/Engines/Craft/Core/Resmelt.cs @@ -5,6 +5,13 @@ using Server.Items; namespace Server.Engines.Craft { + public enum SmeltResult + { + Success, + Invalid, + NoSkill + } + public class Resmelt { public Resmelt() @@ -37,27 +44,44 @@ namespace Server.Engines.Craft m_Tool = tool; } - private bool Resmelt( Mobile from, Item item, CraftResource resource ) + private SmeltResult Resmelt( Mobile from, Item item, CraftResource resource ) { try { if ( CraftResources.GetType( resource ) != CraftResourceType.Metal ) - return false; + return SmeltResult.Invalid; CraftResourceInfo info = CraftResources.GetInfo( resource ); if ( info == null || info.ResourceTypes.Length == 0 ) - return false; + return SmeltResult.Invalid; CraftItem craftItem = m_CraftSystem.CraftItems.SearchFor( item.GetType() ); - if ( craftItem == null || craftItem.Ressources.Count == 0 ) - return false; + if ( craftItem == null || craftItem.Resources.Count == 0 ) + return SmeltResult.Invalid; - CraftRes craftResource = craftItem.Ressources.GetAt( 0 ); + CraftRes craftResource = craftItem.Resources.GetAt( 0 ); if ( craftResource.Amount < 2 ) - return false; // Not enough metal to resmelt + return SmeltResult.Invalid; // Not enough metal to resmelt + + double difficulty = 0.0; + + switch ( resource ) + { + case CraftResource.DullCopper: difficulty = 65.0; break; + case CraftResource.ShadowIron: difficulty = 70.0; break; + case CraftResource.Copper: difficulty = 75.0; break; + case CraftResource.Bronze: difficulty = 80.0; break; + case CraftResource.Gold: difficulty = 85.0; break; + case CraftResource.Agapite: difficulty = 90.0; break; + case CraftResource.Verite: difficulty = 95.0; break; + case CraftResource.Valorite: difficulty = 99.0; break; + } + + if ( difficulty > from.Skills[ SkillName.Mining ].Value ) + return SmeltResult.NoSkill; Type resourceType = info.ResourceTypes[0]; Item ingot = (Item)Activator.CreateInstance( resourceType ); @@ -72,13 +96,13 @@ namespace Server.Engines.Craft from.PlaySound( 0x2A ); from.PlaySound( 0x240 ); - return true; + return SmeltResult.Success; } catch { } - return false; + return SmeltResult.Invalid; } protected override void OnTarget( Mobile from, object targeted ) @@ -91,29 +115,35 @@ namespace Server.Engines.Craft } else { - bool success = false; + SmeltResult result = SmeltResult.Invalid; bool isStoreBought = false; + int message; if ( targeted is BaseArmor ) { - success = Resmelt( from, (BaseArmor)targeted, ((BaseArmor)targeted).Resource ); + result = Resmelt( from, (BaseArmor)targeted, ((BaseArmor)targeted).Resource ); isStoreBought = !((BaseArmor)targeted).PlayerConstructed; } else if ( targeted is BaseWeapon ) { - success = Resmelt( from, (BaseWeapon)targeted, ((BaseWeapon)targeted).Resource ); + result = Resmelt( from, (BaseWeapon)targeted, ((BaseWeapon)targeted).Resource ); isStoreBought = !((BaseWeapon)targeted).PlayerConstructed; } else if ( targeted is DragonBardingDeed ) { - success = Resmelt( from, (DragonBardingDeed)targeted, ((DragonBardingDeed)targeted).Resource ); + result = Resmelt( from, (DragonBardingDeed)targeted, ((DragonBardingDeed)targeted).Resource ); isStoreBought = false; } - if ( success ) - from.SendGump( new CraftGump( from, m_CraftSystem, m_Tool, isStoreBought ? 500418 : 1044270 ) ); // You melt the item down into ingots. - else - from.SendGump( new CraftGump( from, m_CraftSystem, m_Tool, 1044272 ) ); // You can't melt that down into ingots. + switch ( result ) + { + default: + case SmeltResult.Invalid: message = 1044272; break; // You can't melt that down into ingots. + case SmeltResult.NoSkill: message = 1044269; break; // You have no idea how to work this metal. + case SmeltResult.Success: message = isStoreBought ? 500418 : 1044270; break; // You melt the item down into ingots. + } + + from.SendGump( new CraftGump( from, m_CraftSystem, m_Tool, message ) ); } } } diff --git a/Scripts/Engines/Doom/Guardian Room/DarkGuardian.cs b/Scripts/Engines/Doom/Guardian Room/DarkGuardian.cs new file mode 100644 index 000000000..b97c0b344 --- /dev/null +++ b/Scripts/Engines/Doom/Guardian Room/DarkGuardian.cs @@ -0,0 +1,87 @@ +using System; +using Server; +using Server.Items; +using Server.Engines.Doom; + +namespace Server.Mobiles +{ + [CorpseName( "a dark guardians' corpse" )] + public class DarkGuardian : BaseCreature + { + [Constructable] + public DarkGuardian() : base( AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 ) + { + Name = "a dark guardian"; + Body = 78; + BaseSoundID = 0x3E9; + + SetStr( 125, 150 ); + SetDex( 100, 120 ); + SetInt( 200, 235 ); + + SetHits( 150, 180 ); + + SetDamage( 43, 48 ); + + SetDamageType( ResistanceType.Physical, 10 ); + SetDamageType( ResistanceType.Cold, 40 ); + SetDamageType( ResistanceType.Energy, 50 ); + + SetResistance( ResistanceType.Physical, 40, 50 ); + SetResistance( ResistanceType.Fire, 20, 45 ); + SetResistance( ResistanceType.Cold, 50, 60 ); + SetResistance( ResistanceType.Poison, 20, 45 ); + SetResistance( ResistanceType.Energy, 30, 40 ); + + SetSkill( SkillName.EvalInt, 40.1, 50); + SetSkill( SkillName.Magery, 50.1, 60.0 ); + SetSkill( SkillName.Meditation, 85.1, 95.0 ); + SetSkill( SkillName.MagicResist, 50.1, 70.0 ); + SetSkill( SkillName.Tactics, 50.1, 70.0 ); + + Fame = 5000; + Karma = -5000; + + VirtualArmor = 50; + PackNecroReg( 15, 25 ); + PackItem( new DaemonBone( 30 ) ); + } + + public DarkGuardian( Serial serial ) : base( serial ) + { + } + + public override void GenerateLoot() + { + AddLoot( LootPack.Rich ); + AddLoot( LootPack.MedScrolls, 2 ); + } + + public override OppositionGroup OppositionGroup + { + get{ return OppositionGroup.FeyAndUndead; } + } + + public override int TreasureMapLevel{ get{ return 2; } } + public override bool BleedImmune{ get{ return true; } } + public override Poison PoisonImmune{ get{ return Poison.Lethal; } } + public override bool Unprovokable { get { return true; } } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.WriteEncodedInt( 0 ); // version + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadEncodedInt(); + + if ( Region is GuardianRoomRegion ) + Delete(); + } + } +} diff --git a/Scripts/Engines/Doom/Guardian Room/GuardianRoom.cs b/Scripts/Engines/Doom/Guardian Room/GuardianRoom.cs new file mode 100644 index 000000000..15eeceda8 --- /dev/null +++ b/Scripts/Engines/Doom/Guardian Room/GuardianRoom.cs @@ -0,0 +1,599 @@ +using System; +using System.Collections.Generic; +using Server; +using Server.Items; +using Server.Mobiles; +using Server.Regions; +using Server.Commands; + +namespace Server.Engines.Doom +{ + public class GuardianRoomRegion : BaseRegion + { + private static GuardianRoomRegion m_Region; + + public static void Initialize() + { + CommandSystem.Register( "GenGuardianRoom", AccessLevel.Administrator, new CommandEventHandler( GenRoom_OnCommand ) ); + } + + [Usage( "GenGuardianRoom" )] + [Description( "Generates guardian room in doom." )] + public static void GenRoom_OnCommand( CommandEventArgs e ) + { + e.Mobile.SendMessage( "Generating room, please wait." ); + + int count = 0; + + // doors + MetalDoor north = FindItem( new GuardianRoomDoor( DoorFacing.NorthCCW ), 0, 355, 14, -1, Map.Malas, ref count ) as MetalDoor; + MetalDoor south = FindItem( new GuardianRoomDoor( DoorFacing.SouthCW ), 0, 355, 15, -1, Map.Malas, ref count ) as MetalDoor; + + if ( north != null && south != null ) + { + north.Link = south; + south.Link = north; + } + + // pentagram center + FindItem( new Static( 0xFEA ), 0x835, 365, 15, -1, Map.Malas, ref count ); + + // ghost teleporters + Teleporter tele; + tele = FindItem( new GhostTeleporter(), 0x835, 354, 14, -1, Map.Malas, ref count ) as Teleporter; + + if ( tele != null ) + { + tele.PointDest = new Point3D( 349, 176, 14 ); + tele.MapDest = Map.Malas; + } + + tele = FindItem( new GhostTeleporter(), 0x835, 354, 15, -1, Map.Malas, ref count ) as Teleporter; + + if ( tele != null ) + { + tele.PointDest = new Point3D( 349, 176, 14 ); + tele.MapDest = Map.Malas; + } + + // treasure chest spawner + Spawner spawner = new Spawner( 3, 1, 5, 0, 9, "GuardianTreasureChest" ); + spawner = FindItem( spawner, 0, 365, 15, 0, Map.Malas, ref count ) as Spawner; + + if ( spawner != null ) + { + spawner.Movable = false; + spawner.Respawn(); + } + + if ( count > 0 ) + e.Mobile.SendMessage( "Room generating complete. {0} items were generated.", count ); + else + e.Mobile.SendMessage( "Room generating complete. No changes neccessary." ); + } + + public static Item FindItem( Item item, int hue, int x, int y, int z, Map map, ref int count ) + { + Point3D p = new Point3D( x, y, z ); + Type type = item.GetType(); + + foreach ( Item i in map.GetItemsInRange( p, 0 ) ) + { + if ( i.GetType() == type && i.ItemID == item.ItemID && i.Hue == hue ) + { + item.Delete(); + return i; + } + } + + count++; + item.MoveToWorld( p, map ); + + if ( hue > 0 ) + item.Hue = hue; + + return item; + } + + private BaseDoor m_Door; + private List m_Dead; + private Timer m_Timer; + private int m_LightLevel; + + public List Dead + { + get { return m_Dead; } + } + + public bool Active + { + get { return m_Timer != null && m_Timer.Running; } + } + + private static Rectangle2D[] m_Bounds = new Rectangle2D[] + { + new Rectangle2D( new Point2D( 356, 5 ), new Point2D( 375, 25 ) ) + }; + + public GuardianRoomRegion( BaseDoor door ) : base( "NorthDoomPoisonRoom", Map.Malas, 51, m_Bounds ) + { + m_Door = door; + m_Dead = new List(); + m_LightLevel = LightCycle.DungeonLevel; + m_Guardians = new List(); + + ExcludeFromParentSpawns = true; + } + + public override void OnEnter( Mobile m ) + { + if ( !Active && IsTrappable( m, true ) ) + m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( Utility.RandomMinMax( 5, 35 ) ), new TimerCallback( StartTrap ) ); + } + + public override void OnDeath( Mobile m ) + { + base.OnDeath( m ); + + if ( m.IsDeadBondedPet || ( m.Player && m.AccessLevel == AccessLevel.Player ) ) + m_Dead.Add( m ); + + if ( m is DarkGuardian ) + m_Guardians.Remove( m ); + + if ( m_Guardians.Count == 0 ) + Timer.DelayCall( TimeSpan.FromSeconds( 5 ), new TimerCallback( StopTrap ) ); + + List list = GetPoisonableMobiles(); + list.Remove( m ); + + if ( list.Count == 0 ) + Timer.DelayCall( TimeSpan.FromSeconds( 5 ), new TimerCallback( StopTrap ) ); + } + + public override void AlterLightLevel( Mobile m, ref int global, ref int personal ) + { + global = m_LightLevel; + } + + public virtual void PoisonMobiles( Poison poison, int ticks ) + { + List list = GetPoisonableMobiles(); + int number = 0; + int hue = 0x485; + + if ( ticks % 12 == 0 ) // every 60 seconds + { + switch ( poison.Level ) + { + // It is becoming more difficult for you to breathe as the poisons in the room become more concentrated. + case 1: number = 1050001; break; + // You begin to panic as the poison clouds thicken. + case 2: number = 1050003; break; + // Terror grips your spirit as you realize you may never leave this room alive. + case 3: number = 1050056; break; + case 4: + if ( ticks < 50 ) + { + number = 1050057; // The end is near. You feel hopeless and desolate. The poison is beginning to stiffen your muscles. + } + else + { + hue = 0x23F3; + number = 1062091; // The poison is becoming too much for you to bear. You fear that you may die at any moment. + } + + break; + } + } + + foreach ( Mobile m in list ) + { + if ( m.Player && number > 0 ) + m.SendLocalizedMessage( number, null, hue ); + + if ( ( m.Poison == null || m.Poison.Level < poison.Level ) ) + m.ApplyPoison( null, poison ); + } + } + + public virtual void HurtMobiles( int level ) + { + foreach ( Mobile m in GetPoisonableMobiles() ) + { + if ( m.Player ) + { + m.Say( 1062092 ); // Your body reacts violently from the pain. + m.Animate( 32, 5, 1, true, false, 0 ); + } + + m.Damage( Utility.Random( 15, 20 ) ); + + if ( level >= 10 ) + m.Kill(); + } + } + + public virtual List GetPoisonableMobiles() + { + List list = new List(); + + foreach ( Mobile m in GetMobiles() ) + { + if ( IsTrappable( m, false ) ) + list.Add( m ); + } + + return list; + } + + public virtual bool IsTrappable( Mobile m, bool trapStart ) + { + if ( m.Alive ) + { + if ( m.Player && m.AccessLevel == AccessLevel.Player ) + return true; + + BaseCreature bc = m as BaseCreature; + + if ( bc != null ) + { + Mobile master = null; + + if ( bc.Controlled && bc.ControlMaster != null ) + master = bc.ControlMaster; + else if ( !trapStart && bc.Summoned && bc.SummonMaster != null ) + master = bc.SummonMaster; + + if ( master != null ) + return master.Player && master.AccessLevel == AccessLevel.Player; + } + } + + return false; + } + + public virtual bool CanStart( List list ) + { + foreach ( Mobile m in list ) + if ( IsTrappable( m, true ) ) + return true; + + return false; + } + + public virtual void RestartTrap() + { + if ( !Active ) + StartTrap(); + } + + public virtual void StartTrap() + { + List list = GetPoisonableMobiles(); + + if ( !CanStart( list ) ) + return; + + m_Timer = new PoisonRoomTimer( this ); + m_Timer.Start(); + + if ( m_Door != null ) + { + m_Door.Locked = true; + m_Door.Open = false; + + if ( m_Door.Link != null ) + { + m_Door.Link.Locked = true; + m_Door.Link.Open = false; + + Effects.PlaySound( m_Door.Link.Location, Map, 0x1FF ); + } + + Effects.PlaySound( m_Door.Location, Map, 0x1FF ); + } + + foreach ( Mobile m in list ) + m.SendLocalizedMessage( 1050000, null, 0x41 ); // The locks on the door click loudly and you begin to hear a faint hissing near the walls. + + for ( int i = m_Dead.Count - 1; i >= 0; i-- ) + if ( m_Dead[ i ].Alive ) + m_Dead.RemoveAt( i ); + + SpawnGuardians( list.Count * 2 ); + } + + public virtual void StopTrap() + { + Timer.DelayCall( TimeSpan.FromSeconds( Utility.RandomMinMax( 30, 60 ) ), new TimerCallback( RestartTrap ) ); + + if ( m_Door != null ) + { + m_Door.Locked = false; + + if ( m_Door.Link != null ) + { + m_Door.Link.Locked = false; + + Effects.PlaySound( m_Door.Link.Location, Map, 0x1FF ); + } + + Effects.PlaySound( m_Door.Location, Map, 0x1FF ); + } + + if ( m_Timer != null && m_Timer.Running ) + m_Timer.Stop(); + + foreach ( Mobile m in GetPlayers() ) + m.SendLocalizedMessage( 1050055, null, 0x41 ); // You hear the doors unlocking and the hissing stops. + + ClearGuardians(); + } + + #region Spawns + private List m_Guardians; + + public void SpawnGuardians( int amount ) + { + for ( int i = 0; i < amount; ++i ) + { + DarkGuardian guardian = new DarkGuardian(); + + switch ( Utility.Random( 4 ) ) + { + case 0: guardian.MoveToWorld( new Point3D( 364, 15, -1 ), Map.Malas ); break; + case 1: guardian.MoveToWorld( new Point3D( 366, 15, -1 ), Map.Malas ); break; + case 2: guardian.MoveToWorld( new Point3D( 365, 14, -1 ), Map.Malas ); break; + case 3: guardian.MoveToWorld( new Point3D( 365, 16, -1 ), Map.Malas ); break; + } + + m_Guardians.Add( guardian ); + } + } + + public void ClearGuardians() + { + foreach ( Mobile m in m_Guardians ) + { + if ( m.Alive && !m.Deleted ) + { + Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x3728, 8, 20, 5042 ); + Effects.PlaySound( m, m.Map, 0x201 ); + + m.Delete(); + } + } + + m_Guardians.Clear(); + } + #endregion + + #region Effects + private static Point3D[] m_GasLocations = new Point3D[] + { + // west + new Point3D( 356, 7, -1 ), new Point3D( 356, 13, -1 ), + new Point3D( 356, 16, -1 ), new Point3D( 356, 22, -1 ), + + // north + new Point3D( 358, 6, -1 ), new Point3D( 363, 6, -1 ), + new Point3D( 368, 6, -1 ), new Point3D( 373, 6, -1 ) + }; + + public virtual void DoGasEffect() + { + for ( int i = Utility.RandomMinMax( 2, 4 ); i > 0; i-- ) + { + int pos = Utility.Random( m_GasLocations.Length ); + int itemID; + + if ( pos <= 3 ) + itemID = 0x1145; + else + itemID = 0x113A; + + Effects.SendLocationParticles( EffectItem.Create( m_GasLocations[ pos ], Map, EffectItem.DefaultDuration ), itemID, 1, 100, 0, 4, 0x139D, 0 ); + } + } + + private static int[] m_PoisonEffects = new int[] + { + 0x36B0, 0x36BD, 0x36CB + }; + + public virtual void DoPoisonEffect( int level ) + { + int hue = 0; + + switch ( level ) + { + default: + case 0: hue = 0xA6; break; + case 1: hue = 0xAA; break; + case 2: hue = 0xAC; break; + case 3: hue = 0xA8; break; + case 4: hue = 0xA4; break; + } + + for ( int i = Utility.RandomMinMax( 5, 7 ); i > 0; i-- ) + { + Point3D p = RandomSpawnLocation( 0, true, true, Point3D.Zero, 0 ); + + if ( p != Point3D.Zero ) + { + IEntity e = EffectItem.Create( p, Map, EffectItem.DefaultDuration ); + int itemID = Utility.RandomList( m_PoisonEffects ); + int duration = Utility.RandomMinMax( 150, 200 ); + + Effects.SendLocationParticles( e, itemID, 1, duration, hue, 0, 0x139D, 0 ); + } + } + } + #endregion + + public class PoisonRoomTimer : Timer + { + private GuardianRoomRegion m_Room; + private int m_Count; + + public PoisonRoomTimer( GuardianRoomRegion room ) : base( TimeSpan.FromSeconds( 1 ), TimeSpan.FromSeconds( 1 ) ) + { + m_Room = room; + m_Count = 0; + } + + public int CurrentPoisonLevel() + { + int poisonLevel = 1 + m_Count / 20; + + if ( poisonLevel > 4 ) + poisonLevel = 4; + + return poisonLevel; + } + + protected override void OnTick() + { + m_Count++; + + if ( m_Count % 5 == 0 && m_Room.Active ) + { + int level = CurrentPoisonLevel(); + + m_Room.PoisonMobiles( Poison.GetPoison( level ), m_Count / 5 ); + } + + if ( m_Count % 8 == 0 && m_Room.Active ) + { + m_Room.DoPoisonEffect( CurrentPoisonLevel() ); + m_Room.DoGasEffect(); + } + + if ( m_Count >= 720 && m_Count % 10 == 0 && m_Room.Active ) + m_Room.HurtMobiles( ( m_Count - 720 ) / 10 ); + } + } + + public class GhostTeleporter : Teleporter + { + private static BaseRegion m_GhostRegion; + + private static Rectangle2D[] m_GhostRegionBounds = new Rectangle2D[] + { + new Rectangle2D( new Point2D( 345, 180 ), new Point2D( 352, 184 ) ), + new Rectangle2D( new Point2D( 342, 172 ), new Point2D( 344, 181 ) ), + new Rectangle2D( new Point2D( 345, 169 ), new Point2D( 352, 172 ) ) + }; + + [Constructable] + public GhostTeleporter() : base() + { + Name = "GhostTeleporter"; + + if ( m_GhostRegion == null ) + { + m_GhostRegion = new BaseRegion( "DoomGhostTeleportRegion", Map.Malas, 55, m_GhostRegionBounds ); + m_GhostRegion.Register(); + } + } + + public GhostTeleporter( Serial serial ) : base( serial ) + { + } + + public override bool OnMoveOver( Mobile m ) + { + if ( !DiedInside( m ) ) + return true; + + return base.OnMoveOver( m ); + } + + public bool DiedInside( Mobile m ) + { + bool valid = false; + + if ( m_Region != null ) + valid = m_Region.Dead.Remove( m ); + + return valid && !m.Alive; + } + + public override void DoTeleport( Mobile m ) + { + if ( m.Corpse != null && !m.Corpse.Deleted ) + { + Point3D location = Point3D.Zero; + + if ( m_GhostRegion != null ) + location = m_GhostRegion.RandomSpawnLocation( 0, true, false, Point3D.Zero, 0 ); + + if ( location == Point3D.Zero ) + location = new Point3D( 349, 176, 14 ); + + m.Corpse.MoveToWorld( location, Map.Malas ); + m.MoveToWorld( location, Map.Malas ); + } + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.WriteEncodedInt( 0 ); // version + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadEncodedInt(); + + if ( m_GhostRegion == null ) + { + m_GhostRegion = new BaseRegion( "DoomGhostTeleportRegion", Map.Malas, 55, m_GhostRegionBounds ); + m_GhostRegion.Register(); + } + } + } + + public class GuardianRoomDoor : MetalDoor + { + public GuardianRoomDoor( DoorFacing facing ) : base( facing ) + { + if ( m_Region == null ) + { + m_Region = new GuardianRoomRegion( this ); + m_Region.Register(); + } + } + + public GuardianRoomDoor( Serial serial ) : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.WriteEncodedInt( 0 ); // version + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadEncodedInt(); + + Locked = false; + + if ( m_Region == null ) + { + m_Region = new GuardianRoomRegion( this ); + m_Region.Register(); + } + } + } + } +} diff --git a/Scripts/Engines/Doom/Guardian Room/GuardiansTreasureChest.cs b/Scripts/Engines/Doom/Guardian Room/GuardiansTreasureChest.cs new file mode 100644 index 000000000..7572cd3a9 --- /dev/null +++ b/Scripts/Engines/Doom/Guardian Room/GuardiansTreasureChest.cs @@ -0,0 +1,179 @@ +using System; +using Server; +using Server.Engines.Doom; + +namespace Server.Items +{ + public class GuardianTreasureChest : LockableContainer + { + private const int m_Level = 6; + + public override bool Decays { get { return true; } } + + public override int DefaultGumpID { get { return 0x42; } } + public override int DefaultDropSound { get { return 0x42; } } + + public override Rectangle2D Bounds + { + get { return new Rectangle2D( 18, 105, 144, 73 ); } + } + + private Timer m_DecayTimer; + + [Constructable] + public GuardianTreasureChest() : base( 0xE41 ) + { + SetChestAppearance(); + Movable = false; + + /* TrapType = TrapType.ExplosionTrap; + TrapPower = m_Level * Utility.Random( 20, 35 );*/ + Locked = true; + + RequiredSkill = 99; + LockLevel = RequiredSkill - Utility.Random( 1, 10 ); + MaxLockLevel = RequiredSkill + 21; + + // According to OSI, loot in level 4 chest is: + // Gold 500 - 900 + // Reagents + // Scrolls + // Blank scrolls + // Potions + // Gems + // Magic Wand + // Magic weapon + // Magic armour + // Magic clothing (not implemented) + // Magic jewelry (not implemented) + // Crystal ball (not implemented) + + // Gold + DropItem( new Gold( Utility.Random( 300, 325 ) ) ); + + // Reagents + for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- ) + { + Item ReagentLoot = Loot.RandomReagent(); + ReagentLoot.Amount = 12; + DropItem( ReagentLoot ); + } + + // Scrolls + for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- ) + { + Item ScrollLoot = Loot.RandomScroll( 0, 47, SpellbookType.Regular ); + ScrollLoot.Amount = 16; + DropItem( ScrollLoot ); + } + + // Drop blank scrolls + DropItem( new BlankScroll( Utility.Random( 1, m_Level ) ) ); + + // Potions + for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- ) + { + Item PotionLoot = Loot.RandomPotion(); + DropItem( PotionLoot ); + } + + // Gems + for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- ) + { + Item GemLoot = Loot.RandomGem(); + GemLoot.Amount = 15; + DropItem( GemLoot ); + } + + // Magic Wand + for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- ) + DropItem( Loot.RandomWand() ); + + // Equipment + for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- ) + { + Item item = Loot.RandomArmorOrShieldOrWeapon(); + + if ( item is BaseWeapon ) + { + BaseWeapon weapon = (BaseWeapon) item; + weapon.DamageLevel = (WeaponDamageLevel) Utility.Random( m_Level ); + weapon.AccuracyLevel = (WeaponAccuracyLevel) Utility.Random( m_Level ); + weapon.DurabilityLevel = (WeaponDurabilityLevel) Utility.Random( m_Level ); + weapon.Quality = WeaponQuality.Regular; + } + else if ( item is BaseArmor ) + { + BaseArmor armor = (BaseArmor) item; + armor.ProtectionLevel = (ArmorProtectionLevel) Utility.Random( m_Level ); + armor.Durability = (ArmorDurabilityLevel) Utility.Random( m_Level ); + armor.Quality = ArmorQuality.Regular; + } + + DropItem( item ); + } + + // Clothing + for ( int i = Utility.Random( 1, 2 ); i > 1; i-- ) + DropItem( Loot.RandomClothing() ); + + // Jewelry + for ( int i = Utility.Random( 1, 2 ); i > 1; i-- ) + DropItem( Loot.RandomJewelry() ); + + // Crystal ball (not implemented) + m_DecayTimer = Timer.DelayCall( TimeSpan.FromMinutes( Utility.RandomMinMax( 1, 5 ) ), new TimerCallback( Delete ) ); + } + + private void SetChestAppearance() + { + bool facing = Utility.RandomBool(); + + switch ( Utility.RandomList( 0, 1, 2 ) ) + { + case 0:// Wooden Chest + ItemID = ( facing ? 0xE42 : 0xE43 ); + GumpID = 0x49; + break; + + case 1:// Metal Chest + ItemID = ( facing ? 0x9AB : 0xE7C ); + GumpID = 0x4A; + break; + + case 2:// Metal Golden Chest + ItemID = ( facing ? 0xE40 : 0xE41 ); + GumpID = 0x42; + break; + } + } + + public override void OnAfterDelete() + { + if ( m_DecayTimer != null || m_DecayTimer.Running ) + m_DecayTimer.Stop(); + + m_DecayTimer = null; + } + + public GuardianTreasureChest( Serial serial ) : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.WriteEncodedInt( 0 ); // version + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadEncodedInt(); + + m_DecayTimer = Timer.DelayCall( TimeSpan.FromMinutes( Utility.RandomMinMax( 1, 5 ) ), new TimerCallback( Delete ) ); + } + } +} diff --git a/Scripts/Engines/Doom/Guardian Room/PoisonRoom.cs b/Scripts/Engines/Doom/Guardian Room/PoisonRoom.cs new file mode 100644 index 000000000..a29480bc6 --- /dev/null +++ b/Scripts/Engines/Doom/Guardian Room/PoisonRoom.cs @@ -0,0 +1,230 @@ +using System; +using System.Collections.Generic; +using Server; +using Server.Mobiles; +using Server.Regions; +using Server.Spells.Fourth; +using Server.Spells.Sixth; +using Server.Spells.Seventh; +using Server.Spells.Chivalry; + +namespace Server.Misc +{ + public class PoisonRoom + { + public virtual int GasEffects { get { return 3; } } + public virtual double TimePerPoisonCast { get { return 3; } } + public virtual int TicksPerPoisonLevel { get { return 15; } } + public virtual Poison MinPoisonLevel { get { return Poison.Lesser; } } + public virtual Poison MaxPoisonLevel { get { return Poison.Lethal; } } + public virtual int GasEffectHeight { get { return 0; } } + public virtual bool HasPoisonSoundEffect { get { return true; } } + + protected PoisonRoomRegion m_Region; + protected PoisonRoomTimer m_Timer; + protected int m_EffectHue = 1166; + protected int m_EffectId = 4518; + protected int m_EffectDuration = 16; + protected List m_Dead; + + public List Dead + { + get { return m_Dead; } + } + + public PoisonRoom( string name, Map map, int priority, Rectangle2D[] rect, int LightLevel ) + { + m_Region = new PoisonRoomRegion( this, name, map, priority, rect, LightLevel ); + m_Region.Register(); + m_Dead = new List(); + } + + public virtual void OnEnter( Mobile m ) + { + if ( m.AccessLevel == AccessLevel.Player && m_Timer == null ) + StartGas(); + } + + public virtual void OnPoison( Poison poison, int tick ) + { + } + + public virtual void StartGas() + { + m_Timer = new PoisonRoomTimer( this ); + m_Timer.Start(); + } + + public virtual void StopGas() + { + if ( m_Timer != null ) + m_Timer.Stop(); + + m_Timer = null; + } + + public virtual void OnExit( Mobile m ) + { + if ( GetPoisonableMobiles( m ).Count == 0 ) + { + StopGas(); + return; + } + } + + public virtual void OnDeath( Mobile m ) + { + m_Dead.Add( m ); + } + + public virtual void DoGasEffect() + { + for ( int i = 0; i < this.GasEffects; ++i ) + RandomGasEffect(); + } + + public virtual void RandomGasEffect() + { + Point3D location = m_Region.RandomSpawnLocation( GasEffectHeight, true, true, Point3D.Zero, 0 ); + + if ( location != Point3D.Zero ) + { + Effects.SendLocationEffect( location, m_Region.Map, 4518, 16, 1, 1166, 0 ); + + if ( HasPoisonSoundEffect ) + Effects.PlaySound( location, m_Region.Map, 0x231 ); + } + } + + public virtual void PoisonPlayers( Poison poison ) + { + List list = GetPoisonableMobiles( null ); + + foreach ( Mobile m in list ) + { + if ( ( m.Poison == null || m.Poison.Level < poison.Level ) ) + m.ApplyPoison( null, poison ); + } + } + + public int CurrentPoisonLevel() + { + if ( m_Timer != null ) + return m_Timer.CurrentPoisonLevel(); + + return 0; + } + + protected virtual bool IsPoisonable( Mobile m ) + { + if ( m.AccessLevel == AccessLevel.Player && m.CheckAlive() && ( m.Player || ( m is BaseCreature && ((BaseCreature)m).Controlled ) ) ) + return true; + + return false; + } + + public virtual List GetPoisonableMobiles( Mobile toexclude ) + { + List list = new List(); + List templist = m_Region.GetMobiles(); + + foreach ( Mobile m in templist ) + { + if ( IsPoisonable( m ) ) + list.Add( m ); + } + + if ( toexclude != null ) + list.Remove( toexclude ); + + return list; + } + + public class PoisonRoomTimer : Timer + { + private PoisonRoom m_Room; + private int m_Count = 0; + + public PoisonRoomTimer( PoisonRoom room ) : base( TimeSpan.FromSeconds( 0 ), TimeSpan.FromSeconds( room.TimePerPoisonCast ) ) + { + m_Room = room; + } + + public int CurrentPoisonLevel() + { + int poisonLevel = m_Room.MinPoisonLevel.Level + m_Count / m_Room.TicksPerPoisonLevel; + + if ( poisonLevel > m_Room.MaxPoisonLevel.Level ) + poisonLevel = m_Room.MaxPoisonLevel.Level; + + return poisonLevel; + } + + protected override void OnTick() + { + m_Count++; + + int poisonLevel = CurrentPoisonLevel(); + + m_Room.OnPoison( Poison.GetPoison( poisonLevel ), m_Count ); + m_Room.PoisonPlayers( Poison.GetPoison( poisonLevel ) ); + m_Room.DoGasEffect(); + } + } + + public class PoisonRoomRegion : BaseRegion + { + private PoisonRoom m_Room; + private int m_LightLevel; + + public PoisonRoomRegion( PoisonRoom room, string name, Map map, int priority, Rectangle2D[] rect, int lightlevel ) : base( name, map, priority, rect ) + { + ExcludeFromParentSpawns = true; + m_Room = room; + m_LightLevel = lightlevel; + } + + public override void OnEnter( Mobile m ) + { + base.OnEnter( m ); + + m_Room.OnEnter( m ); + } + + public override void OnExit( Mobile m ) + { + base.OnExit( m ); + + m_Room.OnExit( m ); + } + + public override void OnDeath( Mobile m ) + { + base.OnDeath( m ); + + m_Room.OnDeath( m ); + } + + public override bool OnResurrect( Mobile from ) + { + return true; + } + + public override void AlterLightLevel( Mobile m, ref int global, ref int personal ) + { + global = m_LightLevel; + } + + public override bool OnBeginSpellCast( Mobile m, ISpell s ) + { + if ( ( s is MarkSpell || s is GateTravelSpell || s is RecallSpell || s is SacredJourneySpell ) && m.AccessLevel == AccessLevel.Player ) + { + m.SendLocalizedMessage( 501802 ); // Thy spell doth not appear to work... + return false; + } + + return base.OnBeginSpellCast( m, s ); + } + } + } +} diff --git a/Scripts/Engines/Doom/Lamp Room/LampController.cs b/Scripts/Engines/Doom/Lamp Room/LampController.cs new file mode 100644 index 000000000..becaeeaf7 --- /dev/null +++ b/Scripts/Engines/Doom/Lamp Room/LampController.cs @@ -0,0 +1,744 @@ +using System; +using System.Collections; +using Server.Commands; +using Server; +using Server.Mobiles; +using Server.Network; + +namespace Server.Items +{ + public class LampController : Item + { + public static void Initialize() + { + CommandSystem.Register( "GenLampPuzzle", AccessLevel.Administrator, new CommandEventHandler( GenLampPuzzle_OnCommand ) ); + } + + [Usage( "GenLampPuzzle" )] + [Description( "Generates lamp room puzzle in doom." )] + public static void GenLampPuzzle_OnCommand( CommandEventArgs e ) + { + e.Mobile.SendMessage( "Generating puzzle, please wait." ); + + Point3D loc = new Point3D( 324, 64, -1 ); + bool exists = false; + + foreach ( Item item in Map.Malas.GetItemsInRange( loc, 0 ) ) + { + if ( item is LampController ) + { + exists = true; + break; + } + } + + if ( !exists ) + { + LampController controller = new LampController(); + controller.MoveToWorld( loc, Map.Malas ); + e.Mobile.SendMessage( "Puzzle generating complete. Puzzle were generated." ); + } + else + e.Mobile.SendMessage( "Puzzle generating complete. Puzzle aleardy exists." ); + } + + public Rectangle2D Rect = new Rectangle2D( 464, 91, 10, 10 ); + public PoisonTimer m_Timer; + + private string m_Code; + private string m_PuzzleCode; + + [CommandProperty( AccessLevel.GameMaster )] + public string PuzzleCode { get { return m_PuzzleCode; } set { m_PuzzleCode = value; } } + + [CommandProperty( AccessLevel.GameMaster )] + public string Code + { + get { return m_Code; } + set + { + m_Code = value; + + if ( m_Code.Length == 4 ) + { + CheckCode(); + } + } + } + + private ArrayList m_Levers; + private ArrayList m_Statues; + private ArrayList m_Pads; + private PuzzleBox m_Box; + private bool m_CanActive; + + [CommandProperty( AccessLevel.GameMaster )] + public bool CanActive { get { return m_CanActive; } set { m_CanActive = value; } } + + private bool Check() + { + foreach ( Item item in World.Items.Values ) + { + if ( item is LampController && !item.Deleted && item != this ) + { + return true; + } + } + + return false; + } + + [Constructable] + public LampController() : base( 0x1BC3 ) + { + if ( Check() ) + { + World.Broadcast( 0x35, true, "Another Lamp's room controller exists in the world!" ); + Delete(); + return; + } + + Visible = false; + Movable = false; + + Setup(); + } + + public void Setup() + { + m_CanActive = true; + m_Code = ""; + m_PuzzleCode = ""; + + m_Levers = new ArrayList(); + m_Statues = new ArrayList(); + m_Pads = new ArrayList(); + + PuzzleLever lever1 = new PuzzleLever( 1 ); + lever1.Controller = this; + lever1.MoveToWorld( new Point3D( 316, 64, 5 ), Map.Malas ); + m_Levers.Add( lever1 ); + + PuzzleLever lever2 = new PuzzleLever( 2 ); + lever2.Controller = this; + lever2.MoveToWorld( new Point3D( 323, 58, 5 ), Map.Malas ); + m_Levers.Add( lever2 ); + + PuzzleLever lever3 = new PuzzleLever( 3 ); + lever3.Controller = this; + lever3.MoveToWorld( new Point3D( 332, 63, 5 ), Map.Malas ); + m_Levers.Add( lever3 ); + + PuzzleLever lever4 = new PuzzleLever( 4 ); + lever4.Controller = this; + lever4.MoveToWorld( new Point3D( 323, 71, 5 ), Map.Malas ); + m_Levers.Add( lever4 ); + + PuzzleStatue statue1 = new PuzzleStatue( 0x12D8 ); + statue1.MoveToWorld( new Point3D( 319, 70, 18 ), Map.Malas ); + m_Statues.Add( statue1 ); + + PuzzleStatue statue2 = new PuzzleStatue( 0x12D9 ); + statue2.MoveToWorld( new Point3D( 329, 60, 18 ), Map.Malas ); + m_Statues.Add( statue2 ); + + PuzzlePad pad1 = new PuzzlePad(); + pad1.MoveToWorld( new Point3D( 324, 58, -1 ), Map.Malas ); + pad1.Visible = false; + m_Pads.Add( pad1 ); + + PuzzlePad pad2 = new PuzzlePad(); + pad2.MoveToWorld( new Point3D( 332, 64, -1 ), Map.Malas ); + pad2.Visible = false; + m_Pads.Add( pad2 ); + + PuzzlePad pad3 = new PuzzlePad(); + pad3.MoveToWorld( new Point3D( 323, 72, -1 ), Map.Malas ); + pad3.Visible = false; + m_Pads.Add( pad3 ); + + PuzzlePad pad4 = new PuzzlePad(); + pad4.MoveToWorld( new Point3D( 316, 65, -1 ), Map.Malas ); + pad4.Visible = false; + m_Pads.Add( pad4 ); + + PuzzlePad pad5 = new PuzzlePad(); + pad5.MoveToWorld( new Point3D( 324, 64, -1 ), Map.Malas ); + m_Pads.Add( pad5 ); + + Teleporter teleporter1 = new Teleporter(); + teleporter1.MapDest = Map.Malas; + teleporter1.PointDest = new Point3D( 353, 172, -1 ); + teleporter1.MoveToWorld( new Point3D( 468, 92, -1 ), Map.Malas ); + + Teleporter teleporter2 = new Teleporter(); + teleporter2.MapDest = Map.Malas; + teleporter2.PointDest = new Point3D( 353, 172, -1 ); + teleporter2.MoveToWorld( new Point3D( 469, 92, -1 ), Map.Malas ); + + Teleporter teleporter3 = new Teleporter(); + teleporter3.MapDest = Map.Malas; + teleporter3.PointDest = new Point3D( 353, 172, -1 ); + teleporter3.MoveToWorld( new Point3D( 470, 92, -1 ), Map.Malas ); + + m_Box = new PuzzleBox(); + m_Box.CanSummon = true; + m_Box.MoveToWorld( new Point3D( 469, 96, 6 ), Map.Malas ); + + m_PuzzleCode = GenerateCode( m_PuzzleCode ); + } + + public void ClearRoom() + { + IPooledEnumerable eable = Map.Malas.GetMobilesInBounds( Rect ); + + ArrayList list = new ArrayList(); + + foreach ( object obj in eable ) + { + if ( obj is Mobile ) + { + Mobile mobile = obj as Mobile; + + list.Add( mobile ); + } + } + + for ( int i = 0; i < list.Count; i++ ) + { + Mobile m = list[ i ] as Mobile; + + if ( m is WandererOfTheVoid ) + { + m.Delete(); + } + else + { + Rectangle2D rect = new Rectangle2D( 342, 168, 16, 16 ); + + int x = Utility.Random( rect.X, rect.Width ); + int y = Utility.Random( rect.Y, rect.Height ); + + if ( x >= 345 && x <= 352 && y >= 173 && y <= 179 ) + { + x = 353; + y = 172; + } + + m.MoveToWorld( new Point3D( x, y, -1 ), Map.Malas ); + } + } + + if ( m_Timer != null ) + { + m_Timer.Stop(); + } + + m_CanActive = true; + m_Box.CanSummon = true; + m_PuzzleCode = ""; + m_PuzzleCode = GenerateCode( m_PuzzleCode ); + } + + public static string[] m_Combinations = new string[] { "1234", "1243", "1324", "1342", "1423", "1432", "2134", "2143", "2314", "2341", "2413", "2431", "3124", "3142", "3214", "3241", "3412", "3421", "4123", "4132", "4213", "4231", "4312", "4321" }; + + public void FreeLevers() + { + for ( int i = 0; i < m_Levers.Count; i++ ) + { + PuzzleLever lever = m_Levers[ i ] as PuzzleLever; + lever.ItemID = 0x108E; + } + + m_Code = ""; + + Timer.DelayCall( TimeSpan.FromSeconds( 30.0 ), new TimerCallback( SayQuitMessage ) ); + } + + public void SayQuitMessage() + { + SayStatues( 1062053, -1 ); // The sands of time have run their course. + + for ( int i = 0; i < m_Levers.Count; i++ ) + { + PuzzleLever lever = m_Levers[ i ] as PuzzleLever; + lever.ItemID = 0x108E; + } + } + + public static string GenerateCode( string puzzle ) + { + // at OSI code scheme is right order of pressed levers + // any press at any of 4 levers is one bit of code + // orientation of lever doesn't play any role + // code can't have equal numbers in it, only different, i.e: 1-4-2-3, no 1-1-1-1 + // so, we have 24 combinations for solving + + string old_code = puzzle; + string new_code = ""; + + while ( new_code == old_code ) + { + new_code = m_Combinations[ Utility.Random( m_Combinations.Length ) ]; + } + + return new_code; + } + + public int CompareCodes( string puzzle, string player ) + { + int result = 0; + + if ( puzzle.Length != player.Length || puzzle.Length > 4 || player.Length > 4 ) + { + return 0; + } + + for ( int i = 0; i < puzzle.Length; i++ ) + { + if ( puzzle[ i ] == player[ i ] ) + { + result++; + } + } + + return result; + } + + public void SayStatues( int message, int souls ) + { + string args = ""; + + if ( souls != -1 ) + { + args = souls.ToString(); + } + + for ( int i = 0; i < m_Statues.Count; i++ ) + { + PuzzleStatue statue = m_Statues[ i ] as PuzzleStatue; + + if ( statue != null ) + { + statue.PublicOverheadMessage( Network.MessageType.Regular, 0x3B2, message, args ); + } + } + } + + public void CheckCode() + { + bool incomplete = false; + + int correct_souls = 0; + + for ( int i = 0; i < m_Pads.Count; i++ ) + { + PuzzlePad pad = m_Pads[ i ] as PuzzlePad; + + if ( pad == null || !pad.Busy ) + { + incomplete = true; + } + } + + correct_souls = CompareCodes( m_PuzzleCode, m_Code ); + + if ( incomplete ) + { + SayStatues( 1050004, -1 ); // The circle is the key, the key is incomplete and so the gate remains closed. + } + else + { + // we don't guess code + if ( correct_souls >= 0 && correct_souls < 4 ) + { + ArrayList players = new ArrayList(); + + for ( int i = 0; i < m_Pads.Count; i++ ) + { + PuzzlePad pad = m_Pads[ i ] as PuzzlePad; + + if ( pad != null && pad.Stander != null && pad.Stander.Alive ) + { + players.Add( pad.Stander ); + } + } + + for ( int j = 0; j < players.Count; j++ ) + { + PlayerMobile player = players[ j ] as PlayerMobile; + + if ( player != null ) + { + Point3D location1 = player.Location; + location1.Z = 49; + + Point3D location2 = player.Location; + location2.Z = -1; + + Effects.SendPacket( player, player.Map, new HuedEffect( EffectType.Moving, Serial.Zero, player.Serial, 0x11B7, location1, location2, 20, 0, true, true, 0, 0 ) ); + Effects.PlaySound( new Point3D( 324, 64, -1 ), Map.Malas, 0x144 ); + Effects.PlaySound( new Point3D( player.X, player.Y, -1 ), Map.Malas, Utility.RandomList( 0x154, 0x14B ) ); + player.Send( new AsciiMessage( Serial.MinusOne, 0xFFFF, MessageType.Label, 0x66D, 3, "", "You are pinned down by the weight of the boulder!!!" ) ); + } + } + + switch ( correct_souls ) + { + case 0: + SayStatues( 1050009, correct_souls ); + break; // The circle of souls has failed to turn the key. The gate remains closed... + case 1: + SayStatues( 1050007, correct_souls ); + break; // ~1_NUM~ soul has turned the key correctly, but the rest have forsaken the circle... + default: + SayStatues( 1050008, correct_souls ); + break; // ~1_NUM~ souls have turned the key correctly, but the rest have forsaken the circle... + } + + for ( int j = 0; j < players.Count; j++ ) + { + PlayerMobile player = players[ j ] as PlayerMobile; + + if ( player != null ) + { + Effects.SendPacket( player, player.Map, new HuedEffect( EffectType.FixedXYZ, Serial.Zero, Serial.Zero, 0x36BD, new Point3D( player.X, player.Y, 0 ), new Point3D( player.X, player.Y, 0 ), 20, 10, true, false, 0, 0 ) ); + Effects.SendPacket( player, player.Map, new HuedEffect( EffectType.FixedFrom, player.Serial, Serial.Zero, 0x36BD, new Point3D( player.X, player.Y, -1 ), new Point3D( player.X, player.Y, -1 ), 20, 10, true, false, 0, 0 ) ); + Effects.PlaySound( new Point3D( player.X, player.Y, -1 ), player.Map, 0x307 ); + + for ( int k = 0; k < 5; k++ ) + { + Effects.SendPacket( player, player.Map, new HuedEffect( EffectType.Moving, Serial.Zero, Serial.Zero, 0x1363 + Utility.Random( 0, 11 ), new Point3D( player.X, player.Y, 0 ), new Point3D( player.X, player.Y, 0 ), 5, 0, false, false, 0, 0 ) ); + Effects.PlaySound( new Point3D( player.X, player.Y, -1 ), Map.Malas, 0x13F ); + Effects.PlaySound( new Point3D( player.X, player.Y, -1 ), Map.Malas, 0x154 ); + + player.Say( "OUCH!" ); + } + + player.Damage( 90, null ); + player.Send( new AsciiMessage( Serial.MinusOne, 0xFFFF, MessageType.Label, 0x66D, 3, "", "A speeding rock hits you in the head!" ) ); + player.SendLocalizedMessage( 502382 ); // You can move! + } + } + } + else + { + // we done it! + PlayerMobile center = ( (PuzzlePad) m_Pads[ 4 ] ).Stander; + + for ( int i = 0; i < m_Pads.Count; i++ ) + { + PuzzlePad pad = m_Pads[ i ] as PuzzlePad; + + if ( pad != null && pad.Stander != null && pad.Stander.Alive ) + { + Effects.SendPacket( pad.Stander, Map.Malas, new HuedEffect( EffectType.FixedXYZ, Serial.Zero, Serial.Zero, 0x1153, new Point3D( 325, 64, -1 ), new Point3D( 325, 64, -1 ), 1, 60, true, false, 0, 0 ) ); + Effects.SendPacket( pad.Stander, Map.Malas, new HuedEffect( EffectType.FixedXYZ, Serial.Zero, Serial.Zero, 0x1153, new Point3D( 325, 64, -1 ), new Point3D( 325, 64, -1 ), 1, 60, true, false, 0, 0 ) ); + Effects.PlaySound( new Point3D( 325, 64, -1 ), Map.Malas, 0x244 ); + + if ( center != null ) + { + Effects.SendPacket( pad.Stander, Map.Malas, new HuedEffect( EffectType.Lightning, center.Serial, Serial.Zero, 0x0, new Point3D( 324, 64, -1 ), new Point3D( 324, 64, -1 ), 0, 0, false, false, 0, 0 ) ); + Effects.SendPacket( pad.Stander, Map.Malas, new ParticleEffect( EffectType.FixedFrom, center.Serial, Serial.Zero, 0x0, new Point3D( 324, 64, -1 ), new Point3D( 324, 64, -1 ), 0, 0, false, false, 0, 0, 0x13A7, 0, 0, center.Serial, 3, 0 ) ); + } + } + } + + if ( center != null ) + { + center.MoveToWorld( new Point3D( 467, 96, -1 ), Map.Malas ); + + if ( m_Timer != null ) + { + m_Timer.Stop(); + } + + m_Timer = new PoisonTimer( this ); + m_Timer.Start(); + m_CanActive = false; + m_Box.CanSummon = true; + } + } + } + + FreeLevers(); + } + + public LampController( Serial serial ) : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.Write( (int) 0 ); // version + + writer.WriteItemList( m_Levers, true ); + writer.WriteItemList( m_Statues, true ); + writer.WriteItemList( m_Pads, true ); + + writer.Write( m_Box ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadInt(); + + m_Code = ""; + m_PuzzleCode = ""; + m_PuzzleCode = GenerateCode( m_PuzzleCode ); + + m_Levers = reader.ReadItemList(); + m_Statues = reader.ReadItemList(); + m_Pads = reader.ReadItemList(); + + m_Box = reader.ReadItem() as PuzzleBox; + + m_CanActive = true; + m_Box.CanSummon = true; + } + + public class PoisonTimer : Timer + { + public LampController m_Controller; + public int count = 1; + + public PoisonTimer( LampController controller ) : base( TimeSpan.FromSeconds( 8.0 ), TimeSpan.FromSeconds( 1.0 ) ) + { + m_Controller = controller; + } + + public void CheckAlive() + { + bool AliveCreatures = false; + + IPooledEnumerable eable = Map.Malas.GetMobilesInBounds( m_Controller.Rect ); + + foreach ( object obj in eable ) + { + if ( obj is Mobile ) + { + Mobile mobile = obj as Mobile; + + if ( mobile != null && mobile.Alive && !( mobile is WandererOfTheVoid ) ) + { + AliveCreatures = true; + } + } + } + + eable.Free(); + + if ( !AliveCreatures ) + { + m_Controller.ClearRoom(); + + Stop(); + } + } + + public void Gas( int level ) + { + int[] x = new int[ 3 ], y = new int[ 3 ]; + + for ( int i = 0; i < x.Length; i++ ) + { + x[ i ] = Utility.Random( m_Controller.Rect.X, m_Controller.Rect.Width ); + y[ i ] = Utility.Random( m_Controller.Rect.Y, m_Controller.Rect.Height ); + } + + int hue = 0xAC; + + Poison poison = null; + + switch ( level ) + { + case 0: + hue = 0xA6; + poison = Poison.Lesser; + break; + case 1: + hue = 0xAA; + poison = Poison.Regular; + break; + case 2: + hue = 0xAC; + poison = Poison.Greater; + break; + case 3: + hue = 0xA8; + poison = Poison.Deadly; + break; + case 4: + hue = 0xA4; + poison = Poison.Lethal; + break; + case 5: + hue = 0xAC; + poison = Poison.Lethal; + break; + } + + Effects.SendLocationParticles( EffectItem.Create( new Point3D( x[ 0 ], y[ 0 ], -1 ), Map.Malas, EffectItem.DefaultDuration ), 0x36B0, 1, Utility.Random( 160, 200 ), hue, 0, 0x1F78, 0 ); + Effects.SendLocationParticles( EffectItem.Create( new Point3D( x[ 1 ], y[ 1 ], -1 ), Map.Malas, EffectItem.DefaultDuration ), 0x36CB, 1, Utility.Random( 160, 200 ), hue, 0, 0x1F78, 0 ); + Effects.SendLocationParticles( EffectItem.Create( new Point3D( x[ 2 ], y[ 2 ], -1 ), Map.Malas, EffectItem.DefaultDuration ), 0x36BD, 1, Utility.Random( 160, 200 ), hue, 0, 0x1F78, 0 ); + + IPooledEnumerable eable = Map.Malas.GetMobilesInBounds( m_Controller.Rect ); + + foreach ( object obj in eable ) + { + if ( obj is Mobile ) + { + Mobile mobile = obj as Mobile; + + if ( mobile != null && poison != null && mobile.Poison == null && !( mobile is WandererOfTheVoid ) ) + { + double chance = ( level + 1 ) * 0.3; + + if ( chance >= Utility.RandomDouble() ) + { + mobile.ApplyPoison( mobile, poison ); + } + } + } + } + + eable.Free(); + } + + protected override void OnTick() + { + CheckAlive(); + + count++; + + int level = (int) ( count / 60 ); + + if ( count % 60 == 0 ) // every minute we need send message to player about level's change + { + int number = 0; + int hue = 0x485; + + switch ( level ) + { + case 1: + number = 1050001; + break; // It is becoming more difficult for you to breathe as the poisons in the room become more concentrated. + case 2: + number = 1050003; + break; // You begin to panic as the poison clouds thicken. + case 3: + number = 1050056; + break; // Terror grips your spirit as you realize you may never leave this room alive. + case 4: + number = 1050057; + break; // The end is near. You feel hopeless and desolate. The poison is beginning to stiffen your muscles. + case 5: + number = 1062091; + hue = 0x23F3; + break; // The poison is becoming too much for you to bear. You fear that you may die at any moment. + } + + IPooledEnumerable eable = Map.Malas.GetMobilesInBounds( m_Controller.Rect ); + + foreach ( object obj in eable ) + { + if ( obj is Mobile ) + { + Mobile mobile = obj as Mobile; + + if ( mobile != null && mobile.Player ) + { + if ( number != 0 ) + { + mobile.SendLocalizedMessage( number, null, hue ); + } + } + } + } + + eable.Free(); + + if ( level == 5 ) + { + PainTimer timer = new PainTimer( m_Controller ); + + timer.Start(); + } + } + + if ( count % 5 == 0 ) // every 5 seconds we fill room with a gas + { + Gas( level ); + } + } + } + + public class PainTimer : Timer + { + public LampController m_Controller; + public int count = 1; + + public PainTimer( LampController controller ) : base( TimeSpan.FromSeconds( 10.0 ), TimeSpan.FromSeconds( 10.0 ) ) + { + m_Controller = controller; + } + + protected override void OnTick() + { + count++; + + IPooledEnumerable eable = Map.Malas.GetMobilesInBounds( m_Controller.Rect ); + + ArrayList targets = new ArrayList(); + + foreach ( Mobile mobile in eable ) + { + targets.Add( mobile ); + } + + for ( int i = 0; i < targets.Count; ++i ) + { + Mobile mobile = targets[ i ] as Mobile; + + if ( mobile != null && !( mobile is WandererOfTheVoid ) ) + { + if ( mobile.Player ) + { + mobile.Say( 1062092 ); // Your body reacts violently from the pain. + + mobile.Animate( 32, 5, 1, true, false, 0 ); + } + + mobile.Damage( Utility.Random( 15, 20 ) ); + + if ( count == 10 ) // at OSI at this second all mobiles is killed and room is cleared + { + mobile.Kill(); + } + } + } + + eable.Free(); + + if ( count == 10 ) + { + if ( m_Controller != null ) + { + m_Controller.ClearRoom(); // clear room + + if ( m_Controller.m_Timer != null ) + { + m_Controller.m_Timer.Stop(); // stop gas effects + } + + Stop(); // stop convulsions + } + } + } + } + } +} diff --git a/Scripts/Engines/Doom/Lamp Room/PuzzleBox.cs b/Scripts/Engines/Doom/Lamp Room/PuzzleBox.cs new file mode 100644 index 000000000..764835e70 --- /dev/null +++ b/Scripts/Engines/Doom/Lamp Room/PuzzleBox.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections; +using Server; +using Server.Mobiles; +using Server.Network; + +namespace Server.Items +{ + public class PuzzleBox : Item + { + private bool m_CanSummon; + + [CommandProperty( AccessLevel.GameMaster )] + public bool CanSummon { get { return m_CanSummon; } set { m_CanSummon = value; } } + + private WandererOfTheVoid m_Wanderer; + + [CommandProperty( AccessLevel.GameMaster )] + public WandererOfTheVoid Wanderer { get { return m_Wanderer; } set { m_Wanderer = value; } } + + public override bool ForceShowProperties { get { return true; } } + + [Constructable] + public PuzzleBox() : base( 0xE80 ) + { + Movable = false; + + m_Wanderer = null; + } + + public PuzzleBox( Serial serial ) : base( serial ) + { + } + + public override void OnDoubleClick( Mobile from ) + { + if ( !from.InRange( this.GetWorldLocation(), 3 ) ) + return; + + if ( m_CanSummon && ( m_Wanderer == null || !m_Wanderer.Alive ) ) + { + m_Wanderer = new WandererOfTheVoid(); + m_Wanderer.MoveToWorld( new Point3D( 467, 94, -1 ), Map.Malas ); + + // I am the guardian of the Tomb of Sektu. Suffer my wrath! + m_Wanderer.PublicOverheadMessage( Network.MessageType.Regular, 0x3B2, 1060002, "" ); + + Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), new TimerCallback( SayFakeMessage ) ); + + m_CanSummon = false; + } + } + + public void SayFakeMessage() + { + // You try to pry the box open, when you notice that there is no opening. It's a fake box. + PublicOverheadMessage( Network.MessageType.Regular, 0x3B2, 1060003, "" ); + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.Write( (int) 0 ); // version + + writer.Write( m_Wanderer ); + writer.Write( (bool) m_CanSummon ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadInt(); + + m_Wanderer = reader.ReadMobile() as WandererOfTheVoid; + m_CanSummon = reader.ReadBool(); + } + } +} diff --git a/Scripts/Engines/Doom/Lamp Room/PuzzleLever.cs b/Scripts/Engines/Doom/Lamp Room/PuzzleLever.cs new file mode 100644 index 000000000..f30fda386 --- /dev/null +++ b/Scripts/Engines/Doom/Lamp Room/PuzzleLever.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections; +using Server; +using Server.Mobiles; +using Server.Network; + +namespace Server.Items +{ + public class PuzzleLever : Item + { + private LampController m_Controller; + private int m_Code; + + [CommandProperty( AccessLevel.GameMaster )] + public LampController Controller + { + get { return m_Controller; } + set { m_Controller = value; } + } + + [CommandProperty( AccessLevel.GameMaster )] + public int Code + { + get { return m_Code; } + set { m_Code = value; } + } + + [Constructable] + public PuzzleLever( int code ) : base( 0x108E ) + { + m_Code = code; + + Hue = 0x66D; + Movable = false; + } + + public PuzzleLever( Serial serial ) : base( serial ) + { + } + + public override void OnDoubleClick( Mobile from ) + { + if ( m_Controller != null && m_Controller.CanActive ) + { + if ( m_Controller.Code.Length < 4 ) + { + m_Controller.Code += m_Code; + + if ( ItemID == 0x108E ) + { + ItemID = 0x108C; + } + else if ( ItemID == 0x108C ) + { + ItemID = 0x108E; + } + + Effects.PlaySound( Location, Map, 0x3E8 ); + } + } + else + { + from.SendLocalizedMessage( 1060001 ); // You throw the switch, but the mechanism cannot be engaged again so soon. + } + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.Write( (int) 0 ); // version + + writer.Write( (int) m_Code ); + writer.Write( m_Controller ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadInt(); + + m_Code = reader.ReadInt(); + m_Controller = reader.ReadItem() as LampController; + } + } +} diff --git a/Scripts/Engines/Doom/Lamp Room/PuzzlePad.cs b/Scripts/Engines/Doom/Lamp Room/PuzzlePad.cs new file mode 100644 index 000000000..155e6e2f0 --- /dev/null +++ b/Scripts/Engines/Doom/Lamp Room/PuzzlePad.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections; +using Server; +using Server.Mobiles; +using Server.Network; + +namespace Server.Items +{ + public class PuzzlePad : Item + { + private PlayerMobile m_Stander; + private bool m_Busy; + + [CommandProperty( AccessLevel.GameMaster )] + public PlayerMobile Stander + { + get { return m_Stander; } + set { m_Stander = value; } + } + + [CommandProperty( AccessLevel.GameMaster )] + public bool Busy + { + get { return m_Busy; } + set { m_Busy = value; } + } + + private InternalStandTimer m_Timer; + + [Constructable] + public PuzzlePad() : base( 0x1822 ) + { + m_Busy = false; + m_Stander = null; + m_Timer = null; + + Hue = 0x4C; + Movable = false; + } + + public override bool HandlesOnMovement { get { return true; } } // Tell the core that we implement OnMovement + + public override bool OnMoveOver( Mobile m ) + { + if ( ( m != null ) && ( m is PlayerMobile ) ) + { + if ( m_Stander == null ) + { + m_Stander = (PlayerMobile) m; + + if ( m_Timer != null ) + { + m_Timer.Stop(); + } + + m_Timer = new InternalStandTimer( this ); + + m_Timer.Start(); + } + } + + return base.OnMoveOver( m ); + } + + public PuzzlePad( 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(); + } + + private class InternalStandTimer : Timer + { + private PuzzlePad m_Pad; + + public InternalStandTimer( PuzzlePad pad ) : base( TimeSpan.FromSeconds( 0.25 ), TimeSpan.FromSeconds( 0.25 ) ) + { + m_Pad = pad; + Priority = TimerPriority.FiftyMS; + } + + private void Vacance() + { + if ( m_Pad != null ) + { + m_Pad.Stander = null; + m_Pad.Busy = false; + } + + Stop(); + } + + protected override void OnTick() + { + if ( m_Pad != null && !m_Pad.Deleted && m_Pad.Stander != null ) + { + if ( !m_Pad.Stander.Deleted && m_Pad.Stander.Alive && m_Pad.Stander.Location == m_Pad.Location ) + { + m_Pad.Busy = true; + } + else + { + Vacance(); + } + } + else + { + Vacance(); + } + } + } + } +} diff --git a/Scripts/Engines/Doom/Lamp Room/PuzzleStatue.cs b/Scripts/Engines/Doom/Lamp Room/PuzzleStatue.cs new file mode 100644 index 000000000..4e7452117 --- /dev/null +++ b/Scripts/Engines/Doom/Lamp Room/PuzzleStatue.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections; +using Server; +using Server.Mobiles; +using Server.Network; + +namespace Server.Items +{ + public class PuzzleStatue : Item + { + [Constructable] + public PuzzleStatue( int itemID ) : base( itemID ) + { + Hue = 0x44E; + Movable = false; + } + + public PuzzleStatue( Serial serial ) : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + + writer.Write( (int) 0 ); // version + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + + int version = reader.ReadInt(); + } + } +} diff --git a/Scripts/Engines/Plants/MainPlantGump.cs b/Scripts/Engines/Plants/MainPlantGump.cs index 9adf40943..c5544506c 100644 --- a/Scripts/Engines/Plants/MainPlantGump.cs +++ b/Scripts/Engines/Plants/MainPlantGump.cs @@ -129,7 +129,11 @@ namespace Server.Engines.Plants PlantTypeInfo typeInfo = PlantTypeInfo.GetInfo( m_Plant.PlantType ); PlantHueInfo hueInfo = PlantHueInfo.GetInfo( m_Plant.PlantHue ); - AddItem( 130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, typeInfo.ItemID, hueInfo.Hue ); + // The large images for these trees trigger a client crash, so use a smaller, generic tree. + if ( m_Plant.PlantType == PlantType.CypressTwisted || m_Plant.PlantType == PlantType.CypressStraight ) + AddItem( 130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, 0x0CCA, hueInfo.Hue ); + else + AddItem( 130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, typeInfo.ItemID, hueInfo.Hue ); } if ( status != PlantStatus.BowlOfDirt ) diff --git a/Scripts/Engines/Plants/PlantItem.cs b/Scripts/Engines/Plants/PlantItem.cs index e5ef1fed3..1b9f176c9 100644 --- a/Scripts/Engines/Plants/PlantItem.cs +++ b/Scripts/Engines/Plants/PlantItem.cs @@ -259,23 +259,38 @@ namespace Server.Engines.Plants if ( m_PlantStatus < PlantStatus.DecorativePlant ) { - string args = string.Format( "#{0}\t#{1}\t#{2}", m_PlantSystem.GetLocalizedHealth(), title, typeInfo.Name ); - - if ( typeInfo.ContainsPlant ) + if ( m_PlantType == PlantType.SugarCanes ) { - // a ~1_HEALTH~ [bright] ~2_COLOR~ ~3_NAME~ - list.Add( hueInfo.IsBright() ? 1061891 : 1061889, args ); + string args = string.Format( "#{0}", m_PlantSystem.GetLocalizedHealth() ); + list.Add ( 1094702, args ); } else { - // a ~1_HEALTH~ [bright] ~2_COLOR~ ~3_NAME~ plant - list.Add( hueInfo.IsBright() ? 1061892 : 1061890, args ); + + string args = string.Format( "#{0}\t#{1}\t#{2}", m_PlantSystem.GetLocalizedHealth(), title, typeInfo.Name ); + + if ( typeInfo.ContainsPlant ) + { + // a ~1_HEALTH~ [bright] ~2_COLOR~ ~3_NAME~ + list.Add( hueInfo.IsBright() ? 1061891 : 1061889, args ); + } + else + { + // a ~1_HEALTH~ [bright] ~2_COLOR~ ~3_NAME~ plant + list.Add( hueInfo.IsBright() ? 1061892 : 1061890, args ); + } } } else { - // a decorative ~1_COLOR~ ~2_TYPE~ plant - list.Add( hueInfo.IsBright() ? 1074267 : 1070973, string.Format( "#{0}\t#{1}", title, typeInfo.Name ) ); + if ( m_PlantType == PlantType.SugarCanes ) + list.Add ( 1094703 ); + else if ( title == 1080528 ) + // a decorative ~2_TYPE~ + list.Add( 1080539, string.Format( "#{0}\t#{1}", title, typeInfo.Name ) ); + else + // a decorative ~1_COLOR~ ~2_TYPE~ plant + list.Add( hueInfo.IsBright() ? 1074267 : 1070973, string.Format( "#{0}\t#{1}", title, typeInfo.Name ) ); } } else if ( m_PlantStatus >= PlantStatus.Seed ) diff --git a/Scripts/Engines/Plants/PlantType.cs b/Scripts/Engines/Plants/PlantType.cs index d118587b9..a691cf519 100644 --- a/Scripts/Engines/Plants/PlantType.cs +++ b/Scripts/Engines/Plants/PlantType.cs @@ -29,7 +29,24 @@ namespace Server.Engines.Plants RareGreenBonsai, RarePinkBonsai, ExceptionalBonsai, - ExoticBonsai + ExoticBonsai, + Cactus, + FlaxFlowers, + FoxgloveFlowers, + HopsEast, + OrfluerFlowers, + CypressTwisted, + HedgeShort, + JuniperBush, + SnowdropPatch, + Cattails, + PoppyPatch, + SpiderTree, + WaterLily, + CypressStraight, + HedgeTall, + HopsSouth, + SugarCanes } public class PlantTypeInfo @@ -60,7 +77,24 @@ namespace Server.Engines.Plants new PlantTypeInfo( 0x28DE, -5, 5, PlantType.RareGreenBonsai, true, false, false ), new PlantTypeInfo( 0x28E1, -5, 5, PlantType.RarePinkBonsai, true, false, false ), new PlantTypeInfo( 0x28E2, -5, 5, PlantType.ExceptionalBonsai, true, false, false ), - new PlantTypeInfo( 0x28E3, -5, 5, PlantType.ExoticBonsai, true, false, false ) + new PlantTypeInfo( 0x28E3, -5, 5, PlantType.ExoticBonsai, true, false, false ), + new PlantTypeInfo( 0x0D25, 0, 0, PlantType.Cactus, false, false, false ), + new PlantTypeInfo( 0x1A9A, 5, 10, PlantType.FlaxFlowers, false, true, false ), + new PlantTypeInfo( 0x0C84, 0, 0, PlantType.FoxgloveFlowers, false, true, false ), + new PlantTypeInfo( 0x1A9F, 5, -25, PlantType.HopsEast, false, false, false ), + new PlantTypeInfo( 0x0CC1, 0, 0, PlantType.OrfluerFlowers, false, true, false ), + new PlantTypeInfo( 0x0CFE, -45, -30, PlantType.CypressTwisted, false, false, false ), + new PlantTypeInfo( 0x0C8F, 0, 0, PlantType.HedgeShort, false, false, false ), + new PlantTypeInfo( 0x0CC8, 0, 0, PlantType.JuniperBush, true, false, false ), + new PlantTypeInfo( 0x0C8E, -20, 0, PlantType.SnowdropPatch, false, true, false ), + new PlantTypeInfo( 0x0CB7, 0, 0, PlantType.Cattails, false, false, false ), + new PlantTypeInfo( 0x0CBE, -20, 0, PlantType.PoppyPatch, false, true, false ), + new PlantTypeInfo( 0x0CC9, 0, 0, PlantType.SpiderTree, false, false, false ), + new PlantTypeInfo( 0x0DC1, -5, 15, PlantType.WaterLily, false, true, false ), + new PlantTypeInfo( 0x0CFB, -45, -30, PlantType.CypressStraight, false, false, false ), + new PlantTypeInfo( 0x0DB8, 0, -20, PlantType.HedgeTall, false, false, false ), + new PlantTypeInfo( 0x1AA1, 10, -25, PlantType.HopsSouth, false, false, false ), + new PlantTypeInfo( 0x246C, -25, -20, PlantType.SugarCanes, false, false, false ) }; public static PlantTypeInfo GetInfo( PlantType plantType ) @@ -83,6 +117,51 @@ namespace Server.Engines.Plants } } + public static PlantType RandomPeculiarGroupOne() + { + switch ( Utility.Random( 5 ) ) + { + case 0: return PlantType.Cactus; + case 1: return PlantType.FlaxFlowers; + case 2: return PlantType.FoxgloveFlowers; + case 3: return PlantType.HopsEast; + default: return PlantType.OrfluerFlowers; + } + } + + public static PlantType RandomPeculiarGroupTwo() + { + switch ( Utility.Random( 4 ) ) + { + case 0: return PlantType.CypressTwisted; + case 1: return PlantType.HedgeShort; + case 2: return PlantType.JuniperBush; + default: return PlantType.SnowdropPatch; + } + } + + public static PlantType RandomPeculiarGroupThree() + { + switch ( Utility.Random( 4 ) ) + { + case 0: return PlantType.Cattails; + case 1: return PlantType.PoppyPatch; + case 2: return PlantType.SpiderTree; + default: return PlantType.WaterLily; + } + } + + public static PlantType RandomPeculiarGroupFour() + { + switch ( Utility.Random( 4 ) ) + { + case 0: return PlantType.CypressStraight; + case 1: return PlantType.HedgeTall; + case 2: return PlantType.HopsSouth; + default: return PlantType.SugarCanes; + } + } + public static PlantType RandomBonsai( double increaseRatio ) { /* Chances of each plant type are equal to the chances of the previous plant type * increaseRatio: @@ -152,6 +231,25 @@ namespace Server.Engines.Plants { switch ( plantType ) { + case PlantType.Cactus: + case PlantType.FlaxFlowers: + case PlantType.FoxgloveFlowers: + case PlantType.HopsEast: + case PlantType.OrfluerFlowers: + case PlantType.CypressTwisted: + case PlantType.HedgeShort: + case PlantType.JuniperBush: + case PlantType.SnowdropPatch: + case PlantType.Cattails: + case PlantType.PoppyPatch: + case PlantType.SpiderTree: + case PlantType.WaterLily: + case PlantType.CypressStraight: + case PlantType.HedgeTall: + case PlantType.HopsSouth: + case PlantType.SugarCanes: + return 1080528; // peculiar + case PlantType.CommonGreenBonsai: case PlantType.CommonPinkBonsai: return 1063335; // common diff --git a/Scripts/Engines/Plants/Seed.cs b/Scripts/Engines/Plants/Seed.cs index 97d615826..d945b65ad 100644 --- a/Scripts/Engines/Plants/Seed.cs +++ b/Scripts/Engines/Plants/Seed.cs @@ -56,6 +56,17 @@ namespace Server.Engines.Plants return new Seed( PlantTypeInfo.RandomBonsai( increaseRatio ), PlantHue.Plain, false ); } + public static Seed RandomPeculiarSeed( int group ) + { + switch ( group ) + { + case 1: return new Seed ( PlantTypeInfo.RandomPeculiarGroupOne(), PlantHue.Plain, false ); + case 2: return new Seed ( PlantTypeInfo.RandomPeculiarGroupTwo(), PlantHue.Plain, false ); + case 3: return new Seed ( PlantTypeInfo.RandomPeculiarGroupThree(), PlantHue.Plain, false ); + default: return new Seed ( PlantTypeInfo.RandomPeculiarGroupFour(), PlantHue.Plain, false ); + } + } + [Constructable] public Seed() : this( PlantTypeInfo.RandomFirstGeneration(), PlantHueInfo.RandomFirstGeneration(), false ) { diff --git a/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs b/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs index 55a769119..f91fa9016 100644 --- a/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs +++ b/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs @@ -594,8 +594,6 @@ namespace Server.Mobiles from.SendLocalizedMessage( 500269 ); // You cannot build that there. else if ( result == AddonFitResult.NotInHouse ) from.SendLocalizedMessage( 1076192 ); // Statues can only be placed in houses where you are the owner or co-owner. - else if ( result == AddonFitResult.DoorsNotClosed ) - from.SendMessage( "You must close all house doors before placing this." ); else if ( result == AddonFitResult.DoorTooClose ) from.SendLocalizedMessage( 500271 ); // You cannot build near the door. } @@ -621,9 +619,6 @@ namespace Server.Mobiles { BaseDoor door = doors[ i ] as BaseDoor; - if ( door != null && door.Open ) - return AddonFitResult.DoorsNotClosed; - Point3D doorLoc = door.GetWorldLocation(); int doorHeight = door.ItemData.CalcHeight; diff --git a/Scripts/Items/Addons/BaseAddon.cs b/Scripts/Items/Addons/BaseAddon.cs index 4399555df..9449d24d1 100644 --- a/Scripts/Items/Addons/BaseAddon.cs +++ b/Scripts/Items/Addons/BaseAddon.cs @@ -12,7 +12,6 @@ namespace Server.Items Valid, Blocked, NotInHouse, - DoorsNotClosed, DoorTooClose, NoWall } @@ -142,9 +141,6 @@ namespace Server.Items { BaseDoor door = doors[i] as BaseDoor; - if ( door != null && door.Open ) - return AddonFitResult.DoorsNotClosed; - Point3D doorLoc = door.GetWorldLocation(); int doorHeight = door.ItemData.CalcHeight; diff --git a/Scripts/Items/Addons/BaseAddonDeed.cs b/Scripts/Items/Addons/BaseAddonDeed.cs index 176c13e58..8fdcd2d75 100644 --- a/Scripts/Items/Addons/BaseAddonDeed.cs +++ b/Scripts/Items/Addons/BaseAddonDeed.cs @@ -83,8 +83,6 @@ namespace Server.Items from.SendLocalizedMessage( 500269 ); // You cannot build that there. else if ( res == AddonFitResult.NotInHouse ) from.SendLocalizedMessage( 500274 ); // You can only place this in a house that you own! - else if ( res == AddonFitResult.DoorsNotClosed ) - from.SendMessage( "You must close all house doors before placing this." ); else if ( res == AddonFitResult.DoorTooClose ) from.SendLocalizedMessage( 500271 ); // You cannot build near the door. else if ( res == AddonFitResult.NoWall ) diff --git a/Scripts/Items/Armor/BaseArmor.cs b/Scripts/Items/Armor/BaseArmor.cs index 2de335c00..c66d6ef3e 100644 --- a/Scripts/Items/Armor/BaseArmor.cs +++ b/Scripts/Items/Armor/BaseArmor.cs @@ -564,13 +564,13 @@ namespace Server.Items CraftItem item = system.CraftItems.SearchFor( GetType() ); - if ( item != null && item.Ressources.Count == 1 && item.Ressources.GetAt( 0 ).Amount >= 2 ) + if ( item != null && item.Resources.Count == 1 && item.Resources.GetAt( 0 ).Amount >= 2 ) { try { Item res = (Item)Activator.CreateInstance( CraftResources.GetInfo( m_Resource ).ResourceTypes[0] ); - ScissorHelper( from, res, m_PlayerConstructed ? (item.Ressources.GetAt( 0 ).Amount / 2) : 1 ); + ScissorHelper( from, res, m_PlayerConstructed ? (item.Resources.GetAt( 0 ).Amount / 2) : 1 ); return true; } catch @@ -1602,7 +1602,7 @@ namespace Server.Items Type resourceType = typeRes; if ( resourceType == null ) - resourceType = craftItem.Ressources.GetAt( 0 ).ItemType; + resourceType = craftItem.Resources.GetAt( 0 ).ItemType; Resource = CraftResources.GetFromType( resourceType ); PlayerConstructed = true; diff --git a/Scripts/Items/Clothing/BaseClothing.cs b/Scripts/Items/Clothing/BaseClothing.cs index 1412fae4d..00c0e68ae 100644 --- a/Scripts/Items/Clothing/BaseClothing.cs +++ b/Scripts/Items/Clothing/BaseClothing.cs @@ -475,6 +475,26 @@ namespace Server.Items return ( m_AosAttributes.SpellChanneling != 0 ); } + public void UnscaleDurability() + { + int scale = 100 + m_AosClothingAttributes.DurabilityBonus; + + m_HitPoints = ( ( m_HitPoints * 100 ) + ( scale - 1 ) ) / scale; + m_MaxHitPoints = ( ( m_MaxHitPoints * 100 ) + ( scale - 1 ) ) / scale; + + InvalidateProperties(); + } + + public void ScaleDurability() + { + int scale = 100 + m_AosClothingAttributes.DurabilityBonus; + + m_HitPoints = ( ( m_HitPoints * scale ) + 99 ) / 100; + m_MaxHitPoints = ( ( m_MaxHitPoints * scale ) + 99 ) / 100; + + InvalidateProperties(); + } + public override bool CheckPropertyConfliction( Mobile m ) { if ( base.CheckPropertyConfliction( m ) ) @@ -931,7 +951,7 @@ namespace Server.Items CraftItem item = system.CraftItems.SearchFor( GetType() ); - if ( item != null && item.Ressources.Count == 1 && item.Ressources.GetAt( 0 ).Amount >= 2 ) + if ( item != null && item.Resources.Count == 1 && item.Resources.GetAt( 0 ).Amount >= 2 ) { try { @@ -943,11 +963,11 @@ namespace Server.Items resourceType = info.ResourceTypes[0]; if ( resourceType == null ) - resourceType = item.Ressources.GetAt( 0 ).ItemType; + resourceType = item.Resources.GetAt( 0 ).ItemType; Item res = (Item)Activator.CreateInstance( resourceType ); - ScissorHelper( from, res, m_PlayerConstructed ? (item.Ressources.GetAt( 0 ).Amount / 2) : 1 ); + ScissorHelper( from, res, m_PlayerConstructed ? (item.Resources.GetAt( 0 ).Amount / 2) : 1 ); res.LootType = LootType.Regular; @@ -993,7 +1013,7 @@ namespace Server.Items Type resourceType = typeRes; if ( resourceType == null ) - resourceType = craftItem.Ressources.GetAt( 0 ).ItemType; + resourceType = craftItem.Resources.GetAt( 0 ).ItemType; Resource = CraftResources.GetFromType( resourceType ); } diff --git a/Scripts/Items/Containers/Container.cs b/Scripts/Items/Containers/Container.cs index f83e4a803..c31e4a456 100644 --- a/Scripts/Items/Containers/Container.cs +++ b/Scripts/Items/Containers/Container.cs @@ -107,6 +107,14 @@ namespace Server.Items return true; } + public override void UpdateTotal( Item sender, TotalType type, int delta ) + { + base.UpdateTotal( sender, type, delta ); + + if ( type == TotalType.Weight && RootParent is Mobile ) + ((Mobile) RootParent).InvalidateProperties(); + } + public override void OnDoubleClick( Mobile from ) { if ( from.AccessLevel > AccessLevel.Player || from.InRange( this.GetWorldLocation(), 2 ) || this.RootParent is PlayerVendor ) @@ -142,7 +150,7 @@ namespace Server.Items public StrongBackpack() { Layer = Layer.Backpack; - Weight = 3.0; + Weight = 13.0; } public override bool CheckHold( Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight ) @@ -170,7 +178,7 @@ namespace Server.Items { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int) 1 ); // version } public override void Deserialize( GenericReader reader ) @@ -178,6 +186,9 @@ namespace Server.Items base.Deserialize( reader ); int version = reader.ReadInt(); + + if ( version == 0 ) + Weight = 13.0; } } diff --git a/Scripts/Items/Deeds/CommodityDeed.cs b/Scripts/Items/Deeds/CommodityDeed.cs index 8e0ddf190..de8d2c91b 100644 --- a/Scripts/Items/Deeds/CommodityDeed.cs +++ b/Scripts/Items/Deeds/CommodityDeed.cs @@ -66,7 +66,7 @@ namespace Server.Items } } - if ( !( m_Commodity is ICommodity ) ) //Apparently, there may be items out there with this. Funky. + if ( m_Commodity != null && !( m_Commodity is ICommodity ) ) //Apparently, there may be items out there with this. Funky. { Timer.DelayCall( TimeSpan.Zero, this.Delete ); } @@ -101,7 +101,7 @@ namespace Server.Items public override int LabelNumber{ get{ return m_Commodity == null ? 1047016 : 1047017; } } - public override void GetProperties(ObjectPropertyList list) + public override void GetProperties( ObjectPropertyList list ) { base.GetProperties( list ); diff --git a/Scripts/Items/Deeds/DragonBardingDeed.cs b/Scripts/Items/Deeds/DragonBardingDeed.cs index 997d79d04..fa5a4112c 100644 --- a/Scripts/Items/Deeds/DragonBardingDeed.cs +++ b/Scripts/Items/Deeds/DragonBardingDeed.cs @@ -132,7 +132,7 @@ namespace Server.Items Type resourceType = typeRes; if ( resourceType == null ) - resourceType = craftItem.Ressources.GetAt( 0 ).ItemType; + resourceType = craftItem.Resources.GetAt( 0 ).ItemType; Resource = CraftResources.GetFromType( resourceType ); diff --git a/Scripts/Items/Food/Beverage.cs b/Scripts/Items/Food/Beverage.cs index 82a46a6fe..b6004cc78 100644 --- a/Scripts/Items/Food/Beverage.cs +++ b/Scripts/Items/Food/Beverage.cs @@ -759,6 +759,17 @@ namespace Server.Items from.SendLocalizedMessage( 1010089 ); // You fill the container with water. } + else if ( targ is Cow ) + { + Cow cow = (Cow)targ; + + if ( cow.TryMilk( from ) ) + { + Content = BeverageType.Milk; + Quantity = MaxQuantity; + from.SendLocalizedMessage( 1080197 ); // You fill the container with milk. + } + } else if ( targ is LandTarget ) { int tileID = ((LandTarget)targ).TileID; diff --git a/Scripts/Items/Jewels/BaseJewel.cs b/Scripts/Items/Jewels/BaseJewel.cs index 2c21d6f4d..a77835f30 100644 --- a/Scripts/Items/Jewels/BaseJewel.cs +++ b/Scripts/Items/Jewels/BaseJewel.cs @@ -375,7 +375,7 @@ namespace Server.Items Type resourceType = typeRes; if ( resourceType == null ) - resourceType = craftItem.Ressources.GetAt( 0 ).ItemType; + resourceType = craftItem.Resources.GetAt( 0 ).ItemType; Resource = CraftResources.GetFromType( resourceType ); @@ -384,9 +384,9 @@ namespace Server.Items if ( context != null && context.DoNotColor ) Hue = 0; - if ( 1 < craftItem.Ressources.Count ) + if ( 1 < craftItem.Resources.Count ) { - resourceType = craftItem.Ressources.GetAt( 1 ).ItemType; + resourceType = craftItem.Resources.GetAt( 1 ).ItemType; if ( resourceType == typeof( StarSapphire ) ) GemType = GemType.StarSapphire; diff --git a/Scripts/Items/Misc/IDurability.cs b/Scripts/Items/Misc/IDurability.cs index 0425bbb9c..9827fea87 100644 --- a/Scripts/Items/Misc/IDurability.cs +++ b/Scripts/Items/Misc/IDurability.cs @@ -5,13 +5,16 @@ namespace Server.Items { interface IDurability { + bool CanFortify { get; } + int InitMinHits { get; } int InitMaxHits { get; } int HitPoints { get; set; } int MaxHitPoints { get; set; } - //Maybe a scale/unscale durability? + void ScaleDurability(); + void UnscaleDurability(); } interface IWearableDurability : IDurability diff --git a/Scripts/Items/Misc/OilCloth.cs b/Scripts/Items/Misc/OilCloth.cs index 66a5b52b3..b54813a3b 100644 --- a/Scripts/Items/Misc/OilCloth.cs +++ b/Scripts/Items/Misc/OilCloth.cs @@ -15,16 +15,9 @@ namespace Server.Items } [Constructable] - public OilCloth() : this( 1 ) - { - } - - [Constructable] - public OilCloth( int amount ) : base( 0x175D ) + public OilCloth() : base( 0x175D ) { Hue = 2001; - Stackable = true; - Amount = amount; } public bool Dye( Mobile from, DyeTub sender ) diff --git a/Scripts/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs b/Scripts/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs index b143e9a71..8e996e886 100644 --- a/Scripts/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs +++ b/Scripts/Items/Special/Bulk Order Rewards/Blacksmithy/PowderOfTemperament.cs @@ -106,186 +106,71 @@ namespace Server.Items return; } - if ( targeted is BaseArmor /*&& (DefBlacksmithy.CraftSystem.CraftItems.SearchForSubclass( targeted.GetType() ) != null)*/ ) + if ( targeted is IDurability && targeted is Item ) { - BaseArmor ar = (BaseArmor)targeted; + IDurability wearable = (IDurability) targeted; + Item item = (Item) targeted; - if ( !ar.CanFortify ) + if ( !wearable.CanFortify ) { from.SendLocalizedMessage( 1049083 ); // You cannot use the powder on that item. return; } - if ( ar.IsChildOf( from.Backpack ) && m_Powder.IsChildOf( from.Backpack ) ) + if ( item.IsChildOf( from.Backpack ) && m_Powder.IsChildOf( from.Backpack ) ) { - int origMaxHP = ar.MaxHitPoints; - int origCurHP = ar.HitPoints; + int origMaxHP = wearable.MaxHitPoints; + int origCurHP = wearable.HitPoints; - int initMaxHP = Core.AOS ? 255 : ar.InitMaxHits; - - ar.UnscaleDurability(); - - if ( ar.MaxHitPoints < initMaxHP ) + if ( origMaxHP > 0 ) { - int bonus = initMaxHP - ar.MaxHitPoints; + int initMaxHP = Core.AOS ? 255 : wearable.InitMaxHits; - if ( bonus > 10 ) - bonus = 10; + wearable.UnscaleDurability(); - ar.MaxHitPoints += bonus; - ar.HitPoints += bonus; - - ar.ScaleDurability(); - - if ( ar.MaxHitPoints > 255 ) ar.MaxHitPoints = 255; - if ( ar.HitPoints > 255 ) ar.HitPoints = 255; - - if ( ar.MaxHitPoints > origMaxHP ) + if ( wearable.MaxHitPoints < initMaxHP ) { - from.SendLocalizedMessage( 1049084 ); // You successfully use the powder on the item. + int bonus = initMaxHP - wearable.MaxHitPoints; - --m_Powder.UsesRemaining; + if ( bonus > 10 ) + bonus = 10; - if ( m_Powder.UsesRemaining <= 0 ) + wearable.MaxHitPoints += bonus; + wearable.HitPoints += bonus; + + wearable.ScaleDurability(); + + if ( wearable.MaxHitPoints > 255 ) wearable.MaxHitPoints = 255; + if ( wearable.HitPoints > 255 ) wearable.HitPoints = 255; + + if ( wearable.MaxHitPoints > origMaxHP ) { - from.SendLocalizedMessage( 1049086 ); // You have used up your powder of temperament. - m_Powder.Delete(); + from.SendLocalizedMessage( 1049084 ); // You successfully use the powder on the item. + + --m_Powder.UsesRemaining; + + if ( m_Powder.UsesRemaining <= 0 ) + { + from.SendLocalizedMessage( 1049086 ); // You have used up your powder of temperament. + m_Powder.Delete(); + } + } + else + { + wearable.MaxHitPoints = origMaxHP; + wearable.HitPoints = origCurHP; + from.SendLocalizedMessage( 1049085 ); // The item cannot be improved any further. } } else { - ar.MaxHitPoints = origMaxHP; - ar.HitPoints = origCurHP; from.SendLocalizedMessage( 1049085 ); // The item cannot be improved any further. + wearable.ScaleDurability(); } } else { - from.SendLocalizedMessage( 1049085 ); // The item cannot be improved any further. - ar.ScaleDurability(); - } - } - else - { - from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it. - } - } - else if ( targeted is BaseWeapon /*&& (DefBlacksmithy.CraftSystem.CraftItems.SearchForSubclass( targeted.GetType() ) != null)*/ ) - { - BaseWeapon wep = (BaseWeapon)targeted; - - if ( !wep.CanFortify ) - { - from.SendLocalizedMessage( 1049083 ); // You cannot use the powder on that item. - return; - } - - if ( wep.IsChildOf( from.Backpack ) && m_Powder.IsChildOf( from.Backpack ) ) - { - int origMaxHP = wep.MaxHitPoints; - int origCurHP = wep.HitPoints; - - int initMaxHP = Core.AOS ? 255 : wep.InitMaxHits; - - wep.UnscaleDurability(); - - if ( wep.MaxHitPoints < initMaxHP ) - { - int bonus = initMaxHP - wep.MaxHitPoints; - - if ( bonus > 10 ) - bonus = 10; - - wep.MaxHitPoints += bonus; - wep.HitPoints += bonus; - - wep.ScaleDurability(); - - if ( wep.MaxHitPoints > 255 ) wep.MaxHitPoints = 255; - if ( wep.HitPoints > 255 ) wep.HitPoints = 255; - - if ( wep.MaxHitPoints > origMaxHP ) - { - from.SendLocalizedMessage( 1049084 ); // You successfully use the powder on the item. - - --m_Powder.UsesRemaining; - - if ( m_Powder.UsesRemaining <= 0 ) - { - from.SendLocalizedMessage( 1049086 ); // You have used up your powder of temperament. - m_Powder.Delete(); - } - } - else - { - wep.MaxHitPoints = origMaxHP; - wep.HitPoints = origCurHP; - from.SendLocalizedMessage( 1049085 ); // The item cannot be improved any further. - } - } - else - { - from.SendLocalizedMessage( 1049085 ); // The item cannot be improved any further. - wep.ScaleDurability(); - } - } - else - { - from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it. - } - } - else if ( targeted is BaseClothing /*&& (DefBlacksmithy.CraftSystem.CraftItems.SearchForSubclass( targeted.GetType() ) != null)*/ ) - { - BaseClothing clothing = (BaseClothing)targeted; - - if ( !clothing.CanFortify ) - { - from.SendLocalizedMessage( 1049083 ); // You cannot use the powder on that item. - return; - } - - if ( clothing.IsChildOf( from.Backpack ) && m_Powder.IsChildOf( from.Backpack ) ) - { - int origMaxHP = clothing.MaxHitPoints; - int origCurHP = clothing.HitPoints; - - int initMaxHP = Core.AOS ? 255 : clothing.InitMaxHits; - - if ( clothing.MaxHitPoints < initMaxHP ) - { - int bonus = initMaxHP - clothing.MaxHitPoints; - - if ( bonus > 10 ) - bonus = 10; - - clothing.MaxHitPoints += bonus; - clothing.HitPoints += bonus; - - if ( clothing.MaxHitPoints > 255 ) clothing.MaxHitPoints = 255; - if ( clothing.HitPoints > 255 ) clothing.HitPoints = 255; - - if ( clothing.MaxHitPoints > origMaxHP ) - { - from.SendLocalizedMessage( 1049084 ); // You successfully use the powder on the item. - - --m_Powder.UsesRemaining; - - if ( m_Powder.UsesRemaining <= 0 ) - { - from.SendLocalizedMessage( 1049086 ); // You have used up your powder of temperament. - m_Powder.Delete(); - } - } - else - { - clothing.MaxHitPoints = origMaxHP; - clothing.HitPoints = origCurHP; - from.SendLocalizedMessage( 1049085 ); // The item cannot be improved any further. - } - } - else - { - from.SendLocalizedMessage( 1049085 ); // The item cannot be improved any further. + from.SendLocalizedMessage( 1049083 ); // You cannot use the powder on that item. } } else diff --git a/Scripts/Misc/AOS.cs b/Scripts/Misc/AOS.cs index a3e5bd2dd..e312c0f69 100644 --- a/Scripts/Misc/AOS.cs +++ b/Scripts/Misc/AOS.cs @@ -910,6 +910,8 @@ namespace Server { if( m_Owner is BaseArmor ) ((BaseArmor)m_Owner).UnscaleDurability(); + else if( m_Owner is BaseClothing ) + ((BaseClothing)m_Owner).UnscaleDurability(); } uint mask = (uint)bitmask; @@ -979,6 +981,8 @@ namespace Server { if( m_Owner is BaseArmor ) ((BaseArmor)m_Owner).ScaleDurability(); + else if( m_Owner is BaseClothing ) + ((BaseClothing)m_Owner).ScaleDurability(); } if( m_Owner.Parent is Mobile ) diff --git a/Scripts/Mobiles/Animals/Cows/Cow.cs b/Scripts/Mobiles/Animals/Cows/Cow.cs index 12228c63e..0fc2d3fb8 100644 --- a/Scripts/Mobiles/Animals/Cows/Cow.cs +++ b/Scripts/Mobiles/Animals/Cows/Cow.cs @@ -6,6 +6,24 @@ namespace Server.Mobiles [CorpseName( "a cow corpse" )] public class Cow : BaseCreature { + private DateTime m_MilkedOn; + + [CommandProperty( AccessLevel.GameMaster )] + public DateTime MilkedOn + { + get { return m_MilkedOn; } + set { m_MilkedOn = value; } + } + + private int m_Milk; + + [CommandProperty( AccessLevel.GameMaster )] + public int Milk + { + get { return m_Milk; } + set { m_Milk = value; } + } + [Constructable] public Cow() : base( AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4 ) { @@ -69,22 +87,53 @@ namespace Server.Mobiles Animate( 8, 0, 3, true, false, 0 ); } - public Cow(Serial serial) : base(serial) + public bool TryMilk( Mobile from ) + { + if ( !from.InLOS( this ) || !from.InRange( Location, 2 ) ) + from.SendLocalizedMessage( 1080400 ); // You can not milk the cow from this location. + if ( Controlled && ControlMaster != from ) + from.SendLocalizedMessage( 1071182 ); // The cow nimbly escapes your attempts to milk it. + if ( m_Milk == 0 && m_MilkedOn + TimeSpan.FromDays( 1 ) > DateTime.Now ) + from.SendLocalizedMessage( 1080198 ); // This cow can not be milked now. Please wait for some time. + else + { + if ( m_Milk == 0 ) + m_Milk = 4; + + m_MilkedOn = DateTime.Now; + m_Milk--; + + return true; + } + + return false; + } + + public Cow( Serial serial ) : base( serial ) { } - public override void Serialize(GenericWriter writer) + public override void Serialize( GenericWriter writer ) { - base.Serialize(writer); + base.Serialize( writer ); - writer.Write((int) 0); + writer.Write( (int) 1 ); + + writer.Write( (DateTime) m_MilkedOn ); + writer.Write( (int) m_Milk ); } - public override void Deserialize(GenericReader reader) + public override void Deserialize( GenericReader reader ) { - base.Deserialize(reader); + base.Deserialize( reader ); int version = reader.ReadInt(); + + if ( version > 0 ) + { + m_MilkedOn = reader.ReadDateTime(); + m_Milk = reader.ReadInt(); + } } } } \ No newline at end of file diff --git a/Scripts/Mobiles/Animals/Mounts/Ethereals.cs b/Scripts/Mobiles/Animals/Mounts/Ethereals.cs index 3046056a0..3926b9c8f 100644 --- a/Scripts/Mobiles/Animals/Mounts/Ethereals.cs +++ b/Scripts/Mobiles/Animals/Mounts/Ethereals.cs @@ -123,9 +123,9 @@ namespace Server.Mobiles public virtual bool Validate( Mobile from ) { - if( !IsChildOf( from.Backpack ) ) + if( Parent == null ) { - from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it. + from.SayTo( from,1010095 ); // This must be on your person to use. return false; } else if( m_IsRewardItem && !Engines.VeteranRewards.RewardSystem.CheckIsUsableBy( from, this, null ) ) diff --git a/Scripts/Mobiles/Animals/Mounts/Hiryu.cs b/Scripts/Mobiles/Animals/Mounts/Hiryu.cs index d699dbf86..ad5cfcbdc 100644 --- a/Scripts/Mobiles/Animals/Mounts/Hiryu.cs +++ b/Scripts/Mobiles/Animals/Mounts/Hiryu.cs @@ -110,6 +110,9 @@ namespace Server.Mobiles if( Utility.RandomDouble() < .33 ) PackItem( Engines.Plants.Seed.RandomBonsaiSeed() ); + + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(3) ); } diff --git a/Scripts/Mobiles/Familiars/HordeMinion.cs b/Scripts/Mobiles/Familiars/HordeMinion.cs index 6effd3f59..9667881a5 100644 --- a/Scripts/Mobiles/Familiars/HordeMinion.cs +++ b/Scripts/Mobiles/Familiars/HordeMinion.cs @@ -12,6 +12,8 @@ namespace Server.Mobiles [CorpseName( "a horde minion corpse" )] public class HordeMinionFamiliar : BaseFamiliar { + public override bool DisplayWeight{ get { return true; } } + public HordeMinionFamiliar() { Name = "a horde minion"; @@ -47,6 +49,7 @@ namespace Server.Mobiles pack = new Backpack(); pack.Movable = false; + pack.Weight = 13.0; AddItem( pack ); } diff --git a/Scripts/Mobiles/Healers/BaseHealer.cs b/Scripts/Mobiles/Healers/BaseHealer.cs index 81497b5aa..44292cc4c 100644 --- a/Scripts/Mobiles/Healers/BaseHealer.cs +++ b/Scripts/Mobiles/Healers/BaseHealer.cs @@ -88,7 +88,6 @@ namespace Server.Mobiles public virtual void OfferResurrection( Mobile m ) { Direction = GetDirectionTo( m ); - Say( 501224 ); // Thou hast strayed from the path of virtue, but thou still deservest a second chance. m.PlaySound( 0x214 ); m.FixedEffect( 0x376A, 10, 16 ); diff --git a/Scripts/Mobiles/Healers/EvilHealer.cs b/Scripts/Mobiles/Healers/EvilHealer.cs index 906bdd2f5..a611458c3 100644 --- a/Scripts/Mobiles/Healers/EvilHealer.cs +++ b/Scripts/Mobiles/Healers/EvilHealer.cs @@ -40,6 +40,12 @@ namespace Server.Mobiles public override bool CheckResurrect( Mobile m ) { + if ( Core.AOS && m.Criminal ) + { + Say( 501222 ); // Thou art a criminal. I shall not resurrect thee. + return false; + } + return true; } diff --git a/Scripts/Mobiles/Healers/EvilWanderingHealer.cs b/Scripts/Mobiles/Healers/EvilWanderingHealer.cs index 673c5a43c..916274bc3 100644 --- a/Scripts/Mobiles/Healers/EvilWanderingHealer.cs +++ b/Scripts/Mobiles/Healers/EvilWanderingHealer.cs @@ -38,6 +38,12 @@ namespace Server.Mobiles public override bool CheckResurrect( Mobile m ) { + if ( Core.AOS && m.Criminal ) + { + Say( 501222 ); // Thou art a criminal. I shall not resurrect thee. + return false; + } + return true; } diff --git a/Scripts/Mobiles/Healers/Healer.cs b/Scripts/Mobiles/Healers/Healer.cs index 028f6890a..767ce699e 100644 --- a/Scripts/Mobiles/Healers/Healer.cs +++ b/Scripts/Mobiles/Healers/Healer.cs @@ -51,6 +51,10 @@ namespace Server.Mobiles Say( 501223 ); // Thou'rt not a decent and good person. I shall not resurrect thee. return false; } + else if ( m.Karma < 0 ) + { + Say( 501224 ); // Thou hast strayed from the path of virtue, but thou still deservest a second chance. + } return true; } diff --git a/Scripts/Mobiles/Healers/WanderingHealer.cs b/Scripts/Mobiles/Healers/WanderingHealer.cs index f39ebbae8..06de3136b 100644 --- a/Scripts/Mobiles/Healers/WanderingHealer.cs +++ b/Scripts/Mobiles/Healers/WanderingHealer.cs @@ -46,6 +46,10 @@ namespace Server.Mobiles Say( 501223 ); // Thou'rt not a decent and good person. I shall not resurrect thee. return false; } + else if ( m.Karma < 0 ) + { + Say( 501224 ); // Thou hast strayed from the path of virtue, but thou still deservest a second chance. + } return true; } diff --git a/Scripts/Mobiles/Monsters/Ants/AntLion.cs b/Scripts/Mobiles/Monsters/Ants/AntLion.cs index 5c123b336..cf6ca343d 100644 --- a/Scripts/Mobiles/Monsters/Ants/AntLion.cs +++ b/Scripts/Mobiles/Monsters/Ants/AntLion.cs @@ -44,6 +44,9 @@ namespace Server.Mobiles PackItem( new Bone( 3 ) ); PackItem( new FertileDirt( Utility.RandomMinMax( 1, 5 ) ) ); + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(2) ); + switch ( Utility.Random( 4 ) ) { case 0: PackItem( new DullCopperOre( Utility.RandomMinMax( 1, 10 ) ) ); break; diff --git a/Scripts/Mobiles/Monsters/Arachnid/Melee/TerathanWarrior.cs b/Scripts/Mobiles/Monsters/Arachnid/Melee/TerathanWarrior.cs index 8f572a60c..fa0ed1a54 100644 --- a/Scripts/Mobiles/Monsters/Arachnid/Melee/TerathanWarrior.cs +++ b/Scripts/Mobiles/Monsters/Arachnid/Melee/TerathanWarrior.cs @@ -41,6 +41,9 @@ namespace Server.Mobiles Karma = -4000; VirtualArmor = 30; + + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(3) ); } public override void GenerateLoot() diff --git a/Scripts/Mobiles/Monsters/Humanoid/Magic/Titan.cs b/Scripts/Mobiles/Monsters/Humanoid/Magic/Titan.cs index bdd66acf2..3d9c39367 100644 --- a/Scripts/Mobiles/Monsters/Humanoid/Magic/Titan.cs +++ b/Scripts/Mobiles/Monsters/Humanoid/Magic/Titan.cs @@ -40,6 +40,9 @@ namespace Server.Mobiles Karma = -11500; VirtualArmor = 40; + + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(1) ); } public override void GenerateLoot() diff --git a/Scripts/Mobiles/Monsters/Humanoid/Melee/Cyclops.cs b/Scripts/Mobiles/Monsters/Humanoid/Melee/Cyclops.cs index d932d9548..73a661529 100644 --- a/Scripts/Mobiles/Monsters/Humanoid/Melee/Cyclops.cs +++ b/Scripts/Mobiles/Monsters/Humanoid/Melee/Cyclops.cs @@ -5,13 +5,13 @@ using Server.Targeting; namespace Server.Mobiles { - [CorpseName( "a cyclops corpse" )] + [CorpseName( "a cyclopean corpse" )] public class Cyclops : BaseCreature { [Constructable] public Cyclops() : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 ) { - Name = "a cyclops"; + Name = "a cyclopean warrior"; Body = 75; BaseSoundID = 604; diff --git a/Scripts/Mobiles/Monsters/Humanoid/Melee/Mummy.cs b/Scripts/Mobiles/Monsters/Humanoid/Melee/Mummy.cs index 8bcbf6226..4dd325e05 100644 --- a/Scripts/Mobiles/Monsters/Humanoid/Melee/Mummy.cs +++ b/Scripts/Mobiles/Monsters/Humanoid/Melee/Mummy.cs @@ -41,6 +41,9 @@ namespace Server.Mobiles VirtualArmor = 50; + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(2) ); + PackItem( new Garlic( 5 ) ); PackItem( new Bandage( 10 ) ); } diff --git a/Scripts/Mobiles/Monsters/Humanoid/Melee/RestlessSoul.cs b/Scripts/Mobiles/Monsters/Humanoid/Melee/RestlessSoul.cs index c715b42c7..030c320cd 100644 --- a/Scripts/Mobiles/Monsters/Humanoid/Melee/RestlessSoul.cs +++ b/Scripts/Mobiles/Monsters/Humanoid/Melee/RestlessSoul.cs @@ -15,7 +15,7 @@ namespace Server.Mobiles [Constructable] public RestlessSoul() : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.4, 0.8 ) { - Name = "a restless soul"; + Name = "restless soul"; Body = 0x3CA; Hue = 0x453; @@ -71,12 +71,12 @@ namespace Server.Mobiles public override int GetIdleSound() { - return 0x1BF; + return 0x107; } public override int GetAngerSound() { - return 0x107; + return 0x1BF; } public override int GetDeathSound() diff --git a/Scripts/Mobiles/Monsters/LBR/Jukas/JukaMage.cs b/Scripts/Mobiles/Monsters/LBR/Jukas/JukaMage.cs index 9cf2297d6..23daccec3 100644 --- a/Scripts/Mobiles/Monsters/LBR/Jukas/JukaMage.cs +++ b/Scripts/Mobiles/Monsters/LBR/Jukas/JukaMage.cs @@ -64,6 +64,9 @@ namespace Server.Mobiles PackItem( new ArcaneGem() ); + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(4) ); + m_NextAbilityTime = DateTime.Now + TimeSpan.FromSeconds( Utility.RandomMinMax( 2, 5 ) ); } diff --git a/Scripts/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs b/Scripts/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs index 59f37917a..bf4a156d1 100644 --- a/Scripts/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs +++ b/Scripts/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs @@ -56,6 +56,9 @@ namespace Server.Mobiles Karma = 5000; VirtualArmor = 28; // Don't know what it should be + + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(1) ); } public override void GenerateLoot() diff --git a/Scripts/Mobiles/Monsters/ML/Misc/Magic/GreaterDragon.cs b/Scripts/Mobiles/Monsters/ML/Misc/Magic/GreaterDragon.cs index 3ec3adddd..1fdb06c2a 100644 --- a/Scripts/Mobiles/Monsters/ML/Misc/Magic/GreaterDragon.cs +++ b/Scripts/Mobiles/Monsters/ML/Misc/Magic/GreaterDragon.cs @@ -63,7 +63,7 @@ namespace Server.Mobiles public override bool AutoDispel{ get{ return !Controlled; } } public override int TreasureMapLevel{ get{ return 5; } } public override int Meat{ get{ return 19; } } - public override int Hides{ get{ return 20; } } + public override int Hides{ get{ return 30; } } public override HideType HideType{ get{ return HideType.Barbed; } } public override int Scales{ get{ return 7; } } public override ScaleType ScaleType{ get{ return ( Body == 12 ? ScaleType.Yellow : ScaleType.Red ); } } diff --git a/Scripts/Mobiles/Monsters/Misc/Magic/Wisp.cs b/Scripts/Mobiles/Monsters/Misc/Magic/Wisp.cs index 9485caaf4..1fe161553 100644 --- a/Scripts/Mobiles/Monsters/Misc/Magic/Wisp.cs +++ b/Scripts/Mobiles/Monsters/Misc/Magic/Wisp.cs @@ -51,6 +51,9 @@ namespace Server.Mobiles VirtualArmor = 40; + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(3) ); + AddItem( new LightSource() ); } diff --git a/Scripts/Mobiles/Monsters/Misc/Melee/PlagueBeast.cs b/Scripts/Mobiles/Monsters/Misc/Melee/PlagueBeast.cs index 596308362..452a8aaa3 100644 --- a/Scripts/Mobiles/Monsters/Misc/Melee/PlagueBeast.cs +++ b/Scripts/Mobiles/Monsters/Misc/Melee/PlagueBeast.cs @@ -40,6 +40,9 @@ namespace Server.Mobiles VirtualArmor = 30; PackArmor( 1, 5 ); + + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(4) ); } public override void GenerateLoot() diff --git a/Scripts/Mobiles/Monsters/Reptile/Magic/SerpentineDragon.cs b/Scripts/Mobiles/Monsters/Reptile/Magic/SerpentineDragon.cs index ad8da53db..c4cb784c5 100644 --- a/Scripts/Mobiles/Monsters/Reptile/Magic/SerpentineDragon.cs +++ b/Scripts/Mobiles/Monsters/Reptile/Magic/SerpentineDragon.cs @@ -42,6 +42,9 @@ namespace Server.Mobiles Karma = 15000; VirtualArmor = 36; + + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(2) ); } public override void GenerateLoot() diff --git a/Scripts/Mobiles/Monsters/SE/BakeKitsune.cs b/Scripts/Mobiles/Monsters/SE/BakeKitsune.cs index 339f8d667..614e7745e 100644 --- a/Scripts/Mobiles/Monsters/SE/BakeKitsune.cs +++ b/Scripts/Mobiles/Monsters/SE/BakeKitsune.cs @@ -60,6 +60,96 @@ namespace Server.Mobiles public override int Hides{ get{ return 10; } } public override HideType HideType{ get{ return HideType.Barbed; } } public override FoodType FavoriteFood{ get{ return FoodType.Fish; } } + public override bool ShowFameTitle{ get{ return false; } } + public override bool ClickTitle{ get{ return false; } } + public override bool PropertyTitle{ get{ return false; } } + + public override void OnCombatantChange() + { + if ( Combatant == null && !IsBodyMod && !Controlled && m_DisguiseTimer == null && Utility.RandomBool() ) + m_DisguiseTimer = Timer.DelayCall( TimeSpan.FromSeconds( Utility.RandomMinMax( 15, 30 ) ), new TimerCallback( Disguise ) ); + } + + public override bool OnBeforeDeath() + { + RemoveDisguise(); + + return base.OnBeforeDeath(); + } + + #region Disguise + private Timer m_DisguiseTimer; + + public void Disguise() + { + if ( Combatant != null || IsBodyMod || Controlled ) + return; + + FixedEffect( 0x376A, 8, 32 ); + PlaySound( 0x1FE ); + + Female = Utility.RandomBool(); + + if ( Female ) + { + BodyMod = 0x191; + Name = NameList.RandomName( "female" ); + } + else + { + BodyMod = 0x190; + Name = NameList.RandomName( "male" ); + } + + Title = "the mystic llama herder"; + Hue = Race.Human.RandomSkinHue(); + HairItemID = Race.Human.RandomHair( this ); + HairHue = Race.Human.RandomHairHue(); + FacialHairItemID = Race.Human.RandomFacialHair( this ); + FacialHairHue = HairHue; + + switch ( Utility.Random( 4 ) ) + { + case 0: AddItem( new Shoes( Utility.RandomNeutralHue() ) ); break; + case 1: AddItem( new Boots( Utility.RandomNeutralHue() ) ); break; + case 2: AddItem( new Sandals( Utility.RandomNeutralHue() ) ); break; + case 3: AddItem( new ThighBoots( Utility.RandomNeutralHue() ) ); break; + } + + AddItem( new Robe( Utility.RandomNondyedHue() ) ); + + m_DisguiseTimer = null; + m_DisguiseTimer = Timer.DelayCall( TimeSpan.FromSeconds( 75 ), new TimerCallback( RemoveDisguise ) ); + } + + public void RemoveDisguise() + { + if ( !IsBodyMod ) + return; + + Name = "a bake kitsune"; + Title = null; + BodyMod = 0; + Hue = 0; + HairItemID = 0; + HairHue = 0; + FacialHairItemID = 0; + FacialHairHue = 0; + + DeleteItemOnLayer( Layer.OuterTorso ); + DeleteItemOnLayer( Layer.Shoes ); + + m_DisguiseTimer = null; + } + + public void DeleteItemOnLayer( Layer layer ) + { + Item item = FindItemOnLayer( layer ); + + if ( item != null ) + item.Delete(); + } + #endregion public override void OnGaveMeleeAttack( Mobile defender ) { @@ -180,6 +270,8 @@ namespace Server.Mobiles SetResistance( ResistanceType.Poison, 40, 60 ); SetResistance( ResistanceType.Energy, 40, 60 ); } + + Timer.DelayCall( TimeSpan.Zero, new TimerCallback( RemoveDisguise ) ); } } } diff --git a/Scripts/Mobiles/Monsters/SE/Kappa.cs b/Scripts/Mobiles/Monsters/SE/Kappa.cs index a98d75d1c..0c00524d0 100644 --- a/Scripts/Mobiles/Monsters/SE/Kappa.cs +++ b/Scripts/Mobiles/Monsters/SE/Kappa.cs @@ -51,10 +51,10 @@ namespace Server.Mobiles case 2: PackItem( new Axle() ); break; } } + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(4) ); } - - public override void GenerateLoot() { AddLoot( LootPack.Meager ); @@ -126,11 +126,10 @@ namespace Server.Mobiles if ( m.Alive ) { int damageGiven = AOS.Damage( m, from, 5, 0, 0, 0, 0, 100 ); - from.Hits += damageGiven; } else - { + { EndLifeDrain( m ); } } @@ -165,7 +164,7 @@ namespace Server.Mobiles } if ( amt > 0 ) { - SpillAcid( target, amt, "slime" ); + SpillAcid( target, amt ); from.SendLocalizedMessage( 1070820 ); if ( Mana > 14) Mana -= 15; @@ -175,6 +174,11 @@ namespace Server.Mobiles base.OnDamage( amount, from, willKill ); } + public override Item NewHarmfulItem() + { + return new AcidSlime( TimeSpan.FromSeconds(10), 5, 10 ); + } + public Kappa( Serial serial ) : base( serial ) { } diff --git a/Scripts/Mobiles/Monsters/SE/TsukiWolf.cs b/Scripts/Mobiles/Monsters/SE/TsukiWolf.cs index ca39d13af..c8e360789 100644 --- a/Scripts/Mobiles/Monsters/SE/TsukiWolf.cs +++ b/Scripts/Mobiles/Monsters/SE/TsukiWolf.cs @@ -47,7 +47,8 @@ namespace Server.Mobiles Fame = 8500; Karma = -8500; - + if ( Core.ML && Utility.RandomDouble() < .33 ) + PackItem( Engines.Plants.Seed.RandomPeculiarSeed(1) ); switch( Utility.Random( 10 ) ) { diff --git a/Scripts/Mobiles/Vendors/NPC/AnimalTrainer.cs b/Scripts/Mobiles/Vendors/NPC/AnimalTrainer.cs index fcfb3069f..79ab34e4d 100644 --- a/Scripts/Mobiles/Vendors/NPC/AnimalTrainer.cs +++ b/Scripts/Mobiles/Vendors/NPC/AnimalTrainer.cs @@ -297,7 +297,7 @@ namespace Server.Mobiles { Container bank = from.FindBankNoCreate(); - if ( bank != null && bank.ConsumeTotal( typeof( Gold ), 30 ) ) + if ( ( from.Backpack != null && from.Backpack.ConsumeTotal( typeof( Gold ), 30 ) ) || ( bank != null && bank.ConsumeTotal( typeof( Gold ), 30 ) ) ) { pet.ControlTarget = null; pet.ControlOrder = OrderType.Stay; diff --git a/Scripts/Multis/BaseHouse.cs b/Scripts/Multis/BaseHouse.cs index bcbfa4996..26669f287 100644 --- a/Scripts/Multis/BaseHouse.cs +++ b/Scripts/Multis/BaseHouse.cs @@ -1004,6 +1004,8 @@ namespace Server.Multis return HasSecureAccess( from, ((ISecurable)item).Level ); else if ( item is Container ) return IsCoOwner( from ); + else if ( item.Stackable ) + return true; else if ( item is BaseLight ) return IsFriend( from ); else if ( item is PotionKeg ) @@ -1405,7 +1407,7 @@ namespace Server.Multis } else { - m_Trash.MoveToWorld( from.Location, from.Map ); + from.SendLocalizedMessage( 502117 ); // You already have a trash barrel! } } @@ -3417,7 +3419,7 @@ namespace Server.Multis } else { - if ( targeted is VendorRentalContract || ( targeted is Container && ((Container)targeted).FindItemByType( typeof( VendorRentalContract ) ) != null ) ) + if ( targeted is VendorRentalContract ) { from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1062392 ); // You must double click the contract in your pack to lock it down. from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 501732 ); // I cannot lock this down! @@ -3475,7 +3477,7 @@ namespace Server.Multis } else { - if ( targeted is VendorRentalContract || ( targeted is Container && ((Container)targeted).FindItemByType( typeof( VendorRentalContract ) ) != null ) ) + if ( targeted is VendorRentalContract ) { from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1062392 ); // You must double click the contract in your pack to lock it down. from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 501732 ); // I cannot lock this down! diff --git a/Scripts/Skills/AnimalLore.cs b/Scripts/Skills/AnimalLore.cs index 8846f6753..b13578e45 100644 --- a/Scripts/Skills/AnimalLore.cs +++ b/Scripts/Skills/AnimalLore.cs @@ -122,6 +122,16 @@ namespace Server.SkillHandlers return String.Format( "
{0}%
", val ); } + #region Mondain's Legacy + private static string FormatDamage( int min, int max ) + { + if ( min <= 0 || max <= 0 ) + return "
---
"; + + return String.Format( "
{0}-{1}
", min, max ); + } + #endregion + private const int LabelColor = 0x24E5; public AnimalLoreGump( BaseCreature c ) : base( 250, 50 ) @@ -255,6 +265,14 @@ namespace Server.SkillHandlers AddHtmlLocalized( 153, 240, 160, 18, 1061650, LabelColor, false, false ); // Energy AddHtml( 320, 240, 35, 18, FormatElement( c.EnergyDamage ), false, false ); + #region Mondain's Legacy + if ( Core.ML ) + { + AddHtmlLocalized( 153, 258, 160, 18, 1076750, LabelColor, false, false ); // Base Damage + AddHtml( 300, 258, 55, 18, FormatDamage( c.DamageMin, c.DamageMax ), false, false ); + } + #endregion + AddButton( 340, 358, 5601, 5605, 0, GumpButtonType.Page, page + 1 ); AddButton( 317, 358, 5603, 5607, 0, GumpButtonType.Page, page - 1 ); } @@ -278,8 +296,18 @@ namespace Server.SkillHandlers AddHtmlLocalized( 153, 222, 160, 18, 1044061, LabelColor, false, false ); // Anatomy AddHtml( 320, 222, 35, 18, FormatSkill( c, SkillName.Anatomy ), false, false ); - AddHtmlLocalized( 153, 240, 160, 18, 1044090, LabelColor, false, false ); // Poisoning - AddHtml( 320, 240, 35, 18, FormatSkill( c, SkillName.Poisoning ), false, false ); + #region Mondain's Legacy + if ( c is CuSidhe ) + { + AddHtmlLocalized( 153, 240, 160, 18, 1044077, LabelColor, false, false ); // Healing + AddHtml( 320, 240, 35, 18, FormatSkill( c, SkillName.Healing ), false, false ); + } + else + { + AddHtmlLocalized( 153, 240, 160, 18, 1044090, LabelColor, false, false ); // Poisoning + AddHtml( 320, 240, 35, 18, FormatSkill( c, SkillName.Poisoning ), false, false ); + } + #endregion AddImage( 128, 260, 2086 ); AddHtmlLocalized( 147, 258, 160, 18, 3001032, 200, false, false ); // Lore & Knowledge diff --git a/Scripts/Skills/DetectHidden.cs b/Scripts/Skills/DetectHidden.cs index f0fc75183..85135d574 100644 --- a/Scripts/Skills/DetectHidden.cs +++ b/Scripts/Skills/DetectHidden.cs @@ -20,7 +20,7 @@ namespace Server.SkillHandlers src.SendLocalizedMessage( 500819 );//Where will you search? src.Target = new InternalTarget(); - return TimeSpan.FromSeconds( 1.0 ); + return TimeSpan.FromSeconds( 6.0 ); } private class InternalTarget : Target diff --git a/Scripts/Skills/Stealing.cs b/Scripts/Skills/Stealing.cs index 2c443b884..8c40b9206 100644 --- a/Scripts/Skills/Stealing.cs +++ b/Scripts/Skills/Stealing.cs @@ -150,10 +150,10 @@ namespace Server.SkillHandlers m_Thief.SendLocalizedMessage( 1010586 ); // YOU STOLE THE SIGIL!!! (woah, calm down now) - if ( sig.LastMonolith != null ) + if ( sig.LastMonolith != null && sig.LastMonolith.Sigil != null ) { sig.LastMonolith.Sigil = null; - - sig.LastStolen = DateTime.Now; + sig.LastStolen = DateTime.Now; + } return sig; } diff --git a/Scripts/Spells/Fifth/PoisonField.cs b/Scripts/Spells/Fifth/PoisonField.cs index 3be55cee6..dfd13c5b5 100644 --- a/Scripts/Spells/Fifth/PoisonField.cs +++ b/Scripts/Spells/Fifth/PoisonField.cs @@ -4,6 +4,7 @@ using Server.Targeting; using Server.Network; using Server.Misc; using Server.Items; +using Server.Mobiles; namespace Server.Spells.Fifth { @@ -183,7 +184,9 @@ namespace Server.Spells.Fifth p = Poison.Regular; } - m.ApplyPoison( m_Caster, p ); + if ( m.ApplyPoison( m_Caster, p ) == ApplyPoisonResult.Poisoned ) + if ( SpellHelper.CanRevealCaster( m ) ) + m_Caster.RevealingAction(); } public override bool OnMoveOver( Mobile m ) diff --git a/Scripts/Spells/Fourth/FireField.cs b/Scripts/Spells/Fourth/FireField.cs index edd2a06f3..4a71882b6 100644 --- a/Scripts/Spells/Fourth/FireField.cs +++ b/Scripts/Spells/Fourth/FireField.cs @@ -4,6 +4,7 @@ using Server.Targeting; using Server.Network; using Server.Misc; using Server.Items; +using Server.Mobiles; namespace Server.Spells.Fourth { @@ -184,6 +185,9 @@ namespace Server.Spells.Fourth { if ( Visible && m_Caster != null && (!Core.AOS || m != m_Caster) && SpellHelper.ValidIndirectTarget( m_Caster, m ) && m_Caster.CanBeHarmful( m, false ) ) { + if ( SpellHelper.CanRevealCaster( m ) ) + m_Caster.RevealingAction(); + m_Caster.DoHarmful( m ); int damage = m_Damage; @@ -257,6 +261,9 @@ namespace Server.Spells.Fourth while ( m_Queue.Count > 0 ) { Mobile m = (Mobile)m_Queue.Dequeue(); + + if ( SpellHelper.CanRevealCaster( m ) ) + caster.RevealingAction(); caster.DoHarmful( m ); diff --git a/Scripts/Spells/Necromancy/PoisonStrike.cs b/Scripts/Spells/Necromancy/PoisonStrike.cs index 41fb28a2f..f737e3eb4 100644 --- a/Scripts/Spells/Necromancy/PoisonStrike.cs +++ b/Scripts/Spells/Necromancy/PoisonStrike.cs @@ -62,9 +62,12 @@ namespace Server.Spells.Necromancy if( map != null ) { List targets = new List(); + + if ( Caster.CanBeHarmful(m, false ) ) + targets.Add( m ); foreach( Mobile targ in m.GetMobilesInRange( 2 ) ) - if( (Caster == targ || m == targ || SpellHelper.ValidIndirectTarget( Caster, targ )) && Caster.CanBeHarmful( targ, false ) ) + if( ( targ != Caster ) && ( SpellHelper.ValidIndirectTarget( Caster, targ ) && Caster.CanBeHarmful( targ, false) ) ) targets.Add( targ ); for( int i = 0; i < targets.Count; ++i ) diff --git a/Scripts/Spells/Ninjitsu/ShadowJump.cs b/Scripts/Spells/Ninjitsu/ShadowJump.cs index 0e1799ba2..2252bc67f 100644 --- a/Scripts/Spells/Ninjitsu/ShadowJump.cs +++ b/Scripts/Spells/Ninjitsu/ShadowJump.cs @@ -120,8 +120,7 @@ namespace Server.Spells.Ninjitsu { m_Owner.FinishSequence(); - if ( !from.CheckSkill( SkillName.Hiding, 0.0, 100.0 ) ) //TODO: Hiding check or stealth check? - from.RevealingAction(); + Server.SkillHandlers.Stealth.OnUse( from ); } } } diff --git a/Scripts/Spells/Sixth/ParalyzeField.cs b/Scripts/Spells/Sixth/ParalyzeField.cs index fbd662280..c4d3d8686 100644 --- a/Scripts/Spells/Sixth/ParalyzeField.cs +++ b/Scripts/Spells/Sixth/ParalyzeField.cs @@ -3,6 +3,7 @@ using Server.Targeting; using Server.Items; using Server.Network; using Server.Misc; +using Server.Mobiles; namespace Server.Spells.Sixth { @@ -161,6 +162,9 @@ namespace Server.Spells.Sixth { if ( Visible && m_Caster != null && (!Core.AOS || m != m_Caster) && SpellHelper.ValidIndirectTarget( m_Caster, m ) && m_Caster.CanBeHarmful( m, false ) ) { + if ( SpellHelper.CanRevealCaster( m ) ) + m_Caster.RevealingAction(); + m_Caster.DoHarmful( m ); double duration; diff --git a/Scripts/Spells/Spellweaving/NatureFury.cs b/Scripts/Spells/Spellweaving/NatureFury.cs index dd448c7b3..0a03dac8c 100644 --- a/Scripts/Spells/Spellweaving/NatureFury.cs +++ b/Scripts/Spells/Spellweaving/NatureFury.cs @@ -69,18 +69,14 @@ namespace Server.Spells.Spellweaving if ( house != null) if ( !house.IsFriend ( Caster ) ) return; - - if( !SpellHelper.FindValidSpawnLocation( map, ref p, m_MobileTarg ) ) + if (m != null) //say "Target can not be seen" if you target directly a mobile, like in OSI + { + Caster.SendLocalizedMessage( 500237 ); // Target can not be seen. + } + else if ( map == null || !map.CanSpawnMobile( p.X, p.Y, p.Z ) ) { Caster.SendLocalizedMessage( 501942 ); // That location is blocked. } - - //say "Target can not be seen" if you target directly a mobile, like in OSI - if (m != null) - { - Caster.SendLocalizedMessage(500237); // Target can not be seen. - } - else if( SpellHelper.CheckTown( p, Caster ) && (m_MobileTarg ? CheckHSequence( m ) : CheckSequence()) ) { TimeSpan duration = TimeSpan.FromSeconds( Caster.Skills.Spellweaving.Value/24 + 25 + FocusLevel*2 ); @@ -89,8 +85,7 @@ namespace Server.Spells.Spellweaving m = null; NatureFury nf = new NatureFury( m ); - if ( !Caster.InLOS ( p ) ) - return; + BaseCreature.Summon( nf, false, Caster, p , 0x5CB, duration ); Timer t = null; @@ -112,8 +107,7 @@ namespace Server.Spells.Spellweaving { private NatureFurySpell m_Owner; - public InternalTarget( NatureFurySpell owner ) - : base( 10, true, TargetFlags.None ) + public InternalTarget( NatureFurySpell owner ) : base( 10, true, TargetFlags.None ) { m_Owner = owner; CheckLOS = true; @@ -124,8 +118,6 @@ namespace Server.Spells.Spellweaving if( o is IPoint3D ) m_Owner.Target( (IPoint3D)o ); } - - protected override void OnTargetFinish( Mobile from ) { if( m_Owner != null ) diff --git a/Scripts/Spells/Third/Teleport.cs b/Scripts/Spells/Third/Teleport.cs index 6b651a8ba..60e1c78c6 100644 --- a/Scripts/Spells/Third/Teleport.cs +++ b/Scripts/Spells/Third/Teleport.cs @@ -95,6 +95,16 @@ namespace Server.Spells.Third } m.PlaySound( 0x1FE ); + + IPooledEnumerable eable = m.GetItemsInRange( 0 ); + + foreach ( Item item in eable ) + { + if ( item is ParalyzeFieldSpell.InternalItem || item is PoisonFieldSpell.InternalItem || item is FireFieldItem ) + item.OnMoveOver( m ); + } + + eable.Free(); } FinishSequence();