From c52504151bbd42c124b443cfcbaead0be096dd0d Mon Sep 17 00:00:00 2001 From: eos Date: Sun, 22 Apr 2012 04:10:06 +0000 Subject: [PATCH] - IPTable update when deleting accounts, so the creation IP address gets a new account spot. - Added AdminGump option for removing account access IP addresses. - Firebombs now cancel the target properly when exploding. - Fixed item placement bug when creating firebombs. - Added criminal check option to Teleporter. - Fixed item placement bug when opening MIBs. - Made SOS flipable. - Opening an SOS will no longer close other SOS gumps. - Corrected Leafblade to be a Fencing weapon. - Meer mages no longer cast plagues on pets, only on players. - Corrected skills typo in CorruptedSoul. - Movement induced by angering a monster during taming will now respect movement timers. - Teleporting into keep walls is no longer possible. - Removed the ability to have line of sight under a house plot through house walls. - Added the Frozen mobile flag, providing clients with information on when they are frozen. (The client then disallows movement.) - Fix for character statue redeeding issues. --- Scripts/Accounting/Account.cs | 3 + .../Character Statue Maker/CharacterStatue.cs | 16 +- .../Gumps/CharacterStatueGump.cs | 33 +--- Scripts/Gumps/AdminGump.cs | 162 +++++++++++++++--- Scripts/Items/Misc/Firebomb.cs | 58 ++++++- Scripts/Items/Misc/OilCloth.cs | 20 +-- Scripts/Items/Misc/Teleporter.cs | 25 ++- .../Fishing/Misc/MessageInABottle.cs | 3 +- Scripts/Items/Skill Items/Fishing/Misc/SOS.cs | 5 +- Scripts/Items/Weapons/ML Weapons/Leafblade.cs | 1 + .../Mobiles/Monsters/LBR/Meers/MeerMage.cs | 34 ++-- .../ML/Humanoid/Melee/CorruptedSoul.cs | 2 +- Scripts/Skills/AnimalTaming.cs | 3 +- Scripts/Spells/Ninjitsu/ShadowJump.cs | 17 +- Scripts/Spells/Third/Teleport.cs | 16 +- Server/Item.cs | 15 ++ Server/Map.cs | 8 +- Server/Mobile.cs | 10 +- 18 files changed, 309 insertions(+), 122 deletions(-) diff --git a/Scripts/Accounting/Account.cs b/Scripts/Accounting/Account.cs index c4895aa5e..57d5c6055 100644 --- a/Scripts/Accounting/Account.cs +++ b/Scripts/Accounting/Account.cs @@ -57,6 +57,9 @@ namespace Server.Accounting m_Mobiles[i] = null; } + if ( m_LoginIPs.Length != 0 && AccountHandler.IPTable.ContainsKey( m_LoginIPs[0] ) ) + --AccountHandler.IPTable[m_LoginIPs[0]]; + Accounts.Remove( m_Username ); } diff --git a/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs b/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs index 5e7fc5047..be6e3405e 100644 --- a/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs +++ b/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs @@ -232,7 +232,7 @@ namespace Server.Mobiles Frozen = true; - if( m_SculptedBy == null || Map == Map.Internal ) + if( m_SculptedBy == null || Map == Map.Internal ) // Remove preview statues { Timer.DelayCall( TimeSpan.Zero, new TimerCallback( Delete ) ); } @@ -246,7 +246,7 @@ namespace Server.Mobiles InvalidateProperties(); } - public void Demolish( Mobile by ) + public bool Demolish( Mobile by ) { CharacterStatueDeed deed = new CharacterStatueDeed( null ); @@ -260,11 +260,15 @@ namespace Server.Mobiles if ( m_Plinth != null ) m_Plinth.Delete(); + + return true; } else { by.SendLocalizedMessage( 500720 ); // You don't have enough room in your backpack! deed.Delete(); + + return false; } } @@ -602,6 +606,14 @@ namespace Server.Mobiles plinth.MoveToWorld( loc, map ); statue.InvalidatePose(); + /* + * TODO: Previously the maker wasn't deleted until after statue + * customization, leading to redeeding issues. Exact OSI behavior + * needs looking into. + */ + m_Maker.Delete(); + statue.Sculpt( from ); + from.CloseGump( typeof( CharacterStatueGump ) ); from.SendGump( new CharacterStatueGump( m_Maker, statue, from ) ); } diff --git a/Scripts/Engines/VeteranRewards/Character Statue Maker/Gumps/CharacterStatueGump.cs b/Scripts/Engines/VeteranRewards/Character Statue Maker/Gumps/CharacterStatueGump.cs index fc3748158..bfa81da8b 100644 --- a/Scripts/Engines/VeteranRewards/Character Statue Maker/Gumps/CharacterStatueGump.cs +++ b/Scripts/Engines/VeteranRewards/Character Statue Maker/Gumps/CharacterStatueGump.cs @@ -10,7 +10,6 @@ namespace Server.Gumps { private Item m_Maker; private CharacterStatue m_Statue; - private Timer m_Timer; private Mobile m_Owner; private enum Buttons @@ -81,20 +80,6 @@ namespace Server.Gumps AddButton( 107, 294, 0xFAB, 0xFAD, (int) Buttons.Restore, GumpButtonType.Reply, 0 ); AddHtmlLocalized( 142, 294, 80, 20, 1076193, 0x7FFF, false, false ); // Restore } - - m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 2.5 ), TimeSpan.FromSeconds( 2.5 ), new TimerCallback( CheckOnline ) ); - } - - private void CheckOnline() - { - if ( m_Owner != null && m_Owner.NetState == null ) - { - if ( m_Timer != null ) - m_Timer.Stop(); - - if ( m_Statue != null && !m_Statue.Deleted ) - m_Statue.Delete(); - } } private int GetMaterialNumber( StatueType type, StatueMaterial material ) @@ -141,7 +126,7 @@ namespace Server.Gumps public override void OnResponse( NetState state, RelayInfo info ) { - if ( m_Statue == null || m_Statue.Deleted || m_Maker == null || m_Maker.Deleted || !m_Maker.IsChildOf( state.Mobile.Backpack ) ) + if ( m_Statue == null || m_Statue.Deleted ) return; bool sendGump = false; @@ -205,25 +190,13 @@ namespace Server.Gumps sendGump = true; } - else + else // Close { - m_Statue.Delete(); + sendGump = !m_Statue.Demolish( state.Mobile ); } if ( sendGump ) state.Mobile.SendGump( new CharacterStatueGump( m_Maker, m_Statue, m_Owner ) ); - - if ( m_Timer != null ) - m_Timer.Stop(); - } - - public override void OnServerClose( NetState owner ) - { - if ( m_Timer != null ) - m_Timer.Stop(); - - if ( m_Statue != null && !m_Statue.Deleted ) - m_Statue.Delete(); } } } diff --git a/Scripts/Gumps/AdminGump.cs b/Scripts/Gumps/AdminGump.cs index 1a8f6fee1..f6b06cb0c 100644 --- a/Scripts/Gumps/AdminGump.cs +++ b/Scripts/Gumps/AdminGump.cs @@ -11,6 +11,7 @@ using Server.Network; using Server.Accounting; using Server.Commands; using Server.Multis; +using Server.Misc; namespace Server.Gumps { @@ -102,7 +103,7 @@ namespace Server.Gumps public int GetButtonID( int type, int index ) { - return 1 + (index * 10) + type; + return 1 + (index * 11) + type; } public static string FormatTimeSpan( TimeSpan ts ) @@ -979,35 +980,37 @@ namespace Server.Gumps AddHtml( 10, 195, 400, 20, Color( Center( "Client Addresses" ), LabelColor32 ), false, false ); - AddButtonLabeled( 200, 225, GetButtonID( 5, 16 ), "View all shared accounts" ); - AddButtonLabeled( 200, 245, GetButtonID( 5, 17 ), "Ban all shared accounts" ); - AddButtonLabeled( 200, 265, GetButtonID( 5, 18 ), "Firewall all addresses" ); + AddButtonLabeled( 227, 225, GetButtonID( 5, 16 ), "View all shared accounts" ); + AddButtonLabeled( 227, 245, GetButtonID( 5, 17 ), "Ban all shared accounts" ); + AddButtonLabeled( 227, 265, GetButtonID( 5, 18 ), "Firewall all addresses" ); + AddButtonLabeled( 227, 285, GetButtonID( 5, 34 ), "Clear all addresses" ); - AddHtml( 195, 295, 210, 80, Color( "List of IP addresses which have accessed this account.", LabelColor32 ), false, false ); + AddHtml( 225, 315, 180, 80, Color( "List of IP addresses which have accessed this account.", LabelColor32 ), false, false ); - AddImageTiled( 15, 219, 176, 156, 0xBBC ); - AddBlackAlpha( 16, 220, 174, 154 ); + AddImageTiled( 15, 219, 206, 156, 0xBBC ); + AddBlackAlpha( 16, 220, 204, 154 ); AddHtml( 18, 221, 114, 20, Color( "IP Address", LabelColor32 ), false, false ); if ( listPage > 0 ) - AddButton( 154, 223, 0x15E3, 0x15E7, GetButtonID( 1, 0 ), GumpButtonType.Reply, 0 ); + AddButton( 184, 223, 0x15E3, 0x15E7, GetButtonID( 1, 0 ), GumpButtonType.Reply, 0 ); else - AddImage( 154, 223, 0x25EA ); + AddImage( 184, 223, 0x25EA ); if ( (listPage + 1) * 6 < m_List.Count ) - AddButton( 171, 223, 0x15E1, 0x15E5, GetButtonID( 1, 1 ), GumpButtonType.Reply, 0 ); + AddButton( 201, 223, 0x15E1, 0x15E5, GetButtonID( 1, 1 ), GumpButtonType.Reply, 0 ); else - AddImage( 171, 223, 0x25E6 ); + AddImage( 201, 223, 0x25E6 ); if ( m_List.Count == 0 ) - AddHtml( 18, 243, 170, 60, Color( "This account has not yet been accessed.", LabelColor32 ), false, false ); + AddHtml( 18, 243, 200, 60, Color( "This account has not yet been accessed.", LabelColor32 ), false, false ); for ( int i = 0, index = (listPage * 6); i < 6 && index >= 0 && index < m_List.Count; ++i, ++index ) { AddHtml( 18, 243 + (i * 22), 114, 20, Color( m_List[index].ToString(), LabelColor32 ), false, false ); AddButton( 130, 242 + (i * 22), 0xFA2, 0xFA4, GetButtonID( 8, index ), GumpButtonType.Reply, 0 ); AddButton( 160, 242 + (i * 22), 0xFA8, 0xFAA, GetButtonID( 9, index ), GumpButtonType.Reply, 0 ); + AddButton( 190, 242 + (i * 22), 0xFB1, 0xFB3, GetButtonID( 10, index ), GumpButtonType.Reply, 0 ); } goto case AdminGumpPage.AccountDetails_Access; @@ -1024,34 +1027,34 @@ namespace Server.Gumps AddHtml( 10, 195, 400, 20, Color( Center( "Address Restrictions" ), LabelColor32 ), false, false ); - AddTextField( 200, 225, 120, 20, 0 ); + AddTextField( 227, 225, 120, 20, 0 ); - AddButtonLabeled( 330, 225, GetButtonID( 5, 19 ), "Add" ); + AddButtonLabeled( 352, 225, GetButtonID( 5, 19 ), "Add" ); - AddHtml( 195, 255, 210, 120, Color( "Any clients connecting from an address not in this list will be rejected. Or, if the list is empty, any client may connect.", LabelColor32 ), false, false ); + AddHtml( 225, 255, 180, 120, Color( "Any clients connecting from an address not in this list will be rejected. Or, if the list is empty, any client may connect.", LabelColor32 ), false, false ); - AddImageTiled( 15, 219, 176, 156, 0xBBC ); - AddBlackAlpha( 16, 220, 174, 154 ); + AddImageTiled( 15, 219, 206, 156, 0xBBC ); + AddBlackAlpha( 16, 220, 204, 154 ); AddHtml( 18, 221, 114, 20, Color( "IP Address", LabelColor32 ), false, false ); if ( listPage > 0 ) - AddButton( 154, 223, 0x15E3, 0x15E7, GetButtonID( 1, 0 ), GumpButtonType.Reply, 0 ); + AddButton( 184, 223, 0x15E3, 0x15E7, GetButtonID( 1, 0 ), GumpButtonType.Reply, 0 ); else - AddImage( 154, 223, 0x25EA ); + AddImage( 184, 223, 0x25EA ); if ( (listPage + 1) * 6 < m_List.Count ) - AddButton( 171, 223, 0x15E1, 0x15E5, GetButtonID( 1, 1 ), GumpButtonType.Reply, 0 ); + AddButton( 201, 223, 0x15E1, 0x15E5, GetButtonID( 1, 1 ), GumpButtonType.Reply, 0 ); else - AddImage( 171, 223, 0x25E6 ); + AddImage( 201, 223, 0x25E6 ); if ( m_List.Count == 0 ) - AddHtml( 18, 243, 170, 60, Color( "There are no addresses in this list.", LabelColor32 ), false, false ); + AddHtml( 18, 243, 200, 60, Color( "There are no addresses in this list.", LabelColor32 ), false, false ); for ( int i = 0, index = (listPage * 6); i < 6 && index >= 0 && index < m_List.Count; ++i, ++index ) { AddHtml( 18, 243 + (i * 22), 114, 20, Color( m_List[index].ToString(), LabelColor32 ), false, false ); - AddButton( 160, 242 + (i * 22), 0xFB1, 0xFB3, GetButtonID( 8, index ), GumpButtonType.Reply, 0 ); + AddButton( 190, 242 + (i * 22), 0xFB1, 0xFB3, GetButtonID( 8, index ), GumpButtonType.Reply, 0 ); } goto case AdminGumpPage.AccountDetails_Access; @@ -1592,6 +1595,67 @@ namespace Server.Gumps from.SendGump( new AdminGump( from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, notice, a ) ); } + public static void RemoveLoginIP_Callback( Mobile from, bool okay, object state ) + { + if ( from.AccessLevel < AccessLevel.Administrator ) + return; + + object[] states = (object[])state; + + Account a = (Account)states[0]; + IPAddress ip = (IPAddress)states[1]; + + string notice; + + if ( okay ) + { + IPAddress[] ips = a.LoginIPs; + + if ( ips.Length != 0 && ip == ips[0] && AccountHandler.IPTable.ContainsKey( ips[0] ) ) + --AccountHandler.IPTable[ip]; + + List newList = new List( ips ); + newList.Remove( ip ); + a.LoginIPs = newList.ToArray(); + + notice = String.Format( "{0} : Removed address.", ip ); + } + else + { + notice = "You have chosen not to remove the address."; + } + + from.SendGump( new AdminGump( from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, notice, a ) ); + } + + public static void RemoveLoginIPs_Callback( Mobile from, bool okay, object state ) + { + if ( from.AccessLevel < AccessLevel.Administrator ) + return; + + Account a = (Account)state; + + string notice; + + if ( okay ) + { + IPAddress[] ips = a.LoginIPs; + + if ( ips.Length != 0 && AccountHandler.IPTable.ContainsKey( ips[0] ) ) + --AccountHandler.IPTable[ips[0]]; + + a.LoginIPs = new IPAddress[0]; + + notice = "All addresses in the list have been removed."; + } + else + { + notice = "You have chosen not to clear all addresses."; + } + + from.SendGump( new AdminGump( from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, notice, a ) ); + } + public override void OnResponse( Server.Network.NetState sender, RelayInfo info ) { int val = info.ButtonID - 1; @@ -1628,8 +1692,8 @@ namespace Server.Gumps } } - int type = val % 10; - int index = val / 10; + int type = val % 11; + int index = val / 11; switch ( type ) { @@ -2411,6 +2475,32 @@ namespace Server.Gumps break; } + case 34: // Clear login addresses + { + Account a = m_State as Account; + + if ( a == null ) + break; + + IPAddress[] ips = a.LoginIPs; + + if ( ips.Length == 0 ) + { + from.SendGump( new AdminGump( from, AdminGumpPage.AccountDetails_Access_ClientIPs, 0, null, "This account has not yet been accessed.", m_State ) ); + } + else + { + StringBuilder sb = new StringBuilder(); + sb.AppendFormat( "You are about to clear the address list for account {0}. Do you wish to continue?", a ); + + for ( int i = 0; i < ips.Length; ++i ) + sb.AppendFormat( "
- {0}", ips[i] ); + + from.SendGump( new WarningGump( 1060635, 30720, sb.ToString(), 0xFFC000, 420, 400, new WarningGumpCallback( RemoveLoginIPs_Callback ), a ) ); + } + + break; + } default: { index -= 50; @@ -2746,6 +2836,28 @@ namespace Server.Gumps } } + break; + } + case 10: + { + if ( m_List != null && index >= 0 && index < m_List.Count ) + { + if ( m_PageType == AdminGumpPage.AccountDetails_Access_ClientIPs ) + { + IPAddress ip = m_List[index] as IPAddress; + + if ( ip == null ) + break; + + Account a = m_State as Account; + + if ( a == null ) + break; + + from.SendGump( new WarningGump( 1060635, 30720, String.Format( "You are about to remove address {0} from account {1}. Do you wish to continue?", ip, a ), 0xFFC000, 420, 280, new WarningGumpCallback( RemoveLoginIP_Callback ), new object[] { a, ip } ) ); + } + } + break; } } diff --git a/Scripts/Items/Misc/Firebomb.cs b/Scripts/Items/Misc/Firebomb.cs index dc2a2bae6..326b631a3 100644 --- a/Scripts/Items/Misc/Firebomb.cs +++ b/Scripts/Items/Misc/Firebomb.cs @@ -11,6 +11,7 @@ namespace Server.Items private Timer m_Timer; private int m_Ticks = 0; private Mobile m_LitBy; + private List m_Users; [Constructable] public Firebomb() : this( 0x99B ) @@ -53,21 +54,27 @@ namespace Server.Items if ( Core.AOS && (from.Paralyzed || from.Frozen || (from.Spell != null && from.Spell.IsCasting)) ) { - //to prevent exploiting for pvp - from.SendLocalizedMessage( 1075857 ); // You can not use that while paralyzed. + // to prevent exploiting for pvp + from.SendLocalizedMessage( 1075857 ); // You cannot use that while paralyzed. return; - } + } if ( m_Timer == null ) { m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 1 ), TimeSpan.FromSeconds( 1 ), new TimerCallback( OnFirebombTimerTick ) ); m_LitBy = from; - from.SendLocalizedMessage( 1060581 ); //You light the firebomb! Throw it now! + from.SendLocalizedMessage( 1060582 ); // You light the firebomb. Throw it now! } else - from.SendLocalizedMessage( 1060582 ); //You've already lit it! Better throw it now! + from.SendLocalizedMessage( 1060581 ); // You've already lit it! Better throw it now! - from.BeginTarget( 12, true, TargetFlags.None, new TargetCallback( OnFirebombTarget ) ); + if ( m_Users == null ) + m_Users = new List(); + + if ( !m_Users.Contains( from ) ) + m_Users.Add( from ); + + from.Target = new ThrowTarget( this ); } private void OnFirebombTimerTick() @@ -103,10 +110,24 @@ namespace Server.Items if ( HeldBy != null ) HeldBy.DropHolding(); + if ( m_Users != null ) + { + foreach ( Mobile m in m_Users ) + { + ThrowTarget targ = m.Target as ThrowTarget; + + if ( targ != null && targ.Bomb == this ) + Target.Cancel( m ); + } + + m_Users.Clear(); + m_Users = null; + } + if ( RootParent is Mobile ) { Mobile parent = (Mobile)RootParent; - parent.SendLocalizedMessage( 1060583 ); //The firebomb explodes in your hand! + parent.SendLocalizedMessage( 1060583 ); // The firebomb explodes in your hand! AOS.Damage( parent, Utility.Random( 3 ) + 4, 0, 100, 0, 0, 0 ); } else if ( RootParent == null ) @@ -181,6 +202,27 @@ namespace Server.Items MoveToWorld( new Point3D( p ), map ); } + + private class ThrowTarget : Target + { + private Firebomb m_Bomb; + + public Firebomb Bomb + { + get { return m_Bomb; } + } + + public ThrowTarget( Firebomb bomb ) + : base( 12, true, TargetFlags.None ) + { + m_Bomb = bomb; + } + + protected override void OnTarget( Mobile from, object targeted ) + { + m_Bomb.OnFirebombTarget( from, targeted ); + } + } } public class FirebombField : Item @@ -205,7 +247,7 @@ namespace Server.Items public override void Serialize( GenericWriter writer ) { - //Don't serialize these... + // Don't serialize these... } public override void Deserialize( GenericReader reader ) diff --git a/Scripts/Items/Misc/OilCloth.cs b/Scripts/Items/Misc/OilCloth.cs index 8f091bcab..aa38fe414 100644 --- a/Scripts/Items/Misc/OilCloth.cs +++ b/Scripts/Items/Misc/OilCloth.cs @@ -61,15 +61,15 @@ namespace Server.Items { from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it. } + else if ( obj is Item && ((Item)obj).RootParent != from ) + { + from.SendLocalizedMessage( 1005425 ); // You may only wipe down items you are holding or carrying. + } else if ( obj is BaseWeapon ) { BaseWeapon weapon = (BaseWeapon)obj; - if ( weapon.RootParent != from ) - { - from.SendLocalizedMessage( 1005425 ); // You may only wipe down items you are holding or carrying. - } - else if ( weapon.Poison == null || weapon.PoisonCharges <= 0 ) + if ( weapon.Poison == null || weapon.PoisonCharges <= 0 ) { from.LocalOverheadMessage( Network.MessageType.Regular, 0x3B2, 1005422 ); // Hmmmm... this does not need to be cleaned. } @@ -106,7 +106,7 @@ namespace Server.Items from.LocalOverheadMessage( Network.MessageType.Regular, 0x3B2, 1005422 ); // Hmmmm... this does not need to be cleaned. } } -//Added for Firebomb + #region Firebomb else if ( obj is BaseBeverage ) { BaseBeverage beverage = (BaseBeverage) obj; @@ -115,11 +115,9 @@ namespace Server.Items { Firebomb bomb = new Firebomb( beverage.ItemID ); bomb.Name = beverage.Name; - Point3D loc = beverage.Location; - beverage.Delete(); - from.AddToBackpack( bomb ); - bomb.Location = loc; + beverage.ReplaceWith( bomb ); + from.SendLocalizedMessage( 1060580 ); // You prepare a firebomb. Consume(); } @@ -128,7 +126,7 @@ namespace Server.Items { from.SendLocalizedMessage( 1060579 ); // That is already a firebomb! } -//Firebomb end + #endregion else { from.SendLocalizedMessage( 1005426 ); // The cloth will not work on that. diff --git a/Scripts/Items/Misc/Teleporter.cs b/Scripts/Items/Misc/Teleporter.cs index e3ecf1aad..fee425095 100644 --- a/Scripts/Items/Misc/Teleporter.cs +++ b/Scripts/Items/Misc/Teleporter.cs @@ -8,7 +8,7 @@ namespace Server.Items { public class Teleporter : Item { - private bool m_Active, m_Creatures, m_CombatCheck; + private bool m_Active, m_Creatures, m_CombatCheck, m_CriminalCheck; private Point3D m_PointDest; private Map m_MapDest; private bool m_SourceEffect; @@ -79,6 +79,13 @@ namespace Server.Items set { m_CombatCheck = value; InvalidateProperties(); } } + [CommandProperty( AccessLevel.GameMaster )] + public bool CriminalCheck + { + get { return m_CriminalCheck; } + set { m_CriminalCheck = value; InvalidateProperties(); } + } + public override int LabelNumber{ get{ return 1026095; } } // teleporter [Constructable] @@ -103,6 +110,7 @@ namespace Server.Items m_Creatures = creatures; m_CombatCheck = false; + m_CriminalCheck = false; } public override void GetProperties( ObjectPropertyList list ) @@ -183,7 +191,14 @@ namespace Server.Items if ( m_Active ) { if ( !m_Creatures && !m.Player ) + { return true; + } + else if ( m_CriminalCheck && m.Criminal ) + { + m.SendLocalizedMessage( 1005561, "", 0x22 ); // Thou'rt a criminal and cannot escape so easily. + return true; + } else if ( m_CombatCheck && SpellHelper.CheckCombat( m ) ) { m.SendLocalizedMessage( 1005564, "", 0x22 ); // Wouldst thou flee during the heat of battle?? @@ -205,8 +220,9 @@ namespace Server.Items { base.Serialize( writer ); - writer.Write( (int) 3 ); // version + writer.Write( (int) 4 ); // version + writer.Write( (bool) m_CriminalCheck ); writer.Write( (bool) m_CombatCheck ); writer.Write( (bool) m_SourceEffect ); @@ -229,6 +245,11 @@ namespace Server.Items switch ( version ) { + case 4: + { + m_CriminalCheck = reader.ReadBool(); + goto case 3; + } case 3: { m_CombatCheck = reader.ReadBool(); diff --git a/Scripts/Items/Skill Items/Fishing/Misc/MessageInABottle.cs b/Scripts/Items/Skill Items/Fishing/Misc/MessageInABottle.cs index b7feacfe7..c6ca20d41 100644 --- a/Scripts/Items/Skill Items/Fishing/Misc/MessageInABottle.cs +++ b/Scripts/Items/Skill Items/Fishing/Misc/MessageInABottle.cs @@ -102,8 +102,7 @@ namespace Server.Items { if ( IsChildOf( from.Backpack ) ) { - Consume(); - from.AddToBackpack( new SOS( m_TargetMap, m_Level ) ); + ReplaceWith( new SOS( m_TargetMap, m_Level ) ); from.LocalOverheadMessage( Network.MessageType.Regular, 0x3B2, 501891 ); // You extract the message from the bottle. } else diff --git a/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs b/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs index b73e5206f..a701670f1 100644 --- a/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs +++ b/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs @@ -4,6 +4,7 @@ using Server.Gumps; namespace Server.Items { + [Flipable( 0x14ED, 0x14EE )] public class SOS : Item { public override int LabelNumber @@ -80,7 +81,7 @@ namespace Server.Items } [Constructable] - public SOS( Map map, int level ) : base( 0x14ED ) + public SOS( Map map, int level ) : base( 0x14EE ) { Weight = 1.0; @@ -167,7 +168,7 @@ namespace Server.Items else entry = MessageEntry.Entries[m_MessageIndex = Utility.Random( MessageEntry.Entries.Length )]; - from.CloseGump( typeof( MessageGump ) ); + //from.CloseGump( typeof( MessageGump ) ); from.SendGump( new MessageGump( entry, m_TargetMap, m_TargetLocation ) ); } else diff --git a/Scripts/Items/Weapons/ML Weapons/Leafblade.cs b/Scripts/Items/Weapons/ML Weapons/Leafblade.cs index 428a39512..165b57bb6 100644 --- a/Scripts/Items/Weapons/ML Weapons/Leafblade.cs +++ b/Scripts/Items/Weapons/ML Weapons/Leafblade.cs @@ -22,6 +22,7 @@ namespace Server.Items public override int OldSpeed{ get{ return 42; } } public override int DefMissSound{ get{ return 0x239; } } + public override SkillName DefSkill { get { return SkillName.Fencing; } } public override int InitMinHits{ get{ return 30; } } // TODO public override int InitMaxHits{ get{ return 60; } } // TODO diff --git a/Scripts/Mobiles/Monsters/LBR/Meers/MeerMage.cs b/Scripts/Mobiles/Monsters/LBR/Meers/MeerMage.cs index c9b5b4191..e0c4df685 100644 --- a/Scripts/Mobiles/Monsters/LBR/Meers/MeerMage.cs +++ b/Scripts/Mobiles/Monsters/LBR/Meers/MeerMage.cs @@ -96,7 +96,7 @@ namespace Server.Mobiles { if ( bc.ControlMaster.Map == this.Map && bc.ControlMaster.InRange( this, 12 ) && !UnderEffect( bc.ControlMaster ) ) { - combatant = bc.ControlMaster; + Combatant = combatant = bc.ControlMaster; } } } @@ -112,7 +112,15 @@ namespace Server.Mobiles for( int i=0; i<5; i++ ) { - switch( i ) + int x = combatant.X + coord[i][0]; + int y = combatant.Y + coord[i][1]; + + Point3D loc = new Point3D( x, y, combatant.Map.GetAverageZ( x, y ) ); + + if ( !combatant.Map.CanSpawnMobile( loc ) ) + continue; + + switch ( i ) { case 0: rabid = new EnragedRabbit( this ); break; case 1: rabid = new EnragedHind( this ); break; @@ -122,29 +130,11 @@ namespace Server.Mobiles } rabid.FocusMob = combatant; - - int x = combatant.X + coord[i][0]; - int y = combatant.Y + coord[i][1]; - - /* - Once in a while OSI's dont spawn all 5, and - I can only attribute this to a bad spawn location - so I will do this. - */ - - Point3D loc = new Point3D( x, y, combatant.Map.GetAverageZ( x, y )); - if ( combatant.Map.CanSpawnMobile( loc ) ) - { - rabid.MoveToWorld( loc, combatant.Map ) ; - } - else - { - rabid.Delete(); - } + rabid.MoveToWorld( loc, combatant.Map ); } this.Say( 1071932 ); //Creatures of the forest, I call to thee! Aid me in the fight against all that is evil! } - else + else if ( combatant.Player ) { this.Say( true, "I call a plague of insects to sting your flesh!" ); m_Table[combatant] = Timer.DelayCall( TimeSpan.FromSeconds( 0.5 ), TimeSpan.FromSeconds( 7.0 ), new TimerStateCallback( DoEffect ), new object[]{ combatant, 0 } ); diff --git a/Scripts/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs b/Scripts/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs index 1a66de10d..c285fa5d4 100644 --- a/Scripts/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs +++ b/Scripts/Mobiles/Monsters/ML/Humanoid/Melee/CorruptedSoul.cs @@ -37,7 +37,7 @@ namespace Server.Mobiles SetResistance( ResistanceType.Energy, 51, 60 ); SetSkill( SkillName.MagicResist, 80.2, 89.4 ); - SetSkill( SkillName.Tactics, 81.3-89.9 ); + SetSkill( SkillName.Tactics, 81.3, 89.9 ); SetSkill( SkillName.Wrestling, 80.1, 88.7 ); Fame = 5000; diff --git a/Scripts/Skills/AnimalTaming.cs b/Scripts/Skills/AnimalTaming.cs index bd0ace671..a2797b1a9 100644 --- a/Scripts/Skills/AnimalTaming.cs +++ b/Scripts/Skills/AnimalTaming.cs @@ -203,7 +203,8 @@ namespace Server.SkillHandlers creature.BardPacified = false; - creature.Move( creature.Direction ); + if ( creature.AIObject != null ) + creature.AIObject.DoMove( creature.Direction ); if ( from is PlayerMobile && !(( (PlayerMobile)from ).HonorActive || TransformationSpellHelper.UnderTransformation( from, typeof( EtherealVoyageSpell )))) creature.Combatant = from; diff --git a/Scripts/Spells/Ninjitsu/ShadowJump.cs b/Scripts/Spells/Ninjitsu/ShadowJump.cs index 5ebdc8e64..1d327fde7 100644 --- a/Scripts/Spells/Ninjitsu/ShadowJump.cs +++ b/Scripts/Spells/Ninjitsu/ShadowJump.cs @@ -3,6 +3,7 @@ using System.Collections; using Server.Network; using Server.Items; using Server.Mobiles; +using Server.Regions; using Server.Targeting; namespace Server.Spells.Ninjitsu @@ -55,7 +56,10 @@ namespace Server.Spells.Ninjitsu Map map = Caster.Map; SpellHelper.GetSurfaceTop( ref p ); - + + Point3D from = Caster.Location; + Point3D to = new Point3D( p ); + PlayerMobile pm = Caster as PlayerMobile; // IsStealthing should be moved to Server.Mobiles if ( !pm.IsStealthing ) @@ -70,26 +74,27 @@ namespace Server.Spells.Ninjitsu { Caster.SendLocalizedMessage( 502359, "", 0x22 ); // Thou art too encumbered to move. } - else if ( !SpellHelper.CheckTravel( Caster, TravelCheckType.TeleportFrom ) || !SpellHelper.CheckTravel( Caster, map, new Point3D( p ), TravelCheckType.TeleportTo )) + else if ( !SpellHelper.CheckTravel( Caster, TravelCheckType.TeleportFrom ) || !SpellHelper.CheckTravel( Caster, map, to, TravelCheckType.TeleportTo )) { } else if ( map == null || !map.CanSpawnMobile( p.X, p.Y, p.Z ) ) { Caster.SendLocalizedMessage( 502831 ); // Cannot teleport to that spot. } - else if ( SpellHelper.CheckMulti( new Point3D( p ), map, true, 5 ) ) + else if ( SpellHelper.CheckMulti( to, map, true, 5 ) ) { Caster.SendLocalizedMessage( 502831 ); // Cannot teleport to that spot. } + else if ( Region.Find( to, map ).GetRegion( typeof( HouseRegion ) ) != null ) + { + Caster.SendLocalizedMessage( 502829 ); // Cannot teleport to that spot. + } else if ( CheckSequence() ) { SpellHelper.Turn( Caster, orig ); Mobile m = Caster; - Point3D from = m.Location; - Point3D to = new Point3D( p ); - m.Location = to; m.ProcessDelta(); diff --git a/Scripts/Spells/Third/Teleport.cs b/Scripts/Spells/Third/Teleport.cs index c80291e94..ce6733415 100644 --- a/Scripts/Spells/Third/Teleport.cs +++ b/Scripts/Spells/Third/Teleport.cs @@ -50,6 +50,9 @@ namespace Server.Spells.Third SpellHelper.GetSurfaceTop( ref p ); + Point3D from = Caster.Location; + Point3D to = new Point3D( p ); + if ( Factions.Sigil.ExistsOn( Caster ) ) { Caster.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil. @@ -61,16 +64,20 @@ namespace Server.Spells.Third else if ( !SpellHelper.CheckTravel( Caster, TravelCheckType.TeleportFrom ) ) { } - else if ( !SpellHelper.CheckTravel( Caster, map, new Point3D( p ), TravelCheckType.TeleportTo ) ) + else if ( !SpellHelper.CheckTravel( Caster, map, to, TravelCheckType.TeleportTo ) ) { } else if ( map == null || !map.CanSpawnMobile( p.X, p.Y, p.Z ) ) { Caster.SendLocalizedMessage( 501942 ); // That location is blocked. } - else if ( SpellHelper.CheckMulti( new Point3D( p ), map ) ) + else if ( SpellHelper.CheckMulti( to, map ) ) { - Caster.SendLocalizedMessage( 501942 ); // That location is blocked. + Caster.SendLocalizedMessage( 502831 ); // Cannot teleport to that spot. + } + else if ( Region.Find( to, map ).GetRegion( typeof( HouseRegion ) ) != null ) + { + Caster.SendLocalizedMessage( 502829 ); // Cannot teleport to that spot. } else if ( CheckSequence() ) { @@ -78,9 +85,6 @@ namespace Server.Spells.Third Mobile m = Caster; - Point3D from = m.Location; - Point3D to = new Point3D( p ); - m.Location = to; m.ProcessDelta(); diff --git a/Server/Item.cs b/Server/Item.cs index 16d709070..8c3e72e39 100644 --- a/Server/Item.cs +++ b/Server/Item.cs @@ -4533,6 +4533,21 @@ namespace Server this.Delete(); } + public virtual void ReplaceWith( Item newItem ) + { + if ( m_Parent is Container ) + { + ((Container)m_Parent).AddItem( newItem ); + newItem.Location = m_Location; + } + else + { + newItem.MoveToWorld( GetWorldLocation(), m_Map ); + } + + Delete(); + } + [CommandProperty( AccessLevel.GameMaster )] public bool QuestItem { diff --git a/Server/Map.cs b/Server/Map.cs index d3d46215e..06ec72bfd 100644 --- a/Server/Map.cs +++ b/Server/Map.cs @@ -1895,12 +1895,13 @@ namespace Server for( int i = 0; i < pathCount; ++i ) { Point3D point = path[i]; + int pointTop = point.m_Z + 1; LandTile landTile = Tiles.GetLandTile( point.X, point.Y ); int landZ = 0, landAvg = 0, landTop = 0; GetAverageZ( point.m_X, point.m_Y, ref landZ, ref landAvg, ref landTop ); - if( landZ <= point.m_Z && landTop >= point.m_Z && (point.m_X != end.m_X || point.m_Y != end.m_Y || landZ > end.m_Z || landTop < end.m_Z) && !landTile.Ignored ) + if( landZ <= pointTop && landTop >= point.m_Z && (point.m_X != end.m_X || point.m_Y != end.m_Y || landZ > end.m_Z || landTop < end.m_Z) && !landTile.Ignored ) return false; /* --Do land tiles need to be checked? There is never land between two people, always statics.-- @@ -1945,7 +1946,7 @@ namespace Server flags = id.Flags; height = id.CalcHeight; - if( t.Z <= point.Z && t.Z + height >= point.Z && (flags & (TileFlag.Window | TileFlag.NoShoot)) != 0 ) + if( t.Z <= pointTop && t.Z + height >= point.Z && (flags & (TileFlag.Window | TileFlag.NoShoot)) != 0 ) { if( point.m_X == end.m_X && point.m_Y == end.m_Y && t.Z <= end.m_Z && t.Z + height >= end.m_Z ) continue; @@ -1990,11 +1991,12 @@ namespace Server for( int j = 0; j < count; ++j ) { Point3D point = path[j]; + int pointTop = point.m_Z + 1; Point3D loc = i.Location; //if ( t.Z <= point.Z && t.Z+height >= point.Z && ( height != 0 || ( t.Z == dest.Z && zd != 0 ) ) ) if( loc.m_X == point.m_X && loc.m_Y == point.m_Y && - loc.m_Z <= point.m_Z && loc.m_Z + height >= point.m_Z ) + loc.m_Z <= pointTop && loc.m_Z + height >= point.m_Z ) { if( loc.m_X == end.m_X && loc.m_Y == end.m_Y && loc.m_Z <= end.m_Z && loc.m_Z + height >= end.m_Z ) continue; diff --git a/Server/Mobile.cs b/Server/Mobile.cs index 35795eaff..dc5e0279c 100644 --- a/Server/Mobile.cs +++ b/Server/Mobile.cs @@ -1673,6 +1673,7 @@ namespace Server if( m_Paralyzed != value ) { m_Paralyzed = value; + Delta( MobileDelta.Flags ); this.SendLocalizedMessage( m_Paralyzed ? 502381 : 502382 ); @@ -1725,6 +1726,7 @@ namespace Server if( m_Frozen != value ) { m_Frozen = value; + Delta( MobileDelta.Flags ); if( m_FrozenTimer != null ) { @@ -1750,7 +1752,7 @@ namespace Server { if( !m_Frozen ) { - m_Frozen = true; + Frozen = true; m_FrozenTimer = new FrozenTimer( this, duration ); m_FrozenTimer.Start(); @@ -7803,6 +7805,9 @@ namespace Server { int flags = 0x0; + if( m_Paralyzed || m_Frozen ) + flags |= 0x01; + if( m_Female ) flags |= 0x02; @@ -7826,6 +7831,9 @@ namespace Server { int flags = 0x0; + if( m_Paralyzed || m_Frozen ) + flags |= 0x01; + if( m_Female ) flags |= 0x02;